收藏 分享(赏)

Windows API编程入门教程.pdf

上传人:HR专家 文档编号:6299447 上传时间:2019-04-05 格式:PDF 页数:28 大小:224.34KB
下载 相关 举报
Windows API编程入门教程.pdf_第1页
第1页 / 共28页
Windows API编程入门教程.pdf_第2页
第2页 / 共28页
Windows API编程入门教程.pdf_第3页
第3页 / 共28页
Windows API编程入门教程.pdf_第4页
第4页 / 共28页
Windows API编程入门教程.pdf_第5页
第5页 / 共28页
点击查看更多>>
资源描述

1、Wi ndows AP I编程入门教程学习各种高级外挂制作技术,马上去百度搜索(魔鬼作坊),点击第一个站进入,快速成为做挂达人。大家好再次自我介绍一下我是beyondcode,这次心血来潮,计划着做一系列关于Wi ndowsA P I编程的教程,用于帮助一些在Wi ndows A P I编程上有疑惑的,纳闷的,迷惑的新手朋友们。先解释一些术语或名词吧S D K是S oft w a r e D e vel opme nt Ki t的简写,也就是软件开发包的意思,其中就包含了我们写程序要用到的一些头文件,库,工具,帮助文档之类的。Wi ndows AP I编程是指调用Wi ndows的接口函数来进

2、行程序的编写,例如Me s s a geBox就是一个AP I函数或者说接口函数。怎么说都可以,自己理解就行。如果你连这个都不太懂,我想也不会搜到这篇文章了吧 为什么做这个系列教程呢,请听我一一道来先,最近遇到一些事一些人,让我真的感觉在这方面的引导入门文章真的很是匮乏,加上Wi ndows S D K头文件中那些复杂,庞大,烦人的宏定义与数据类型定义,对于一个新手来说(我所说的新手不单只刚接触编程的,还特指那些在其他语言领域有比较高造诣的朋友)一个纯S D K写的hel l owor l d程序都算是一个有些困难和挑战的任务了吧。本着帮助别人,高兴自己的原则,我有了这个打算,当然对自己以前所

3、学,所经历做一次回忆,也是这次计划的一部分。声明一下,本系列教程是面向广大初次接触WI N 32 S D K程序编写的新手朋友们的,如果你是高手,一笑而过吧当然,除了一笑而过,也多谢你们提出指正文章中的错误,以免我误人子弟啊 谢谢O k废话不多说,进入正题,今天第一篇,讲什么?对于一个新人来说,第一次接触S D K编程或者说AP I编程,什么最迷惑你们的,我们讲它,我觉得Wi ndows S D K中那烦人的数据类型定义和宏定义应该算这个很角色吧。其实微软的本意也是善良的,为了减轻程序员的负担,和为了编程的方便,才花了那么多心思与精力定义出了这么一大套数据类型与宏定义,这也是我为什么在之前说它

4、烦人都是加上引号的原因,因为他不是真的烦人,熟练了,你不但不觉得它烦,反而离不开它了,呵呵,日久深情也就是这么来的。呵呵先看几个数据类型定义吧t ypedef f l oat F L O AT ;t ypedef l ong L O N G ;t ypedef s hort S HO R Tt ypedef i nt I N T ;t ypedef c har C H A R ;f l oat , l ong, s hort , i nt , c har这几个数据类型都是大家熟悉的C / C + +的数据类型吧,微软将他们重新定义了一下,很简单,就是改变名字为大写了,这样做的目的大概是微软为了

5、编码的方便吧,输入法大小写都不用切换了,多人性化呀呵呵。再看几个数据类型定义的例子t ypedef unsi gned i nt UI N T ;t ypedef unsi gned i nt UI N T 32;t ypedef s i gned i nt I N T 32;t ypedef unsi gned l ong D WO R D ;t ypedef unsi gned s hort WO R D ;这些数据类型的定义就稍微有实质性作用一些了,注意观察,他们都比较短了,不用写那么长了,而且也还比较直观,如果我要定义一个无符号整形,我就不用写unsi gned i nt a ;这么长

