给定一个窗口,如何确定它是否是winforms应用程序的一部分? [英] Given a window, how can I determine if it is part of a winforms application?

查看:34
本文介绍了给定一个窗口,如何确定它是否是winforms应用程序的一部分?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有Winforms应用程序的主要形式的句柄,还有我要检查的窗口(它可能是应用程序的一部分,也可能不是该应用程序的一部分).我已经尝试过使用GetParent进行迭代,但是它似乎不起作用.

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). I've tried iterating using GetParent, but it doesn't seem to work.

我实际上想做的是检测一个模式窗口(例如MsgBox),获取它的控件,并在控件满足某些要求(例如 Button ).

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).

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

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.

代码如下:

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

}

推荐答案

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

A convenience function (C++) to determine whether two windows identified by their HWND belong to the same process would look like this:

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(用户界面特权隔离)的约束,并且在获得有效输入后始终会成功.返回值是ID,不需要清理.

The GetWindowThreadProcessId is not subject to UIPI (User Interface Privilege Isolation) and will always succeed given valid input. The return values are IDs and do not need to be cleaned up.

翻译成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 );
    }
}

这篇关于给定一个窗口,如何确定它是否是winforms应用程序的一部分?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