GetCursorPos question
|
|
Thread rating:  |
Patrick Weidener - 30 Jul 2008 12:45 GMT I want to call the MouseDown event in a usercontrol when the DblClick event occurs. I don't want to use subclassing this time, I would need a quick solution. However, I cannot call MouseDown directly, because I don't know the position where the DblClick occured. I thought of using GetCursorPos and then somehow calculate the position where the dblclick occured on the control because GetCursorPos tells me where the mouse pointer is on the screen and not on the usercontrol. I guess that I need ClientToScreen to get the real coordinates, but I didn't find any samples for what I need.
expvb - 30 Jul 2008 13:19 GMT >I want to call the MouseDown event in a usercontrol when the DblClick event >occurs. [quoted text clipped - 6 lines] > I guess that I need ClientToScreen to get the real coordinates, but I > didn't find any samples for what I need. You need ScreenToClient, and convert to twips or whatever scale mode you are using.
Larry Serflaten - 30 Jul 2008 13:25 GMT > I want to call the MouseDown event in a usercontrol when the DblClick > event occurs. [quoted text clipped - 6 lines] > I guess that I need ClientToScreen to get the real coordinates, but I > didn't find any samples for what I need. Add the code below to a new form and see what happens. See if that will give you a few ideas...
LFS
Private Sub Form_DblClick() Form_MouseDown -1, 0, 0, 0 End Sub
Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single) Static mB%, mS%, mX!, mY! If Button >= 0 Then mB = Button mS = Shift mX = X mY = Y End If Debug.Print "Down at "; mX, mY End Sub
Patrick Weidener - 30 Jul 2008 14:42 GMT Thanks to both of you.
I'm still having problems distinguishing which button was pressed. I think my code is right, but GetAsynKeyState doesn't seem to be able to handle it correctly if clicks appear fast. For now, I'll just assume that the vbLeftButton is down.
Private Sub UserControl_DblClick()
Dim P As POINTAPI GetCursorPos P
ScreenToClient UserControl.hwnd, P
Dim X As Single Dim Y As Single
X = P.X * Screen.TwipsPerPixelX Y = P.Y * Screen.TwipsPerPixelY
Dim iButton%
If GetAsyncKeyState(vbLeftButton) Then iButton = vbLeftButton ElseIf GetAsyncKeyState(vbRightButton) Then iButton = vbRightButton Else iButton = vbMiddleButton End If
UserControl_MouseDown iButton, 0, X, Y
End Sub
Dave O. - 30 Jul 2008 16:16 GMT > Thanks to both of you. > [quoted text clipped - 29 lines] > > End Sub I'm sure all that stuff above is not needed, make a few variables that are visible to the whole user control: something like a couple of longs lngX and lngY and a boolean bnLeft then in the user control Mouse_Down event you have: lngX = X lngY = Y bnLeft = (Button = 1) being public these values will be available in the Double_Click event thus rendering all that GetAsyncKeyState stuff superfluous. You can either use the ScreenToClient or just add the user control coordinates to the X & Y values
Regards Dave O
Patrick Weidener - 30 Jul 2008 16:32 GMT LOL, you're right. Thanks.
Patrick Weidener - 30 Jul 2008 17:02 GMT I found a logical error... I cannot use the method you suggested because there is nothing that tells me whether it's a left DoubleClick or a right DoubleClick. You may have forgotten that when DblClick occurs, there is no MouseDown event which might tell me which button was pressed.
You have to subclass to find that out.
I could be wrong but I think I'm not.
Ivar - 30 Jul 2008 17:30 GMT When you created the user control, did you use the wizard and use the pre-selected methods? If you did then re create the control without using any of the available properties, methods or events and create your own without mapping any of them, that way you have total control of what happens when and how.
Ivar
Ivar - 30 Jul 2008 17:45 GMT Just had a little play, This is what I did New Project, new form, added UserControl In the form I put this code:
Option Explicit Private Sub UserControl11_DoubleClick(Button As Integer, _ X As Single, Y As Single) MsgBox "UserControl_DoubleClick, Button = " & _ Button & ". X = " & X & " Y = " & Y End Sub
In the usercontrol I put this code:
Option Explicit
Private MyButton As Integer Private MyX As Single, MyY As Single Public Event DoubleClick(Button As Integer, _ X As Single, Y As Single)
Private Sub UserControl_DblClick() RaiseEvent DoubleClick(MyButton, MyX, MyY) End Sub
Private Sub UserControl_Initialize() UserControl.ScaleMode = vbPixels End Sub
Private Sub UserControl_MouseDown(Button As Integer, _ Shift As Integer, X As Single, Y As Single) MyButton = Button MyX = X: MyY = Y End Sub
Does this do what you are after?
Ivar
Patrick Weidener - 30 Jul 2008 18:32 GMT > Does this do what you are after? I am not sure.
Let's say you manage to create a DblClick with 2 clicks without creating a MouseDown down first (because you're clicking really fast), then how would you know that the DblClick is created with vbLeftButton and not vbRightButton?
If creating a DblClick without raising MouseDown first is NOT possible, then I am wrong.
mayayana - 30 Jul 2008 19:07 GMT > Let's say you manage to create a DblClick with 2 clicks without creating > a MouseDown down first (because you're clicking really fast), then how [quoted text clipped - 3 lines] > If creating a DblClick without raising MouseDown first is NOT possible, > then I am wrong. I just tried it on a form. Clicking fast I get only one MouseDown per double click, but in no case was there *no* MouseDown.
Interestingly, in Spy++ I see that a left double click causes the message WM_LBUTTONDBLCLK. It seems strange that VB wasn't designed to send the button value through as a parameter of the DblClick sub.
Ivar - 30 Jul 2008 19:51 GMT I think what you are saying is: If the user double clicks the user control then a double click event should fire, but, if the user does not do a second click then the mouse down event should fire. Can't be done because (Obviously) the mouse has to go down in order to click. (I don't mean to patronize). The only way I can see to do this is to test if the double click happens, and if it don't then reaise the mouse down event, Try the fiollowing code to see if this is what you are looking for. In the form:
Option Explicit
Private Sub UserControl11_DoubleClick(Button As Integer, _ X As Single, Y As Single) MsgBox "UserControl_DoubleClick, Button = " & _ Button & ". X = " & X & " Y = " & Y End Sub
Private Sub UserControl11_MouseDown(Button As Integer, X As Single, Y As Single) MsgBox "UserControl_MouseDown , Button = " & _ Button & ". X = " & X & " Y = " & Y End Sub
In the user control: Option Explicit Private Declare Function GetDoubleClickTime Lib "user32" () As Long Private Declare Function GetTickCount& Lib "kernel32" () Private MyButton As Integer Private MyX As Single, MyY As Single Private DBClickTime As Long Private TimeNow As Long Private MouseCameUp As Boolean Public Event DoubleClick(Button As Integer, _ X As Single, Y As Single) Public Event MouseDown(Button As Integer, X As Single, Y As Single)
Private Sub UserControl_DblClick() RaiseEvent DoubleClick(MyButton, MyX, MyY) End Sub
Private Sub UserControl_Initialize() UserControl.ScaleMode = vbPixels DBClickTime = GetDoubleClickTime End Sub
Private Sub UserControl_MouseDown(Button As Integer, _ Shift As Integer, X As Single, Y As Single) MyButton = Button MyX = X: MyY = Y TimeNow = GetTickCount MouseCameUp = False Do Until MouseCameUp = True If (GetTickCount - TimeNow) > DBClickTime Then RaiseEvent MouseDown(Button, X, Y) Exit Do End If DoEvents Loop End Sub
Private Sub UserControl_MouseUp(Button As Integer, _ Shift As Integer, X As Single, Y As Single) MouseCameUp = True End Sub
Does this help?
Ivar
BeastFish - 30 Jul 2008 20:44 GMT What is it you are trying to accomplish? Just wondering, because if you are just trying to compensate for double clicks (i.e., double clicks were swallowing click events or whatever), you can disable double clicking for your usercontrol with some API magic...
UC's (General)(Declarations)
Private Declare Function GetClassLong Lib "user32" Alias "GetClassLongA" _ (ByVal hWnd As Long, ByVal nIndex As Long) As Long Private Declare Function SetClassLong Lib "user32" Alias "SetClassLongA" _ (ByVal hWnd As Long, ByVal nIndex As Long, _ ByVal dwNewLong As Long) As Long Private Const GCL_STYLE As Long = (-26) Private Const CS_DBLCLKS As Long = &H8
Private Sub UserControl_Initialize() ' Remove doubleclick from UC Dim MyStyle As Long MyStyle = GetClassLong(Me.hWnd, GCL_STYLE) MyStyle = MyStyle And Not CS_DBLCLKS SetClassLong Me.hWnd, GCL_STYLE, MyStyle End Sub
> I want to call the MouseDown event in a usercontrol when the DblClick > event occurs. [quoted text clipped - 6 lines] > I guess that I need ClientToScreen to get the real coordinates, but I > didn't find any samples for what I need. Patrick Weidener - 31 Jul 2008 01:26 GMT BeastFish,
thank you! That's pretty!
|
|
|