6、了,只需U I N T a ;多简单,多明了,所以我说其实不烦人吧。其中D WO R D算是S D K程序中可以经常看见的一个数据类型了,经常被使用,很多新手也就不明白,这是什么数据类型啊,现在看到了吧,其实就是无符号长整形unsi gned l ong,给他取了个外号而已 没什么技术含量,所以不用怕,程序中究竟是写unsi gned l ong还是D WO R D都看你自己心情,因为他们都代表同一种数据类型。下面再介绍2个很重要的,经常被使用到的,无处不在的数据类型WP AR A M, L P AR A M先看看他们定义吧t ypedef L O N G _PT R L P AR A M;t

7、 ypedef U I N T _PT R WP AR A M ;先告诉你,这2个数据类型很重要,不是危言耸听,以后你写S D K程序就知道了,看他们的定义如上,有些迷糊?别,我们一步一步分析,我们分析L P AR A M。首先定义L P AR A M为L O N G _PT R也就是用L P AR A M的地方也就可以写成L O N G _PT R,L O N G _PT R又是被定义成什么的呢?t ypedef l ong L O N G _PT R ;看到了吗?也就是l ong所以归根结底,L P AR A M就是l ong型,所有L P AR A M型的变量,你都可以直接使用l ong

8、数据类型代替。不过不推荐这样,至于为什么,各位思考思考呢 以上这些数据类型是参考MS D N中的说明,或者可以查看Wi nDe f . h这个头文件查看这些Wi ndows数据类型的定义,那么也请各位自己推推看L A R A M和WP AR A M的真面目吧各位朋友在推导的过程中可能发现L O N G _PT R的定义是这样写的#if def i ned( _WI N 64)t ypedef _int 64 L O N G _PT R ;#el s et ypedef l ong L O N G _PT R ;#endif这是什么意思呢,能看懂英文都能知道这在定义些什么,如果定义了_WI N

9、64这个宏那么就定义L O N G _PT R为_int 64,否则定义L O N G _PT R为l ong。很简单吧也就是说如果_WI N 64这个宏在前面被定义了,那么这里的L O N G _PT R就被定义为_int 64这个在64位编程下的数据类型,否则就定义为l ong型,这样说应该比较好理解了吧。在这里,各位就不必深究_int 64了,在目前的主流32位编程下很少使用它啦。理解就ok了。这样定义是微软为了程序员编写的程序能在32位与64位下都能编译而采用的伎俩。有关这些Wi ndows的数据类型,想查看他们的真面目,其实很简单,在VC 6. 0, VS 2008这些集成开发环境里

10、面,你只需要在一个数据类型上面点击右键,在弹出菜单中选择 G ot oD e f i na t i on 或者是查看定义就可以看到了,如果看到的还不是最终面目,在继续上面步骤。直到看到它的本质数据类型为止。通过这样,新手对于Wi ndows的这些复杂的数据类型定义也就有了根本的认识,不再是迷迷糊糊,在以后的编程中也就不会出现不知道用哪种数据类型或者哪些数据类型之间可以相互转换的情况了。不过还需要多多观察与练习才是啊 下面再来看一看w i ndows中定义的一些宏#def i ne VO I D void#def i ne C O N S T c onst2个最简单的宏,也是只变成大写而已,难道

11、又是为了方便程序员不切换输入法?还真的人性化呀。Wi ndows S D K中的宏定义是最庞大的,最复杂的,但也是最灵活的,为什么这样说,先不告诉你,我会在以后的系列文章中一点一点的讲解,累积,因为太多了,也比较复杂,我们就采取在需要用到的时候才讲解它,目前看来还没这个必要了解那么多,就了解上面2个很简单的好了,像其他如:WI N AP I C A L L B A C K G e t Wi ndowT e xt这些宏现在讲了不但记不住还会增加你们的负担。,我们就在以后要用到的时候再做讲解。到这里第一篇系列文章的内容也就差不多了。新手朋友们哪些地方迷惑的,提出来,我可以考虑是否加在后续的文章中进

