API method for getting window's controls - c++

I've searched quite a while in MSDN, couldn't find it.
In fact, I don't even know how controls are called in API. they are not declared as a "Window", right? (No hwnd for them, I wasn't sure because I saw a method which seemed like it could return a control but it returns an hwnd.)
So lets say I have a window's handle. I want to recieve it's controls (a textbox, button, checkbox....)
What are the methods to do this? And again, how are the controls called in API?
Thanks for helpers.

They're called Windows and HWNDs are handles to these windows, just like a fopen() returns a handle to a file.
These are all the functions you'll need. Try EnumChildWindows

Related

which window is on top on the other

I have 2 windows and I want to know which window is on the top of the other?
I tried to test using GetWindowLong and comparing the results but no chance.
LONG wndState1 = ::GetWindowLong(handler1, GWL_EXSTYLE);
LONG wndState2 = ::GetWindowLong(handler2, GWL_EXSTYLE);
both results is equal to 256.
Edited: In the picture below I have the dialog of notepad++ is on top of the FileZilla, How do I Get That by Code.
Is there a trick for that ?
THank you
GetWindowLong is used to retrieve style information for a particular window.
In order to get the top-most window, use
HWND WINAPI GetForegroundWindow(void);
You will still need to know the window handles (HWND) for the processes you're interested in so that you can find out which process owns the foreground window.
Note that this API can only return the window that the user is interacting with (or has interacted with most recently).
UPDATE:
I agree with Remy that there isn't any API to do that. The only way I can think of to actually do that is to install a global hook and intercept certain messages (e.g. WM_ACTIVATE, WM_SETFOCUS and so on). Since you will also retrieve the timestamps for the messages, it should be simple to infer which window is on top of any other window. This will require you to write a dll but this is relatively simple to do. I can't guarantee this will work either though I think it will (I've written a global hook but never used it to find out the z-order of windows)

::PostMessage doesn't work when I am tabbed in to another program

In our Program we have a Dialog from a separate dll open to display infomation. I need to close this dialog when our system timer causes the system to lock.
I send information to the dll by registering a system message in both my MainFrm and EditDisplayDll
SYSTEMLOCK = RegisterWindowMessage("SystemLock");
When I sent the message via
::PostMessage(GetActiveWindow()->m_hWnd,SYSTEMLOCK,0,0);
The message correctly sends to my EditDisplayDll and closes the dialog when the system locks; however, if I alt tab while waiting for the timeout and use another program(firefox, outlook, etc.) the message never correctly calls to the EditDisplayDll. The MainFrm and other windows inside of the MainFrm correctly lockout and hide themselves in either case.
I have tried also using HWND_BROADCAST with PostMessage and SendNotifyMessage. I have also tried to use FindWindow() and FindWindowEx() to specifically call the EditDisplayDll.
I cannot use something like GetDlgItem() because my MainFrm.cpp doesn't have access to this dll.
My decision to use GetActiveWindow() was because I believe it looks to windows specific to my program no matter what window I am in as seen in the imagery in Foreground Vs Active window
Finally, my question is, is there a way to call all Windows in my program no matter what program I am currently in or is there another way I could get access to the specific IDD of the EditDisplayDll in order to send the SYSTEMLOCK message to it?
CWnd *cWndED = FindWindow(_T("EditDisplay"),_T("EditDisplay")); HWND
hwnd = (HWND)cWndED;
You should use win32 API ::FindWindow with proper class, window name. And do not cast CWnd pointer to HWND. Your code should look like:
HWND hWnd = ::FindWindow(_T("ProperClass"), _T("ProperNmae"));
if (hWnd != NULL)
{
::PostMessage(hWnd, YOUR_MESSAGE, ....);
}
I will suggest you to find your Dll window class and name using Spy++ and then try to find that using above method. Remember it's always better to use native API for this kind of tasks.
FindWindow is a good solution if you know both, name of the window and the element.
If you want to get the HWND of your window - no element inside the window -, you can pass as first parameter NULL.
::FindWindow(NULL, _T("WindowName"));
Back to your code: If you are lucky your PostMessage does nothing, otherwise the active window may catch your message. Who knows how/if it is handled in the active window ? Use the PostMessage if you have a valid IsWindow(HWND) from FindWindow or FindWindowEx.
In case you want a CWnd from your HWND take a look at this. (The call may be slow)
HWND hWnd = ::FindWindow(_T("ClassName"), _T("WindowName"));
if (hWnd && IsWindow(hWnd))
{
::PostMessage(hWnd, MESSAGE_TO_BE_SEND, lParam_or_Flags);
}

How to get HWND in win32?

Is there way to get the HWND handler of my window?
I'm using win32.
You could call GetActiveWindow to get the active control in your application, then repeatedly call GetParent on the returned handle until it returns NULL. The last valid handle you get should be the handle of your main window.
The easier way as someone else said is to store the returned value from CreateWindow somewhere.
It's probably good to understand why there is no simple way. It all boils down to "which window?". You'll likely have multiple windows visible on your screen, right now. For instance, the taskbar at the bottom of your screen is a window. even your own app typically has more than one. For instance, the "File Save" dialog is a window. Even the simple MessageBox is a window.
So, how do you identify which window you're talking about? The common answer is that you identify them by their HWND. So, to get the position of the "File Save" dialog window, you ask for the position associated with that HWND. Obviously, you can get any property that way, except the HWND itself ! It makes sense to ask the X/Y position of HWND(0x5e21), but it's stupid to ask which HWND belongs to HWND(0x5e21).
Now, it may happen that you have another more-or-less unique property and you want to get the HWND from that. For instance, you may have an X/Y position. In that case, WindowFromPoint(xy) will return the HWND at that position.
But the most common case is that you need to react to a Windows message for your window. In that case, you get the HWND of your window as the first argument of your WindowProc().
So, unless you tell us what unique information you do have, we can't tell you how to find the matching HWND.
Didn't you create your window via CreateWindow() or CreateWindowEx()? The CreateWindowEx() function and the CreateWindow() function both return the HWND of the newly created window.
Also, the operating system passes you the HWND of your window(s) via your window procedure. It's not a function that you call; it's a function that the operating system calls to let your application do any processing that's needed.

Find a window using c++ and modifying controls

I would like to use c++ without mfc(and not clr) in order to modify textbox's and activate a button on a form outside of my project. I don't know where to start. I've done a lot of searching but can only find information for VB. A starting point would help.
Thanks.
I tried this and it doesn't seem to work.
HWND fWindow = FindWindow(NULL ,(LPCWSTR)"title");
and I also tried this
HWND fWindow = FindWindow(NULL ,LPCWSTR("title"));
I ALSO tried using LPTSTR instead of LPCWSTR, incase it was a unicode deal.
Maybe I don't understand this microsoft LPCWSTR and LPTSTR crap.
I also tried
HWND fWindow = FindWindow(NULL,TEXT("title"));
and that didn't work.
I guess the windows api must just be broken.
I tried the function on other programs...I'm using xp and I tried catching the calculator, and an explorer window, and something else. But I got nothing.
Heres some of the exact code I'm using to try and figure this out.
HWND face = NULL;
face = FindWindow(NULL,TEXT("My Computer"));
LPSTR title = TEXT("");
GetWindowText(face,title,250);
if(face != NULL)
{
MessageBox(NULL,title,TEXT("WOOP"),1);
}
face = nothing.
title = ""
Bear in mind, I'm not actually trying to hook explorer, I just want to figure out how to get it to work.
Use spy++ or winspector to see the actual "text" of the window.
(Strictly speaking, the caption of the window need not match it's window text. Especially true of "fancy" windows which paint their own caption.)
The following works fine for me (using Calc.exe to test).
HWND hwnd = NULL;
hwnd = FindWindow(NULL,_T("Calculator"));
TCHAR title[251];
if(hwnd != NULL)
{
GetWindowText(hwnd,title,250);
MessageBox(NULL,title,_T("WOOP"),MB_OK);
}
else
MessageBox(NULL,_T("No such window."),_T("OOPS"),MB_OK);
Edit: You should have used _TEXT instead of TEXT.
One way to do this is to use FindWindow to get a handle to the form. Then if you know the button and edit window Ids, you can use GetDlgItem to get their window handles. If you dont know the ids, you can use EnumChildWindows to examine all of the controls on the form.
Once you have the window handles for the controls, you can use SetWindowText to set the text on the edit control, and send a WM_COMMAND message to the form window with the button ID as the command value to make the form think that the button has been clicked.
There are a lot of ways to go about this once you have the correct window handles. There are security issues when you use the window handles of another process, but if the process isn't secured, then inter-process use of window handles just works. For a secured process, you won't be able to find out the window handles.
The windows API provides Methods for this. These should be independent of MFC and CLR, as they are plain win32. I had a project once accessing the Form fields of an Applictation from a loaded DLL (don't ask why).
you might want to look here (Codeproject)
or here (msdn)
At first, you need to obtain a handle to the process you want to access.
When have this, you can use GetDlgItem() (search msdn for that) to retrieve a handle to the desired textbox.
With this handle, you should be able to modify the control in question.
If your trying to get big (and do some more UI automation), you sould have a closer look at these:
Microsoft Active Accessibility
IAccessible2
Microsoft UI Automation
Windows Automation API (Win7)

How to add custom item to system menu in C++?

I need to enumerate all running applications. In particular, all top windows. And for every window I need to add my custom item to the system menu of that window.
How can I accomplish that in C++?
Update.
I would be more than happy to have a solution for Windows, MacOS, and Ubuntu (though, I'm not sure if MacOS and Ubuntu have such thing as 'system menu').
For Windows, another way to get the top-level windows (besides EnumWindows, which uses a callback) is to get the first child of the desktop and then retrieve all its siblings:
HWND wnd = GetWindow(GetDesktopWindow(), GW_CHILD);
while (wnd) {
// handle 'wnd' here
// ...
wnd = GetNextWindow(wnd, GW_HWNDNEXT);
}
As for getting the system menu, use the GetSystemMenu function, with FALSE as the second argument. The GetMenu mentioned in the other answers returns the normal window menu.
Note, however, that while adding a custom menu item to a foreign process's window is easy, responding to the selection of that item is a bit tricky. You'll either have to inject some code to the process in order to be able to subclass the window, or install a global hook (probably a WH_GETMESSAGE or WH_CBT type) to monitor WM_SYSCOMMAND messages.
Once you have another window's top level handle, you may be able to call GetMenu() to retrieve the Window's system menu and then modify it, eg:
HMENU hMenu = GetMenu(hwndNext);
You can use EnumWindows() to enumerate top level Windows.
I don't have a specific answer for the second part of your question, but if you subclass the window, I imagine you can modify the system menu.
EDIT: or do what Chris said: call GetMenu()
Re: the update - please note that not even Microsoft Windows requires windows to have a sytem menu. GetMenu( ) may return 0. You'll need to intercept window creation as well, because each new top window presumably needs it too.
Also, what you propose is rather intrusive to other applications. How are you going to ensure they don't break when you modify their menus? And how are you going to ensure you suppress the messages? In particular, how will you ensure you intercept them before anyone else sees them? To quote Raymond Chen, imagine what happens if two programs would try that.