March 8th, 2004, 06:29 PM
get a control's ID
How can i get a control's ID of another app?
In example: there is a button on a setup app that i want the id off of so i can send messages to it.
March 8th, 2004, 06:46 PM
I do not think you can do what you want that way. You probably need to look at the app using Spy++ or a similair tool to find the structure of the application to determine where the button is, and then use FindWindow to go through the chain of windows until you get to your button, and then use the buttons handle to send messages, etc.
March 8th, 2004, 06:59 PM
well i wish that would work but it can't, the id of the button i want changes everytime you restart the program, and the reason it does that is because it's a setup program(installshield). So if anyone else has any idea please let me know.
March 8th, 2004, 07:19 PM
Well i guess what im trying to say is how to get the handle of a control from another program. Not ID.
I see Enumchildwindows alot, how do i use it, can i get a sample?
March 8th, 2004, 08:14 PM
does anyone know how to get the handle of a button control without knowing its id.
March 8th, 2004, 08:24 PM
Why can't you use FindWindow like a suggested to find the handle of the window you want (the button)?
Here is a quick and dirty example that finds the edit control (the address bar in Enternet Explorer on a NT based system):
// grabs url from address bar in ie and displays in Edit Control on dialog
HWND hwnd = ::FindWindow("IEFrame", NULL);
hwnd = ::FindWindowEx(hwnd, 0, "WorkerW", NULL);
hwnd = ::FindWindowEx(hwnd, 0, "ReBarWindow32", NULL);
hwnd = ::FindWindowEx(hwnd, 0, "ComboBoxEx32", NULL);
hwnd = ::FindWindowEx(hwnd, 0, "ComboBox", NULL);
hwnd = ::FindWindowEx(hwnd, 0, "Edit", NULL);
int iLen = ::SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0);
char *lpszBuffer = new char[iLen+1];
::SendMessage(hwnd, WM_GETTEXT,(WPARAM)iLen+1, (LPARAM)lpszBuffer);
delete  lpszBuffer;
March 8th, 2004, 09:21 PM
do you have to go through each window its in to get to the edit box.
March 8th, 2004, 09:29 PM
You have to go through the chain of parent windows.
If you open Internet Explorer, and then run Spy++, and use the find tool, drag the find tool to the edit control where you enter a URL. Then in Spy++ it will bring you to that window. There you can see what the window class type is (at the end of the line), and the chain of parent windows and there class types all the way up to the main application window. Then use use FindWindow and FindWindowEx to go through the chain of parent windows (only windows that are in the direct chain to the window you want), starting from the applications main window.
Try it with Internet Explorer, and you should be able to see where I got the info to use in my example.
ie. The edit control's (Edit class) parent is a ComboBox class, whos parent is a ComboBoxEx32 class, who's parent is a ToolbarWindow32 class, etc, up until you get to the main app window which is a IEFrame class.
Last edited by RussG1; March 8th, 2004 at 09:34 PM.
March 8th, 2004, 09:37 PM
Ok here is what i got on my program.
HWND hwnd = ::FindWindow("TWizardForm", NULL);
hwnd = ::FindWindowEx(hwnd, 0, "TButton", NULL);
now how would i use sendmessage to click that button?
March 8th, 2004, 09:53 PM
OK, so your button is a direct child window of the main application window? (i.e. The main application window is it's parent?), and the class types shown in Spy++ are "TWizardForm" and "TButton"?
If so, then you now have the HWND of the button and you can use SendMessage to send whatever TButton messages you want to the window. I do not know what a TButton class is so I am not sure what messages are valid for it, to be able to give an example, but you can see in my IE example, that I used SendMessage using the HWND of the Edit Comtrol, to first get the length of the text in the edit control, and then to retrieve the text from the edit control.
Last edited by RussG1; March 8th, 2004 at 11:34 PM.
March 8th, 2004, 09:54 PM
ok what if i wanted to try BN_CLICKED how would i put that into sendmessage?
March 8th, 2004, 09:57 PM
BTW, to send a Button Clicked message you would need to send the message to it's parent window using SendMessage with WM_COMMAND, and the HWND of the Button, etc, and the BN_CLICKED message (I believe, give me a sec and I will check and try to provide an example).
Last edited by RussG1; March 8th, 2004 at 11:33 PM.
March 8th, 2004, 09:57 PM
i know i have to use WM_COMMAND like this
but i dont know what to put for WPARAM and LPARAM for BN_CLICKED.
March 8th, 2004, 10:20 PM
Ok, it is a little trickier for Button clicked because you need to send the message to the parent window, and you need the control's ID. This can be found in Spy++ as well, if you double click on the button window in Spy++ you will see properties for that window includings it's control ID and then do like the following.
This sends a click to the "9" button in the Windows Calculator (in Scientific Mode).
Uses MAKEWPARAM macro to create the WPARAM value.
First param is the control ID from Spy++ and second is the message you want to send (i.e. BN_CLICKED).
HWND hwndParent = NULL;
HWND hwndButton = NULL;
hwndParent = ::FindWindow("SciCalc", NULL);
hwndButton = ::FindWindowEx(hwndParent, 0, "Button", "9");
::SendMessage(hwndParent, WM_COMMAND, MAKEWPARAM(0x00000085, BN_CLICKED), (LPARAM)hwndButton);
Last edited by RussG1; March 8th, 2004 at 10:51 PM.
March 8th, 2004, 10:34 PM
Hmm, I just remembered that you stated that your control id changes (now I understand the original question)? I will have to think about that for a sec...
Last edited by RussG1; March 8th, 2004 at 11:22 PM.
Click Here to Expand Forum to Full Width