I'm trying to get a window handle on a child window in my process and the only information I have is the window class name. Are there any win32 functions I can use for that? I'm doing this from C#.
A bit more detail: This is a Visual Studio plugin, written in C#. So my process is visual studio, which has lots of windows. One of them has a window class "VsTipWindow". I don't know the immediate parent window of that window, all I have is the class name. Is there any way for me to get the window handle from just that?
FindWindow is the Win32 call you want for this (or FindWindowEx if there's more than one window with that particular class name, and FindWindow isn't returning the one you're looking for).
just additional information..
maybe it's useful to know that you can get the handle of a window from a point
WindowFromPoint
http://msdn.microsoft.com/en-us/library/ms633558(VS.85).aspx
First off it should be noted that there is not a 1 to 1 relationship between windows and window classes, more than one window could use the same class.
I guess your only option is to call EnumChildWindows recursivly starting with the top level Visual Studio window (Or some other window higher in the window hierarchy if you know one that is a grandparent of the VsTipWindow window) In the callback function from EnumChildWindows you would call GetClassName and compare the string with VsTipWindow until you find the window.
Since you talked about unknown parent I'm assuming that you are after a child window, but if this window is a top level window, you need to use EnumWindows (And you should probably use GetWindowThreadProcessId to make sure you get the correct process also after you find a window with that classname)
(I'm sure .NET has functions that do the same thing as the native api, or you'd have to PInvoke)
A Win32 window class is the generic implementation of a control, the handle of the windows is the instance of the control. So you will have multiple window handles with the same window class (e.g.: EDIT). Strictly speaking, a window class is the pointer to the window procedure.
Frameworks like .net (and even MFC) tend to share few window class for all the windows controls, and then they will dispatch to the appropriate controls (i.e. they have a single generic window procedure). This is the same also for big applications like Visual Studio or Office.
So this renders very difficult to detect a specific windows just through its window class. However, you can enumerate all the windows that have a specific windows class with FindWindow, you will get also the window text that may help you. Using GetWindowThreadProcessId you can detect if the window is belonging to Visual Studio.
Related
I have a compiled c# console application and I would like to have an option to change a certain window (*.exe from, lets say, task manager) position and size.
Is it possible via the namespaces provided in VS2010?
The target window isn't connected in any way to the exe compiled by VS.
As said in the comments, you definitely have to use the SetWindowPos function.
You will need the window handle. For this you could call EnumWindows, checking the executable file name for each window using GetWindowModuleFileName.
Pseudo code:
foreach window in EnumWindows()
if GetWindowModuleFileName(window) == "program.exe"
SetWindowPos(window, ...)
These functions belong to the Windows API. To call them you will need to P/invoke (pinvoke.net might be of great help).
It's quite possible:
To change window position or/and size you may use SetWindowPos
http://msdn.microsoft.com/en-us/library/windows/desktop/ms633545(v=vs.85).aspx
In order find out window's handle (hWnd argument) you may found useful
FindWindow
http://msdn.microsoft.com/en-us/library/windows/desktop/ms633499(v=vs.85).aspx
EnumWindows
http://msdn.microsoft.com/en-us/library/windows/desktop/ms633497(v=vs.85).aspx
I need to see the component type, meaning the name of the class that was programmed, of a clicked control in another process. I need the type so I can react to the clicked control and then do some Automation tasks.
Right now I am doing the following:
1. I FindWindow() from Win32 to find the main window handle of the process.
2. Then, I get call EnumChildWindows(), also from Win32, and get the window handles of all the children of the main window handle.
3. Now it gets tricky. When I call GetClassName(), it returns WindowsForms10.STATIC.app [...] since the controls I am trying to read are custom.
How can I get the type of the clicked control using the window handles from EnumChildWindows() ? Is what I am trying to do even possible?
I have been looking into using SendMessage() from Win32 to the process but it seems that there is no system defined message that could help.
I'm afraid that it's not possible. A handle just refers to internal data of the window that Windows needs. There is no information beyond that available.
You can get the class name, but it is neither standardized nor unique. Most controls that are not basic-functionality controls like buttons, lists, etc. are derived from a very primitive one, namely "Static". But again, there's no information about the high-level WinForms control available.
This leads to the fact that, even if you knew the type, you cannot just cast the pointer/handle, because there no data behind it.
Can you somehow restate your problem? Maybe use Remote Procedure Calls? Does it work without the high-level WinForms objects? Things like clicking, moving or renaming work with plain Win32 API.
Instance A is trying to restore instance B's window, but I can't get the B's window handle. I think the problem is that the window is being minimized by B to the system tray using:
this.Visibility = Visibility.Hidden;
And A is trying to get B's window handle using:
Process process = Process.GetCurrentProcess();
Process.GetProcessesByName(process.ProcessName).First().MainWindowHandle;
Which is equal to IntPtr.Zero.
I also tried to get the window handle by class name using Spy++ but the class name has a per-instance GUID in the following format:
HwndWrapper[FileName.exe;;ad445199-cf93-48a4-bd24-2f97d54c8af8]
That is because what you want basically doesn't exists, and the concept of MainWindowHandle is a gross misnomer that sneaked into the .Net Framework for everlasting confusion. From There can be more than one (or zero): Converting a process to a window:
"I have a thread ID. How do I get the
corresponding window?"
You can use the EnumThreadWindows
function to get all the windows on the
thread.
"Yes, I know about EnumThreadWindows,
but how do I get the window that I
want?"
Well, you haven't said what you wanted
yet.
"I want the window that corresponds to
the thread."
But which one? How will you decide
among all the windows?
"That's what I'm asking you!"
But you haven't yet described what you
want.
"I want the window corresponding to
the thread. Why won't you answer my
question?"
Note that saying, "I am looking for
the top-level unowned window" is a
step forward, but it still doesn't
uniquely identify a window. There can
be multiple top-level unowned windows
in a process. For example, Explorer
typically has lots of top-level
unowned windows. There's the desktop,
the taskbar, your open folder windows,
and property sheets. If you ask for
"the" top-level unowned window of
Explorer, which one do you want?
Perhaps people are getting the idea
that there is a way to uniquely
specify "the" window for a process
because the System.Diagnostics.Process
object has a property called
MainWindowHandle. The documentation
for that property doesn't do anything
to dispel the notion, either. I have
no idea how that property decides
among multiple top-level unowned
windows.
The topic is also elaborated in MSDN Q&A Get the Main Window:
Q How can I find the main window for a process? I'm writing a Spy-like tool and I need to get the main window (HWND) for a process so I can send it a message like WM_ACTIVATEAPP.
A Which main window do you mean?
I am trying to use the win32 API to set the parent of an application to a panel in my C# application.
When I inspect it using Spy++ the application loads in 2 main forms ThunderRT6Main and ThunderRT6MDIForm both with the same title.
I have found the handle of both of these and tried to call SetParent on them both but the window does nothing and does not move anywhere...
Is there something funky I need to do when invoking SetParent() on a VB6 app?
ThunderRT6Main is the hidden owner of every top level form in VB6. It sets the application icon, the one you see in the Applications tab of Task Manager. You can read this interesting article
A window can have a parent or an owner but not both
Basicly you might need WS_CHILD set before calling SetParent.
What is the best way to programmatically restore and give focus to a third-party application (say, GoogleTalk or Twhirl) running in the system tray? I am writing my utility in C#, but I obviously have no control over the third-party application.
Use something like FindWindow /FindWindowEx to find the hidden window and get its window handle and then call ShowWindow ( handle, SW_NORMAL) to unhide it.
Use a tool like Spy++ (can be found in the visual studio tools menu) to find the parameters which can be passed on to FindWindow to locate the desired window.
Use an API call to send mouse click events to the system tray? Google WM_SENDMSG SendMessage Win32 API for a starting point
There's also another API call for setting focus once the window's back up.