【转】关于CreateWindow的HINSTANCE参数?

学习Windows程序设计时,看见CreateWindows中有参数HINSTANCE,但不知道其用途,于是上网搜得两资料,并且,得出结果是,用于区分不同的应用实例。

 

What is the HINSTANCE passed to CreateWindow and RegisterClass used for?

 

One of the less-understood parameters to the CreateWindow function and theRegisterClass function is the HINSTANCE (either passed as a parameter or as part ofthe WNDCLASS structure).

The window class name is not sufficient to identify the class uniquely. Each process has its own window class list, and each entry in the window class list consists of an instance handle and a class name. For example, here's what the window class list might look like if a program has two DLLs, both of which register a class name "MyClass", passing the DLL's handle as the HINSTANCE.

 HINSTANCEClass name
1.USER32.DLLStatic
2.USER32.DLLButton
3.USER32.DLLListbox
4.USER32.DLLCombobox
5.USER32.DLLEdit
6.A.DLLMyClass
7.B.DLLMyClass

When it comes time to create a window, each module then passes its ownHINSTANCE when creating the window, and the window manager uses the combination of the instance handle and the class name to look up the class.

CreateWindow("MyClass", ..., hinstA, ...); // creates class 6
CreateWindow("MyClass", ..., hinstB, ...); // creates class 7
CreateWindow("MyClass", ..., hinstC, ...); // fails

This is why it is okay if multiple DLLs all register a class called "MyClass"; the instance handle is used to tell them apart.

There is an exception to the above rule, however. If you pass the CS_GLOBALCLASSflag when registering the class, then the window manager will ignore the instance handle when looking for your class. All of the USER32 classes are registered as global. Consequently, all of the following calls create the USER32 edit control:

CreateWindow("edit", ..., hinstA, ...);
CreateWindow("edit", ..., hinstB, ...);
CreateWindow("edit", ..., hinstC, ...);

If you are registering a class for other modules to use in dialog boxes, you need to register as CS_GLOBALCLASS, because as we saw earlier the internal CreateWindow call performed during dialog box creation to create the controls passes the dialog'sHINSTANCE as the HINSTANCE parameter. Since the dialog instance handle is typically the DLL that is creating the dialog (since that same HINSTANCE is used to look up the template), failing to register with the CS_GLOBALCLASS flag means that the window class lookup will not find the class since it's registered under the instance handle of the DLL that provided the class, not the one that is using it.

In 16-bit Windows, the instance handle did other things, too, but they are no longer relevant to Win32.

A common mistake is to pass the HINSTANCE of some other module (typically, the primary executable) when registering a window class. Now that you understand what the HINSTANCE is used for, you should be able to explain the consequences of registering a class with the wrong HINSTANCE.

Published Monday, April 18, 2005 4:47 AM by oldnewthing Filed under: Code

 

来自: http://zouxiaochuan.bokee.com/6551054.html

 

 

译者按:老汉当初学习 Windows 编程的时候就对此问题有过疑惑,后来明白了,却懒得写一篇总结性的东西。这是在 The Old New Thing 的 Blog 上发现的,翻译过来,权且为新手释疑。原文的链接为 http://blogs.msdn.com/oldnewthing/archive/2005/04/18/409205.aspx。

CreateWindow 函数和 RegisterClass 函数(译者注:以及这两个函数相应的 Ex 后缀版本)中很少被人理解的一个参数是 HINSTANCE(或者作为参数传递或者作为 WNDCLASS 结构的一部分)。

窗口类名不足以唯一地标志窗口类。每个进程有自己的窗口类列表,窗口类列表中的每一项都由一个实例句柄和一个类名字组成。例如,如果一个程序有两个 DLL,每个都注册了一个名为“MyClass”的窗口类,并且将 DLL 的句柄作为 HINSTANCE 传递,则窗口类列表看起来就象这样:

 

  HINSTANCE  Class name 
1 USER32.DLL  Static
2 USER32.DLL Button 
3 USER32.DLL ListBox 
4 USER32.DLL ComboBox 
5 USER32.DLL Edit 
6 A.DLL MyClass 
7 B.DLL MyClass 

当要创建窗口时,每个模块传递它自己的 HINSTANCE,窗口管理器使用实例句柄和窗口类的组合来寻找窗口类。

 

CreateWindow("MyClass", ..., hinstA, ...); // 创建窗口类 6 
CreateWindow("MyClass", ..., hinstB, ...); // 创建窗口类 7 
CreateWindow("MyClass", ..., hinstC, ...); // 失败 

