How to stop a timer when mouse is scrolling or on top of scrollbar in listbox - vb.net

I'm looking for a way to detect and switch off a timer when the mouse cursor is scrolling a listbox.
There is an easy way despite to create a new class like this one?link
Would be possible to check rectangle location of listbox 1 scroll bar and say: if mouse is in this range then timer1.stop?
EDIT1:
In order to create a rectangle I'm using
If e.X >= 364 AndAlso e.X <= 446 AndAlso e.Y >= 86 AndAlso e.Y <= 144 Then
MessageBox.Show("Clicked within the rectangle")
Else
MessageBox.Show("Clicked outside the rectangle")
End If
449-359 are the Top left corner location of the rectangle
while the rectangle size is x30 y156
The problem is I don't know in which event let it run!
Listbox click event doesn't recognize scrollbar as "inside of listbox"
Form_mouse click event doesn't recognize listbox scroll bar as a click in the form.
There is an event that despite the control you are on, it will let you play with this workaround?
Thanks

Here is what I posted on MSDN using this C# code. There is no code presented below that will restart the Timer.
Public Class BetterListBox
Inherits ListBox
' Event declaration
Public Delegate Sub BetterListBoxScrollDelegate(ByVal Sender As Object, ByVal e As BetterListBoxScrollArgs)
Public Event Scroll As BetterListBoxScrollDelegate
' WM_VSCROLL message constants
Private Const WM_VSCROLL As Integer = &H115
Private Const SB_THUMBTRACK As Integer = 5
Private Const SB_ENDSCROLL As Integer = 8
Protected Overrides Sub WndProc(ByRef m As Message)
' Trap the WM_VSCROLL message to generate the Scroll event
MyBase.WndProc(m)
If m.Msg = WM_VSCROLL Then
Dim nfy As Integer = m.WParam.ToInt32() And &HFFFF
If (nfy = SB_THUMBTRACK OrElse nfy = SB_ENDSCROLL) Then
RaiseEvent Scroll(Me, New BetterListBoxScrollArgs(Me.TopIndex, nfy = SB_THUMBTRACK))
End If
End If
End Sub
Public Class BetterListBoxScrollArgs
' Scroll event argument
Private mTop As Integer
Private mTracking As Boolean
Public Sub New(ByVal top As Integer, ByVal tracking As Boolean)
mTop = top
mTracking = tracking
End Sub
Public ReadOnly Property Top() As Integer
Get
Return mTop
End Get
End Property
Public ReadOnly Property Tracking() As Boolean
Get
Return mTracking
End Get
End Property
End Class
End Class
Then in your form subscribe to the Scroll event. Requires the ListBox above in your project, one Timer enabled and a Label.
Private Sub BetterListBox1_Scroll(Sender As Object, e As BetterListBox.BetterListBoxScrollArgs) _
Handles BetterListBox1.Scroll
Timer1.Enabled = False
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
Label1.Text = Now.ToString()
End Sub

Related

How to raise click event of a panel by clicking on its controls in Vb.net

I've a custom TableLayoutPanel:
Public Class CustomTLP
Inherits TableLayoutPanel
Private labelText As Label = New Label()
Public Sub New([variousParam])
[...]
labelText.Text = "Hello Dolly!"
Me.Controls.Add(labelText, 0, 0)
End Sub
End Class
And, in another class, I create a new CustomTLP and its mouse click handler
Dim w As CustomTLP = New CustomTLP (Me, dName)
aFlowLayout.Controls.Add(w)
AddHandler w.MouseClick, AddressOf Me.ABeautifulOperation
The problem is that when i click on the CustomTLP label, the handler doesn't detect the event.
The only solution that came to my mind is to set ABeautifulOperation as public and call it from a label-click handler, but I don't think is an elegant solution... Is there a way to raise the clickevent of the panel? Something like this ( in CustomTLP):
AddHandler labelText.Click, AddressOf labelClicked
[...]
Private Sub labelClicked(sender As Object, e As EventArgs)
' Raise Me.MouseClick
End Sub
As suggested by GSerg, just call the base OnClick() method when your Label is clicked:
Private Sub labelClicked(sender As Object, e As EventArgs)
Me.OnClick(e)
End Sub
Here's a VB version of the Custom Label that will ignore mouse events, thus allowing the parent control to handle them:
Public Class CustomLabel
Inherits Label
Protected Overrides Sub WndProc(ByRef m As Message)
Const WM_NCHITTEST As Integer = &H84
Const HTTRANSPARENT As Integer = (-1)
If m.Msg = WM_NCHITTEST Then
m.Result = New IntPtr(HTTRANSPARENT)
Else
MyBase.WndProc(m)
End If
End Sub
End Class

Mimic an IR remote Volume Button

