加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

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

(2010-04-15 01:02:44)
标签:

杂谈

用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;
    
/// 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 great website.It includes almost all the API fuctoin to be used in C#.
    
/// </summary>

    class FindWindow
    
...{
        [DllImport(
"user32")]
        [
returnMarshalAs(UnmanagedType.Bool)]
        
//IMPORTANT LPARAM  must be 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, don't know who wrote it.
  
// Compiles with Visual Studio .NET on Windows XP. Tab size=3.
  
//
  
// ---
  
// This class encapsulates the process of finding window with given class name
  
// as descendant of 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 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) ...

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有