flat assembler
Message board for the users of flat assembler.

Index > Windows > Stupid question: Mouse-Click and Keyboard-Event

Goto page 1, 2  Next
Author
Thread Post new topic Reply to topic
SPTH



Joined: 24 Jul 2004
Posts: 91
SPTH 01 Dec 2006, 17:09
Hey,

I want to create a programm, which simulates a mouse click at the current position of the mouse; which can change the position of the mouse; and which can simulate a key-click. (with FASM of course)

The problem is, that I was not able to find an Win32 API for it; i've already searched MSDN and used google, but just found information how to work with these events, but not how to create them.

Does anybody knows the APIs?

Thanks a lot for the answeres.

kind regards,
Mario
Post 01 Dec 2006, 17:09
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 01 Dec 2006, 18:01
Search for WindowFromPoint and GetCursorPos (maybe you will need ChildWindowFromPoint too). Then use SendMessage to simulate the click event on the window.
Post 01 Dec 2006, 18:01
View user's profile Send private message Reply with quote
coconut



Joined: 02 Apr 2004
Posts: 326
Location: US
coconut 01 Dec 2006, 22:08
you can use keybd_event or sendmessage with wm_keydown/wm_keyup api's
Post 01 Dec 2006, 22:08
View user's profile Send private message Reply with quote
SPTH



Joined: 24 Jul 2004
Posts: 91
SPTH 01 Dec 2006, 22:58
Thank you, that helped a lot. I can get the handle of the top-window now.

But SendMessage does not work - please take a look:

Code:

        invoke  MessageBox, 0x0, "change to notepad", "blah", 0x0

        invoke  Sleep, 3000

        invoke  GetForegroundWindow
        mov     dword [hWindow], eax


        invoke  Sleep, 1000

        invoke  SendMessage, \
                dword [hWindow], \
                "aaa", \
                0x0, \
                0x0, \
    


I want to write "aaa" to notepad, for example. The handle is correct - tested with SetForegroundWindow. But nothing appears in NotePad.

What could be the problem? And how can I send a MouseClick? I can not find useful explanations with google and msdn, sorry. Just general SendMessage stuff.

kind regards,
Mario
Post 01 Dec 2006, 22:58
View user's profile Send private message Reply with quote
coconut



Joined: 02 Apr 2004
Posts: 326
Location: US
coconut 02 Dec 2006, 03:26
would be something like (in pseudo code)

invoke findwindowex 0,0,notepad_class,0 ;find notepad
invoke findwindowex eax,0,edit_class,0 ;find notepads edit window
mov [hwndedit],eax ;store edit hwnd for later use
invoke sendmessage,[hwndedit],WM_KEYDOWN,41,0 ;send 'A'
invoke sendmessgae,[hwndedit],WM_KEYUP,41,0 ;send 'A'


for mouse you could do:

invoke sendmessage,[hwndedit],WM_LBUTTONDOWN,0
invoke sendmessage,[hwndedit],WM_LBUTTONUP,0

which would simulate a left mouse click into edit window (which may have no effect)
Post 02 Dec 2006, 03:26
View user's profile Send private message Reply with quote
SPTH



Joined: 24 Jul 2004
Posts: 91
SPTH 02 Dec 2006, 05:02
Great, thanks for the answeres - now I was able to send keys to NotePad (via FindWindowEx). Well, the real program should send keys to a program with unknown class-names and child-class names.

I want to send a key or a mouse-click to a child-window; which is at the position of the mouse. I've tried it again with Notepad - but ChildWindowFromPoint returns 0x0.

In MSDN:
ChildWindowFromPoint -> Return Values: "If the function succeeds, the return value is the handle of the child window that contains the point, even if the child window is hidden or disabled. If the point lies outside the parent window, the return value is NULL. If the point is within the parent window but not within any child window, the return value is the handle to the parent window."

Code:
.data

  hWindow dd 0x0
  hCurWin dd 0x0

  tagPOINT:
    POINT_x     dd 0x0
    POINT_y     dd 0x0



