Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

winHWND := hwnd()


  • Please log in to reply
18 replies to this topic
corrupt
  • Members
  • 2558 posts
  • Last active: Nov 01 2014 03:23 PM
  • Joined: 29 Dec 2004
Here's the request (many possible uses)... :) . I realize that there are a few ways to accomplish this using other methods but I think that this would be a simple and very handy solution...

GuiGetHWND(["Control", "GUI #"])

Returns the Unique ID (HWND) of the specified AutoHotkey window or control.

Control - classNN or variable name of an AutoHotkey control
GUI # - The number of the GUI window where the control exists (defaults to the default Gui window)

- If Control is not specified then the function returns the HWND of the Gui Window instead
- If both Control and GUI # are not specified then the function returns the HWND of the default AutoHotkey Gui window.

Edit: changed suggested function name.
Edit Again: The following function seems to work in most cases using ClassNN to identify the control:
GuiGetHWND(xxClassNN="", xxGUI=0)
{
  If (xxGUI)
    Gui, %xxGUI%:+LastFound
  xxGui_hwnd := WinExist()
  If xxClassNN=
    Return, xxGui_hwnd
  ControlGet, xxOutputVar, Hwnd,, %xxClassNN%, ahk_id %xxGui_hwnd%
Return, xxOutputVar
}
It would be great if the ability to use a control's associated variable name could be added though... Does anyone have any suggestions?

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
You probably already know that the HWND of a GUI window can be retrieved (even if hidden) via:

Gui +LastFound
hwnd := WinExist()

As for the hwnd of GUI controls: Although I can see that such a feature would be useful, I think the percentage of people who use control hwnds in their scripts is quite low. If true, adding a built-in function (especially one with such a short name) might not be justified.

However, there is a plan to improve SendMessage/PostMessage and some of the control-targeting commands so that it's easier to work with GUI windows and their controls (perhaps by allowing control variable names in place of ClassNN). If you have some scripting need for which you can't find a suitable solution, perhaps you could post it to see if anyone else can think of anything (and if not, that would help justify adding a new function or command).

Thanks.

corrupt
  • Members
  • 2558 posts
  • Last active: Nov 01 2014 03:23 PM
  • Joined: 29 Dec 2004
Hi Chris. Thanks for the quick reply :) . I'd prefer not to use Gui +LastFound and wnd := WinExist() in some cases. I usually need to know the HWND of a Window and/or control before the window has been displayed and before any other code has been executed. Using the Active window for determining the HWND of a Gui window is not a reliable method IMO as other apps could be running that steal focus. As I mentioned, there are other methods of retrieving a HWND of a window/control depending on circumstances but I was hoping to simplify the code. I'm currently working on putting together a few Gui functions and an IDE for creating AutoHotkey Gui based scripts. A command like this could greatly simplify things (especially in making the code easier to read and understand) when working with dynamically created windows/controls.

I see your point about the name of the function. It is a bit short and not very creative. Something like GetHwnd or GuiGetHwnd (or any other name of you choosing) would work ok. I may be wrong but wouldn't this be a fairly quick addition to make as AutoHotkey should be able to determine a HWND of one of it's own windows/controls fairly easily?

PhiLho
  • Moderators
  • 6850 posts
  • Last active: Jan 02 2012 10:09 PM
  • Joined: 27 Dec 2005
We already have ControlGet Hwnd, can't we have GuiControlGet Hwnd? Chris may even have mentionned the possibility of such extension in the past (IIRC).
Posted Image vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004

I usually need to know the HWND of a Window and/or control before the window has been displayed and before any other code has been executed.

That can be done with +LastFound because it works even on hidden windows.

Using the Active window for determining the HWND of a Gui window is not a reliable method IMO as other apps could be running that steal focus.

The LastFound method does not rely on the window being active.

I may be wrong but wouldn't this be a fairly quick addition to make as AutoHotkey should be able to determine a HWND of one of it's own windows/controls fairly easily?

