C# winform 如何获取打开窗口?包含父窗口和子窗口

一叶无秋 2018-10-22 10:45:42
如何通过WinAPI 获取当前打开的父窗口和子窗口 Form, 在没有焦点的情况下。
...全文
1022 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
一叶无秋 2019-05-20
  • 打赏
  • 举报
回复

//根据传入的窗口句柄,获取到同级、顶级、低级的窗口,根据GetWindowCmd 传入的不同获取也不同,详细看GetWindowCmd 类说明
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr GetWindow(IntPtr hWnd, GetWindowCmd uCmd);

 private void SysCycleCheckNetTimer_Tick{
                  
                    Form m_ActiveForm = null;
                    //这句是我传入的父窗口Handle 查询能不能 获取到 父窗口form对象
                    IntPtr winPtr = GetWindow(this.Handle, GetWindowCmd.GW_HWNDFIRST);
                    m_ActiveForm = FromHandle(winPtr) as Form;
         
                    //if (m_ActiveForm != null)
                    //{
                    //    MessageBox.Show("找到了");
                    //}
                    //3、从父窗口获取Handle循环取得所有子窗口
                    while (winPtr != IntPtr.Zero)
                    {
                        //4、继续获取下一个子窗口
                        winPtr = GetWindow(winPtr, GetWindowCmd.GW_HWNDNEXT);
                        m_ActiveForm = FromHandle(winPtr) as Form;
                        //排除没用的窗口一个是父窗口另一个 m_ActiveForm.Name 为空的 不知道什么窗口,所以根据空值来排除 剩余的就是其他激活中窗口
                        if (m_ActiveForm != null && this.Handle != winPtr&&!string.IsNullOrEmpty(m_ActiveForm.Name))
                        {
                            MessageBox.Show("找到了111" + m_ActiveForm.Name);
                        }
                    }

}

 public enum GetWindowCmd : uint
    {
        /// <summary>
        /// 返回的句柄标识了在Z序最高端的相同类型的窗口。
        /// 如果指定窗口是最高端窗口,则该句柄标识了在Z序最高端的最高端窗口;
        /// 如果指定窗口是顶层窗口,则该句柄标识了在z序最高端的顶层窗口:
        /// 如果指定窗口是子窗口,则句柄标识了在Z序最高端的同属窗口。
        /// </summary>
        GW_HWNDFIRST = 0,
        /// <summary>
        /// 返回的句柄标识了在z序最低端的相同类型的窗口。
        /// 如果指定窗口是最高端窗口,则该柄标识了在z序最低端的最高端窗口:
        /// 如果指定窗口是顶层窗口,则该句柄标识了在z序最低端的顶层窗口;
        /// 如果指定窗口是子窗口,则句柄标识了在Z序最低端的同属窗口。
        /// </summary>
        GW_HWNDLAST = 1,
        /// <summary>
        /// 返回的句柄标识了在Z序中指定窗口下的相同类型的窗口。
        /// 如果指定窗口是最高端窗口,则该句柄标识了在指定窗口下的最高端窗口:
        /// 如果指定窗口是顶层窗口,则该句柄标识了在指定窗口下的顶层窗口;
        /// 如果指定窗口是子窗口,则句柄标识了在指定窗口下的同属窗口。
        /// </summary>
        GW_HWNDNEXT = 2,
        /// <summary>
        /// 返回的句柄标识了在Z序中指定窗口上的相同类型的窗口。
        /// 如果指定窗口是最高端窗口,则该句柄标识了在指定窗口上的最高端窗口;
        /// 如果指定窗口是顶层窗口,则该句柄标识了在指定窗口上的顶层窗口;
        /// 如果指定窗口是子窗口,则句柄标识了在指定窗口上的同属窗口。
        /// </summary>
        GW_HWNDPREV = 3,
        /// <summary>
        /// 返回的句柄标识了指定窗口的所有者窗口(如果存在)。
        /// GW_OWNER与GW_CHILD不是相对的参数,没有父窗口的含义,如果想得到父窗口请使用GetParent()。
        /// 例如:例如有时对话框的控件的GW_OWNER,是不存在的。
        /// </summary>
        GW_OWNER = 4,
        /// <summary>
        /// 如果指定窗口是父窗口,则获得的是在Tab序顶端的子窗口的句柄,否则为NULL。
        /// 函数仅检查指定父窗口的子窗口,不检查继承窗口。
        /// </summary>
        GW_CHILD = 5,
        /// <summary>
        /// (WindowsNT 5.0)返回的句柄标识了属于指定窗口的处于使能状态弹出式窗口(检索使用第一个由GW_HWNDNEXT 查找到的满足前述条件的窗口);
        /// 如果无使能窗口,则获得的句柄与指定窗口相同。
        /// </summary>
        GW_ENABLEDPOPUP = 6
    }
这就是解决方法
weixin_42501466 2019-05-17
  • 打赏
  • 举报
回复
引用 4 楼 一叶无秋的回复:
好了 问题我已近解决了,就是我上面发的内容,就是解决方法。
这么麻烦,winform好像是有一个对象可以获取本进程打开的窗口
一叶无秋 2018-10-24
  • 打赏
  • 举报