.code
start:

        invoke  MessageBox, 0x0, "change to notepad", "blah", 0x0

        invoke  Sleep, 3000

        invoke  GetCursorPos, tagPOINT

        invoke  GetForegroundWindow
        mov     dword [hWindow], eax

        invoke  ChildWindowFromPoint, dword [hWindow], tagPOINT
        mov     dword [hCurWin], eax   

        cmp   eax, 0x0
        je      shit 

        invoke  MessageBox, 0x0, hWindow, hCurWin, 0x0  

invoke ExitProcess, 0x0

shit:
.end start          
    


Do you have any idea why this does not work?

kind regards,
Mario
Post 02 Dec 2006, 05:02
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 02 Dec 2006, 14:05
Quote:

I want to send a key or a mouse-click to a child-window; which is at the position of the mouse

So why do you use GetForegroundWindow? Use WindowFromPoint and then ChildWindowFromPoint.

Not sure but for the child part maybe you will need something like this
Code:
.loop: ; First time EAX contains the result of WindowFromPoint
invoke ChildWindowFromPoint, eax, tagPOINT
test eax, eax
jz .exit
mov [hWindow], eax
jmp .loop
; if you have a PPro class CPU this is better:
; .loop:
; invoke ChildWindowFromPoint, eax, tagPOINT
; test eax, eax
; cmovnz [hWindow], eax
; jnz .loop
.exit:    
Post 02 Dec 2006, 14:05
View user's profile Send private message Reply with quote
coconut



Joined: 02 Apr 2004
Posts: 326
Location: US
coconut 02 Dec 2006, 14:30
do you want to send keys/mouse to the window under the mouse, or a edit class child of that window?
Post 02 Dec 2006, 14:30
View user's profile Send private message Reply with quote
SPTH



Joined: 24 Jul 2004
Posts: 91
SPTH 02 Dec 2006, 16:00
Thanks a lot - now it works :-)

The problem was a wrong description in MSDN:

Quote:

HWND WindowFromPoint(

POINT Point // structure with point
);


Right would be:

Quote:

HWND WindowFromPoint(
LONG x // X_Point
LONG y // Y_Point
);


Two arguments, not just one pointer to the POINT Structure[/quote]
Post 02 Dec 2006, 16:00
View user's profile Send private message Reply with quote
Goplat



Joined: 15 Sep 2006
Posts: 181
Goplat 02 Dec 2006, 16:36
SPTH: Actually, the definition is correct, but you're supposed to put the actual POINT on the stack, not a pointer to it.
Post 02 Dec 2006, 16:36
View user's profile Send private message Reply with quote
SPTH



Joined: 24 Jul 2004
Posts: 91
SPTH 02 Dec 2006, 17:36
Ok, thank you - this makes sense: POINT-Structure = 2x dword -> I have to push 2x dwords, not two arguments (which is here the same).

I've finished the code - if anybody is interested in:
Code:
.data

  hWindow dd 0x0

  tagPOINT:
    POINT_x     dd 0x0
    POINT_y     dd 0x0

  POINT_Struc:
    X_PS        dw 0x0
    Y_PS        dw 0x0

lpClassName: times 0x30 db 0x0

.code
start:

        invoke  MessageBox, 0x0, "change to notepad", "blah", 0x0

        invoke  Sleep, 3000

        invoke  GetCursorPos, tagPOINT

        invoke  WindowFromPoint, dword[POINT_x], dword[POINT_y]
        mov     dword [hWindow], eax

        invoke  GetClassName, dword[hWindow], lpClassName, 0x20

        mov     eax, dword [POINT_x]
        mov     dword [POINT_Struc], eax

        mov     eax, dword [POINT_y]
        mov     word[Y_PS], ax


        invoke  SendMessage, [hWindow], WM_CHAR, 67, 0
        invoke  Sleep, 3000


        invoke SendMessage,[hWindow], WM_LBUTTONDOWN, 0x0, dword [POINT_Struc]
        invoke SendMessage,[hWindow], WM_LBUTTONUP, 0x0, dword [POINT_Struc]

        invoke  Sleep, 1000
        invoke  SendMessage, [hWindow], WM_CHAR, 67, 0


        invoke  MessageBox, 0x0, "End", lpClassName, 0x0