It would be very small in code size, but I've received criticism about the complexity of AutoHotkey and its documentation -- criticism that I agree with. Therefore, it seems best not to add new functions, commands, and built-in variables unless they would benefit more than 1% of users. This proposed feature might meet that requirement, but it would help to see more usage examples to help justify it.

In any case, the ability for non-GUI commands to work more easily with GUI controls is already on the to-do list. I wish I had more time to work on development, but lately hosting issues and other support tasks have been a distraction.

Thanks for understanding.

corrupt
  • Members
  • 2558 posts
  • Last active: Nov 01 2014 03:23 PM
  • Joined: 29 Dec 2004
Thanks for the reply. Using Gui, +LastFound at the beginning of the script seems to work ok. It does seem really cryptic though. How many users would likely think of doing that to accurately get the HWND of an AutoHotkey window (even after reading the help)? While I understand wanting to cut down on unnecessarily adding functions and commands I think this one would simplify things considerably for anyone that looks in the help file for how to retrieve a HWND. I'm not sure I understand why many methods (most buried in the help) should be used instead of one generic one. As you have noticed there are many reasons to use a HWND of a window/control in a script. I'm guessing that's why you have recently added the ability to a couple existing commands. This functionality makes more sense as a function IMO though as this is where this type of data would be used in most cases.

foom
  • Members
  • 386 posts
  • Last active: Jul 04 2007 04:53 PM
  • Joined: 19 Apr 2006
I was about to request this feature too. I need this feature for a include script i am working on. I need to know the hwnd of the gui and contolls because i want to send messages to the scriptwindow itself and dont want the user of my includescript to have to find the hwnds with windowspy.

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
Something will be implemented eventually but I don't know when. In the meantime, here's an alternate way to get control HWNDs:

Gui +LastFound
GuiHwnd := WinExist()
FirstControlHwnd := DllCall("GetDlgItem", uint, GuiHwnd, int, 3)

In the above, the red 3 signifies the first control in the window. To get the second control, use 4; and for the third, use 5; and so on.

The numbers of the controls are the order in which they were originally added.

ParanoidX
  • Members
  • 148 posts
  • Last active: Jan 14 2007 02:00 AM
  • Joined: 16 Dec 2005
a more progressive logical guess would be..

WinGet, ,hwnd, +lastfound

according to my understanding of command consistency

since Winget is where handles etc. is retreived.

But at the same time, it doesn't bother me either way and I believe Chris has enough on his plates. As long as it can be achieved. I have no probs.

and thx Chris for the hard work! really appreciate it! :wink:
Posted Image
546F206C69766520
6973204368726973742C0D746F2064696520
6973206761696E2E0D285068696C20313A323129

corrupt
  • Members
  • 2558 posts
  • Last active: Nov 01 2014 03:23 PM
  • Joined: 29 Dec 2004
Gui, Add, ListView, r20 w380, Gui #|HWND

Loop, 20 {

  mv1++4

  Gui, %A_Index%:Show, x%mv1% y%mv1% w400 h400, Window # %A_Index%

  Gui, %A_Index%:+LastFound

  Gui, %A_Index%:Add, Button, gb1, Button1

  Gui, %A_Index%:Add, Edit,, Edit1

  Gui%A_Index%_hwnd := WinExist()

  LV_Add("", "Gui " A_Index, Gui%A_Index%_hwnd)

}

MsgBox, Click Button1 to retrieve the specified HWND.

WinActivate, ahk_id %Gui1_hwnd%

Return



b1:

; - If Control is not specified then the function returns the HWND of the Gui Window instead 

; - If both Control and GUI # are not specified then the function returns the HWND of the default AutoHotkey Gui window. 

InputBox, w1_OutputVar, Get HWND, Please specify the number of the GUI Window:,, 200, 200,,,,, 10

InputBox, b1_OutputVar, Get HWND, Please specify the ClassNN of the control,, 200, 200,,,,, Button1

Res1 := GuiGetHWND(b1_OutputVar, w1_OutputVar)

