C#查找指定窗口的子窗口的句柄

c# 中调用EnumChildWindow c# 中调用windows api函数 //原函数定义 BOOL WINAPI EnumChildWindows( _In_opt_ HWND hWndParent, _In_ WNDENUMPROC lpEnumFunc, _In_ LPARAM lParam ); //C#定义 [DllImport("user32.dl 阅读详情

用axWebBrowser加载HTML网页时,真正显示内容的窗体并不是axWebBrowser,而是其子窗口的子窗口一个名为Internet Explorer_Server的类。从spy++可知:

 

公司需要在网页上进行手写,需要对Internet Explorer_Server进行操作,而通过axWebBrowser的Handle不能直接操作Internet Explorer_Server。于是在网上搜到Paul DiLascia写的一个CFindWnd类,是用C++写的,由于我用C#进行了改写。

这个类主要用的的API 是EnumChildWindows和FindWindowEx,第一个遍历指定窗口下的子窗口,第二个查找指定名称的窗口,如果找到返回此窗口Handle。

该类的用法:

FindWindow fw = new FindWindow(wndHandle, "ChildwndClassName"); //实例化,第一个参数是要查找的起始窗口的句柄;第二个参数是要查找的窗口的类的名称。现在我们需要的传的是"Internet Explorer_Server"。

IntPtr ip = fw.FoundHandle;//FindWindow的公共属性FoundHandle就是查找到的窗口的句柄。

完整的类如下: 

using  System;
using  System.Collections.Generic;
using  System.Text;
using  System.Runtime.InteropServices;

namespace  SystemManager.Utility
{
    
/// <summary>
    
/// This class is to find the given window's child window accroding to the given child window's name.
    
/// The useage: FindWindow fw = new FindWindow(wndHandle, "ChildwndClassName"); IntPtr ip = fw.FoundHandle;
    
/// I adapt the code from Paul DiLascia,who is the MSDN Magazine's writer.
    
/// The original class is named CFindWnd which is written in C++, and you could get it on Internet.
    
/// www.pinvoke.net is a great website.It includes almost all the API fuctoin to be used in C#.
    
/// </summary>

    class FindWindow
    
{
        [DllImport(
"user32")]
        [
return: MarshalAs(UnmanagedType.Bool)]
        
//IMPORTANT : LPARAM  must be a pointer (InterPtr) in VS2005, otherwise an exception will be thrown
        private static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr i);
        
//the callback function for the EnumChildWindows
        private delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter);

        
//if found  return the handle , otherwise return IntPtr.Zero
        [DllImport("user32.dll", EntryPoint = "FindWindowEx")]
        
private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

  
private string m_classname; // class name to look for
       
        
private IntPtr m_hWnd; // HWND if found
        public IntPtr FoundHandle
        
{
            
get return m_hWnd; }
        }

  
// ctor does the work--just instantiate and go
  public FindWindow(IntPtr hwndParent, string classname)  
  
{            
            m_hWnd 
= IntPtr.Zero;
            m_classname 
= classname;
            FindChildClassHwnd(hwndParent, IntPtr.Zero);
  }


        
/// <summary>
        
/// Find the child window, if found m_classname will be assigned 
        
/// </summary>
        
/// <param name="hwndParent">parent's handle</param>
        
/// <param name="lParam">the application value, nonuse</param>
        
/// <returns>found or not found</returns>

        //The C++ code is that  lParam is the instance of FindWindow class , if found assign the instance's m_hWnd
        private bool FindChildClassHwnd(IntPtr hwndParent, IntPtr lParam)
        
{
            EnumWindowProc childProc 
= new EnumWindowProc(FindChildClassHwnd);
            IntPtr hwnd 
= FindWindowEx(hwndParent, IntPtr.Zero, this.m_classname, string.Empty);
            
if (hwnd != IntPtr.Zero)
            
{
                
this.m_hWnd = hwnd; // found: save it
                return false// stop enumerating
            }

            EnumChildWindows(hwndParent, childProc, IntPtr.Zero); 
// recurse  redo FindChildClassHwnd
            return true;// keep looking
        }

    }

}

 

 注意:在VS2005中,MDA检查的很严格,LPARAM是64位,要用IntPtr表示(网上有人用long来表示,我试了,MDA会抛出异常)。http://pinvoke.net 是个不错的网站,它包含了几乎所有的API在.NET中的调用说明,还有例子。