12、行解说。本S D K系列入门教程需要你们的支持。谢谢。今天,开始第二篇文章,这章我准备介绍一下Wi ndows平台下编程中U ni c ode编码和AS C I I编码的相关问题。不知道各位新手朋友们遇到这样的问题没有呢,新建一个Wi ndows应用程序,调用Me s s a geB ox这个函数,准备让它弹出一段提示文本,可是编译器在编译的时候却报错说,不能将c onst c har *或者c onst c har 转换为c onst w c har _t *之类的提示呢,很多刚接触Wi ndows AP I编程的朋友们在这里可能就卡住了,不知如何下手解决了,其实,这就是U ni c ode

13、编码和A S C I I编码的问题了。我下面就会一一道来关于U ni c ode和A S C I I具体的编码是怎么的,我这里就不详细介绍了,也介绍不了,如果需要深入了解,网上有很多这方面的专门文章,我这里就只对Uni c ode编码和A S C I I编码在Wi ndows平台下的编程相关的内容进行介绍。我们都知道Uni c ode和A S C I I最大的区别就是Uni c ode采用2个字节来存储一个字符,不管是英文,汉字,还是其他国家的文字,都有能用2个字节来进行编码,而A S C I I采用一个字节存储一个字符,所以对于英文的编码,那是足够的了,可是对于汉字的编码,则必须采用一些特殊

14、的方法,用2个A S C I I字符来表示一个汉字。我们在写程序的过程中,势必要和字符打交道,要输入,获取,显示字符,到底是选用Uni c ode字符呢还是A S C I I字符呢,这都是各位自己的权利。但为了程序的通用性和符合目前操作系统的主流趋势,Uni c ode编码是被推荐的。由于Uni c ode字符要比A S C I I字符占用的空间大一倍,编译出来的程序在体积上和占用的内存上必定要大一些,不过这并不是什么很大的问题。所以微软目前的S D K中保留了2套A P I,一套用于采用U ni c ode编码处理字符的程序的编写,一套用于采用A S C I I编码处理字符的程序的编写。例如

15、,我们上面提到的Me s s a geB ox,它其实不是一个函数名,而是一个宏定义,我们先来看看它是怎么被定义的,再来讨论它。#if def UN I C O D E#def i ne Me s s a geB ox Me s s a geB oxW#el s e#def i ne Me s s a geB ox Me s s a geB oxA#endif看到了吗?很简单是不是,如果定义了U N I C O D E这个宏那么就定义Me s s a geBox为Me s s a geB oxW,如果没有定义U N I C O D E这个宏,那么就定义Me s s a geBox为Me s s

16、 a geB oxA,Me s s a geB ox后面的W和A就是代表宽字节( Uni c ode)和AS C I I,这样,其实存在于S D K中的函数是Me s s a geB oxW和Me s s a geB oxA这两个函数.Me s s a geB ox只是一个宏而已。所以在程序中,这3个名字你都可以使用,只不过需要注意的是,使用Me s s a geB oxA的话,那么你要注意传给它的参数,字符都必须是单字节,也就是A S C I I,在程序中就是c har,如果使用Me s s a geB oxW的话,那么,字符都必须使用U ni c ode,程序中就是w c har _t。但

17、是这样有个非常不方便的地方那就是,如果你使用W后缀系列的函数的话,那么你的程序使用的字符就是U ni c ode字符编码的,但是如果你需要用这个程序的源代码编译出字符采用A S C I I编码的程序,那么需要改动的地方就太大了。凡是涉及到字符操作的地方都需要改变。那么,有没有比较好的办法不做更改就可以用同样的代码编译出A S C I I版本的程序呢。当然有,就是我们在编程的时候尽量使用不带后缀的宏定义,如上例,就使用Me s s a geB ox,其中的参数也不明确使用c har还是w c har _t而是使用微软给我们定义的T C HA R字符数据类型,它的定义和上面Me s s a geB