If (Res1 AND b1_OutputVar<>"")

  MsgBox, Here's the HWND you requested for Gui%w1_OutputVar%`, %b1_OutputVar%:`n%res1%

Else If (Res1)

  MsgBox, Here's the HWND you requested for Gui%w1_OutputVar%:`n%res1%

Else

  MsgBox, The HWND you requested was not found. 

Return



GuiClose:

ExitApp





; **********************************

; GuiGetHWND

; **********************************

GuiGetHWND(xxClassNN="", xxGUI=0)

{

  If (xxGUI)

    Gui, %xxGUI%:+LastFound

  xxGui_hwnd := WinExist()

  If xxClassNN=

    Return, xxGui_hwnd

  ControlGet, xxOutputVar, Hwnd,, %xxClassNN%, ahk_id %xxGui_hwnd%

Return, xxOutputVar

}

; **********************************







Thalon
  • Members
  • 641 posts
  • Last active: Jan 02 2017 12:17 PM
  • Joined: 12 Jul 2005
I can only signup this wish also :D

Thalon

foom
  • Members
  • 386 posts
  • Last active: Jul 04 2007 04:53 PM
  • Joined: 19 Apr 2006
This bugged me so i investigated the source of ahk. As it seams to me changes needed to support GuiControlGet a Hwnd option are very little.

In script_gui.cpp: In the function "ResultType Line::GuiControlGet(char *aCommand, char *aControlID, char *aParam3)" add

case GUICONTROLGET_CMD_HWND:
return output_var.Assign(control.hwnd);

as last case in "switch(guicontrolget_cmd)".



In script.h: Change "enum GuiControlGetCmds" to the following.

enum GuiControlGetCmds {GUICONTROLGET_CMD_INVALID, GUICONTROLGET_CMD_CONTENTS, GUICONTROLGET_CMD_POS
, GUICONTROLGET_CMD_FOCUS, GUICONTROLGET_CMD_FOCUSV, GUICONTROLGET_CMD_ENABLED, GUICONTROLGET_CMD_VISIBLE
, GUICONTROLGET_CMD_HWND
};



In script.h: In the function "static GuiControlGetCmds ConvertGuiControlGetCmd(char *aBuf, int *aWindowIndex = NULL)" add

if (!stricmp(aBuf, "Hwnd")) return GUICONTROLGET_CMD_HWND;

before the return.


In case this is all that is needed i see no reason not to support it as this will greatly enchance the ability to create helpers for controls that take the vVariableName as the ControlID. This would make helpers much easier to use than by using ClassNN.

toralf
  • Moderators
  • 4035 posts
  • Last active: Aug 20 2014 04:23 PM
  • Joined: 31 Jan 2005
Yes, yes, yes. I currently set focus to the control I need the HWND for. But that requires the GUI to be visible. This would make a big improvement. Thanks for looking into the source code.
Ciao
toralf
 
I use the latest AHK version (1.1.15+)
Please ask questions in forum on ahkscript.org. Why?
For online reference please use these Docs.

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
The code required to add the feature is not the issue. The issue is that adding a feature to treat the symtoms of a problem is not as good as directly correcting the problem.

In this case, the problem seems to be that some commands like SendMessage do not accept GUI variables as a means to uniquely identify a control. So perhaps such commands should be extended instead of adding a new feature that might quickly become obsolete. Since that requires careful planning, it should be prioritized against other planned features.

foom
  • Members
  • 386 posts
  • Last active: Jul 04 2007 04:53 PM
  • Joined: 19 Apr 2006

In this case, the problem seems to be that some commands like SendMessage do not accept GUI variables as a means to uniquely identify a control. So perhaps such commands should be extended instead of adding a new feature that might quickly become obsolete. Since that requires careful planning, it should be prioritized against other planned features.

Adding this functionallity make it aviable anywhere and not only in sendmessage like what you suppose. And as philho said. Its aviable in ControlGet why not add it to GuiControlGet?