invoke ExitProcess, 0x0 
    
Post 02 Dec 2006, 17:36
View user's profile Send private message Reply with quote
farrier



Joined: 26 Aug 2004
Posts: 274
Location: North Central Mississippi
farrier 03 Dec 2006, 04:17
I use the following in a program which brings DownloadAcceleratorPlus to the topmost window, moves the mouse pointer to one of two buttons--based on user choice--and "clicks" the mouse. I use this when in the country with 24K dial-up, and downloading podcasts takes 4-5 hours. Sometimes the connection to a download server is lost, and the program "clicks" the resume or resume all button. This only works for servers supporting "resume download".

Code:
        .elseif [wmsg], e, WM_TIMER
                .if     [choice], e, 0
                        xor     eax, eax
                        jmp     .dir_out
                .endif
                invoke  FindWindow, _DAP, 0
                push    eax
                invoke  ShowWindow, eax, SW_RESTORE
                pop             eax
                push    eax
                invoke  GetWindowRect, eax, dapRect             ;get coordinates of DAP window
                mov             eax, [dapRect.left]
                mul             [xFactor]
                add             eax, [xDisp]
                mov             [dapRect.left], eax
                mov             eax, [dapRect.top]
                mul             [yFactor]
                add             eax, [yDisp]
                mov             [dapRect.top], eax
                pop             eax
                push    eax
                invoke  SetForegroundWindow, eax
                pop             eax
                invoke  SetActiveWindow, eax
                invoke  mouse_event, MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_MOVE, [dapRect.left], [dapRect.top], NULL, NULL
                invoke  mouse_event, MOUSEEVENTF_LEFTDOWN, NULL, NULL, NULL, NULL
                invoke  Sleep, 100
                invoke  mouse_event, MOUSEEVENTF_LEFTUP, NULL, NULL, NULL, NULL    


This gets executed every X seconds in the WM_TIMER handling section.

hth,

farrier
[/code]

_________________
Some Assembly Required
It's a good day to code!
U.S.Constitution; Bill of Rights; Amendment 1:
... the right of the people peaceably to assemble, ...
The code is dark, and full of errors!
Post 03 Dec 2006, 04:17
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 03 Dec 2006, 16:30
Post 03 Dec 2006, 16:30
View user's profile Send private message Reply with quote
farrier



Joined: 26 Aug 2004
Posts: 274
Location: North Central Mississippi
farrier 04 Dec 2006, 10:37
Okay, I avoided SendInput when I wrote this because I was still running Win95. So this was fairly easy and it works.

Code:
;               invoke  mouse_event, MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_MOVE, [dapRect.left], [dapRect.top], NULL, NULL
;               invoke  mouse_event, MOUSEEVENTF_LEFTDOWN, NULL, NULL, NULL, NULL
;               invoke  Sleep, 100
;               invoke  mouse_event, MOUSEEVENTF_LEFTUP, NULL, NULL, NULL, NULL
                ;set data for mouse move
                push    [dapRect.left]
                pop     [click_event.mi.dx]
                push    [dapRect.top]
                pop     [click_event.mi.dy]
                mov     [click_event.mi.dwFlags], MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_MOVE
                ;set data for left click down
                mov     [down_event.mi.dwFlags], MOUSEEVENTF_LEFTDOWN
                ;set data for left click up
                mov     [up_event.mi.dwFlags], MOUSEEVENTF_LEFTUP
                invoke  SendInput, 3, click_event, sizeof.INPUT
    

Using the following:
Code:
.data
click_event     INPUT   INPUT_MOUSE, 0          ;move
down_event      INPUT   INPUT_MOUSE, 0          ;button_down
up_event        INPUT   INPUT_MOUSE, 0          ;button_up
    

