c# - 给定一个窗口,我如何确定它是否是 winforms 应用程序的一部分?

标签 c# .net winforms winapi

我有 Winforms 应用程序主窗体的句柄,以及我要检查的窗口(可能是也可能不是应用程序的一部分)。我尝试过使用 GetParent 进行迭代,但似乎不起作用。

我本质上想做的是检测模式窗口(例如MsgBox),获取它的控件,并在控件满足某些要求(例如成为Button)时发送按钮单击消息>).

现在,虽然我可以检测模式窗口是否打开,并且可以找到当前聚焦的窗口,但我不知道当前聚焦的窗口是否是检测到的模式窗口。本质上,如果我打开一个模型窗口,然后打开一个完全不同的程序,它会尝试查找该外部程序的控件。

代码如下:

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

}

最佳答案

用于确定由 HWND 标识的两个窗口是否属于同一进程的便捷函数 (C++) 如下所示:

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

GetWindowThreadProcessId不受 UIPI (User Interface Privilege Isolation) 的约束并且在给出有效输入的情况下总是会成功。返回值是ID,不需要清理。

转换为 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 );
    }
}

关于c# - 给定一个窗口,我如何确定它是否是 winforms 应用程序的一部分?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24320758/

相关文章:

c# - 从内存流播放视频

c# - 语义版本控制和依赖性更改

.net - 需要一个练习建议来帮助我学习和锻炼.NET

c# - 在网格中查找偏移量

.net - 使用 StructureMap 配置 Prism

c# - C# WinForm中如何根据不同选项设计设置UI?

c# - 为 WinForm TreeView 控件实现向后导航和向前导航按钮功能

c# - 向列表框添加控件

c# - Linq:双值列表 - 后继值之间的差异

c# - 使用反射创建对象