 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
David Andersen
Joined: 15 Jul 2005 Posts: 85 Location: Denmark
|
Posted: Tue Nov 28, 2006 11:07 am Post subject: |
|
|
Ok. Let's say a symbolic 100$...  |
|
| Back to top |
|
 |
PhiLho
Joined: 27 Dec 2005 Posts: 6721 Location: France (near Paris)
|
Posted: Wed Nov 29, 2006 10:52 am Post subject: |
|
|
I am not too sure of your ultimate goal, which seems to be a macro recorder. Did you saw Thalon's update for AutoScriptWriter?
You seem to want to get a sequence of active controls, ie. a list of controls getting focus and their order. The difficulty is to get the classNN of the control without using ControlFocus which is problematic.
Using pure DllCalls is hard, if possible, because AutoHotkey creates these classNN by using EnumChildWindows API function which requires a callback function, something we can't do in AHK.
Well, I found a solution, perhaps it is usable for you: I first get a list of the controls of the active window. Then I poll the control with focus using the API function pointed out by Chris. The trick is that I map the handles of these controls to their classNN (for a given instance, of course).
Let me know if I am closer of your needs.
| Code: | WinGet ctrlList, ControlList, A
; Built an array indexing the control names by their hwnd
Loop Parse, ctrlList, `n
{
ControlGet hwnd, Hwnd, , %A_LoopField%, A
hwnd += 0 ; Convert from hexa to decimal
ctrlList@%hwnd% := A_LoopField
}
; This script retrieves the ahk_id (HWND) of the active window's focused control.
; This script requires Windows 98+ or NT 4.0 SP3+.
GetFocusedControl()
{
guiThreadInfoSize = 48
VarSetCapacity(guiThreadInfo, guiThreadInfoSize, 0)
addr := &guiThreadInfo
DllCall("RtlFillMemory"
, "UInt", addr
, "UInt", 1
, "UChar", guiThreadInfoSize) ; Below 0xFF, one call only is needed
If not DllCall("GetGUIThreadInfo"
, "UInt", 0 ; Foreground thread
, "UInt", &guiThreadInfo)
{
ErrorLevel := A_LastError ; Failure
Return 0
}
focusedHwnd := *(addr + 12) + (*(addr + 13) << 8) + (*(addr + 14) << 16) + (*(addr + 15) << 24)
Return focusedHwnd
}
#c::
SetTimer ShowFocus, 200
ShowFocus:
hwnd := GetFocusedControl()
ctrl := ctrlList@%hwnd%
ToolTip Focus on %ctrl%
Return
Escape::ExitApp
| Tested on Wordpad, I can still select a word with double-click. _________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2") |
|
| Back to top |
|
 |
David Andersen
Joined: 15 Jul 2005 Posts: 85 Location: Denmark
|
Posted: Wed Nov 29, 2006 11:25 am Post subject: |
|
|
| EXCELLENT PhiLho! A perfectly working solution. If you send me a private message with your email address, I will transfer the money to you. |
|
| Back to top |
|
 |
David Andersen
Joined: 15 Jul 2005 Posts: 85 Location: Denmark
|
Posted: Wed Nov 29, 2006 1:48 pm Post subject: |
|
|
I have tested your code a bit more and it seems like the whole code (including the initialization) can be run several times per second without taking too much CPU capacity. I, therefore, think that it could be used instead of the current ControlGetFocus, because it does not hinder the double-click. |
|
| Back to top |
|
 |
Chris Site Admin
Joined: 02 Mar 2004 Posts: 10467
|
Posted: Wed Nov 29, 2006 5:42 pm Post subject: |
|
|
| David Andersen wrote: | | it could be used instead of the current ControlGetFocus, because it does not hinder the double-click. | It can't be used unconditionally because then the command would no longer work on Windows 95/NT4-pre-SP3. However, I've made a note to implement this in AutoHotkey v2 so that newer OSes will get the benefit (the old method will still be used on older OSes).
Thanks. |
|
| Back to top |
|
 |
Mistrel
Joined: 12 Sep 2005 Posts: 188
|
Posted: Thu Mar 15, 2007 9:46 pm Post subject: |
|
|
| Chris wrote: | Assuming that isn't sufficient, you could limit your calls to ControlGetFocus to only when a keystroke or mouseclick occurs. A keystroke event can be detected with the Input command. A mouseclick can be detected by making all mouse buttons into pass-through hotkeys:
~LButton::
~RButton::
~MButton::
; For LButton in particular, give time for a double click to occur beforehand:
Sleep, 500
ControlGetFocus, FocusedControl, A
return |
I would like to make a comment here for anyone using the forum search that Chris's example returns the control name of the control last active since the script is activated before the mouse click actually happens.
The following hotkey would be correct if you want to retrieve the name of the control last active after the mouse is clicked.
| Code: | ~LButton up::
~RButton up::
~MButton up::
Sleep, 500
ControlGetFocus, FocusedControl, A
msgbox %FocusedControl%
return |
And here is another method that does not require Sleep.
| Code: | ~LButton::
~MButton::
if (KeyDown=1 || KeyDown="") {
MouseGetPos, , , id, FocusedControl ;Get the ID of the control beneath the mouse
}
msgbox %FocusedControl%
return
~LButton up::
~MButton up::
KeyDown=1
return |
|
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|