I have a small media player application I've programmed which works really well.
I've even managed an on screen remote control (obviously just a Form with Buttons made to look like a virtual remote control) and yes I've also integrated an Arduino to be able to use a real remote control, but forget the Arduino remote control just for now my question is about the Virtual remote control I'm trying to build.
Programming a Button is quite elementary: it's one of the first things we learn in Vb.net, but that's just in a single click scenario.
If I look at a real TV remote, I can either click (most common with volume buttons) the volume up or down and the response is either that the volume goes up or down by one unit, or I can hold the same button down and it repeats the process changing the unit several times up or down depending on how long before I release the button again.
How would I achieve this?
I have tried googling this but everything I get back as a search result talks about a physical mouse button as apposed to what I need which is a Button control.
An example of an UserControl that provides the functionality of Up/Down spin buttons.
It uses two standard Buttons, a Label and a Timer.
To set it up, add a new UserControl to the Project:
Set its BackColor to Color.Transparent
Add two Buttons, select both and add event handlers to the MouseDown, MouseUp, KeyDown and KeyUp events (selecting both, you'll add 4 method)
Two Unicode chars (U+25B2 and U+25BC) are used to show the arrows. Setup the Buttons' Font size and Color as required (the sample UC uses Segoe UI as Font).
Anchor the upper Button to Left/Top/Right
Anchor the lower Button to Left/Bottom/Right
Anchor the Label to Left/Right
A Timer is created in the UC constructor, its Interval value set to 300. This value represents the initial speed of the increment when a mouse Button or keyboard key is held down. It's decremented each time the Timer ticks until it reaches a threshold defined by the UC's Speed public property (which is internally limited to the (1:10) range).
The maximum and minimum increment are defined by the UC's Min and Max public properties
The Value public property gets or sets the current increment.
The Timer is started when a Mouse Button or a Keyboard key are pressed and stopped when they're released. When the Timer.Tick event is raised, the Timer.Interval is decreased by 25ms until the max Speed value is reached. Since the initial value is set to 300ms and the maximum Speed is limited to 10, the minimum Interval value is 50ms, which is close to the System.Windows.Form.Timer official resolution.
The minimum Interval needs to be considered if these values are changed, to avoid overlapping Tick events.
This is how it works:
Imports System.Windows.Forms
Public Class SpinButtons
Private buttonsTimer As Timer = Nothing
Private timerThrottle As Integer = 0
Private timerIncrement As Integer = 0
Private m_Speed As Integer = 10
Private m_Value As Integer = 0
Public Sub New()
InitializeComponent()
Me.components = New System.ComponentModel.Container()
buttonsTimer = New Timer With {.Interval = 300}
Me.components.Add(buttonsTimer)
End Sub
Public Property Max As Integer = 100
Public Property Min As Integer = 0
Public Property Speed As Integer
Get
Return m_Speed
End Get
Set
m_Speed = Math.Max(Math.Min(Value, 10), 1)
End Set
End Property
Public Property Value As Integer
Get
Return m_Value
End Get
Set
m_Value = Value
SetIncrementValue()
End Set
End Property
Private Sub buttonsTimer_Tick(sender As Object, e As EventArgs)
SetIncrementValue()
If timerThrottle <= m_Speed Then
timerThrottle += 1
buttonsTimer.Interval -= 25
End If
End Sub
Private Sub btnUp_MouseDown(sender As Object, e As MouseEventArgs) Handles btnUp.MouseDown, btnDown.MouseDown
ButtonPressed(DirectCast(sender, Button))
SetIncrementValue()
End Sub
Private Sub btnUp_MouseUp(sender As Object, e As MouseEventArgs) Handles btnUp.MouseUp, btnDown.MouseUp
ButtonReleased(DirectCast(sender, Button))
End Sub
Private Sub btnUp_KeyDown(sender As Object, e As KeyEventArgs) Handles btnUp.KeyDown, btnDown.KeyDown
ButtonPressed(DirectCast(sender, Button))
SetIncrementValue()
End Sub
Private Sub btnUp_KeyUp(sender As Object, e As KeyEventArgs) Handles btnUp.KeyUp, btnDown.KeyUp
ButtonReleased(DirectCast(sender, Button))
End Sub
Private Sub SetIncrementValue()
m_Value += timerIncrement
m_Value = Math.Max(Math.Min(m_Value, Max), Min)
lblCounter.Text = m_Value.ToString()
End Sub
Private Sub ButtonPressed(btn As Button)
btn.ForeColor = Color.LawnGreen
timerIncrement = If(btn Is btnUp, 1, -1)
buttonsTimer.Enabled = True
End Sub
Private Sub ButtonReleased(btn As Button)
buttonsTimer.Enabled = False
buttonsTimer.Interval = 300
timerThrottle = 0
timerIncrement = 0
btn.ForeColor = Color.White
End Sub
Protected Overrides Sub OnFontChanged(e As EventArgs)
MyBase.OnFontChanged(e)
Me.btnUp.Font = Me.Font
Me.btnDown.Font = Me.Font
End Sub
Protected Overrides Sub OnResize(e As EventArgs)
MyBase.OnResize(e)
Me.MinimumSize = New Size(CInt(Me.Font.Size * 2), Me.btnUp.Height + Me.btnDown.Height + lblCounter.Height)
End Sub
End Class

How do I code out with numeric keypads with multi textboxes?

I'm trying to code out a programme where the user sees a form and in that form, there are 2 text boxes and 10 buttons.
Username:
Password:
1 2 3
4 5 6
7 8 9
0
I've tried this code
Private Sub Btn1_Click(sender As Object, e As EventArgs) Handles Btn1.Click
If UsernameTextbox.Focused = True Then
UsernameTextbox.Text = UsernameTextbox.Text + "1"
End If
End Sub
I understand that clicking on Btn1 will steal the focus from the text box. So how can I write the programme?
One option would be to declare a variable of type Control and, in the Leave event handler for each control, assign the sender to that variable. You can then use that variable in the Click event handler of your Button to determine which control had focus and possibly reassign back to that control and then update it appropriately. You can do the lot with two event handlers, e.g.
Private previouslyActiveTextBox As TextBox
Private Sub TextBoxes_Leave(sender As Object, e As EventArgs) Handles TextBox2.Leave,
TextBox1.Leave
previouslyActiveTextBox = DirectCast(sender, TextBox)
End Sub
Private Sub Buttons_Click(sender As Object, e As EventArgs) Handles Button3.Click,
Button2.Click,
Button1.Click
previouslyActiveTextBox.Select()
previouslyActiveTextBox.SelectedText = CStr(DirectCast(sender, Button).Tag)
End Sub
That code handles multiple events with a single method in both cases. It also requires that you assign the number for each Button to the Tag property of that control. Note that it also sets the SelectedText, rather than appending to the Text property. That is more correct because it will add the new text where the caret is actually located and replace text if it is selected.
An even better option might be to use a custom button control that doesn't take focus. Here's one I prepared earlier:
http://www.vbforums.com/showthread.php?459890-Building-Blocks-for-an-On-screen-Keyboard
Items within a ToolStrip do not grab focus when clicked. While the standard ToolStrip usage is as a menu bar, there is nothing that prevents you from using it as a container for buttons laid out in a grid. In fact, the class ToolStrip.LayoutStyle Property allows you select a table style.
The following is a proof-of-concept custom ToolStrip that is prepopulated with the buttons to create a number pad like control. The control has sufficient function to work as intended, but is not locked down to prevent misuse by manipulating the Items collection and other properties.
Public Class NumPadToolstrip : Inherits ToolStrip
Private _ButtonSize As Size = New Size(50, 50)
Private _ButtonMargin As Padding = New Padding(5)
Private _ButtonBackColor As Color = Color.Ivory
Public Sub New()
MyBase.New
LayoutStyle = ToolStripLayoutStyle.Table
Dim settings As TableLayoutSettings = CType(LayoutSettings, TableLayoutSettings)
settings.ColumnCount = 3
settings.RowCount = 4
AddButtons(7, 9)
AddButtons(4, 6)
AddButtons(1, 3)
AddButtons(0, 0)
Dock = DockStyle.None
AutoSize = True
BackColor = Color.LightGray
End Sub
Public Property ButtonSize As Size
Get
Return _ButtonSize
End Get
Set(value As Size)
If value <> _ButtonSize Then
_ButtonSize = value
UpdateButtonSizes()
End If
End Set
End Property
Public Property ButtonMargin As Padding
Get
Return _ButtonMargin
End Get
Set(value As Padding)
If value <> _ButtonMargin Then
_ButtonMargin = value
UpdateMargins()
End If
End Set
End Property
Public Property ButtonBackColor As Color
Get
Return _ButtonBackColor
End Get
Set(value As Color)
If value <> _ButtonBackColor Then
_ButtonBackColor = value
UpdateButtonBackColor()
End If
End Set
End Property
Private Sub AddButtons(start As Int32, [end] As Int32)
For num As Int32 = start To [end]
Dim b As New ToolStripButton With {.Text = num.ToString(),
.Size = ButtonSize,
.Margin = ButtonMargin,
.BackColor = ButtonBackColor,
.AutoSize = False}
AddHandler b.Paint, Sub(sender As Object, e As PaintEventArgs)
With e.Graphics
Dim r As Rectangle = e.ClipRectangle
r.Inflate(-1, -1)
r.Location = Point.Empty
.DrawRectangle(Pens.Black, r)
End With
End Sub
Items.Add(b)
Next
End Sub
Private Sub UpdateButtonSizes()
SuspendLayout()
For Each btn As ToolStripButton In Items.OfType(Of ToolStripButton)
btn.Size = _ButtonSize
Next
ResumeLayout()
End Sub
Private Sub UpdateMargins()
SuspendLayout()
For Each btn As ToolStripButton In Items.OfType(Of ToolStripButton)
btn.Margin = _ButtonMargin
Next
ResumeLayout()
End Sub
Private Sub UpdateButtonBackColor()
SuspendLayout()
For Each btn As ToolStripButton In Items.OfType(Of ToolStripButton)
btn.BackColor = _ButtonBackColor
Next
ResumeLayout()
End Sub
End Class
Add the above class to your project and perform a build operation. The NumPadToolstrip control should then be available in the ToolBox. Add the control to the form and then add a handler for its ItemClicked event to pass the proper text to the TextBox.
Private Sub NumPadToolstrip1_ItemClicked(sender As Object, e As ToolStripItemClickedEventArgs) Handles NumPadToolstrip1.ItemClicked
Dim tb As TextBoxBase = TryCast(ActiveControl, TextBoxBase)
If tb IsNot Nothing Then tb.SelectedText = e.ClickedItem.Text
End Sub

VB.NET Custom Menu in Panel

Hi I'm implementing a custom menu in a panel like this image (link) below..
heres the link http://i.imgur.com/5OlRk9c.png
My question is, how can I detect that the user clicks on another part of my form excepts the menu panel and buttons(inside the red circle).
I already used the LostFocus event but nothing happens.
Please help.
You can trap mouse messages before they get routed to the controls via IMessageFilter. Then you can check to see if the cursor position is inside or outside the bounds of your panel. Here's a simple example with Panel1:
Public Class Form1
Private WithEvents filter As New MyFilter
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Application.AddMessageFilter(filter)
End Sub
Private Sub filter_LeftClick() Handles filter.LeftClick
Dim rc As Rectangle = Panel1.RectangleToScreen(Panel1.ClientRectangle)
If Not rc.Contains(Cursor.Position) Then
Debug.Print("Click outside of Panel1")
End If
End Sub
Private Class MyFilter
Implements IMessageFilter
Public Event LeftClick()
Private Const WM_LBUTTONDOWN As Integer = &H201
Public Function PreFilterMessage(ByRef m As System.Windows.Forms.Message) As Boolean Implements System.Windows.Forms.IMessageFilter.PreFilterMessage
Select Case m.Msg
Case WM_LBUTTONDOWN
RaiseEvent LeftClick()
End Select
Return False
End Function
End Class
End Class

VB.NET How can I popup a game-safe notification?

How can I, in VB.NET, display a notification on-screen, such as that this will be "game-safe".
Eg: "Theres only 30 minutes left until you will be logged out!".
The notification should not take focus from the game (eg "steal input") and the notification should only be shown for like 5-10 seconds and then disappear by itself.
The notification should also be safe when talking about anticheats, like Punkbuster, VAC and such.
Any ideas?
I don't know about "game safe" as I don't know what those games are looking for to trigger an alert.
What you can do is override ShowWithoutActivation() and return true so that your form does not get focus when shown. Additionally, you can set the WS_EX_TRANSPARENT extended window style so that all mouse messages literally go right through your form. Apps underneath won't even know your form is there. Finally, set Opacity so that you can see through it partially. Oh...the timer is in there to close it after ten seconds:
Public Class frmNotification
Private WithEvents Tmr As New System.Windows.Forms.Timer
Private Sub frmNotification_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.Opacity = 0.5 ' Make it so you can see thru it partially
Me.FormBorderStyle = Windows.Forms.FormBorderStyle.None
' make it appear in the bottom right of the screen
Me.StartPosition = FormStartPosition.Manual
Dim rc As Rectangle = Screen.GetWorkingArea(Me)
Me.Location = New Point(rc.Right - Me.Width, rc.Bottom - Me.Height)
Tmr.Interval = TimeSpan.FromSeconds(10).TotalMilliseconds
Tmr.Start()
End Sub
Private Const WS_EX_TRANSPARENT As Integer = &H20
' Make all mouse events PASS RIGHT THRU IT:
Protected Overrides ReadOnly Property CreateParams() As System.Windows.Forms.CreateParams
Get
Dim cp As CreateParams = MyBase.CreateParams
cp.ExStyle = cp.ExStyle Or WS_EX_TRANSPARENT
Return cp
End Get
End Property
' Show it without activating it:
Protected Overrides ReadOnly Property ShowWithoutActivation() As Boolean
Get
Return True
End Get
End Property
Private Sub Tmr_Tick(sender As Object, e As EventArgs) Handles Tmr.Tick
Me.Close()
End Sub
End Class