这就是为什么多个 DLL 都创建名为“MyClass”的类可以成功,实例句柄用来将它们区别开来。

但是上述规则有一个例外。如果在你注册窗口类时指定了 CS_GLOBALCLASS 标志,那么窗口管理器在寻找你的窗口类时将忽略实例句柄。所有的 USER32 窗口类都被注册为全局的。因而,下面所有的调用都会创建 USER32 的编辑框控件:

 

CreateWindow("edit", ..., hinstA, ...); 
CreateWindow("edit", ..., hinstB, ...); 
CreateWindow("edit", ..., hinstC, ...); 

如果你要注册一个用在其他模块的对话框里的窗口类,你就需要注册为 CS_GLOBALCLASS,因为像我们先前看到的,在对话框创建过程中,创建控件执行的内部 CreateWindow 调用会把对话框的 HINSTANCE 用作 HINSTANCE 参数。因为对话框的实例句柄通常是创建该对话框的 DLL(因为相同的 HINSTANCE 要用来寻找对话框模板),不使用 CS_GLOBALCLASS 标志注册意味着寻找窗口类时将不能找到该类,因为它注册于提供该窗口类的 DLL 的实例句柄名下而不是使用它的那个。

在 16 位 Windows 中,实例句柄还要用来做其他事情,但在 Win32 里已经没有关系了。

一个常见的错误是在注册窗口类时传递一些其他的 HINSTANCE 进去(典型地,主执行程序的)。现在了解了 HINSTANCE 的用途,你就应该能够解释用错误的 HINSTANCE 注册窗口类的后果了。

 

来自:http://blog.sina.com.cn/s/blog_538457490100mhj8.html

转载于:https://blog.51cto.com/neicole/1211057

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/436150.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java对象间的转型,详细讲述Java中的对象转型

向上转型:子类对象转为父类,父类可以是接口。公式:Father f new Son();Father是父类或接口,son是子类。向下转型:父类对象转为子类。公式:Son s (Son)f;我们将形参设为父类Animal类型,当执行t…

给C盘减减肥,让你电脑飞一般速度!

当你买了台新电脑时,觉得性能,速度,你都比较满意,但是随着时间推移,你觉得你C盘空间越来越小,速度也降下了,那我们该怎么办呢?对于菜鸟来说,有一点你必须注意&#xff1a…

C++设计模式之一 工厂模式(简单工厂、工厂和抽象工厂)

今天开始这个系列之前,心里有些恐慌,毕竟园子里的高手关于设计模式的经典文章很多很多,特别是大侠李会军、吕震宇 老师的文章更是堪称经典。他们的文笔如行云流水,例子活泼生动,讲解深入浅出。好在他们都是用C#描述&am…

【转】Windows消息传递机制详解

林炳文Evankaka原创作品。转载请注明出处http://blog.csdn.net/evankaka Windows是一个消息(Message)驱动系统。Windows的消息提供了应用程序之间、应用程序与Windows系统之间进行通信的手段。应用程序想要实现的功能由消息来触发,并且靠对消…

matlab中邮递员问题实例,中国邮递员问题matlab

中国邮递员问题的EXCEL求... 1页 免费 对中国邮递员问题的数理... 4页 1下载券 中国邮递员问题matlab 6页 1下载券 喜欢...中国邮递员问题摘要:欧拉图起源于哥尼斯堡七桥问题,通过图中所有边一次且仅一次行遍...中国邮递员问题 (Chinese Postman Problem) 主要内容 七桥问题与一…

Response.Redirect(),Server.Transfer(),Server.Execute()的区别