18、 ox函数的定义差不多,都是根据是否定义了UN I C O D E这个宏来判断是将T C HA R定义为c har还是w c har _t,所以这样一来,这个T C H A R的数据类型就是可变的了,它根据工程的设置而定义为相应的最终字符类型,这样我们的程序就可以不做任何更改就可以轻松的编译出另外一个版本的了。是不是非常方便。前面2篇文章纯文字的介绍比较多,因为很多是概念性的,需要理解,后面的文章我准备配合一些小示例程序,使用一些简单的A P I函数,遇到的相关的概念在一并介绍的方法进行。所以,前2篇文章如果各位朋友不是很能理解,不用担心,影响不是很大,经过后面的学习,你就会慢慢的理解前面所说

19、的内容了。下面我罗列一些我们在Wi ndows平台下编程经常使用到的和字符或字符串有关的数据类型。c har和w c har _t这两个类型大家绝对不会陌生吧,一个是单字节的字符类型,一个是宽字节的字符类型(也就是U ni c ode字符)。c har c = b ;w c ha_t w c = L b ;上面我就分别定义了2个变量c和w c,相信第一个定义大家都看的懂,就是定一个字符变量c,其中保存了 b这个字符。那么第二个呢?我相信还是很多人都看的懂,要是你看不懂也没关系,现在就告诉你,也是定义一个字符变量w c,只不过这个字符变量是Uni c ode字符变量,用2个字节来保存一个字符,而

20、上面的c这个字符变量只有一个字节来保存,那么在 b前面的L又是什么意思呢,它就表示这里的 b这个字符是一个U ni c ode字符,所以第二个定义的意思就是将L b这个Uni c ode字符保存到w c这个U ni c ode字符变量中。如果我要定义一个字符数组怎么定义呢?用分别用单字节的c har和宽字节的w c har _ t来定义就应该是:c har c 10;w c har _t w c 10;如果是要带初始化的字符数组的声明,我们来看看怎么写c har c = “ beyondcode“ ;w c har _t w c = L “ beyondcode“ ;看到了吗,宽字节的操作其实

21、和单字节的字符操作一样吧,只是在前面加上L表示是宽字节的字符或者字符串。上面都是属于C / C + +中的知识,并没有涉及太多Wi ndows中的数据类型,那么各位朋友们在Wi ndows编程中看到的满到处都是的T C H A R , L P S T R , L P C S T R , L P WS T R , L P C WS T R ,L P T S T R , L P C T S T R这些数据类型又是怎么回事呢?别急,我们一步一步的来,最后我会联系到那上面去的。上面的你都知道或者是理解了的话,那我们继续,除了可以声明一个字符数组,我还可以定义一个字符指针变量来指向一个字符数组,当然这个

22、字符数组可以是U nic ode的宽字节字符数组,也可以是单字节字符数组,如下:c har c = “ hel l o beyondcode“ ; / /定义一个字符数组w c har _t w c = L “ he l l o beyondcode“ ; / /定义一个宽字节字符数组c har *p = c ; / /定义一个字符指针,指向刚才的字符数组w c har _t *wp = w c ; / /定义一个宽字节字符指针,指向刚才的宽字节字符数组这样之后,我就可以通过指针来改变刚才我们定义的2个数组,例如:p 0 = H ;w p0 = L H ;把上面2个数组的第一个字符通过指针改变

23、成大写。这里是可以通过指针来修改的,因为我没有定义指针为常量指针,也就是没有加c onst修饰符。如果我像下面这样定义的话,那么就不能通过这些指针来改变他们所指向的数据了,而是只有读取他们。c onst c har *p = c ;c onst w c har _t *wp = w c ;上面将的都是C / C + +的基础知识,有点啰嗦,为了照顾新手朋友们嘛,下面我们就来看看Wi ndows是怎么定义它的数据类型的首先,定义了C H A R , WC H A R的这2个字符数据类型,就是我们上面讨论的两个字符数据类型改了一下名字而已。现在你还不昏吧 t ypedef c har C HA R

