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

2016-01-29 11:55 58 1 收藏

获得 Win32 窗口句柄的更好的方法,获得 Win32 窗口句柄的更好的方法

【 tulaoshi.com - C语言心得技巧 】

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

编译/NorthTibet

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com)

原文出处: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窗口的方法来禁用上下

来源:https://www.tulaoshi.com/n/20160129/1483879.html

延伸阅读
中午休息时,在FOX API(我常用的Win32 API浏览器)上发现了一个简单极好用的Win32API函数,是用来判断本地文件或远程机器文件是否存在的: 1. Private Declare Function PathFileExists Lib "shlwapi.dll" Alias "PathFileExistsA" (ByVal pszPath As String) As Long 这是封装在Shell32.DLL系统文件里的一个函数,既可以判断本地文件是否存在...
众 所 周 知, 在Windows95/98 的Win32 on Intel x86 体 系 中 利 用 了 处 理 器 的 三 环 保 护 模 型 中 的 零 环(Ring0, 最 高 权 限 级 别) 和 三 环(Ring3, 最 低 权 限 级 别)。 一 般 应 用 程 序 都 运 行 在Ring3 下, 受 到 严 格 的" 保 护", 只 能 规 矩 地 使 用Win32API。 如 果 我 们 想 进 行 一 些 系 ...
解决Office报错提示“不是有效的win32应用程序” 好不容易将系统上的Office全部升级到最新版本Office2010,使用还算不错,挺顺手,挺方便的,一直使用没什么其他异常现象。但有一次被同事改动了一下,连他自己也不知道改动了哪里,从那以后每每打开文档,就弹出错误提示:不是有效的win32应用程序。该如何修复呢?相信遇到此问题的不只我一...
这一次我们将深入探讨如何在 C# 中使用 Win32 和其他现有库。 C# 用户经常提出两个问题:我为什么要另外编写代码来使用内置于 Windows 中的功能?在框架中为什么没有相应的内容可以为我完成这一任务?当框架小组构建他们的 .NET 部分时,他们评估了为使 .NET 程序员可以使用 Win32 而需要完成的工作,结果发现 Win32 API 集非常庞大。...
Win95和线程 Win95 为每个线程的创建损失大约200个字节的内存。因此,如果你进行许多连接,你不应该在Win95运行mysqld很长时间,因为MySQL的每个连接都创建一个新线程!WinNT和Win98不能容忍这个bug。 阻塞式读(blocking read) MySQL为每个连接使用一个阻塞式读取,这意味着: 一个连接将不在8个小时后自动被断开,就像MySQL的Unix版本所...

经验教程

966

收藏

95
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部