回复
父窗口和子窗口没有父子关系, form2 是show(), 出来的,我举例:form1 主窗体, 有form2到form9 几个窗体,怎么获取到那些窗口是在打开(激活)中,我这是要做一个 禁用所有窗体上所有控件功能, 所以根本不知道那些窗口在用,所以需要用winAPI,

[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern IntPtr GetForegroundWindow();
GetForegroundWindow(); 只能获取到 聚焦的窗口,不是所有打开中的窗口,所以不行
一叶无秋 2018-10-24
  • 打赏
  • 举报
回复

[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr GetWindow(IntPtr hWnd, GetWindowCmd uCmd);
private void SysCycleCheckNetTimer_Tick{
//IntPtr win = FindWindow(null, "Form1");
//Form m_ActiveForm = FromHandle(win) as Form;
Form m_ActiveForm = null;
IntPtr winPtr = GetWindow(this.Handle, GetWindowCmd.GW_HWNDFIRST);
m_ActiveForm = FromHandle(winPtr) as Form;
//if (m_ActiveForm != null)
//{
// MessageBox.Show("找到了");
//}
//3、循环取得桌面下的所有子窗口
while (winPtr != IntPtr.Zero)
{
//4、继续获取下一个子窗口
winPtr = GetWindow(winPtr, GetWindowCmd.GW_HWNDNEXT);
m_ActiveForm = FromHandle(winPtr) as Form;
if (m_ActiveForm != null && this.Handle != winPtr)
{
MessageBox.Show("找到了111" + m_ActiveForm.Name);
}
}

}

public enum GetWindowCmd : uint
{
/// <summary>
/// 返回的句柄标识了在Z序最高端的相同类型的窗口。
/// 如果指定窗口是最高端窗口,则该句柄标识了在Z序最高端的最高端窗口;
/// 如果指定窗口是顶层窗口,则该句柄标识了在z序最高端的顶层窗口:
/// 如果指定窗口是子窗口,则句柄标识了在Z序最高端的同属窗口。
/// </summary>
GW_HWNDFIRST = 0,
/// <summary>
/// 返回的句柄标识了在z序最低端的相同类型的窗口。
/// 如果指定窗口是最高端窗口,则该柄标识了在z序最低端的最高端窗口:
/// 如果指定窗口是顶层窗口,则该句柄标识了在z序最低端的顶层窗口;
/// 如果指定窗口是子窗口,则句柄标识了在Z序最低端的同属窗口。
/// </summary>
GW_HWNDLAST = 1,
/// <summary>
/// 返回的句柄标识了在Z序中指定窗口下的相同类型的窗口。
/// 如果指定窗口是最高端窗口,则该句柄标识了在指定窗口下的最高端窗口:
/// 如果指定窗口是顶层窗口,则该句柄标识了在指定窗口下的顶层窗口;
/// 如果指定窗口是子窗口,则句柄标识了在指定窗口下的同属窗口。
/// </summary>
GW_HWNDNEXT = 2,
/// <summary>
/// 返回的句柄标识了在Z序中指定窗口上的相同类型的窗口。
/// 如果指定窗口是最高端窗口,则该句柄标识了在指定窗口上的最高端窗口;
/// 如果指定窗口是顶层窗口,则该句柄标识了在指定窗口上的顶层窗口;
/// 如果指定窗口是子窗口,则句柄标识了在指定窗口上的同属窗口。
/// </summary>
GW_HWNDPREV = 3,
/// <summary>
/// 返回的句柄标识了指定窗口的所有者窗口(如果存在)。
/// GW_OWNER与GW_CHILD不是相对的参数,没有父窗口的含义,如果想得到父窗口请使用GetParent()。
/// 例如:例如有时对话框的控件的GW_OWNER,是不存在的。
/// </summary>
GW_OWNER = 4,
/// <summary>
/// 如果指定窗口是父窗口,则获得的是在Tab序顶端的子窗口的句柄,否则为NULL。
/// 函数仅检查指定父窗口的子窗口,不检查继承窗口。
/// </summary>
GW_CHILD = 5,
/// <summary>
/// (WindowsNT 5.0)返回的句柄标识了属于指定窗口的处于使能状态弹出式窗口(检索使用第一个由GW_HWNDNEXT 查找到的满足前述条件的窗口);
/// 如果无使能窗口,则获得的句柄与指定窗口相同。
/// </summary>
GW_ENABLEDPOPUP = 6
}

这是我在网上找了很多资料才找到的,通过windowsAPI 获取到桌面窗口程序,但是不稳定,EnumChildWindows比FromHandle 获取窗口要好些,但是一直没有找到例子。
一叶无秋 2018-10-24
  • 打赏
  • 举报
回复
好了 问题我已近解决了,就是我上面发的内容,就是解决方法。
qq_3958 2018-10-23
  • 打赏
  • 举报
回复
引用
https://blog.csdn.net/momojiang5/article/details/50384728
了解一下

13,347

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 .NET技术前瞻
社区管理员
  • .NET技术前瞻社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