24、 ;t ypedef w c har _t WC H A R ;然后,用刚才定义的C HA R , WC H A R这2个字符数据类型去定义了一系列其他字符指针类型。t ypedef C H A R *LP S T R ;t ypedef WC H A R *LP WS T R ;这样一定义之后,L P S T R的就是C H A R *,而C H A R又是c har,所以L P S T R的本质就是c har *,也就是我们上面熟悉的不能再熟悉的字符指针,那L P WS T R不用我推导,相信你也推导出来了吧。不过我还是推导一下,L P WS T R是WC H A R *,WC H A R

25、是w c har _t,这样L P WS T R就是w c har _t *,也就是我们上面讨论的宽字节字符指针。上面这些定义都是在Wi nNT . h这个头文件中定义的,读者朋友们有兴趣在这个头文件里面去挖掘挖掘吧,上面2个定义我只是提取了重要的部分,其实在里面他还定义了其他很多别名.看了L P S T R , L P WS T R是怎么一回事之后,我们再接再厉,看看L P C S T R , L P C WS T R这2个数据类型又是怎么一回事呢,老规矩,先看w i ndows的定义。t ypedef C O N S T C H A R *LP C S T R ;t ypedef C O

26、N S T WC H A R *LP C WS T R ;和上面的比较,名字中就多了一个大写的C,这个C的含义就代表是c onst修饰符,也就是我们上面所说的常量指针,指向的内容不能通过这个指针被改变,但可以读取。定义中的大写的C O N S T也是一个宏,我在第一篇文章中就讲过了,代换出来也就是c onst,所以请读者自己推导一下这两个数据类型的本质是什么。所以,在w i ndows平台下的编程过程中,凡是可以使用c har *的地方,你都可以使用L P S T R来代替,凡是可以使用w c har _t *的地方,你都可以使用L P WS T R来代替,至于怎么用,还是那句老话,看你个人心

27、情,只不过Wi ndows的A P I函数中关于字符串的都是使用L P这种数据类型。但是你还是可以给他传递c har *或者w c har _t* ,只要他们的本质是一样的,那怎么不可以呢 下面,我们来看一看一些示例。c har c = c ;和C H A R c = c ;是一样的w c har _t w c = L w ;和WC H A R w c = L w ;是一样的c har * p和L P S T R p是一样的w c har _t * w p和L P WS T R w p是一样的再来看看动态内存分配怎么写的呢c har * p = new c har 10; / /动态分配了十个

28、字符也可以写成C H A R * p = new C H A R 10;L P S T R p = new C H A R 10;L P S T R p = new c har 10;宽字节的再来一次w c har _t * w p = new w c har _t 10;也可以写成下面这些形式WC H A R * w p = new WC H A R 10;L P WS T R w p = new WC H A R 10;L P WS T R w p = new w c har _t 10;上面定义的这些字符指针p , w p都没有用c onst修饰符,所以可以通过他们来修改他们所指向的内容

29、。这里留给读者一个问题,怎么定义有c onst修饰符的字符指针呢,都可以用什么形式来写呢,写得越多越好哟。通过上面这些,我想你大概已经了解了L P S T R , L P C S T R , L P WS T R , L P C WS T R这四个数据类型了,他们无非就是:L P S T R - - - - - - - c har *L P C S T R - - - - - - - c onst c har *L P WS T R - - - - - - - w c har _t *L P C WS T R - - - - - - - - c onst w c har _t *下面我提一个问

30、题,如果你在你的程序中使用的字符串都是通过L P WS T R , L P C WS T R这种宽字节( Uni c ode)字符指针来进行操作的,那么在Uni c ode环境下编译,完全没有问题,如果这时你需要编译一套AS C I I版本的程序,那你会怎么办呢?你说将用L P WS T R和L P C WS T R的地方全部换成L P S T R和L P C S T R,再将字符串前面的L去掉就可以了,对,这是一种方法,但是!所有人在这里都应该知道我要说但是,这也太麻烦了吧。难道没有通用点的方法吗?有!所有人在这里也都知道我会说有,呵呵。那就是使用微软的通用数据类型,说通用数据类型有点太专业

