当前位置: 首页 > 图文教程 > 开发语言 > VC++ > 获得 Win32 窗口句柄的更好的方法

VC++
在类VC的界面实现中加入目录树
软件换肤技术在 BCB 中的实现
利用非模窗口生成MDI介面
报表输出轻松搞定
Windows 中不规则窗体的编程实现
解说Win32的窗口子类化
使用测试优先方法开发用户界面
一个简单的登录对话框的实现
一个简单的日记本程序
从资源中加载皮肤
一个在RichEdit中添加表情图象的类
ActiveSkin 4.3 软件换肤在VC中的实现
一种另类“关于(About)”对话框的动态显示方法
对话框打印预览及打印
关于如何换肤、子类化的解决方案
制作 MSN、QQ 的消息提示窗口
如何对 BCGControlBarPro 进行换肤
定制个性化的对话框窗口类
改变窗口中的光标形状
更新MFC中的视图,跟踪.NET Framework中的事件

VC++ 中的 获得 Win32 窗口句柄的更好的方法


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-30   浏览: 95 ::
收藏到网摘: n/a

获得 Win32 窗口句柄的更好的方法
----动态生成并显示 HTML 文档
  ----再谈禁用HTML的上下文菜单...

编译/NorthTibet

原文出处:MSDN Magazine C++ Q&A


下载源代码

 译者注:
在以前的VC知识库 Online Journal 上有三篇文章:

“VC6中使用CHtmlView在对话框控制中显示HTML文件”(第六期)
“如何禁用HTML页面的上下文菜单”(第十一期)
“Convert CHtmlView to CHtmlCtrl...”(第十七期)

    这三篇文章的原文实际上都出自 MSDN Magazine 及其前身 MSJ 的“C++ Q&A”专栏作家 Paul DiLascia 之手。此君从1995年开始就成为 MS 在 C++/MFC 方面的高级写手,Paul 在 Windows 应用开发领域的造诣颇深。直到现在仍然在为该专栏撰写技术文章,只不过其文章已不仅仅涉及 C++/MFC,偶尔也写一些 C#。为了微软的 .NET 战略,Paul 可谓忠实、勤奋和敬业......
    本文是以上文章所涉及内容的延伸。如果你已经对前述文章讨论的东西了然于心,那么可以直接切入本文的正题。如果你没有看过上面提到的文章,建议最好先看一下,以便了解本文内容的背景,这样对于理解本文所讨论的东西会更有帮助。

 背景简介
  话说在第六期的“VC6中使用CHtmlView在对话框控制中显示HTML文件”一文中,主要讨论并示范了如何改进 MFC 的 CHtmlView 类,使它能处理基于对话框的应用和各种其它类型的窗口应用,其思路是通过创建 CHtmlView 的派生类 CHtmlCtrl,使得 CHtmlView 摆脱了对文档/视图的依赖。
  在第十一期的“如何禁用HTML页面的上下文菜单”一文中,主要讨论了如何通过子类化 IE 服务器窗口(Internet Explorer_Server)来禁用 CHtmlCtrl 的上下文菜单。实际上,真正显示HTML的窗口并不是浏览器(CHtmlView/CHtmlCtrl)窗口,而是一个名为“Internet Explorer_Server”的最底层的子孙窗口。这一点可以通过 Spy++ 来证实,为了获得该窗口的句柄(HWND),在实现过程中使用了一个函数 GetLastChild(HWND hwndParent),其定义如下:

static HWND GetLastChild(HWND hwndParent){ HWND hwnd = hwndParent; while (TRUE) { HWND hwndChild = ::GetWindow(hwnd, GW_CHILD); if (hwndChild==NULL) return hwnd; hwnd = hwndChild; } return NULL;}
   通过这个函数返回某个父窗口下的最后一个子窗口,也就是说返回子窗口的子窗口的子窗口......直到不再有子窗口为止。可惜这个函数要获得正确的运行结果是有前提的,那就是窗口层次只能是一层,并且最终的窗口后裔是“Internet Explorer_Server”窗口。 在通常情况下,这个假设都成立。不幸的是,如果 HTML 文档中包含象 ComBoxes(组合框) 这样的控制时,这个假设就不灵了。用 Spy++ 不难发现情况并不象你期望的那样Internet Explorer_Server是最后的子窗口。实际上,在IE中,Edit 和 Button 控制并非人们所想象的那样是子窗口。

获得 Win32 窗口句柄的更好的方法
   为了解决这个问题,本文设计了一个更加完善的类:CFindWnd,用更好的算法专门来获取 IE 窗口。CFindWnd 查找某个窗口(给定窗口名字)的第一个子窗口。 例如,它的使用方法如下:
CFindWnd ies(m_hWnd, "Internet Explorer_Server");myHwndIE = ies.m_hWnd;
这个类的构造函数调用函数:
 FindChildClassHwnd(hwndParent, (LPARAM)this)
函数,该函数又调用:
 EnumChildWindows 和 FindWindowEx 
搜索所有后裔窗口直到找到类名匹配窗口为止。FindWindow 用来查找最顶层窗口,而搜索子窗口还得用 FindWindowEx,它是 Win32 API 函数。CFindWnd 返回第一个匹配的窗口,所以它只被用于查找你期望只有一个实例的窗口。通常在搜索特定窗口时,一般最保险的做法都是检查窗口类名。

百家争鸣
   有一个读者来信指出:根本没有必要使用子类IE窗口的方法来禁用上下