Response.Redirect(),Server.Transfer(),Server.Execute()的区别 1、Response.Redirect(): Response.Redirect方法导致浏览器链接到一个指定的URL。当Response.Redirect()方法被调用时,它会创建一个应答,应答头中指出了状态代 码302(表示目…

设计模式C++实现(2)——单例模式

软件领域中的设计模式为开发人员提供了一种使用专家设计经验的有效途径。设计模式中运用了面向对象编程语言的重要特性:封装、继承、多态,真正领悟设计模式的精髓是可能一个漫长的过程,需要大量实践经验的积累。最近看设计模式的书&#xff0…

php聊天室技术,PHP聊天室技术

PHP聊天室技术推荐查看本文HTML版本1.前言上网聊天是时下最流行的交友方式。各大网站推出的聊天室都各具特色。聊天室主要分为WebChat、BBSChat两种。BBSChat是基于Telnet的Tcp协议,是BBS的附设功能,需要客户端Telnet程序。WebChat则采用…

【转】深入理解Windows消息机制

转自:https://blog.csdn.net/liulianglin/article/details/14449577 今天我们来学一学Windows消息机制,我们知道在传统的C语音程序中,当我们需要打开一个文件时,我们可以调用fopen()函数,这个函数最后又会调用操作系统…

System.Drawing.Color.FromArgb(144,238,255);

if(dg.Items[i].Cells[iRow].Text "没完成") { dg.Items[i].BackColorSystem.Drawing.Color.FromArgb(144,238,255); } if(dg.Items[i].Cells[iRow].Text "已完成") { dg.Items[i].BackColorSystem.Drawing.Color.LightGreen;…

设计模式C++实现(3)——建造者模式

软件领域中的设计模式为开发人员提供了一种使用专家设计经验的有效途径。设计模式中运用了面向对象编程语言的重要特性:封装、继承、多态,真正领悟设计模式的精髓是可能一个漫长的过程,需要大量实践经验的积累。最近看设计模式的书&#xff0…

php tp 模板assign,thinkphp中怎么让assign在另一个模板里使用呢?

比如现在我有a.html和名字为b的控制器,现在我在b控制器里assing(‘b’,$b),那么请问在a.html中怎么调用b控制器中的assign呢?回复讨论(解决方案)代码是这样的Controller:public function a(){$this->display();}public function b(){if(IS_AJAX){$imageD(‘Image’);$b$ima…

【转】详解Windows消息分类以及WM_COMMAND与WM_NOTIFY的区别,以及模拟发送控件通知消息

转自:http://blog.sina.com.cn/s/blog_4b3c1f950100nten.html Windows消息的分类 1. 标准消息(队列消息) 除WM_COMMAND之外,所有以WM_开头的消息都是标准消息,如WM_MOUSEMOVE、WM_LBUTTONUP、WM_KEYDOWN、WM_CHAR。…

宽字符串忽略大小写比较的实现(原)

宽字符串忽略大小写比较的实现(原) 孙文涛 2008-07-24 在Mac机器平台上没有wcsicmp 或 wcscasecmp之类的函数实现对宽字符忽略大小写的比较,所以实现了好几种方法。 一个自然的思路是: (1) wcscpy 原字符串到tmp字符串; (2) tolower tmp字符串; (3) 然后调用仅存的w…

有关JAVA考试中数据库的题,javaee期末考试题库,用javaEE编写一个题库系统,要怎么做...

javaEE数据库简单问题。你插入2113数据库的时候是把5261它封装为一4102个对象插入的吗?1653如果封装为一个User对象版的权话(User对象有ID和LEVEL两个属性)ResultSet rs ps.executeQuery();User user new User();if(rs.hasNext()){user rs.next();}关于javaee 中j…

wince下获取mac地址的简单方法!

下,可以通过访问注册表获取mac地址,可是非常可惜的是有些系统的注册表不提供这个键值,另外也可以通过 DeviceIoControl这类函数获得,但是所有方法要么不全面,要么不够简单或者有些平台bsp包根本就不支持,我…

【转】虚拟键码

虚拟键码保存在WM_KEYDOWN、WM_KEYUP、WM_SYSKEYDOWN和WM_SYSKEYUP讯息的wParam参数中。此代码标识按下或释放的键。 中文名 虚拟键码 保存在 WM_KEYDOWN等 程 序 Windows程序 代码标识 按下或释放的键 目录 1 简介2 虚拟键表▪ 完整的虚拟键码表▪ 键盘的扫描码、…

循环赛日程表算法

题目:有n2^k个运动员要进行循环赛。现要设计一个满足以下要求的比赛日程表: (1)每个选手必须与其他n-1个选手各赛一次 (2)每个选手一天只能赛一次 (3)循环赛一共进行n-1天 解题思路&…

js有没有类似php的sleep函数,JavaScript-jQuery有没有类似sleep方法?

cronRun.sleep function(n) {for (var i0,jn*1000;i}}小飞写的function sleep(n) {var start new Date().getTime();while(true) if(new Date().getTime()-start > n) break;}貌似 Date new 的过多啊不过我在我本本上测的 好像不怎么管用,不知道为什么 是不是和…

GetAdaptersInfo获取MAC地址

源代码&#xff1a;#include<atlbase.h>#include<atlconv.h>#include"iphlpapi.h"#pragma comment(lib,"Iphlpapi.lib")int main(int argc,char*argv[]){PIP_ADAPTER_INFO pAdapterInfo;PIP_ADAPTER_INFO pAdapterNULL;DWORD dwRetVal0;pAdapt…