31、了,其实也就那样,请听我慢慢分析来。我在上一篇文章中说过,凡是涉及字符串操作的AP I函数有2套,一个A系列的,一套W系列的,还有一套宏,能根据不同的工程环境定义成不同的A P I函数名。那么在字符类型上微软也使用几乎同样的技术,定义了一套宏能根据不同的工程环境定义成不同的字符数据类型。我上面就提到过的T C H A R , L P T S T R , L P C T S T R就是这样的类型。首先说说T C H A R,它是被这样定义的:#if def U N I C O D Et ypedef WC H A R T C HA R ;#el s et ypedef c har T C H A

32、 R看到了吗?它也是根据UN I C O D E这个宏被定义没有,如果被定义了,那么T C H A R代表的数据类型就是WC H A R,也就是w c har _t,如果没被定义,那么T C HA R就代表的是c har同样L P T S T R , L P C T S T R也是这样的,考虑到篇幅,我就只列出L P T S T R来给大家看看了#if def U N I C O D Et ypedef L P WS T R L P T S T R ;#el s et ypedef L P S T R L P T S T R ;这个是我简化了的定义,真实面目有些复杂,不过意思也是如此,有兴趣可

33、以自己看看,在Wi nNT . h这个头文件中。下面再次解释一下上面这个L P T S T R的定义,还是老样子,根据U N I C O D E这个宏被定义与否来决定怎么定义L P T S T R,如果是定义了U N I C O D E这个宏,表示当前工程环境是Uni c ode环境,那么L P T S T R就被定义为了L P WS T R,L P WS T R就是我们前面所讲的w c har _t *,所以此时L P T S T R代表的数据类型就是w c har _t *,如果这时的工程没有定义UN I C O D E这个宏,那么就定义L P T S T R为L P S T R,而L P

34、 S T R就是我们前面所说的c har *,所以这是的L P T S T R就代表c har *。懂了吗?各位,我都觉得自己有些啰嗦了 不好意思 然后还有一个宏需要讲一下,由于我们使用通用数据类型,那么我事先就不知道我的源代码需要在U ni c ode下编译还是在AS C I I环境下编译,所以如下这种情况T C H A R t c = a ;或者是T C HA R t c = L a ;是否合适呢?前面我已经说过了字符或字符串常量前面加L代表这是宽字节的字符或字符串,将一个宽字节字符赋值给一个T C H A R数据类型的变量t c,什么情况下是正确的呢?各位思考一下呢?如果当前工程是Uni

35、 c ode环境,那么T C H A R数据类型就是w c har _t的宽字节类型,所以t c就是宽字节字符变量,那么上面第二个赋值语句就是正确的,而第一个就是错误的。如果反过来,当前的工程是A S C I I环境,那么T C HA R代表的是c har这种数据类型,那么第一个赋值语句就是正确的,而第二个就是错误的了。分析了这么多,我就是要讲一个宏_T( ) ,只要将字符或者字符串常量放在_T( )这个宏里面,那么这个宏就能根据当前的环境决定是否在字符或字符串前面加L,如下面:T C H A R t c = _T( A ) ;如果这么写,在不需要改写源代码的情况下,就可以编译出U ni c

36、ode和AS C I I两套程序而只需要改变工程的环境而已。这篇文章的内容大概就这么多了,关于后续文章的内容安排,我会适当采纳各位朋友的留言来进行安排。在这里我介绍的是Wi ndows平台下的和字符串操作有关的数据类型,至于MF C中的C S t r i n g类,c + +标准库中的s t r i ng,我就不做讲解了。大家好,还是我beyondcode,再次见面,前面介绍的那么多理论知识,你们都懂了吗?就算还没有彻底领悟,但至少还是有那么一点意识了吧,知道有那么一回事了吧。这一篇我打算通过一个小小小例子,来回忆一下我们以前介绍的相关知识,如Wi ndows的数据类型,特别是和字符和字符串操

