AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

ControlGetFocus disables Doubleclick
Goto page Previous  1, 2
 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Bug Reports
View previous topic :: View next topic  
Author Message
David Andersen



Joined: 15 Jul 2005
Posts: 85
Location: Denmark

PostPosted: Tue Nov 28, 2006 11:07 am    Post subject: Reply with quote

Ok. Let's say a symbolic 100$... Wink
Back to top
View user's profile Send private message Send e-mail Visit poster's website
PhiLho



Joined: 27 Dec 2005
Posts: 6721
Location: France (near Paris)

PostPosted: Wed Nov 29, 2006 10:52 am    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
David Andersen



Joined: 15 Jul 2005
Posts: 85
Location: Denmark

PostPosted: Wed Nov 29, 2006 11:25 am    Post subject: Reply with quote

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
View user's profile Send private message Send e-mail Visit poster's website
David Andersen



Joined: 15 Jul 2005
Posts: 85
Location: Denmark

PostPosted: Wed Nov 29, 2006 1:48 pm    Post subject: Reply with quote

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. Cool I, therefore, think that it could be used instead of the current ControlGetFocus, because it does not hinder the double-click.
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Chris
Site Admin


Joined: 02 Mar 2004
Posts: 10467

PostPosted: Wed Nov 29, 2006 5:42 pm    Post subject: Reply with quote

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
View user's profile Send private message Send e-mail
Mistrel



Joined: 12 Sep 2005
Posts: 188

PostPosted: Thu Mar 15, 2007 9:46 pm    Post subject: Reply with quote

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
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Bug Reports All times are GMT
Goto page Previous  1, 2
Page 2 of 2

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group