Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Question
Sunday, July 9, 2017 2:38 PM
I am trying to detect when the user clicks the left mouse button anywhere on screen using an API function. The API declaration looks like this :-
Public Const VK_LBUTTON = &H1
Public Const VK_RBUTTON = &H2
'Public Declare Function GetKeyState Lib "user32.dll" (ByVal vKey As Long) As Integer 'Not Used
Public Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer 'fetch mouse button status
The set up is something like this - a user opens a 'pop-up' form from a main form and only while the pop-up form is open, I need to detect whether the mouse has been left clicked anywhere on the screen. That is on any form that might be open in the database application or any area of the screen outside the database such as the desktop, task bar, etc. From the InterWeb it looks like the API call to use is the GetAsyncKeyState function which detects key and mouse presses but this does not seem to work properly in Access. The code I am using looks like this :-
Private Sub Form_Timer()
Dim vRet As Integer
vRet = GetAsyncKeyState(VK_LBUTTON) 'fetch current left button state (MouseDown or MouseUp)
If vRet <> 0 Then 'if return <> 0 then
Me.txtStatus = "L Button Down" 'show button status
Else
Me.txtStatus = "" 'clear status
End If
DoEvents 'refresh display
End Sub
which runs at 10mS intervals in the Timer event of the pop-up form. What happens is that it works fine if the mouse is clicked anywhere except on an open Access form, that is the text box shows "L Button Down" while the button is held down and blank when it isn't. However, if the mouse is clicked on any Access form object the mouse down event is not recognised (although bizarrely, clicking on the form borders is) but the function does return a non-zero value when the mouse button is released which lasts for a few milliseconds. Does anyone know what is going on here or is there some other API call which will work in this situation?
There is also another similar API function called GetKeyState but this is not ASynchronous so I don't think it is appropriate for this type of code.
This question was first posted to the Utter Access forum HERE, and there is a small demo database there that shows the problem.
Peter Hibbs.
All replies (17)
Wednesday, July 19, 2017 9:37 PM âś…Answered
Edward,
I did not use the exact suggestion from Imb but it did give me the idea of using the Deactivate event of the pop-up form to hide itself which seems to work so far so I think we can close this thread for now.
Peter Hibbs.
Sunday, July 9, 2017 5:19 PM
Couldn't you capture clicking on the Access form with the Form_Activate or Form_Keydown event?
-Tom. Microsoft Access MVP
Sunday, July 9, 2017 6:41 PM
A Windows hook can be used to capture mouse activity anywhere on the screen. The API functions to install and remove hooks are SetWindowsHookEx and UnhookWindowsHookEx, respectively. The types of hooks that are of interest are WH_MOUSE and WH_MOUSE_LL. Hooks require a callback function and the callback function for WH_MOUSE is described at MouseProc callback function while the WH_MOUSE_LL callback is described at LowLevelMouseProc callback function.
Sunday, July 9, 2017 7:10 PM
Hi Tom,
This code is part of a 'generic' project (i.e. it could be used with any form in the database which could be dozens or more) so I don't think it would be practical. I would need to add some code (albeit fairly small code) to every other form that might be open at the time this code is in use.
The Activate option does sort of work although it only triggers when the mouse button is released which may cause some issues but as I say, it would be better if I can trigger my code when the mouse button is pressed regardless of where it is on the screen.
If you have any other ideas then I would be pleased to try them out.
Peter Hibbs.
Sunday, July 9, 2017 7:40 PM
Hi RLWA32,
I did come across this site in my research and I think this is probably the only way to do what I want but unfortunately I don't speak C++. Do you have any examples of these calls using VBA?
Peter Hibbs.
Sunday, July 9, 2017 9:30 PM
This code is part of a 'generic' project (i.e. it could be used with any form in the database which could be dozens or more) so I don't think it would be practical. I would need to add some code (albeit fairly small code) to every other form that might be open at the time this code is in use.
Hi Peter,
I am crazy/wild about generalization. On this moment I have some 100 different applications, all working with the same 6 forms (on the way to reduce it to 5 or 4).
Until now I have never asked myself your question. But I wonder, what do you want you achieve with it?
Imb.
Sunday, July 9, 2017 9:37 PM
I did come across this site in my research and I think this is probably the only way to do what I want but unfortunately I don't speak C++. Do you have any examples of these calls using VBA?
Peter,
As you may have guessed I do this kind of work in C++ and I don't have any VBA code for it in my toolbox.
Sunday, July 9, 2017 10:11 PM
Hi Imb,
Well, what I am trying to do is simulate the drop down list of a Combo box using a Continuous type form with the aim of allowing a developer to have color coded items in the drop down list. That part is working fine but the problem is that to achieve this properly I need to have the form open in 'Pop Up' mode and the problem with that is that I then need to be able to close that form if the user clicks anywhere else on the screen. As you know, this is what happens with a standard Combo box, when the drop down list is visible the user can click anywhere on the parent form (or outside the parent form) to close down the drop down list and whatever control they click on will be 'activated' after the list disappears.
I have played with other options like providing a 'Close' button on the pop-up form but this is too different (IMO) from standard practice to be acceptable and the method I am seeking should really be possible - somehow!
If I can get it working properly I may publish it but we will have to see.
I hope that answers your question.
Peter Hibbs.
Sunday, July 9, 2017 10:13 PM
Hi RLWA32,
OK, I will give this some thought and see if I can get it working in VBA (unless anyone else can provide some suitable code).
Thanks,
Peter Hibbs.
Monday, July 10, 2017 1:56 PM
Try here for vb example.
Monday, July 10, 2017 2:00 PM
Well, what I am trying to do is simulate the drop down list of a Combo box using a Continuous type form with the aim of allowing a developer to have color coded items in the drop down list. That part is working fine but the problem is that to achieve this properly I need to have the form open in 'Pop Up' mode and the problem with that is that I then need to be able to close that form if the user clicks anywhere else on the screen.
Hi Peter,
Thanks for your answer.
In my systematics I make numerous dynamical menus (the same form with different code), among them lists like in a Combo box. These menus can have all kind of appearances, like color, and additional functionalities, like zoom-in in the originating record, and many more...
I can make a form self-closing, that is that it closes when a different form is activated. I think that is about what you want to realise, but I am still struggling with your "pop-up" mode. Why do you need that. For me it feels that a pop-up form is still open while a different form can become active.
When a form must be self-closing, I assign the formname, in the Open event, to a global variable. When any form is opened, it checks in the Activate event for this variable. If the variable has a formname as value, then that form is closed. In my systematics this is a "build in" feature, with my limited number of forms that are re-used almost ad-infinitum.
Imb.
Monday, July 10, 2017 2:01 PM
@msbad1959 - your link didn't come through.
Daniel Pineault, 2010-2017 Microsoft MVP
Professional Support: http://www.cardaconsultants.com
MS Access Tips and Code Samples: http://www.devhut.net
Monday, July 10, 2017 3:43 PM
Hi Imb,
Yes, you are correct that my aim with the mouse click is just to close the pop up form. Your idea of the global variable is an interesting idea although it still requires some code in the Activate event of all the other forms (or at least the forms that could be visible on screen).
If the post from msbad1959 can supply a link to some VBA code for the 'hook' code I might look at that as well but your suggestion is a possible alternative.
Why did I use a pop up form? Good question, I have just tried my code with a 'normal' form and it seems to work! Having said that, this code is pretty complicated and there are many things to be checked and I guess there was a good reason at the time. It has been a few weeks since I did any work on the project and I will need to get back into it again to to see if this option will work for every possible situation.
Thanks for a few more ideas.
Peter Hibbs.
Monday, July 10, 2017 5:16 PM | 1 vote
Yes, you are correct that my aim with the mouse click is just to close the pop up form. Your idea of the global variable is an interesting idea although it still requires some code in the Activate event of all the other forms (or at least the forms that could be visible on screen).
Hi Peter,
You can set your first (or your next) step to generalization.
In the Activate event of each form you can place the line: OnFormActivate Me. If necessary, this can be automated.
Then in a general module you declare:
Sub OnFormActivate (cur_form As Form)
...
If (glo_closeform > "") Then
DoCmd.Close acForm glo_closeform
glo_closeform = ""
End If
...
End Sub
If you have further checks to do on Activate, place these in the OnFormActivate routine. This is then immediately available in all forms.
Imb.
Monday, July 10, 2017 9:34 PM
Hi Imb,
OK, thanks. I will try your suggestion tomorrow and see how it works out for the project.
Peter.
Wednesday, July 19, 2017 7:34 AM
Hi Peter,
Has your issue been resolved from the suggestion from Imb? If it has, I would suggest you mark the helpful reply as answer, if not, please feel free to let us know your current issue.
Best Regards,
Edward
MSDN Community Support
Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact [email protected].
Tuesday, August 1, 2017 3:23 AM
Hi Peter Hibbs,
I can see that you mentioned in your last post that you want to close this thread.
the thread is still open.
to close the thread you need to mark the answer.
I suggest you to mark the appropriate suggestion as an answer that helped you to solve the issue.
so that we can close that thread.
if you do not mark the answer then thread will remain open.
Regards
Deepak
MSDN Community Support
Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact [email protected].