This post will answer some questions like :
"how do i press a button on a minimized window?"
"how do i select this f****** menu item, WinMenuSelectItem doesn't work with it?!"
"this is a skinnable window.... how do i send a cmd that works everytime?"
"and what about *hidden* windows?!"
requirements:
Winspector Spy (http://www.windows-spy.com)
AHK's latest version
Note: I'm using WinXP Pro (SP1) ... if you use a different OS then your params may change (only applicable to apps like wordpad and notepad etc that come with windows, for others params won't change).
first try selecting the Insert > Picture in outlook express's new message window by WinMenuSelectItem...
WinMenuSelectItem, New Message,, &Insert, &Picture...
even try AU3's command:
WinMenuSelectItem ( "New Message", "", "&Insert" , "&Picture...")
i had no luck!
now try this:
PostMessage, 0x111, 40239, 0, , New Messageworks like a charm!!
but what the hell is that?... 0x111 is that hex code of wm_command message. and 40239 is the code that this particular window understands as menu-item 'Insert Picture' selection.
now let me tell u how to find this value:
open Winspector Spy and new message window. drag the crosshair from Winspector Spy's window to new message window's titlebar. now right click the selected window in the list on left and select 'messages'. right click the blank window and select 'edit msg filter' . press the 'filter all' button and then dbl click 'wm_command' on the list on left. this way you will only monitor this message.
now go to New Message window and select Insert> Picture.
come back to Winspector Spy and pres the traffic light button to pause monitoring... now expand the wm_command messages that've accumulated (forget others if any). now what you want to look for is a code 0 message. sometimes there're wm_command messages saying 'win activated' or 'win distroyed' and other crap... not needed. u'll find that there's be a message saying 'Control ID: 40239' ...that's it!
now put that in the above command and u've got it!! ..its the wparam value.
for next example i'm taking paint bcoz possibly everyone will have that. now let's say its an app where u've to select a tool from a toolbar using AHK. say dropper tool is to be selected.
what'd u do? ... most probably a mouse click at the toolbar button. right?... but toolbars can be moved and hidden! ...this one can be moved/hidden too... so if the target user has done any of this then ur script will fail at that point. but the following command will still work:
PostMessage, 0x111, 639,,,untitled - Paint
also mouse clicks requires window activation.... while this doesn't!!!
here are some more examples:
;makes writing color teal in wordpad ;PostMessage, 0x111, 32788, 0, , Document - WordPad ;opens about box in notepad ;PostMessage, 0x111, 65, 0, , Untitled - Notepad ;toggles word-wrap in notepad ;PostMessage, 0x111, 32, 0, , Untitled - Notepad ;play/pause in Windows Media Player ;PostMessage, 0x111, 32808, 0, , Windows Media Player
Note: There are apps with which this technique doesn't work. I've had mixed luck with VB and Delphi apps. This technique is best used with C, C++ apps. With VB apps the 'LParam' of the same command keeps changing from one run to another. With Delphi apps... the GUI of some apps doesn't even use wm_command. It probably uses mouse pos & clicks.
You can find the offline version of this tutorial in the AutoHotkey help file (link in PostMessage/SendMessage command help)
This was Postmessage, sendmessage works the same way but additionally waits for a return value... this has uses too, like it can get you the currently playing track in winamp (see AHK help for example script)
Here are a couple of notes :
1. The note above regarding OS being XP and msg values changing with different OSes is purely cautionary. if you've found a msg that works on your system (with a certain version of a software) then you can be sure it'll work on another system too with the same version of the software. most softwares keep these msg values same even on different versions (eg. windows media player and winamp).
2. If you've set the filter to show only wm_command in Winspector Spy and still you're getting a flood of messages then right click that message and select hide (msg name)... you don't want to have a look at a msg that appears without you interacting with the target software.
3. The right pointing arrow in Winspector Spy shows the msg values and the blurred left pointing arrows show the returned value. A 0 (zero) value can by default safely be taken as 'no error' (use it with sendmessage, the retrun value is in %errorlevel%).
4. for posting to part - title match add this to script:
SetTitleMatchMode, 2
for posting to hidden windows add this to script:
DetectHiddenWindows, On
a cool example:
;this will suspend the hotkeys of a running AHK script! ;PostMessage, 0x111, 32800,,,AutoHotkey v1.0.
this was to get you acquainted with the advanced commands that Chris has put in AHK... well it took some coaxing to get him to do it but it was well worth it!!
I've uploaded a long list of messages that can be sent from ahk here
You can use this script to find the hex code of a particular message very fast. The code also gets copied to the clipboard.
MainWnd = MsgSeeker by Rajat SetKeyDelay, 0 Loop, Read, %A_ScriptDir%\messages.txt { IfEqual, A_LoopReadLine,, Continue ItemList = %ItemList%|%A_LoopReadLine% } StringTrimLeft, ItemList, ItemList, 1 Gui, +Border -Caption Gui, Font,, Courier Gui, Add, Edit, x6 y5 w650 h20, Gui, Add, ListBox, x6 y35 w770 h220 vSelItem, Gui, Add, Button, x666 y5 w50 h20 Default, &Open Gui, Add, Button, x726 y5 w50 h20, &Add Gui, Show, h252 w781, %MainWnd% SetTimer, GetText, 100 Return Up:: IfWinNotActive, %MainWnd%, { Send, {Up} Return } ControlGetFocus, CurrCtrl, %MainWnd% IfEqual, CurrCtrl, Edit1 ControlSend, ListBox1, {Up}, %MainWnd% Return Down:: IfWinNotActive, %MainWnd%, { Send, {Down} Return } ControlGetFocus, CurrCtrl, %MainWnd% IfEqual, CurrCtrl, Edit1 ControlSend, ListBox1, {Down}, %MainWnd% Return GetText: ControlGetText, CurrText, Edit1, %MainWnd% IfNotEqual, CurrText, %LastText% { LastText = %CurrText% MatchList = Loop, Parse, ItemList, | { CurrItem = %A_LoopField% MatchFound = Y Loop, Parse, CurrText, %A_Space% IfNotInString, CurrItem, %A_LoopField% MatchFound = N IfEqual, MatchFound, Y MatchList = %MatchList%|%CurrItem% } StringTrimLeft, MatchList, MatchList, 1 GuiControl,, ListBox1, |%MatchList% } Return ButtonOpen: GetKeyState, ShKey, Shift ControlFocus, ListBox1, %MainWnd% ControlSend, ListBox1, {Space}, %MainWnd% Gui, Submit Sleep, 50 IfEqual, ShKey, D, StringUpper, SelItem, SelItem StringGetPos, tPos, SelItem, %A_Tab% StringLeft, SelItem, SelItem, %tPos% ClipBoard = %SelItem% ExitApp Return ButtonAdd: ControlGetText, CurrText, Edit1, %MainWnd% IfEqual, CurrText,, Return FileAppend, `n%CurrText%, %A_ScriptDir%\Files\ItemList.txt ItemList = %ItemList%|%CurrText% LastText = Return ButtonExit: GuiEscape: GuiClose: ExitApp
go and explore.... and share your experiences.
feedback is welcome!
This tutorial is not meant for total newbies... no offence meant, but as AHK help already considers these as advanced functions so if after reading the tutorial u've not made head or tail of it, then plz forget it.