I have a window which runs in separate thread. I need to get the handle of that window in another thread.
I can't use ::FindWindow API, because the window name will change, as my application can run in other languages. Plus, I don't have access to the resource string used for window name.
I can't use ::GetActiveWindow also, as the calling thread id and the active window thread id is different.
Please suggest some solution.
It is not necessary to pass the window name to the FindWindow function. You can pass NULL for the window name and find the window using only the lpClassName parameter.
MFC normally assigns window class names automatically, but you can control a window's class name by registering a unique name with AfxRegisterClass and creating the window with that registered class name.
Related
Using the MFC, I have multiple derived classes
class CImageView : public CFormView
{
};
and open 3 windows all with the same dialog ID.
Is that valid and they wont interfere with each other?
I know it is not valid to have the same dialog ID for child windows within the dialog.
Thanks
Yes, this is perfectly fine. It's just the resource id identifying the dialog resource to use to create the window. The resulting view windows are actually created with different/unique window handle (HWND) values. The reason child controls should not have duplicate ID's is because it would confuse API's like GetDlgItem, which are used to retrieve a specific control's HWND based on the ID specified.
Sincerely,
Only child windows have control ID's. Pop-up windows do not have a control ID; the API has no way of setting one. If you look at the documentation for CreateWindowEx, you'll see that the hMenu argument is overloaded. It's used to set a control ID only when creating a child window.
The dialog ID you are referring to really is the identifier used to look up a DIALOGEX resource in the executable image's resource section. Once the dialog is created, that ID is gone. Using multiple dialogs created from the same dialog template is safe, and multiple instances will not interfere with each other.
I have a simple C++ program that waits for a certain process to start, but the name of that process could be changed by the user. Is there a way to check if it is running without knowing it's name?
Working with the WinAPI you can check the window class of the given process. Since the name of the process can be changed. "A window class is a set of attributes that the system uses as a template to create a window. Every window is a member of a window class. All window classes are process specific." from msdn.microsoft
Is there any way to change name of process?
I am developing App in MFC c++, but I want it to be invisible for HWND FindWindow(Name Window, Clasename of Window) function.
It is easy to change Caption of main window, but I have no idea how to change classname of Window.
To set the window class name of your main window in MFC you first call AfxRegisterClass (doing this in InitInstance, before the window is created) with your desired classname and then in the mainframe class override CMainFrame::PreCreateWindow and modify the passed in CREATESTRUCT with your desired classname.
This can be useful if you want another process to easily find your main HWND, but it is not very useful to try and make your window invisible to FindWindow.
I am looking at some MFC/C++ CView object subclass like this:
BOOL CCustomView::CreateView(DWORD dwStyle,
CDocument * pDocument,
CWnd * pParent,
String title)
{
...
CString className = AfxRegisterWndClass(CS_DBLCLKS,
::LoadCursor(NULL, IDC_IBEAM));
return Create(className, title, dwStyle,
rect, pParent, -1, &context);
}
What I don't like about this, although maybe it's normal for MFC application programming, is that the runtime Window Class Name, is not a name of my own choosing. If later, I wanted to find this window, from another Win32 application, and find the window by window class name, I'd have to use the ugly "Afx:123:39843:39843" strings, and actually, I don't know if those window class names can be counted on to not change. I'd rather change the window class to "CCustomView", but still have it have the same behaviours as the window class created above. How do I do that?
There are better ways to solve your problem. The typical protocol I use is:
Register a window message using RegisterWindowMessage in both applications. The message name should contain a GUID to make it unique
In Application A, use
PostMessage(HWND_BROADCAST, registeredMsg, idIWantToFindYou, HWNDofA)
to publish your window handle to all top level windows. since there's more than one use for registered messages, and you should limit the number of messages you register, use idIWantTofindYou to distinguish between different commands for your message.
The receiving application(s) B now have the window handle of the sender, and can establish a connection (e.g. by
PostMessage(HWNDofA, registeredMessage, idHereIsMyHWnd, HWNDofB)
The upside of this mechanism is not running into problems with unresponsive programs. However, the "connection" isn't immediate, so you have to change your program flow. Alternatively, you can use EnumWindows and SendMessageTimeout to probe all top-level windows.
If you need to use the window class:
The class name assigned by MFC is only so window classes with the same attributes get reused. I am not aware of any problems with using your own window classes.
So the following should work:
Fill a WNDCLASS or WNDCLASSEX with the required attributes
Use DefWindowProc as WNDPROC (that's what MFC does, MFC's WNDPROC is set when creating the window)
Use AfxRegisterClass or RegisterClass to register the window class. AfxRegisterClass checks if the class is already registered and if the class is registered from a DLL, it will unregister the class when the DLL is unloaded. Otherwise they are roughly equivalent.
In my (PowerBuilder) application, I'd like to be able to determine the graphicobject object which corresponds to a given window handle.
Simply iterating over the Control[] array and comparing the value returned by the Handle() function for each of the child controls doesn't work, since not all objects in my application are children of the main window (consider of login dialogs).
Any PowerScript or C/C++ solution would be acceptable.
Is there maybe some window message I could send to window handles, and this message is only understood by PowerBuilder windows, which would the respond with their internal object name, or the like?
Is it a requirement to determine the object from the handle, or do you just want to identify an object, for example to know where the code you need to modify is? I made a tool that does the latter, but it uses object focus, rather than window handles.
(added 2010-06-21) For windows that aren't children of the main window you could explicitly check each of these window class names with isValid(). Then for each valid window, dig through looking for the handle. This should work as long as you only open one instance of the window class at a time. If you open multiple instances, I think you'll need to add a registration mechanism to the open of those windows so the application has a way to access them.