flat assembler
Message board for the users of flat assembler.

Index > Windows > capturing mouse double-clicks

Author
Thread Post new topic Reply to topic
oobie-noobie



Joined: 01 Apr 2008
Posts: 10
oobie-noobie
Hi,

The following code does capture the WM_LBUTTONDBLCLK but also captures the WM_LBUTTONDOWN first, due to the way windows sends the DBLCLK message (WM_LBUTTONDOWN, WM_LBUTTONUP, WM_LBUTTONDBLCLK, and WM_LBUTTONUP)

I need to be able to capture both WM_LBUTTONDBLCLK and WM_LBUTTONDOWN but can't seem to figure how to get the DBLCLK message to the sub without triggering the BUTTONDOWN sub.

Any ideas would be greatly appreciated Wink

Code:
format PE GUI 4.0
entry start

include '%fasminc%\win32axp.inc'

section '.code' code readable executable

  start:
        invoke  GetModuleHandle, 0
        mov     [wc.hInstance],eax
        invoke  RegisterClass,wc
        invoke  CreateWindowEx,WS_EX_CLIENTEDGE,myClass,NULL,WS_VISIBLE+WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 300, 400, NULL, NULL, [wc.hInstance],NULL
        mov     [hWndMain], eax
  msg_loop:
        invoke  GetMessage,msg,NULL, 0, 0
        or      eax,eax
        jz      end_loop
        invoke  TranslateMessage,msg
        invoke  DispatchMessage,msg
        jmp     msg_loop
  end_loop:
        invoke  ExitProcess,[msg.wParam]

proc wndProc hwnd,wmsg,wparam,lparam
        push    ebx esi edi
        cmp     [wmsg],WM_DESTROY
        je      .wmDESTROY
        cmp     [wmsg], WM_LBUTTONDOWN
        je      .wmLBUTTONDOWN
        cmp     [wmsg], WM_LBUTTONDBLCLK
        je      .wmLBUTTONDBLCLK
        jmp     .wmDEFAULT
    .wmDEFAULT:
        invoke  DefWindowProc,[hwnd],[wmsg],[wparam],[lparam]
        jmp     .wmBYE
    .wmLBUTTONDBLCLK:
        invoke  MessageBox, 0, lbdcStr, 0, MB_OK
        xor     eax, eax
        jmp     .wmBYE
    .wmLBUTTONDOWN:
        invoke  MessageBox, 0, lbdStr, 0, MB_OK
        xor     eax, eax
        jmp     .wmBYE
    .wmDESTROY:
        invoke  PostQuitMessage, 0
        xor     eax,eax
        jmp     .wmBYE
    .wmBYE:
        pop     edi esi ebx
        ret
endp


section '.data' data readable writeable

wc              WNDCLASS CS_DBLCLKS, wndProc, 0, 0, NULL, NULL, NULL, COLOR_BTNFACE+1, NULL, myClass
myClass         db "test", 00
hWndMain        dd ?
msg             MSG
lbdStr          db "Left button down", 00
lbdcStr         db "Left button double click", 00

section '.idata' import data readable writeable

library kernel32,'KERNEL32.DLL',\
        user32,  'USER32.DLL'

include '%fasminc%\apia\Kernel32.inc'
include '%fasminc%\apia\User32.inc'
    
Post 04 Apr 2008, 21:18
View user's profile Send private message Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 3038
Location: vpcmipstrm
bitRAKE
Use GetDoubleClickTime result to know how long to wait for double click message. I don't like it though. Seems like common usage on Google Code search.

_________________
¯\(°_o)/¯ unlicense.org
Post 04 Apr 2008, 23:04
View user's profile Send private message Visit poster's website Reply with quote
Yardman



Joined: 12 Apr 2005
Posts: 245
Location: US
Yardman
[ Post removed by author. ]