And:
Code:
INPUT_MOUSE             equ 0
INPUT_KEYBOARD          equ 1
INPUT_HARDWARE          equ 2
KEYEVENTF_EXTENDEDKEY   equ 1h
KEYEVENTF_KEYUP         equ 2h
KEYEVENTF_UNICODE       equ     4h
KEYEVENTF_SCANCODE      equ     8h
MOUSEEVENTF_MOVE        equ 1h
MOUSEEVENTF_LEFTDOWN    equ 2h
MOUSEEVENTF_LEFTUP      equ 4h
MOUSEEVENTF_RIGHTDOWN   equ 8h
MOUSEEVENTF_RIGHTUP     equ 10h
MOUSEEVENTF_MIDDLEDOWN  equ 20h
MOUSEEVENTF_MIDDLEUP    equ 40h
MOUSEEVENTF_XDOWN       equ     80h
MOUSEEVENTF_XUP         equ     100h
MOUSEEVENTF_WHEEL       equ 800h
MOUSEEVENTF_VIRTUALDESK equ     4000h
MOUSEEVENTF_ABSOLUTE    equ 8000h

KEYINPUT        struct
        wVk             dw      ?
        wScan           dw      ?
        dwFlags         dd      ?
        time            dd      ?
        dwExtraInfo     dd      ?
KEYINPUT        ends

HARDWAREINPUT   struct
        uMsg    dd      ?
        wParamL dw      ?
        wParamH dw      ?
HARDWAREINPUT   ends

MOUSEINPUT      struct
        dx              dd      ?
        dy              dd      ?
        mouseData       dd      ?
        dwFlags         dd      ?
        time            dd      ?
        dwExtraInfo     dd      ?
MOUSEINPUT      ends

INPUT   struct
        type    dd      ?
        union
                mi      MOUSEINPUT
                ki      KEYINPUT
                hi      HARDWAREINPUT
        ends
INPUT   ends    

_________________
Some Assembly Required
It's a good day to code!
U.S.Constitution; Bill of Rights; Amendment 1:
... the right of the people peaceably to assemble, ...
The code is dark, and full of errors!
Post 04 Dec 2006, 10:37
View user's profile Send private message Reply with quote
OzzY



Joined: 19 Sep 2003
Posts: 1029
Location: Everywhere
OzzY 04 Dec 2006, 14:32
It's just easier to use AutoIt.
But it's nice to see how things actually work! Very Happy
Post 04 Dec 2006, 14:32
View user's profile Send private message Reply with quote
SPTH



Joined: 24 Jul 2004
Posts: 91
SPTH 04 Dec 2006, 23:07
One more question:

I want to send F1-Key to a window, but it may not be the forground window.

Code:

        invoke  keybd_event, VK_F1, 0x0, 0x0, 0x0
    


That means, I can not use that code.
I've tried wm_keydown and wm_keyup, but it does not work with VK_F1.

Does anybody know, how I can send Key-Events to a window, which is not the forground window!?

And second question:
I want to click to the window, but the mouse POINT is relative to the POINT of the window. Do you know the API, which returns the position of the window (so I can calculate the relative position of the mouse POINT)

thanks you so much - I would have never coded this program without your help (never used window's messages or events with assembler. it's very interesting, but it is part of multi-threating - which I've never used that stuff)

kind regards,
Mario
Post 04 Dec 2006, 23:07
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 04 Dec 2006, 23:12
Using SendMessage?
Post 04 Dec 2006, 23:12
View user's profile Send private message Reply with quote
coconut



Joined: 02 Apr 2004
Posts: 326
Location: US
coconut 05 Dec 2006, 00:29
try maybe GetWindowInfo or GetWindowRect
Post 05 Dec 2006, 00:29
View user's profile Send private message Reply with quote
coconut



Joined: 02 Apr 2004
Posts: 326
Location: US
coconut 06 Dec 2006, 22:04
how do you know VK_F1 doesnt work? F1 is usually reserved for bringing up help topics, do you expect some other result?
Post 06 Dec 2006, 22:04
View user's profile Send private message Reply with quote
Picnic



Joined: 05 May 2007
Posts: 1391
Location: Piraeus, Greece
Picnic 05 Jun 2008, 17:55
Hi all,
Which keyboard event, what way should i use to have fast keyboard response ?
Now i'm moving my sprite 4 directions using GetKeyState inside a WM_TIMER event.

thanks in advance.
Post 05 Jun 2008, 17:55
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:  
Goto page 1, 2  Next

< 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-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.