附Paul DiLascia用C++写的CFindWnd类: 

  ////////////////////////////////////////////////////////////////
   //  MSDN Magazine -- August 2003
  
//  If this code works, it was written by Paul DiLascia.
  
//  If not, I don't know who wrote it.
  
//  Compiles with Visual Studio .NET on Windows XP. Tab size=3.
  
//
  
//  ---
  
//  This class encapsulates the process of finding a window with a given class name
  
//  as a descendant of a given window. To use it, instantiate like so:
  
//
  
//  CFindWnd fw(hwndParent,classname);
  
//
  
//  fw.m_hWnd will be the HWND of the desired window, if found.
  
//
   class  CFindWnd  {
  
private:
  
//////////////////
  // This private function is used with EnumChildWindows to find the child
  
// with a given class name. Returns FALSE if found (to stop enumerating).
  
//
  static BOOL CALLBACK FindChildClassHwnd(HWND hwndParent, LPARAM lParam) {
  CFindWnd 
*pfw = (CFindWnd*)lParam;
  HWND hwnd 
= FindWindowEx(hwndParent, NULL, pfw->m_classname, NULL);
  
if (hwnd) {
  pfw
->m_hWnd = hwnd; // found: save it
  return FALSE; // stop enumerating
  }

  EnumChildWindows(hwndParent, FindChildClassHwnd, lParam); 
// recurse
  return TRUE; // keep looking
  }

  
public:
  LPCSTR m_classname; 
// class name to look for
  HWND m_hWnd; // HWND if found
  
// ctor does the work--just instantiate and go
  CFindWnd(HWND hwndParent, LPCSTR classname)
  : m_hWnd(NULL), m_classname(classname)
  
{
  FindChildClassHwnd(hwndParent, (LPARAM)
this);
  }

  }
;

 

2009年更新
通过实验得知,FindWindowEx可以通过classname或caption(也就是窗口的title)查找窗口,且如果第一个参数传IntPtr.Zero的话,将从Windows最顶层窗口开始查找,但是窗口很多的话这样会非常的慢,所以加入Timeout的判断,如果超时还没找到,返回false。

用法:FindWindow fw = new FindWindow(IntPtr.Zero, null, "ThunderDFrame", 10);//查找Title为ThunderDFrame的窗口,如果10秒内还没找到,返回false

代码如下:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace Util
{
    class FindWindow
    {
        [DllImport("user32")]
        [return: MarshalAs(UnmanagedType.Bool)]
        //IMPORTANT : LPARAM  must be a pointer (InterPtr) in VS2005, otherwise an exception will be thrown
        private static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr i);
        //the callback function for the EnumChildWindows
        private delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter);

        //if found  return the handle , otherwise return IntPtr.Zero
        [DllImport("user32.dll", EntryPoint = "FindWindowEx")]
        private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

        private string m_classname; // class name to look for
        private string m_caption; // caption name to look for

        private DateTime start;
        private int m_timeout;//If exceed the time. Indicate no windows found.

        private IntPtr m_hWnd; // HWND if found
        public IntPtr FoundHandle
        {
            get { return m_hWnd; }
        }

        private bool m_IsTimeOut;
        public bool IsTimeOut
        {
            get{return m_IsTimeOut;}
            set { m_IsTimeOut = value; }
        }

        // ctor does the work--just instantiate and go
        public FindWindow(IntPtr hwndParent, string classname, string caption, int timeout)
        {
            m_hWnd = IntPtr.Zero;
            m_classname = classname;
            m_caption = caption;
            m_timeout = timeout;
            start = DateTime.Now;
            FindChildClassHwnd(hwndParent, IntPtr.Zero);
        }

        /**/
        /// <summary>
        /// Find the child window, if found m_classname will be assigned 
        /// </summary>
        /// <param name="hwndParent">parent's handle</param>
        /// <param name="lParam">the application value, nonuse</param>
        /// <returns>found or not found</returns>
        //The C++ code is that  lParam is the instance of FindWindow class , if found assign the instance's m_hWnd
        private bool FindChildClassHwnd(IntPtr hwndParent, IntPtr lParam)
        {
            EnumWindowProc childProc = new EnumWindowProc(FindChildClassHwnd);
            IntPtr hwnd = FindWindowEx(hwndParent, IntPtr.Zero, m_classname, m_caption);
            if (hwnd != IntPtr.Zero)
            {
                this.m_hWnd = hwnd; // found: save it
                m_IsTimeOut = false;
                return false; // stop enumerating
            }

            DateTime end = DateTime.Now;

            if (start.AddSeconds(m_timeout) < end)
            {
                m_IsTimeOut = true;
                return false;
            }

            EnumChildWindows(hwndParent, childProc, IntPtr.Zero); // recurse  redo FindChildClassHwnd
            return true;// keep looking
        }
    }
}

 

