用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) ...
加载中,请稍候......