Sign in to follow this  
Followers 0
Dae

WinGetHandle

7 posts in this topic

I've been reading through a lot of "click minimized windows" topics. I tried all the scripts and none of them worked. They all use WinGetHandle() for the handle, and nobody seems to have problems with it. I'm not even trying it on a minimized window either. Although Larry's appears to work, I wonder why the others don't. I'd be great if I could use WinGetHandle() instead. The below right clicks the desktip icon 2 columns over, and 3 rows down.

Replace ControlGetHandle($title, "", $control) with WinGetHandle($title) and the script won't work.

AutoItSetOption("WinTitleMatchMode", 4)

SendClick("right", "Program Manager", "SysListView321", 125, 215)

Func SendClick($click, $title, $control, $x, $y)
    Local $HWND = ControlGetHandle($title, "", $control)
    ;Local $HWND = WinGetHandle($title)
    
    If @error Then
        Return 0
    Else
        Local $BUTTON, $BUTTONDOWN, $BUTTONUP
        
        If $click == "left" Then
            $BUTTONDOWN = 0x00000201
            $BUTTONUP = 0x00000202
            $BUTTON = 0x00000001
        ElseIf $click == "right" Then
            $BUTTONDOWN = 0x00000204
            $BUTTONUP = 0x00000205
            $BUTTON = 0x00000002
        Else
            Return 0
        EndIf

        Local $COORD = MakeLong($x, $y)
        Local $user32 = DLLOpen("user32.dll")
        
        DLLCall($user32, "int", "PostMessage", "hwnd", $HWND, "int", $BUTTONDOWN, "int", $BUTTON, "long", $COORD)
        DLLCall($user32, "int", "PostMessage", "hwnd", $HWND, "int", $BUTTONUP, "int", $BUTTON, "long", $COORD)
        
        DLLClose($user32)
        
        Sleep(175 + Random(1, 25, 1));
        
        Return 1
    EndIf
EndFunc

Func MakeLong($loWord, $hiWord)
    Return BitOR($hiWord * 0x10000, BitAND($loWord, 0xFFFF))
EndFunc

BTW I'm also trying it on "MSN Messenger" (which control classnameNN is "DirectUIHWND1").

Any help is greatly appreciated!

Share this post


Link to post
Share on other sites



Using WinGetHandle works very well for games, usually. The game I wrote my _MouseClick function for is Dark Ages and it works beautifully. I had to write another one with a control handle to make it work on Windows forms, however, but the control-based one doesn't work on the game. It all depends on what you're using it for.

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Thought I'd clarify a little more, with examples.

The following clicks the pause button for my Winamp:

#include "PostMessage_UDF.au3"

Opt("WinTitleMatchMode", 4)

$hWnd = WinGetHandle("classname=Winamp v1.x")
If @error Then Exit

_MouseClick($hWnd, "left", 75, 100)oÝ÷ Ù.Â)ebqëajÒ#ºËaj÷­¢Ç§u£(ºÇ'$¶a{§v7öÍ7ê§vz-iÊ'¶º%Z)ÚhzÉ÷öØZ½å¢Ú0±Ê'¶º%°z0z÷«¶¢YhÂ)àrXËay'§tX¥y»­¶è¥¢Ú0°¸¯xǬ±éàz²Â)Ý£®¶­sb6æ6ÇVFRgV÷Cµ÷7DÖW76vUõTDbæS2gV÷C° ¤÷BgV÷CµvåFFÆTÖF6ÖöFRgV÷C²ÂB ¤vÆö&Âb33c¶væBÒvävWDæFÆRgV÷C¶6Æ76æÖSÔÕvæF÷t6Æ72gV÷C²¤bW'&÷"FVâW@ ¥ôÖ÷W6T6Æ6²6öçG&öÄvWDæFÆRb33c¶væBÂgV÷C²gV÷C²ÂgV÷C´F&V7ETtäCgV÷C²ÂgV÷C¶ÆVgBgV÷C²ÂcrÂS

Had to get the control's handle for that one because it uses Windows controls.

So, you see: you have to get a handle for the lower-most 'control' to which you're sending the mouseclick. If a window doesn't use controls, get a handle to the window; if it does use controls, get a handle to the control. Games generally do not use controls.

Edited by Outshynd

Share this post


Link to post
Share on other sites

Sweeeet, thank you very much for the fine explanation Outshynd.

Share this post


Link to post
Share on other sites

Thought I'd attach the PostMessage_UDF.au3 that I use. Keep in mind: it's written specifically for one game so much of it won't be any use to you but you can look at the functions and copy the ones you need/want.

PostMessage_UDF.au3

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Thought I'd attach the PostMessage_UDF.au3 that I use. Keep in mind: it's written specifically for one game so much of it won't be any use to you but you can look at the functions and copy the ones you need/want.

Looks cool, I'm trying to learn from it. Could you tell please me why you did these?

1) I noticed you're using 1 for left and 2 for right clicks in _MouseClick (which are actually 0x001 and 0x002 in full) but for left clicks in game you use 0. It doesn't seem like anything is required, so using 0 is fine, but 1 (0x001) isn't required for left clicks at all anyway. Wouldn't the game possibly catch onto that? Any other reason for using 0 instead of 1 in game?

