Hi,
How can I determine If a mouse button is clicked, in- or outside the form
Printable View
Hi,
How can I determine If a mouse button is clicked, in- or outside the form
The simplest solution is using GetAsyncKeyState with Timer
vb Code:
Option Explicit Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer Private Sub Form_Load() Timer1.Interval = 250 ' less interval may cause performance issues Timer1.Enabled = True End Sub Private Sub Timer1_Timer() ' Checking left mouse button. If GetAsyncKeyState(1) = 0 Then Me.Caption = "L up" Else Me.Caption = "L down" End If ' ' Checking right mouse button. ' If GetAsyncKeyState(2) = 0 Then ' Me.Caption = "R up" ' Else ' Me.Caption = "R down" ' End If End Sub
The advanced solution is hooking the mouse https://www.codeproject.com/Articles...e-Mouse-Events
You can use getcursorpos api. This will give you (when you use pointapi which you have to use) the X and Y of mouse in screen coord. You compare the X and Y with your Form Left, Top, Right, and Bottom to determine if mouse is inside/outside your form
I don't have any examples. If I wanted to make a program that detected were the mouse is at any point in time and someone told me to use GetCursorPos I would first Google GetCursorPos and find existing examples on the net then I would take those examples and study them and using the info I got begin to write my program then if I had problems with that program I would come here to VBForums and ask specific questions. I would do all this for you but I really don't have the time nor patience for all that crap so I would probably wind up doing what your doing and ask someone here to give me the code
Above code detect mouse click inside and outside the form but it isn't get mouse position, the next one do
vb Code:
Option Explicit Private Type POINTAPI X As Long Y As Long End Type Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer Private Sub Form_Load() Timer1.Interval = 250 ' less interval may cause performance issues Timer1.Enabled = True End Sub Private Sub Timer1_Timer() Dim pt As POINTAPI ' Checking left mouse button. If GetAsyncKeyState(1) <> 0 Then GetCursorPos pt Me.Caption = "L down at x= " & pt.X & "y= " & pt.Y End If ' ' Checking right mouse button. ' If GetAsyncKeyState(2) <> 0 Then ' GetCursorPos pt ' Me.Caption = "R down at x= " & pt.X & "y= " & pt.Y ' End If End Sub
It appears to me that you could use some code that tells you if you are inside or outside the Form.
Maybe this
Code:Private Sub Timer1_Timer()
Dim pt As POINTAPI
Dim MyApp As String
' Checking left mouse button.
If GetAsyncKeyState(1) <> 0 Then
GetCursorPos pt
If GetActiveWindow = Me.hWnd Then MyApp = "Inside" Else MyApp = "outside"
Me.Caption = MyApp & " Left down at x = " & pt.X & ", y= " & pt.Y
Exit Sub
End If
' Checking right mouse button.
If GetAsyncKeyState(2) <> 0 Then
GetCursorPos pt
If GetActiveWindow = Me.hWnd Then MyApp = "Inside" Else MyApp = "outside"
Me.Caption = MyApp & " Right down at x = " & pt.X & ", y= " & pt.Y
End If
End Sub
@Code Dummy. I don't think this is a form. I think it is that dropdown picturebox, within a usercontrol, he was asking questions about, several days ago. But Form_Deactivate is what I think you are referring to.
A timer approach like you & 4x2y mentioned may be good enough? Subclassing is another option. When "dropdown" is shown, set focus to it, subclass & look for WM_KillFocus message, hide and stop subclass when lost focus or other code hides the "dropdown". Subclassing for a novice isn't an easy solution. Made even more difficult, because the "dropdown" contains other controls, per that other thread. So, WM_KillFocus really applies to any part of the project not associated with the picturebox or another app altogether.
I think you're right. Had to go back and do some searching. If it is a form, then subclassing can still be an option, though a harder one for novices. In this case, WM_ActivateApp could be the message to trap. Your solution would be easier if the short timer interval is good enough.
Unfortunately, Form_Deactivate & Form_Activate are project related events, not interactive outside of the project.
I used GetActiveWindow and it seems to work just fine (see my earlier post)
Why goes that way to know if click inside the form, there is MouseDown event can be used (for the form or any control inside it), so using Timer, GetAsyncKeyState and GetCursorPos should be used to detect clicks outside the form.
OK, I tell you what, you use the MouseDown events and put code in them for the Form and all 100 controls and I'll use one simple API in the Timer sub
Thank you dears I think that is what I'm looking for I searched what you posted and got these two Codes (Sorry, these are only a copy/paste from another forum)
And the second one is:Code:Private Declare Function GetActiveWindow Lib "user32" () As Long
Private Sub Timer1_Timer()
If GetActiveWindow <> 0 Then
'if GetActiveWindow is non-zero
Label1.Caption = "I have the focus"
Else
'if GetActiveWindow is zero
Label1.Caption = "Another program has the focus"
End If
End Sub
Code:Private Declare Function GetActiveWindow Lib "user32" () As Long
Private Declare Function GetWindowTextA Lib "user32" (ByVal hwnd _
As Long, ByVal lpString As String, ByVal aint As Long) As Long
Private Declare Function GetForegroundWindow Lib "user32" () As Long
Private Sub Command1_Click()
Dim myhwnd As Long
Dim s As String
Dim iret As Long
Dim nullhwnd As Long
s = Space(256)
myhwnd = GetActiveWindow()
iret = GetWindowTextA(myhwnd, s, 256)
Debug.Print myhwnd, s
Shell "Calc.exe", 1
' Wait for CALC.EXE to launch under Windows NT:
DoEvents
nullhwnd = GetActiveWindow()
myhwnd = GetForegroundWindow()
s = Space(256)
iret = GetWindowTextA(nullhwnd, s, 256)
Debug.Print nullhwnd, s
s = Space(256)
iret = GetWindowTextA(myhwnd, s, 256)
Debug.Print myhwnd, s
End Sub
Mahmood,
The reason I didn't reply earlier as I didn't feel you were adequately clear on what you wanted. Here are some of the different scenarios I could envision:
- Are you talking about clicking on another form within the same application?
- If not the same application, do we need to detect clicks on the desktop?
- Is it some specific other application about which we're worried about clicks?
- What are we trying to do once we detect a click that has occurred somewhere else?
- Are we truly talking about a "click" or are we talking about a mouse-down-and-drag?
- If we're talking about mouse-down, then the whole issue of "who has captured the mouse" comes into play.
- Why wasn't the actual task of what you're trying to do outlined for us?
There are some system wide mouse hooks floating around. But they're certainly not highly advised. Again, I'd be willing to brainstorm if you're willing to outline what you're trying to do in more detail.
Best Regards,
Elroy
Many thanks Elroy
-No I didn't mean clicking neither on another form within the same application nor another application.
-Yes, Clicking (Or mouse-down) on desktop (Any where Out-Side the application)
-No, there is no worried application!
-I have a custom drop-down menu, I want to hide it , On mouse-down (Or clicking) out-side . . .
-Clicking or Mouse-down something like that
-what is that?
-All are these I mentioned above
I will be happy with your advises and guidance.
Warm Regards
Mahmood
You do realize, Mahmood, that 4x2y posted for you the simplest way to detect mouse up/down anywhere and returns the screen position of the mouse (post 5) and I added an API to detect inside/outside your Form (post 8). Perhaps you are not interested in those and are looking for something else more complex
Seems like a job for WM_ACTIVATEAPP
or better yet, why not close the menu as soon as it loses focus? isn't this handled automatically by the popup menu call?
How are you showing the custom popup menu? The built in popup menu automatically hides itself, as long as the calling window has prior focus.
My code in post #2 should do the job, anyway to be more clear try the following
Code:Option Explicit
Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
Private Sub Form_Load()
Timer1.Interval = 250 ' less interval may cause performance issues
Timer1.Enabled = True
End Sub
Private Sub Timer1_Timer()
' Checking left mouse button.
If GetAsyncKeyState(1) <> 0 Then
' Call the code to hide your custom drop-down menu
Timer1.Enabled = False ' we don't need after hiding the menu, don't forget to enable it again when showing the menu.
End If
' Checking right mouse button.
If GetAsyncKeyState(2) <> 0 Then
' Call the code to hide your custom drop-down menu
Timer1.Enabled = False ' we don't need after hiding the menu, don't forget to enable it again when showing the menu.
End If
End Sub
This is not my code. I got it from another site, many moons ago. I think this is what you are searching for, but hey, even I can (and still do) make mistakes :) :
Attachment 151205
No, but he did, he already descried what is exactly he want, just review his answer for each point Elroy asked, and after all codes provided to him, he is still asking for advice, so i have advised him "code in post #21 is VERY ENOUGH!!"
No! and Yes
Many thanks, Code Dummy for your code and 4x2y.
No, your code is enough for me but because I'm a beginner I interested in different codes Elroy did not understand my question I replied to him I expect he has a different idea which can improve me for next time.
Then please mark your thread resolved and rep people helped you
See the link in my first reply (post #2)