37、作相关的数据类型,还有就是Uni c ode和A S C I I在A P I函数上的具体体现。另外,S D K编程交流群已经建立,很多朋友踊跃参加,系列文章和群的发展离不开你们。群号: 81543028。O k,我们正式开始,我打算从一个简单的S D K程序开始,别怕,就几行代码而已 / * B Ybeyondcode*/#inc l ude i nt WI N A P I Wi nMa i n( H I N S T AN C E hI ns t a nce , H I N S T AN C E hPr e vI ns t a nce , L P S T R l pCm dLi ne ,i n

38、t nShowC m d)Me s s a geB oxA( N UL L , “ H e l l o beyondcode“ , “ T i t l e “ , MB _OK ) ;r e t ur n 0;复制代码程序你已经看到了,这恐怕就是一个最简单的带窗口的S D K程序了吧,如果你能写出代码行数比这个还少,又带窗口显示字符串的S D K程序,欢迎交流,呵呵,开个玩笑。程序倒是简单,可是我还是要问一问,这个程序,你通过观察我在字符串的处理,还是在A P I函数的调用,还是主函数的参数写法,你能看出什么问题呢? . . . . . . . . . . . . . . . . . . .

39、. . . . . . . . . . . . . . . . . .对,就是我全部明确指出是单字节版本的,Wi nMa i n的第三个参数是L P T S T R类型,调用的Me s s a geB ox是带A后缀的单字节版本,字符串常量“ H e l l o beyondcode“和“ T i t l e “都没有使用L前缀。那么第二个问题来了,如果我告诉你我现在的工程环境是使用U ni c ode字符集(工程使用的字符集可以在【项目】- 工程属性弹出的属性页中的【配置属性】中的【常规】左边的【字符集】中设置),那么我上面的程序能正常通过编译吗?当然能,因为我已经试过了,不信你也可以试试,

40、可是为什么呢?这是因为我指定的参数和函数需要的参数都是单字节版本的,也就是说他们相互匹配。要是我这里将Me s s a geB ox A改成Me s s a geB ox W呢?就会出错吧,因为Me s s a geB oxW的第二个,和第三个参数是需要L P C WS T R,通过上一篇学习,我们知道也就是c onst w c har _t *,而我给出的两个字符串常量却没有用L前缀.也就是说他们是单字节的,传给宽字节版本的Me s s a geB oxW当然就类型不匹配了啊,所以就通不过编译了吧。通过上面的学习,我再出一个问题,如果我此时的工程环境是使用Uni c ode字符集,而这里我不

41、用Me s s a geBoxA,也不用Me s s a geB oxW,而是用Me s s a geB ox,其他的都不变,结果会怎么样呢?不能理解的可以加群讨论哟 好了,单字节版本的程序,我们已经看到了,我们再来看看我们怎么才能把它改成宽字节版本的呢?其实需要改的地方不多,也就5处Wi nMa i n改成w Wi nMa i n,Wi nMa i n的第三个参数改成L P WS T R,Me s s a geB oxA改成W,两个字符串常量加L就ok了。/ * B Y beyondcode*/#inc l ude i nt WI N AP I w Wi nMa i n( HI N S T

42、AN C E hI ns t a nc e , H I N S T AN C E hPr e vIns t a nce , L P WS T Rl pCm dLi ne, i nt nShowC m d )Me s s a geB oxW( N UL L , L “ H e l l o B e yondcode“ , L “ T i t l e “ , MB _OK ) ;r e t ur n 0;复制代码如果我想写一个代码比较通用的版本,也就是可以不用改动代码,就能编译出U ni c ode和AS C I I的两个版本的程序,我应该怎么写呢?其实就是我上一篇重点讨论的,凡是涉及到字符串的都不

43、明确指出是Uni c ode还是AS C I I版本的,调用的A P I函数凡是涉及到字符串参数的都不明确指出调用是A后缀的还是W后缀的函数,而是调用没有后缀的函数,如上面的Me s s a geB ox,这样就能写出代码比较通用的程序了。那么我们现在来把我们上面的程序改一改,让它通用/ * B Y beyondcode*/#inc l ude #inc l ude i nt WI N A P I _t Wi nMa i n( H I N S T AN C E hI ns t a nc e , HI N S T A N C E hPr e vI nst a nce , L P T S T Rl

