How to get HWND in win32? - c++

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.

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);
}

Finding BUTTON of another program

I am trying to make my program click the button of another program. The part I am having issues with is identifying the handle of the button. This is the code I have so far:
BOOL CALLBACK EnumChildProc(HWND windowHandle, LPARAM lParam)
{
cout << "hwnd_Child = " << windowHandle << endl;
cout<<"WindowId: "<<GetWindowLongPtr(windowHandle, GWLP_ID)<<endl;
return TRUE;
}
HWND windowHandle = FindWindow(NULL, "nameOfProgramWindow");
EnumChildWindows(windowHandle, EnumChildProc, 0);
What is happening so far is that I find the handle of the parent window of the program. With that handle, I use the EnumChildWindows function to go through each of the child windows... and in 1 of those child windows I will have the window which contains 3 buttons, 1 of which is the button I want to press. In the callback function I need to put the GetWindowLongPtr() function to get the ID of the window I am looking for ... there is a problem though...
The problem is that each time I run this program again, the handle and the ID of the window which contains the buttons will change... So I can't use spy++ to get an ID to compare with the ID gotten since The ID changes. I have tested it out even (thats why i have all the "cout" code there);
Question: How do I then identify the window I am looking for in the callback function (and possibly the button I am looking for)?? PLEASE DON'T say spy++ cause the ID and Handle values change every time I open the program
The handle is always going to change each time that the code runs. Windows dynamically assigns handles. Nothing you or anyone else can do about that. It would be more surprising if it didn't change.
And it's no particular conspiracy that the control's ID changes. The only way that stays the same is if it's hard-coded in the original application, most probably via the use of a resource file. But if the programmer dynamically generates the controls at run-time, then there's no reason they would need to use the same ID. Just so long as they keep track of that ID in some kind of data structure if and when they need it.
You may be able to find another property of the button control that is constant—like the caption. But that's certainly not guaranteed. Lots of programs change the caption to reflect the current state.
The application developer is under no obligation to make it easy for another program to mess with the internals of something that does not belong to them.
Have you considered doing this the right way using UI Automation?

How can I register another win32 message handler

I want to change the message handler for an old legacy app we use but don't have the source for any more. In a dll that we do have the source for I'm wanting to intercept the window messages and then pass them onto the app. Is this possible? I tried something along the lines of:
WNDPROC lpfnWndProc = NULL;
void GetHandler()
{
HINSTANCE hInstance = GetModuleHandle(NULL);
HWND hWnd = GetActiveWindow();
WCHAR lpClassName[1024];
GetClassName(hWnd,lpClassName,1024);
WNDCLASSEX wc;
GetClassInfoEx(hInstance, lpClassName, &wc);
lpfnWndProc = wc.lpfnWndProc;
wc.lpfnWndProc = NewMessageProc;
RegisterClassEx(&wc);
}
However GetActiveWindow fails and just returns NULL. Is there a simpler way to do this. Infact I'd be happy if I could just simply add another message handler.
It is not clear whether you want to subclass specific controls, or all windows of a particular window class.
If you want to subclass specific controls, the section Subclassing Controls in the MSDN describes how to do this, both for ComCtl32.dll version 6 and above, and the legacy procedure of directly replacing a control's window procedure.
If you want to subclass all controls of a particular window class you would have to change the entries stored in the registered window class, using SetClassLongPtr. Note that this will only affect windows subsequently created with that window class. This is a bit of a Catch 22, as you need to have a window handle when calling SetClassLongPtr, limiting the applicability of subclassing a window class.
As for the code you posted, there are a number of issues:
Your call to GetModuleHandle retrieves the wrong HINSTANCE, namely that of the calling application. Since you need the module handle of the module that registers the window class you have to pass the name of the .dll that implements the controls.
Calling GetActiveWindow may or may not return a value, depending on whether or not the calling thread actually does have an active window. In your case it apparently doesn't, so you need another means of retrieving a window handle, such as FindWindowEx.
Your final call to RegisterClassEx doesn't do what you think: It will simply fail, since you cannot re-register a window class with the same name of an existing window class. You need to call SetClassLongPtr instead, as illustrated above.
I'd actually use SetWindowSubclass after getting the HWND of the window you want to modify the behaviour of. SetWindowLong was deprecated as a way to change the WndProc of a window back around the time that CommCtrl.dll version 6 came out. MSDN can tell you all about that particular part of history and its motivation - just look up SetWindowSubclass.
As it stands, assuming the calling thread has an active window, your code will simply create a new window-class with the same attributes as your target window, albeit with a different WndProc - it wont set the wndproc of an existing window.. - (hence my mention of SetWindowLong and SetWindowSubclass)
EDIT: Or at leaast, it would of not for the oversight I made on that point. As pointed-out in a comment below, this call to RegisterClass will actually fail - you can't register the same className more than once.
You should also probably look at the FindWindow function - just give it a NULL lpWindowName, and the (known) class-name of the target window. In the event that the desired window is not the one that's returned, you could use EnumWindows. Simply call GetClassName in the callback function you supply to EnumWindows, subclassing any/all windows whose class-name matches the class-name of the target window.
Once this window has been subclassed, you can consume its messages as you wish, passing them onto the original window-proc as needed.