如何获取窗口内文本框的句柄 一  背景   某种情况下,需要从某窗体获取该窗体文本框内的内容,发现文本框并没有标题名,无法获取文本框控件的句柄。接下来,我将介绍我获取所需文本框控件句柄方法。 二  使用Spy++获取   如图,打开Spy++可以直接获取到“测试窗口”的所有控件句柄。        三  EnumChildWindows遍历所有句柄   一般窗体内文本框前面都有一个lable控件来标注,比如“测试... 阅读详情

相关推荐

在 SAP 里玩转 FTP:标准程序 RSFTP00x 全景解析与落地实践

摘要:SAP系统通过封装的标准FTP程序(RSFTP001-008)提供便捷的文件传输能力,适用于各类集成场景。关键点包括:1)依赖SAPFTP可执行程序和RFC目的地;2)使用RSFTP005进行前置检查并生成RFC配置;3)标准报表各司其职,如RSFTP002用于命令测试、RSFTP007/008提供参考实现;4)开发时组合FTP_CONNECT/COMMAND/DISCONNECT等函数模块。特别注意前台(SAPFTP)与后台(SAPFTPA)的环境差异,这是常见故障点。该方案通过标准化工具链显著降低

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 186

FindWindow、FindWindowEx、EnumWindows、EnumChildWindows使用详解

FindWindow FindWindowEx EnumWindows EnumChildWindows

lzl_li的专栏 4945

前言:关于作者吴秋生博士与此书简介

博士现为田纳西大学,诺克斯维尔分校,地理系的副教授。他的研究兴趣包括地理信息科学(GIS)、遥感和环境建模。更具体地说,对应用地理空间大数据、机器学习和云计算(例如,谷歌地球引擎、微软行星计算机)来研究环境变化,特别是地表水和湿地淹没动态。吴博士是开放科学和可重复研究的倡导者。他开发了几个用于高级地理空间分析的开源软件包(例如,吴博士还在YouTube上发布了数百个有关GIS和地图绘制的视频。更多有关他的开源项目信息,请访问GitHub(查看他的YouTube频道。.....................

韩天放 6027

[原创]C#应用WindowsApi实现查找\枚举(FindWindow、EnumChildWindows)窗体控件,并发送消息。...

首先介绍基本WindowsApi: public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); 函数说明:在窗口列表中寻找与指定条件相符的第一个窗口 导入库:user32.lib 头文件:winuser.h 命名空间 using System.Runtime.InteropSe...

weixin_30500105的博客 1284

c#中通过win32API(FindWindowEx)查找控件句柄实例

函数功能:该函数获得一个窗口句柄,该窗口的类名和窗口名与给定的字符串相匹配。这个函数查找窗口,从排在给定的窗口后面的下 一个窗口开始。在查找时不区分大小写。 函数原型:HWND FindWindowEx(HWND hwndParent,HWND hwndChildAfter,LPCTSTR lpszClass,LPCTSTR lpszWindow); 参数:hwndParent:要查找窗口的父窗口句柄。 如果hwnjParent为NULL,则函数以桌面窗口为父窗口查找桌面窗口的所有窗口

u011555996的博客 3189

c# 查找其他窗口得方法

查找窗口 [DllImport(“User32.dll”, EntryPoint = “FindWindow”)] public extern static IntPtr FindWindow( string lpClassName,string lpWindowName); IntPtr maindHwnd = FindWindow(“WindowsForms10.Window.8.app.0....

suddle的博客 3194

写个类操作窗口句柄操作)

写个类操作窗口句柄操作) 前言:本店绝不含地沟油 顾客:“老板,你这油怎么这么亮呀,跟我平常吃的不一样,不会是地沟油吧?” 回答:“你平常吃的是地沟油!” 继续缅怀逝去的程序员生涯 倒腾WinForm, 是这样的俺想做个方便的类来控制其他程序的窗口,具体就是操作句柄。 这里以改变窗口的输入框(Text)举例,其他自己搞吧,就是调用WinAPI...