44、 pCm dLi ne, i nt nShowC m d )Me s s a geB ox( N U L L , _T( “ He l l o B e yondcode“ ) , _T( “ T i t l e “ ) , MB _OK ) ;r e t ur n 0;复制代码Wi nMa i n被改成了_t Wi nMa i n , _t Wi nMa i n也是一个宏,根据U N I C O D E这个宏被设置与否而被定义成Wi nMa i n或w Wi nMa i n,和L P T S T R是一样的,这里还需要注意的是要包含t c har . h这个头文件,因为_t Wi nMa i

45、n和_T( )这些宏是被定义在里面的。经过上面我们就写出了第一个S D K的可以编译出两个版本的比较通用的程序代码了。是不是有点成就感了呢。下面,我们继续在上面的程序中加一些功能,让它计算1到10的和,然后把结果显示给我们看,这个地方,很多S D K初学者就不知所措了,因为一个和是一个整数,怎么显示这个整数给我们呢,通过对话框? Me s s a geB ox,可是Me s s a geB ox显示的是字符串。而我们这里又不是控制台程序可以使用pr i nt f之类的格式化输出函数来输出数字,也不能使用c out之类的C + +对象来输出,那我们怎么办呢?通过对话框来显示结果是不错的选择,但是

46、对话框需要的是字符串,那我们就把我们的结果格式化到一个字符串里面,然后传送给Me s s a geB o x让它显示出来。那么就需要用到格式化字符串函数,下面我们就介绍w s pri nt f这个函数#if defU N I C O D E#def i ne w s pr i nt f w s pr i nt f W#el s e#def i ne w s pr i nt f w s pr i nt f A#endif / / ! UN I C O D E复制代码说它是函数,是不确切的。因为它实际是一个宏,根据环境被定义成不同的函数名w s pr i nt f W或者w s pr i nt f

47、 A,而我们为了程序的通用性,直接使用w s pri nt f,传递的参数凡是涉及到字符串常量的我们都是用_T( )宏,字符串指针的我们都使用L P T S T R和L P C T S T R。下面我就先贴出添加了功能的程序代码,然后在做分析,你可以先不看分析,自己看一看代码,不懂的猜一猜它的意思。/ * B Y beyondcode*/#inc l ude #inc l ude i nt WI N A P I _t Wi nMa i n( H I N S T AN C E hI ns t a nc e , HI N S T A N C E hPr e vI nst a nce , L P T

48、 S T Rl pCm dLi ne, i nt nShowC m d )i nt s um = 0;f or ( i nt i = 1; i #inc l ude L R E S U L T C A L L B A C K Wi nMe s s a geP r oc ( HW N D hwnd, U I N T m s g, WP AR A M w P a r a m ,L P AR A M l P a r a m ) ;i nt WI N A P I _t Wi nMa i n( H I N S T AN C E hI ns t a nc e , HI N S T A N C E hPr

49、e vI nst a nce , L P T S T Rl pCm dLi ne, i nt nShowC m d )r e t ur n 0;复制代码第一个函数声明,返回类型为L R E S U L T,本质经查看是l ong,然后函数调用约定C A L L B A C K和WI N AP I是一样的,都是_st dc a l l,说明函数调用相关的约定,不必深究。至于为什么用C AL L B A C K是为了意思显而易见,表示是回调函数,什么是回调函数?也就是系统负责调用的,不必你亲自调用的函数,所以你在你的程序里是看不到调用Wi nMe s s a geP r oc这个函数的代码的,你只负责编写它的代码,至于调用,系统会在有消息的时候自动调用它。Wi nMe s s a geP r oc的参数类型和个数是规定好了的,不然系统怎么知道怎么掉用,所以不能更改。再解释一下这四个参数吧,第一个参数是一个窗口的句柄,也就是告诉你,是哪个窗口的消息,第二个参数是消息的类型

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 实用文档 > 简明教程

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报