Last edited by Yardman on 04 Apr 2012, 03:00; edited 1 time in total
Post 05 Apr 2008, 00:19
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17659
Location: In your JS exploiting you and your system
revolution
Usually one would use the double click as an extension to the single click. Then the double click is more logical to use. Example: select with single click and perform-some-operation on double click. Any other use might just end up confusing the user anyway.
Post 05 Apr 2008, 00:35
View user's profile Send private message Visit poster's website Reply with quote
oobie-noobie



Joined: 01 Apr 2008
Posts: 10
oobie-noobie
Thanks for all the replies. All I could find was also the use of a timer (which I don't like either).
I agree revolution, but the app I'm writing is for my own use (and this user is confused enough, lol).

Anyways, here's what I ended up with, not pretty but it gets the job done Wink

Edited here:
also found after plugging this into my main app that you lose the mouse position in the timer wait Sad
I've amended the code below to preserve it

Code:
format PE GUI 4.0
entry start

include '%fasminc%\win32axp.inc'

section '.code' code readable executable

  start:
        invoke  GetModuleHandle, 0
        mov     [wc.hInstance],eax
        invoke  RegisterClass,wc
        invoke  CreateWindowEx,WS_EX_CLIENTEDGE,myClass,NULL,WS_VISIBLE+WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 300, 400, NULL, NULL, [wc.hInstance],NULL
        mov     [hWndMain], eax
        invoke  GetDoubleClickTime
        shr     eax, 1                  ;only waiting half the set double-click time
        mov     [DCT], eax
  msg_loop:
        invoke  GetMessage,msg,NULL, 0, 0
        or      eax,eax
        jz      end_loop
        invoke  TranslateMessage,msg
        invoke  DispatchMessage,msg
        jmp     msg_loop
  end_loop:
        invoke  ExitProcess,[msg.wParam]

proc wndProc hwnd,wmsg,wparam,lparam
        push    ebx esi edi
        cmp     [wmsg],WM_DESTROY
        je      .wmDESTROY
        cmp     [wmsg], WM_LBUTTONDOWN
        jne     @f
        push    [lparam]
        pop     [MousePos]
        invoke  SetTimer, [hwnd], NULL, [DCT], NULL
        xor     eax, eax
        jmp     .wmBYE
    @@:
        cmp     [wmsg], WM_LBUTTONDBLCLK
        jne     @f
        invoke  KillTimer, [hwnd], NULL
        push    [MousePos]
        pop     [lparam]
        jmp     .wmLBUTTONDBLCLK
    @@:
        cmp     [wmsg], WM_TIMER
        jne     @f
        invoke  KillTimer, [hwnd], NULL
        push    [MousePos]
        pop     [lparam]
        jmp     .wmLBUTTONDOWN
    @@:
        jmp     .wmDEFAULT
    .wmDEFAULT:
        invoke  DefWindowProc,[hwnd],[wmsg],[wparam],[lparam]
        jmp     .wmBYE
    .wmLBUTTONDBLCLK:
        invoke  MessageBox, 0, lbdcStr, 0, MB_OK
        xor     eax, eax
        jmp     .wmBYE
    .wmLBUTTONDOWN:
        invoke  MessageBox, 0, lbdStr, 0, MB_OK
        xor     eax, eax
        jmp     .wmBYE
    .wmDESTROY:
        invoke  PostQuitMessage, 0
        xor     eax,eax
        jmp     .wmBYE
    .wmBYE:
        pop     edi esi ebx
        ret
endp


section '.data' data readable writeable

wc              WNDCLASS CS_DBLCLKS, wndProc, 0, 0, NULL, NULL, NULL, COLOR_BTNFACE+1, NULL, myClass
myClass         db "test", 00
hWndMain        dd ?
msg             MSG
lbdStr          db "Left button down", 00
lbdcStr         db "Left button double click", 00
DCT             dd ?
MousePos        dd ?

section '.idata' import data readable writeable

library kernel32,'KERNEL32.DLL',\
        user32,  'USER32.DLL'

include '%fasminc%\apia\Kernel32.inc'
include '%fasminc%\apia\User32.inc'
    
Post 05 Apr 2008, 00:46
View user's profile Send private message Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 3038
Location: vpcmipstrm
bitRAKE
When a double click happens a timer is created for the second WM_LBUTTONDOWN - unless I'm miss reading the code, or the second one isn't sent? Seems to work just fine.

Edit: okay, the second WM_LBUTTONDOWN come before the WM_LBUTTONDBLCLK, and so poses no problem.

_________________
¯\(°_o)/¯ unlicense.org
Post 05 Apr 2008, 01:58
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 3038
Location: vpcmipstrm
bitRAKE
It's like the double click message isn't needed, lol.
Code:
;****************
;* DblClick.asm * 
;**************** 

format pe gui 4.0 

include 'win32axp.inc' 

.code 

  start:  
        invoke  GetModuleHandle, 0 
        mov     [wc.hInstance],eax 
        invoke  LoadCursor,NULL,IDC_ARROW 
        mov     [wc.hCursor],eax 
        invoke  RegisterClass,wc 
        invoke  CreateWindowEx,WS_EX_CLIENTEDGE,myClass,"DblClick",\ 
                               WS_VISIBLE+WS_OVERLAPPEDWINDOW,\ 
                               CW_USEDEFAULT,CW_USEDEFAULT,300,400,\ 
                               NULL,NULL,[wc.hInstance],NULL 
        mov     [hWndMain],eax 
  msg_loop:  
        invoke  GetMessage,msg,NULL,0,0 
        or      eax,eax  
        jz      end_loop  
        invoke  TranslateMessage,msg  
        invoke  DispatchMessage,msg  
        jmp     msg_loop  
  end_loop:  
        invoke  ExitProcess,[msg.wParam]  

proc wndProc hwnd,wmsg,wparam,lparam  
        push    ebx esi edi 
        cmp     [wmsg],WM_DESTROY 
        je      .wmDESTROY  
        cmp     [wmsg],WM_LBUTTONDOWN 
        je      .wmLBUTTONDOWN 
;        cmp     [wmsg],WM_LBUTTONDBLCLK
;        je      .wmLBUTTONDBLCLK
        jmp     .wmDEFAULT 
    .wmDEFAULT:  
        invoke  DefWindowProc,[hwnd],[wmsg],[wparam],[lparam]  
        jmp     .wmBYE  
;    .wmLBUTTONDBLCLK:
;        invoke  KillTimer,[hwnd],1
;        invoke  MessageBox,[hwnd],lbdcStr,myClass,MB_OK
;        xor     eax,eax
;        jmp     .wmBYE
    .wmLBUTTONDOWN:
        test    [WM_Flags],1
        jne     .double
        or      [WM_Flags],1
        invoke  GetDoubleClickTime
        invoke  SetTimer,[hwnd],1,eax,TimerProc
        xor     eax,eax
        jmp     .wmBYE
    .double:
        and     [WM_Flags],-2
        invoke  KillTimer,[hwnd],1
        invoke  MessageBox,[hwnd],lbdcStr,myClass,MB_OK
        xor     eax,eax
        jmp     .wmBYE
    .wmDESTROY:
        invoke  PostQuitMessage,0 
        xor     eax,eax  
        jmp     .wmBYE  
    .wmBYE: 
        pop     edi esi ebx  
        ret  
endp  

proc TimerProc hwnd,uMsg,idEvent,dwTime 
        and     [WM_Flags],-2
        invoke  KillTimer,[hwnd],[idEvent]
        invoke  MessageBox,[hwnd],lbdStr,myClass,MB_OK
endp

.data 
                          ;CS_DBLCLKS
wc              WNDCLASS 0,wndProc,0,0,NULL,NULL,NULL,\
                         COLOR_BTNFACE+1,NULL,myClass 
myClass         db "DblClick",0 
hWndMain        dd ?
WM_Flags        dd ?
msg             MSG  
lbdStr          db "Left button down",0 
lbdcStr         db "Left button double click",0 

.end start    

_________________
¯\(°_o)/¯ unlicense.org
Post 05 Apr 2008, 02:41
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.