bangti5888的博客 158

C#中获得窗体的句柄

代码如下: ... { [DllImport("User32.dll",EntryPoint="FindWindow")] private static extern IntPtr FindWindow(string lpClassName,string lpWindowName); private void test() { IntPtr h...

柳鲲鹏 1450

C#使用API枚举窗体查找句柄或获取包含特定字符串的窗口标题及控件内容

C#使用API枚举窗体查找句柄或获取包含特定字符串的窗口标题及控件内容

yunxiaobaobei的博客 6030

EnumChildWindows 枚举窗体

朕是学Delphi过来的,不少人说网络上VC++的实例代码比较多,之后,个人感觉应该是吧。再后,又想学习外挂,所以,两门语言齐上! 资质甚差劲,换了形式就不懂了!问你死不?!记录!原文出处:http://tech.ddvip.com/2009-04/1239278240114242_8.html EnumChildWindows    函数原型:  BOOL EnumChild

期待下集是个可爱梦儿 2352

C#中捕捉对话框的文本内容 EnumChildWindows

 如何找到桌面上报错的窗口,不管是父窗口还是窗口,而且获得它的出错信息呢? 主要是利用API函数: 复制 保存[DllImport("user32.dll")]public static extern int FindWindowEx(int hwndParent, int hwndChildAfter, string lpszClass, string lps

lovegod12的专栏 2471

C++ 主程序中打开程序窗口隐藏,操作控件 遍历窗口控件句柄EnumChildWindows();获取其他程序进度条数据 操作选择框 按钮点击

1.线程启动程序 system_hide(L"Odin3.exe",SW_SHOW /*SW_HIDE*/); //SHOW是显示 HIDE是隐藏 unsigned int tid = 0; HANDLE handle = (HANDLE)_beginthreadex(NULL, 0, FindWindowsThread, this, 0, &tid); CloseHandle(handle); 2. EnumWindows函数(winuser.h) 通过将句柄传递给每个窗口

qq_42095701的博客 4316

EnumChildWindows 函数 (winuser.h)

通过将每个窗口句柄依次传递给应用程序定义的回调函数,枚举属于指定窗口窗口EnumChildWindows 会一直持续到枚举最后一个窗口或回调函数返回 FALSE。在枚举过程中按 Z 顺序移动或重新定位的窗口将被正确枚举。函数不枚举在枚举之前销毁的窗口,也不枚举在枚举过程中创建的窗口。要枚举其窗口的父窗口句柄。参数一:[in,optional] hWndParent。参数二:[in] lpEnumFunc。如果窗口已创建自己的窗口,参数三:[in] lParam。

程序猿的白兰日常 1213

枚举遍历所有窗口句柄控件类型标题

指定的父窗口枚举窗口、按钮  很早就写过类似spy++和查看密码窗口的东西,一直想给这个小东西再加点特别的。前段时间对软件安装注册发生了兴趣,有些软件如果你不输入正确注册码,那该死的“下一步”按钮就一直disable。这次我就让spy++彻底spy到底,把那个注册用的按钮置亮,让我轻松进入“下一步”,呵呵…。   我的想法是光标移到指定窗口上后,探测这个窗口上到底有多少按钮,如果有,就将它们

MFC备忘录 9388

Sanet.st_Prompt Engineering for LLMs - John Berryman.pdf

Sanet.st_Prompt Engineering for LLMs - John Berryman.pdf

上一篇: 百度之星编程大赛-语言翻译机(C#解答)
下一篇: 使用SqlBulkCopy提高导入数据的性能
iwteih
博客等级 码龄21年 16粉丝 48原创
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值