Answered by:
Highlighted list member at mouse position on .Dropdown

Question
-
I have MyControl.Dropdown run on a combo box KeyPress event (first character only). This neatly drops the box down on first keypress so that the user can see immediately the auto-complete entry in the context of the rest of the value list. This, in turn, allows the user to arrow down to a close entry rather than continuing to type or pick up the mouse.
However, if the mouse pointer happens to be already sitting within screen space occupied by the dropdown box when it appears, the line at the mouse position automatically turns black (i.e. as though it is the current line). My auto-complete works correctly based on characters typed; however, on that first keystroke, the highlighted list member is the one where the mouse pointer is, not the one indicating the result of auto-complete.
For example, if my list consists of numerals 1 through 1000, and the mouse is about half an inch below the combo box, when I type a "2", the DropDown occurs; however, the line with "2" on it is not highlighted; instead, the highlighted might be 7 or 8--wherever the mouse pointer happens to be sitting at that moment. When I then continue and type a "1" (to go to "21"), the focus correctly goes to 21 on the list.
But I find it odd that the mouse position, even though no click is associated with entering characters, "steals" the focus on that first click.
I know, this is fairly geeky; however, I always strive to make everything work smoothly. Any ideas on how to get a combo box dropdown (by .Dropdown method) to ignore the current mouse position and follow auto-complete logic instead?
- Edited by Brian D. Hart Wednesday, November 16, 2016 7:58 AM
Wednesday, November 16, 2016 7:53 AM
Answers
-
Hi Brian,
I was able to duplicate your issue but wasn't able to find a simple solution. So, the only thing I could suggest is for you is to maybe try using an API to move the mouse pointer away from the dropdown area.
See if this article helps...
- Marked as answer by Brian D. Hart Thursday, November 17, 2016 6:25 PM
Thursday, November 17, 2016 6:15 PM -
For what it's worth, I tried this using a simple API call to move the mouse pointer to the top-left corner of the active control (before dropping down the combo box), and it worked without seeming -- to me -- particularly disruptive.
Dirk Goldgar, MS Access MVP
Access tips: www.datagnostics.com/tips.html- Proposed as answer by Deepak Saradkumar PanchalMicrosoft contingent staff Friday, November 18, 2016 2:51 AM
- Marked as answer by Brian D. Hart Friday, November 18, 2016 5:58 AM
Thursday, November 17, 2016 11:32 PM
All replies
-
From the description of the thread it looks like you have issue with highlight the auto correct text instead of Mouse position.
but you did not posted any code.
so we are not able to judge this issue by only description.
if you post the code then we can try to look in to that and test it on our side.
because in your description you had mentioned many things which makes us confused to assume the real situation.
so at this stage our suggestion can mislead you.
so I suggest you to post the code and your desired output.
we will try to suggest you further with that.
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 MSDNFSF@microsoft.com.Thursday, November 17, 2016 3:13 AM -
Here is the code. In short, there is a public module that I call from KeyPress events to drop down the active control upon typing the first character, as long as that character is not 9, 13, or 27 (I do not want to drop down on Tab, Esc, or Enter). For the combo box, AutoExpand is True.
In the standard module:
Public ControlDropDownStatus As Boolean Public Function ControlDropDown(Keystroke As Integer) Select Case Keystroke Case 9, 13, 27 'ignore TAB, ENTER, ESC ControlDropDownStatus = False Case Else Screen.ActiveControl.Dropdown ControlDropDownStatus = True End Select End Function
In my form's module:
Private Sub MyComboBox_Enter() ControlDropDownStatus = False End Sub Private Sub MyComboBox_KeyPress(KeyAscii As Integer) If KeyAscii = 27 Then ControlDropDownStatus = False If Not ControlDropDownStatus Then ControlDropDown (KeyAscii) End Sub
This all works perfectly, but for one thing: if the mouse pointer happens to be sitting somewhere inside the space that becomes occupied by the dropdown box when it drops down, the highlighted line after the first keystroke. In the screenshot below, my mouse pointer (which does not appear in the screen shot) was just below the bottom of the form. As soon as I typed "1" in the box, the box (correctly) dropped down; however, the item "focus" went immediately (and incorrectly) to "8" based on the location of the mouse pointer at that moment. With the mouse moved out of the way, the focus would (correctly) go to "2" instead.
I know it seems (and admittedly may, in fact be) trivial and is, in all likelihood, considered correct behavior for a combo box, but I try to build as much convenience as possible into my applications, and the current behavior is likely to be confusing to users, whose attention will be incorrectly drawn to the "8", while the true value of the box, if the user were to press Enter, would actually (and correctly) be "2". I understand that a combo box is intended to both AutoExpand and follow the mouse and that once the mouse is moved, the focus is to follow the mouse without changing the value until there is a click; however, in this case, where I am doing the dropdown programmatically, it just seems to me that the list member highlighted at the moment of dropdown should be associated with the keyboard event that triggered the dropdown (i.e. AutoExpand), not with the mouse position, since there was no mouse click or movement associated with the dropdown.
- Edited by Brian D. Hart Thursday, November 17, 2016 6:41 PM
Thursday, November 17, 2016 6:00 PM -
Hi Brian,
I was able to duplicate your issue but wasn't able to find a simple solution. So, the only thing I could suggest is for you is to maybe try using an API to move the mouse pointer away from the dropdown area.
See if this article helps...
- Marked as answer by Brian D. Hart Thursday, November 17, 2016 6:25 PM
Thursday, November 17, 2016 6:15 PM -
Thank you. It would probably not be worth writing an API call into my code. After all, this is supposed to just be a little extra convenience to the user. I embed this dropdown code into all my apps, since I have found that it is easier for the user to see the surrounding entries as soon as they begin typing than it is to manually click the dropdown arrow to see the list. But determining the dropdown area based on the numbers of rows so that I can move the mouse out of the way, or moving the mouse to the left or right out of the way, would seem kind of overkill. And you can imagine the response from users were the mouse to mysteriously move out of the way.
I just thought perhaps there was some setting in Access itself allowing the developer to prioritize AutoExpand over mouse position, or at least not picking up mouse position until it is moved.
Thursday, November 17, 2016 6:37 PM -
Hi Brian,
I agree; but unfortunately, I couldn't find a simpler solution since there wasn't a setting I could find to change the default behavior we're seeing.
Good luck with your project.
Thursday, November 17, 2016 7:29 PM -
For what it's worth, I tried this using a simple API call to move the mouse pointer to the top-left corner of the active control (before dropping down the combo box), and it worked without seeming -- to me -- particularly disruptive.
Dirk Goldgar, MS Access MVP
Access tips: www.datagnostics.com/tips.html- Proposed as answer by Deepak Saradkumar PanchalMicrosoft contingent staff Friday, November 18, 2016 2:51 AM
- Marked as answer by Brian D. Hart Friday, November 18, 2016 5:58 AM
Thursday, November 17, 2016 11:32 PM -
This is a good idea! You can "move" the cursor somewhat over the dropdown arrow to simulate the user clicking on it to see the dropdown, which of course drops down because of your .Dropdown code.
Nice work, Dirk.
Friday, November 18, 2016 12:00 AM -
Yes. Thank you, Dirk. I had not considered that. Rather than moving the cursor out of the way, move it to where it would have had to be for a mouse-click-initiated dropdown. That is brilliant and, as you indicate, one place I could move the cursor that would be perfectly logical given the current action.
I will work on this...but would you care to post the API call you used? I assume I would have to first determine the current position of the combo box itself, in particular the dropdown arrow, then move the cursor to that location.
Friday, November 18, 2016 5:58 AM -
Yes. Thank you, Dirk. I had not considered that. Rather than moving the cursor out of the way, move it to where it would have had to be for a mouse-click-initiated dropdown. That is brilliant and, as you indicate, one place I could move the cursor that would be perfectly logical given the current action.
I will work on this...but would you care to post the API call you used? I assume I would have to first determine the current position of the combo box itself, in particular the dropdown arrow, then move the cursor to that location.
Note: I only placed the cursor at the top *left* of the control, not at the top right. That's because I already had code written to do that. Top right will be a bit trickier, because it will require calculating where the top right corner of the control window is, while Windows already knows directly where the top left corner is. I'll look into that, but can't promise to get back to you right away.
This is the code I used:
Option Compare Database Option Explicit Private Type POINT X As Long Y As Long End Type Private Declare Sub ClientToScreen Lib "user32" (ByVal hWnd As Long, lpPoint As POINT) Private Declare Function GetFocus Lib "user32" () As Long Declare Function SetCursorPos Lib "user32" (ByVal X As Long, ByVal Y As Long) As Long Public Function MouseToControl( _ ctl As Access.Control, _ Optional LeaveFocus As Boolean = False) ' Move the mouse cursor to a specific control, passed ' as argument "ctl". By default, the focus will be set to ' that control and left there; however, this behavior can ' be controlled by the optional argument "LeaveFocus". ' If LeaveFocus is True, the focus will be returned to ' the control that originally had it. ' ' Note that <ctl> must be a control that is capable of ' receiving the focus. If it doesn't already have the ' focus, it *will* receive the focus, at least momentarily, ' even if the focus is then set back to the previously active ' control. However, if <ctl> cannot receive the focus -- for ' example, if it's a label control -- then the cursor will ' move to the top left corner of the form. ' ' Copyright © 2016 Dirk Goldgar, DataGnostics LLC ' License is freely granted to use this code in your applications, ' so long as the attribution and copyright remain intact. Dim ctlOld As Access.Control Dim hWnd As Long Dim pt As POINT On Error Resume Next If LeaveFocus Then Set ctlOld = Screen.ActiveControl ctl.SetFocus hWnd = GetFocus ClientToScreen hWnd, pt SetCursorPos pt.X, pt.Y If LeaveFocus Then If Not ctlOld Is Nothing Then ctlOld.SetFocus End If End If End Function
With that code in a standard module, then you would modify your ControlDropDown procedure to add the line:
MouseToControl Screen.ActiveControl
before calling Screen.ActiveControl.Dropdown.
Dirk Goldgar, MS Access MVP
Access tips: www.datagnostics.com/tips.htmlFriday, November 18, 2016 4:43 PM