Getting HWND of current Process

I have a process in c++ in which I am using window API. I want to get the HWND of own process. Kindly guide me how can I make it possible.
If you're talking about getting a process handle, then it's not an HWND (which is a window handle), but a HANDLE (i.e., a kernel object handle); to retrieve a pseudo-handle relative to the current process, you can use GetCurrentProcess as the others explained.
On the other hand, if you want to obtain an HWND (a window handle) to the main window of your application, then you have to walk the existing windows with EnumWindows and to check their ownership with GetWindowThreadProcessId, comparing the returned process ID with the one returned by GetCurrentProcessId. Still, in this case you'd better to save your main window handle in a variable when you create it instead of doing all this mess.
Anyhow, keep always in mind that not all handles are the same: HANDLEs and HWNDs, in particular, are completely different beasts: the first ones are kernel handles (=handles to kernel-managed objects) and are manipulated with generic kernel-handles manipulation functions (DuplicateHandle, CloseHandle, ...), while the second ones are handles relative to the window manager, which is a completely different piece of the OS, and are manipulated with a different set of functions.
Actually, in theory an HWND may have the same "numeric" value of a HANDLE, but they would refer to completely different objects.
Get your console window
GetConsoleWindow();
"The return value is a handle to the window used by the console associated with the calling process or NULL if there is no such associated console."
https://msdn.microsoft.com/en-us/library/windows/desktop/ms683175(v=vs.85).aspx
Get other windows
GetActiveWindow() might NOT be the answer, but it could be useful
"The return value is the handle to the active window attached to the calling thread's message queue. Otherwise, the return value is NULL." > msdn GetActiveWindow() docs
However, the graphical windows are not just popping up - so you should retrieve the handle from the place you/your app've created the window... e.g. CreateWindow() returns HWND handle so all you need is to save&retrieve it...
You are (incorrectly) assuming that a process has only a single HWND. This is not generally true, and therefore Windows can't offer an API to get it. A program could create two windows, and have two HWNDs as a result. OTOH, if your program creates only a single window, it can store that HWND in a global variable.
The GetCurrentProcess() function returns a pseudo-handle which refers to the current process. This handle can be used in most Win32 API functions that take a process handle parameter.
The documentation contains more information about this pseudo-handle, including how to convert it to a real handle if you need to.
You can use HANDLE WINAPI GetCurrentProcess(void); from Kernel32.dll.
See MSDN entry here.
My example is not to deal with process, but maybe you need this:
HWND hwndList = GetDlgItem(hwnd, IDCL_COMBOBOX);
This returns HWND of the control specified by its IDCL_COMBOBOX.
Here is another answer:
this->GetSafeHwnd();