DllCall($user32, "int", "PostMessage", "hwnd", $hWnd, "int", 0x201, "int", 1, "long", $lParam)oÝ÷ Ù«­¢+Ù±±
±° ÀÌØíÕÍÈÌÈ°ÅÕ½Ðí¥¹ÐÅÕ½Ðì°ÅÕ½ÐíA½ÍÑ5ÍÍÅÕ½Ðì°ÅÕ½Ðí¡Ý¹ÅÕ½Ðì°ÀÌØí¡]¹°ÅÕ½Ðí¥¹ÐÅÕ½Ðì°ÁàÈÀаÅÕ½Ðí¥¹ÐÅÕ½Ðì°È°ÅÕ½Ðí±½¹ÅÕ½Ðì°ÀÌØí±AÉ´¤oÝ÷ Ûe¡ÉÚ2¢êh²Ö¦¢ëÞë,j´Çm4mçè­æ¥j.±ç%É,§×hzÉ÷öׯzy¨½ì¨º¹¨ºÇ·"Ç(÷«¶)ඤ{+-®)à°(kjwi¢Ëbazg¬±¨mëmz»ajp¨Úè'§u×­yËZn)b·,"±îbqçmê''b}÷«zwmëpyéò¢êæ¢ërXƧt¶«¯-ý³¬Ê¢}ý¶ë¶ zw«jY¨ºÇ'$¥ªÚ*.ºÇ´ë¬zÍ1ÓMçâ®Ë¡×¢²¬jwmërÝ̨º»ºÚ"µÍØ[
    ÌÍÝÙÌ  ][ÝÚ[ ][ÝË  ][ÝÔÜÝYÜØYÙI][ÝË   ][ÝÚÛ    ][ÝË  ÌÍÚÛ    ][ÝÚ[ ][ÝËK ][ÝÚ[ ][ÝË  ][ÝÛÛÉ][ÝËÓXZÙSÛÊ ÌÍÞ  ÌÍÞJJBØ[
    ÌÍÝÙÌ  ][ÝÚ[ ][ÝË  ][ÝÔÜÝYÜØYÙI][ÝË   ][ÝÚÛ    ][ÝË  ÌÍÚÛ    ][ÝÚ[ ][ÝË  ][ÝÚ[ ][ÝË  ][ÝÛÛÉ][ÝËÓXZÙSÛÊ ÌÍÞ  ÌÍÞJJoÝ÷ Ù«­¢+Ù±±
±° ÀÌØíÕÍÈÌÈ°ÅÕ½Ðí¥¹ÐÅÕ½Ðì°ÅÕ½ÐíA½ÍÑ5ÍÍÅÕ½Ðì°ÅÕ½Ðí¡Ý¹ÅÕ½Ðì°ÀÌØí¡]¹°ÅÕ½Ðí¥¹ÐÅÕ½Ðì°ÁàÈÀÄ°ÅÕ½Ðí¥¹ÐÅÕ½Ðì°À°ÅÕ½Ðí±½¹ÅÕ½Ðì°}5­1½¹ ÀÌØíà°ÀÌØí䤤)±±
±° ÀÌØíÕÍÈÌÈ°ÅÕ½Ðí¥¹ÐÅÕ½Ðì°ÅÕ½ÐíA½ÍÑ5ÍÍÅÕ½Ðì°ÅÕ½Ðí¡Ý¹ÅÕ½Ðì°ÀÌØí¡]¹°ÅÕ½Ðí¥¹ÐÅÕ½Ðì°ÁàÈÀÈ°ÅÕ½Ðí¥¹ÐÅÕ½Ðì°À°ÅÕ½Ðí±½¹ÅÕ½Ðì°}5­1½¹ ÀÌØíà°ÀÌØíä¤

Seems like yours works anyway, but what was your reason for not using it?

Thanks again!

Edited by Dae

Share this post


Link to post
Share on other sites

Everything I learned to write the UDF was from using Spy++ (or Winspector Spy) to spy on the messages received by the game window. I don't remember exactly why I used the wParams that I used--it's been nearly two years since I wrote it. If you use Winspector Spy to monitor mouse/keyboard messages received by a program, you can see for yourself which wParam is used, mine or Larry's. I really don't know which one is correct or if either is. Come to think of it: the wParam (1 for left, 2 for right) in the WM_MOUSEDOWN message had something to do with the mouse button state. 0x01 is mouse button 1, 0x02 is 2. I don't remember why it's important but I can remember it not working when I just used 0.

I found that mouse clicks in the game I was using were much more reliable when a mousemove was posted beforehand. For instance, if I was moving my mouse in the game when the mouseclick was sent, it'd click in the wrong place or not at all.

As far as the converting certain characters with Chr(), I found that the particular game for which I wrote it uses things like VK_OEM_3 (0xC0) in place of tilde (Asc("`") and Asc("~") do not equal 0xC0) so I did a simple StringReplace. Also replaced things like {ENTER} and {SHIFT} with their prospective virtual key codes (all of which can be found here).

Anyway, I'm feeling a bit scatter-brained at the moment so if anything isn't clear just let me know. No offense will be taken. I wish I could remember more for you as to why I did the things I did.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0