[英]Given a window, how can I determine if it is part of a winforms application?
I have handles to the main form of the Winforms application, and the window that I'm trying to check (which may or may not be part of the application). 我有Winforms应用程序的主要形式的句柄,还有我要检查的窗口(它可能是应用程序的一部分,也可能不是该应用程序的一部分)。 I've tried iterating using GetParent, but it doesn't seem to work.
我已经尝试过使用GetParent进行迭代,但是它似乎不起作用。
What I'm essentially trying to do is detect a modal window (such as a MsgBox), get it's controls, and send a button click message if the controls fulfill some requirements (like be a Button
). 我实质上想做的是检测一个模式窗口(例如MsgBox),获取它的控件,并在控件满足某些要求(例如
Button
)时发送按钮单击消息。
Now, while I can detect if a modal window is open, and can find the currently focused window, I have no idea if the currently focused window is the modal window that was detected. 现在,虽然我可以检测是否打开了模态窗口并可以找到当前聚焦的窗口,但是我不知道当前聚焦的窗口是否是检测到的模态窗口。 Essentially, if I open a model window and then open up a completely different program, it tries to find the controls of that external program.
本质上,如果我打开一个模型窗口,然后打开一个完全不同的程序,它将尝试查找该外部程序的控件。
The code is below: 代码如下:
if (pF.Visible && !pF.CanFocus) //Is a Modal Window
{
///TODO: Check if currently active window is a child of the main window
///Gets information of currently active window
string currentActiveWindow = GetActiveWindowTitle();
IntPtr currentActiveHandle = GetActiveWindowHandle();
///Gets 'children' or controls of currently active window
var hwndChild = EnumAllWindows(currentActiveHandle);
///Iterate over all child windows
foreach (IntPtr element in hwndChild) {
const int nChars = 256;
StringBuilder Buff = new StringBuilder(nChars);
IntPtr handle = GetForegroundWindow();
string windowElementType = GetWindowClassName(element);
///Check if the "windows" are buttons
if (GetWindowText(element, Buff, nChars) > 0 && windowElementType=="Button")
{
string windowElement = Buff.ToString();
if (windowElement.ToLower()=="ok")
{
///Send Button click message
const int BM_CLICK = 0x00F5;
SendMessage(element, BM_CLICK, IntPtr.Zero, IntPtr.Zero);
}
}
}
}
A convenience function (C++) to determine whether two windows identified by their HWND
belong to the same process would look like this: 一个便捷函数(C ++),用于确定由其
HWND
标识的两个窗口是否属于同一进程,如下所示:
bool OwnedBySameProcess(HWND hWnd1, HWND hWnd2) {
if ( ::IsWindow(hWnd1) && ::IsWindow(hWnd2) ) {
DWORD procId1 = 0x0;
DWORD procId2 = 0x0;
::GetWindowThreadProcessId(hWnd1, &procId1);
::GetWindowThreadProcessId(hWnd2, &procId2);
return ( procId1 == procId2 );
}
return false;
}
The GetWindowThreadProcessId
is not subject to UIPI (User Interface Privilege Isolation) and will always succeed given valid input. GetWindowThreadProcessId
不受UIPI(用户界面特权隔离)的约束,并且在有效输入的情况下将始终成功。 The return values are IDs and do not need to be cleaned up. 返回值是ID,不需要清理。
Translated to C#: 转换为C#:
public class Helper
{
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool IsWindow(IntPtr hWnd);
[DllImport("user32.dll")]
static extern uint GetWindowThreadProcessId(IntPtr hWnd,
out uint lpdwProcessId);
public static bool OwnedBySameProcess(IntPtr hWnd1, IntPtr hWnd2)
{
if ( !IsWindow(hWnd1) )
throw new ArgumentException("hWnd1");
if ( !IsWindow(hWnd2) )
throw new ArgumentException("hWnd2");
uint procId1 = 0;
GetWindowThreadProcessId(hWnd1, out procId1);
uint procId2 = 0;
GetWindowThreadProcessId(hWnd2, out procId2);
return ( procId1 == procId2 );
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.