Windows API编程入门教程.pdf
《Windows API编程入门教程.pdf》由会员分享,可在线阅读,更多相关《Windows API编程入门教程.pdf(28页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、WindowsAPI 编程入门教程学习各种高级外挂制作技术,马上去百度搜索(魔鬼作坊),点击第一个站进入,快速成为做挂达人。大家好 再次自我介绍一下 我是 beyondcode,这次心血来潮,计划着做一系列关于 WindowsAPI 编程的教程,用于帮助一些在 WindowsAPI 编程上有疑惑的,纳闷的,迷惑的新手朋友们。先解释一些术语或名词吧SDK 是 Software Development Kit 的简写,也就是软件开发包的意思,其中就包含了我们写程序要用到的一些头文件,库,工具,帮助文档之类的。WindowsAPI 编程是指调用 Windows的接口函数来进行程序的编写,例如 Mes
2、sageBox 就是一个 API 函数或者说接口函数。怎么说都可以,自己理解就行。如果你连这个都不太懂,我想也不会搜到这篇文章了吧为什么做这个系列教程呢,请听我一一道来先,最近遇到一些事一些人,让我真的感觉在这方面的引导入门文章真的很是匮乏,加上 Windows SDK 头文件中那些复杂,庞大,烦人的宏定义与数据类型定义,对于一个新手来说(我所说的新手不单只刚接触编程的,还特指那些在其他语言领域有比较高造诣的朋友)一个纯 SDK 写的 helloworld 程序都算是一个有些困难和挑战的任务了吧。本着帮助别人,高兴自己的原则,我有了这个打算,当然对自己以前所学,所经历做一次回忆,也是这次计划的
3、一部分。声明一下,本系列教程是面向广大初次接触 WIN32 SDK 程序编写的新手朋友们的,如果你是高手,一笑而过吧当然,除了一笑而过,也多谢你们提出指正文章中的错误,以免我误人子弟啊谢谢Ok 废话不多说,进入正题,今天第一篇,讲什么?对于一个新人来说,第一次接触 SDK编程或者说 API 编程,什么最迷惑你们的,我们讲它,我觉得 Windows SDK 中那烦人的数据类型定义和宏定义应该算这个很角色吧。其实微软的本意也是善良的,为了减轻程序员的负担,和为了编程的方便,才花了那么多心思与精力定义出了这么一大套数据类型与宏定义,这也是我为什么在之前说它烦人都是加上引号的原因,因为他不是真的烦人,
4、熟练了,你不但不觉得它烦,反而离不开它了,呵呵,日久深情也就是这么来的。呵呵 先看几个数据类型定义吧typedef float FLOAT;typedef long LONG;typedef short SHORTtypedefintINT;typedef char CHAR;float,long,short,int,char 这几个数据类型都是大家熟悉的 C/C+的数据类型吧,微软将他们重新定义了一下,很简单,就是改变名字为大写了,这样做的目的大概是微软为了编码的方便吧,输入法大小写都不用切换了,多人性化呀 呵呵。再看几个数据类型定义的例子typedef unsignedintUINT;ty
5、pedef unsignedintUINT32;typedef signedintINT32;typedef unsigned long DWORD;typedef unsigned short WORD;这些数据类型的定义就稍微有实质性作用一些了,注意观察,他们都比较短了,不用写那么长了,而且也还比较直观,如果我要定义一个无符号整形,我就不用写 unsignedinta;这么长了,只需 UINT a;多简单,多明了,所以我说其实不烦人吧。其中 DWORD 算是 SDK 程序中可以经常看见的一个数据类型了,经常被使用,很多新手也就不明白,这是什么数据类型啊,现在看到了吧,其实就是无符号长整形
6、unsigned long,给他取了个外号而已没什么技术含量,所以不用怕,程序中究竟是写 unsigned long 还是DWORD 都看你自己心情,因为他们都代表同一种数据类型。下面再介绍 2 个很重要的,经常被使用到的,无处不在的数据类型 WPARAM,LPARAM先看看他们定义吧typedef LONG_PTR LPARAM;typedef UINT_PTR WPARAM;先告诉你,这 2 个数据类型很重要,不是危言耸听,以后你写 SDK 程序就知道了,看他们的定义如上,有些迷糊?别,我们一步一步分析,我们分析 LPARAM。首先定义 LPARAM 为LONG_PTR 也就是用 LPAR
7、AM 的地方也就可以写成 LONG_PTR,LONG_PTR 又是被定义成什么的呢?typedef long LONG_PTR;看到了吗?也就是 long 所以归根结底,LPARAM 就是 long 型,所有 LPARAM 型的变量,你都可以直接使用 long 数据类型代替。不过不推荐这样,至于为什么,各位思考思考呢以上这些数据类型是参考 MSDN 中的说明,或者可以查看 WinDef.h 这个头文件查看这些Windows 数据类型的定义,那么也请各位自己推推看 LARAM 和 WPARAM 的真面目吧各位朋友在推导的过程中可能发现 LONG_PTR 的定义是这样写的#if defined(_
8、WIN64)typedef _int64 LONG_PTR;#elsetypedef long LONG_PTR;#endif这是什么意思呢,能看懂英文都能知道这在定义些什么,如果定义了 _WIN64 这个宏 那么就定义 LONG_PTR 为 _int64,否则定义 LONG_PTR 为 long。很简单吧 也就是说如果_WIN64 这个宏在前面被定义了,那么这里的 LONG_PTR 就被定义为_int64 这个在 64 位编程下的数据类型,否则就定义为 long 型,这样说应该比较好理解了吧。在这里,各位就不必深究_int64 了,在目前的主流 32 位编程下很少使用它啦。理解就 ok 了。
9、这样定义是微软为了程序员编写的程序能在 32 位与 64 位下都能编译而采用的伎俩。有关这些 Windows 的数据类型,想查看他们的真面目,其实很简单,在 VC6.0,VS2008 这些集成开发环境里面,你只需要在一个数据类型上面点击右键,在弹出菜单中选择GotoDefination或者是 查看定义就可以看到了,如果看到的还不是最终面目,在继续上面步骤。直到看到它的本质数据类型为止。通过这样,新手对于 Windows 的这些复杂的数据类型定义也就有了根本的认识,不再是迷迷糊糊,在以后的编程中也就不会出现不知道用哪种数据类型或者哪些数据类型之间可以相互转换的情况了。不过还需要多多观察与练习才是
10、啊下面再来看一看 windows 中定义的一些宏#defineVOID void#define CONSTconst2 个最简单的宏,也是只变成大写而已,难道又是为了方便程序员不切换输入法?还真的人性化呀。Windows SDK 中的宏定义是最庞大的,最复杂的,但也是最灵活的,为什么这样说,先不告诉你,我会在以后的系列文章中一点一点的讲解,累积,因为太多了,也比较复杂,我们就采取在需要用到的时候才讲解它,目前看来还没这个必要了解那么多,就了解上面 2 个很简单的好了,像其他如:WINAPICALLBACKGetWindowText 这些宏现在讲了不但记不住还会增加你们的负担。,我们就在以后要用
11、到的时候再做讲解。到这里第一篇系列文章的内容也就差不多了。新手朋友们哪些地方迷惑的,提出来,我可以考虑是否加在后续的文章中进行解说。本 SDK 系列入门教程需要你们的支持。谢谢。今天,开始第二篇文章,这章我准备介绍一下 Windows 平台下编程中 Unicode编码和 ASCII编码的相关问题。不知道各位新手朋友们遇到这样的问题没有呢,新建一个 Windows 应用程序,调用MessageBox 这个函数,准备让它弹出一段提示文本,可是编译器在编译的时候却报错说,不能将 const char*或者 const char 转换为 const wchar_t*之类的提示呢,很多刚接触Window
12、s API 编程的朋友们在这里可能就卡住了,不知如何下手解决了,其实,这就是Unicode编码和 ASCII 编码的问题了。我下面就会一一道来关于 Unicode和 ASCII 具体的编码是怎么的,我这里就不详细介绍了,也介绍不了,如果需要深入了解,网上有很多这方面的专门文章,我这里就只对 Unicode 编码和 ASCII 编码在Windows 平台下的编程相关的内容进行介绍。我们都知道 Unicode 和 ASCII 最大的区别就是 Unicode 采用 2 个字节来存储一个字符,不管是英文,汉字,还是其他国家的文字,都有能用 2 个字节来进行编码,而 ASCII 采用一个字节存储一个字符
13、,所以对于英文的编码,那是足够的了,可是对于汉字的编码,则必须采用一些特殊的方法,用 2 个 ASCII 字符来表示一个汉字。我们在写程序的过程中,势必要和字符打交道,要输入,获取,显示字符,到底是选用 Unicode字符呢还是 ASCII 字符呢,这都是各位自己的权利。但为了程序的通用性和符合目前操作系统的主流趋势,Unicode编码是被推荐的。由于 Unicode字符要比 ASCII 字符占用的空间大一倍,编译出来的程序在体积上和占用的内存上必定要大一些,不过这并不是什么很大的问题。所以微软目前的 SDK 中保留了 2 套 API,一套用于采用 Unicode编码处理字符的程序的编写,一套
14、用于采用 ASCII 编码处理字符的程序的编写。例如,我们上面提到的MessageBox,它其实不是一个函数名,而是一个宏定义,我们先来看看它是怎么被定义的,再来讨论它。#ifdef UNICODE#define MessageBoxMessageBoxW#else#define MessageBoxMessageBoxA#endif看到了吗?很简单是不是,如果定义了 UNICODE 这个宏 那么就定义 MessageBox 为MessageBoxW,如 果 没 有 定 义 UNICODE 这 个 宏,那 么 就 定 义 MessageBox 为MessageBoxA,MessageBox 后
15、面的 W 和A就是代表宽字节(Unicode)和 ASCII,这样,其实存在于 SDK 中的函数是 MessageBoxW 和 MessageBoxA 这两个函数.MessageBox 只是一个宏而已。所以在程序中,这 3 个名字你都可以使用,只不过需要注意的是,使用 MessageBoxA 的话,那么你要注意传给它的参数,字符都必须是单字节,也就是ASCII,在程序中就是char,如果使用MessageBoxW的话,那么,字符都必须使用Unicode,程序中就是 wchar_t。但是这样有个非常不方便的地方那就是,如果你使用 W 后缀系列的函数的话,那么你的程序使用的字符就是 Unicode
16、字符编码的,但是如果你需要用这个程序的源代码编译出字符采用 ASCII 编码的程序,那么需要改动的地方就太大了。凡是涉及到字符操作的地方都需要改变。那么,有没有比较好的办法不做更改就可以用同样的代码编译出 ASCII 版本的程序呢。当然有,就是我们在编程的时候尽量使用不带后缀的宏定义,如上例,就使用 MessageBox,其中的参数也不明确使用 char 还是 wchar_t 而是使用微软给我们定义的 TCHAR 字符数据类型,它的定义和上面 MessageBox 函数的定义差不多,都是根据是否定义了 UNICODE 这个宏来判断是将 TCHAR 定义为 char 还是 wchar_t,所以这
17、样一来,这个 TCHAR 的数据类型就是可变的了,它根据工程的设置而定义为相应的最终字符类型,这样我们的程序就可以不做任何更改就可以轻松的编译出另外一个版本的了。是不是非常方便。前面 2 篇文章纯文字的介绍比较多,因为很多是概念性的,需要理解,后面的文章我准备配合一些小示例程序,使用一些简单的 API 函数,遇到的相关的概念在一并介绍的方法进行。所以,前 2 篇文章如果各位朋友不是很能理解,不用担心,影响不是很大,经过后面的学习,你就会慢慢的理解前面所说的内容了。下面我罗列一些我们在Windows平台下编程经常使用到的和字符或字符串有关的数据类型。char和wchar_t这两个类型大家绝对不会
18、陌生吧,一个是单字节的字符类型,一个是宽字节的字符类型(也就是 Unicode字符)。charc=b;wcha_twc=Lb;上面我就分别定义了 2 个变量 c和 wc,相信第一个定义大家都看的懂,就是定一个字符变量 c,其中保存了b这个字符。那么第二个呢?我相信还是很多人都看的懂,要是你看不懂也没关系,现在就告诉你,也是定义一个字符变量 wc,只不过这个字符变量是 Unicode字符变量,用 2 个字节来保存一个字符,而上面的 c这个字符变量只有一个字节来保存,那么在b前面的 L 又是什么意思呢,它就表示这里的b这个字符是一个 Unicode字符,所以第二个定义的意思就是将 Lb这个 Uni
19、code字符保存到 wc这个 Unicode字符变量中。如果我要定义一个字符数组怎么定义呢?用分别用单字节的 char和宽字节的 wchar_t来定义就应该是:charc10;wchar_t wc10;如果是要带初始化的字符数组的声明,我们来看看怎么写char c=beyondcode;wchar_t wc=Lbeyondcode;看到了吗,宽字节的操作其实和单字节的字符操作一样吧,只是在前面加上 L 表示是宽字节的字符或者字符串。上面都是属于 C/C+中的知识,并没有涉及太多 Windows中的数据类型,那么各位朋友们在 Windows 编程中看到的满到处都是的 TCHAR,LPSTR,LP
20、CSTR,LPWSTR,LPCWSTR,LPTSTR,LPCTSTR 这些数据类型又是怎么回事呢?别急,我们一步一步的来,最后我会联系到那上面去的。上面的你都知道或者是理解了的话,那我们继续,除了可以声明一个字符数组,我还可以定义一个字符指针变量来指向一个字符数组,当然这个字符数组可以是 Unicode 的宽字节字符数组,也可以是单字节字符数组,如下:charc=hello beyondcode;/定义一个字符数组wchar_twc=Lhello beyondcode;/定义一个宽字节字符数组char*p=c;/定义一个字符指针,指向刚才的字符数组wchar_t*wp=wc;/定义一个宽字节字
21、符指针,指向刚才的宽字节字符数组这样之后,我就可以通过指针来改变刚才我们定义的 2 个数组,例如:p0=H;wp0=LH;把上面 2 个数组的第一个字符通过指针改变成大写。这里是可以通过指针来修改的,因为我没有定义指针为常量指针,也就是没有加 const 修饰符。如果我像下面这样定义的话,那么就不能通过这些指针来改变他们所指向的数据了,而是只有读取他们。constchar*p=c;constwchar_t*wp=wc;上面将的都是 C/C+的基础知识,有点啰嗦,为了照顾新手朋友们嘛,下面我们就来看看Windows 是怎么定义它的数据类型的首先,定义了 CHAR,WCHAR 的这 2 个字符数据
22、类型,就是我们上面讨论的两个字符数据类型改了一下名字而已。现在你还不昏吧typedef charCHAR;typedef wchar_tWCHAR;然后,用刚才定义的 CHAR,WCHAR 这 2 个字符数据类型去定义了一系列其他字符指针类型。typedefCHAR*LPSTR;typedefWCHAR*LPWSTR;这样一定义之后,LPSTR 的就是 CHAR*,而 CHAR 又是 char,所以 LPSTR的本质就是char*,也就是我们上面熟悉的不能再熟悉的字符指针,那 LPWSTR 不用我推导,相信你也推导出来了吧。不过我还是推导一下,LPWSTR 是 WCHAR*,WCHAR 是 w
23、char_t,这样 LPWSTR 就是 wchar_t*,也就是我们上面讨论的宽字节字符指针。上面这些定义都是在 WinNT.h 这个头文件中定义的,读者朋友们有兴趣在这个头文件里面去挖掘挖掘吧,上面 2 个定义我只是提取了重要的部分,其实在里面他还定义了其他很多别名.看了 LPSTR,LPWSTR 是怎么一回事之后,我们再接再厉,看看 LPCSTR,LPCWSTR 这 2个数据类型又是怎么一回事呢,老规矩,先看 windows的定义。typedefCONSTCHAR*LPCSTR;typedefCONSTWCHAR*LPCWSTR;和上面的比较,名字中就多了一个大写的 C,这个 C 的含义就
24、代表是 const 修饰符,也就是我们上面所说的常量指针,指向的内容不能通过这个指针被改变,但可以读取。定义中的大写的 CONST 也是一个宏,我在第一篇文章中就讲过了,代换出来也就是 const,所以请读者自己推导一下这两个数据类型的本质是什么。所以,在 windows 平台下的编程过程中,凡是可以使用 char*的地方,你都可以使用 LPSTR来代替,凡是可以使用 wchar_t*的地方,你都可以使用 LPWSTR来代替,至于怎么用,还是那句老话,看你个人心情,只不过 Windows 的 API 函数中关于字符串的都是使用 LP 这种数据类型。但是你还是可以给他传递 char*或者 wch
25、ar_t*,只要他们的本质是一样的,那怎么不可以呢下面,我们来看一看一些示例。charc=c;和 CHAR c=c;是一样的wchar_t wc=Lw;和 WCHAR wc=Lw;是一样的char*p和 LPSTRp 是一样的wchar_t*wp和 LPWSTRwp是一样的再来看看动态内存分配怎么写的呢char*p=new char10;/动态分配了十个字符也可以写成CHAR*p=new CHAR10;LPSTRp=new CHAR10;LPSTRp=new char10;宽字节的再来一次wchar_t*wp=new wchar_t10;也可以写成下面这些形式WCHAR*wp=new WCHA
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Windows API编程入门教程 API 编程 入门教程
限制150内