Windows API编程入门教程
学习各种高级外挂制作技术,马上去百度搜索(魔鬼作坊),点击第一个站进入,快速成为做挂达人。
大家好再次自我介绍一下我是beyondcode,这次心血来潮,计划着做一系列关于Windows API编程的教程,用于帮助一些在Windows API编程上有疑惑的,纳闷的,迷惑的新手朋友们。
先解释一些术语或名词吧SDK是Software Development Kit的简写,也就是软件开发包的意思,其中就包含了我们写程序要用到的一些头文件,库,工具,帮助文档之类的。
Windows API编程是指调用Windows的接口函数来进行程序的编写,例如MessageBox就是一个API函数或者说接口函数。怎么说都可以,自己理解就行。如果你连这个都不太懂,我想也不会搜到这篇文章了吧~·
为什么做这个系列教程呢,请听我一一道来先,最近遇到一些事一些人,让我真的感觉在这方面的引导入门文章真的很是匮乏,加上Windows SDK头文件中那些复杂,庞大,'烦人'的宏定义与数据类型定义,对于一个新手来说(我所说的新手不单只刚接触编程的,还特指那些在其他语言领域有比较高造诣的朋友)一个纯SDK写的helloworld程序都算是一个有些困难和挑战的任务了吧。本着帮助别人,高兴自己的原则,我有了这个打算,当然对自己以前所学,所经历做一次回忆,也是这次计划的一部分。
声明一下,本系列教程是面向广大初次接触WIN32SDK程序编写的新手朋友们的,如果你是高手,一笑而过吧~当然,除了一笑而过,也多谢你们提出指正文章中的错误,以免我误人子弟啊~~谢谢
Ok废话不多说,进入正题,今天第一篇,讲什么?对于一个新人来说,第一次接触SDK 编程或者说API编程,什么最迷惑你们的,我们讲它,我觉得Windows SDK中那'烦人'的数据类型定义和宏定义应该算这个很角吧。。
其实微软的本意也是善良的,为了减轻程序员的负担,和为了编程的方便,才花了那么多心思与精力定义出了这么一大套数据类型与宏定义,这也是我为什么在之前说它烦人都是加上引号的原因,因为他不是真的烦人,熟练了,你不但不觉得它烦,反而离不开它了,呵呵,日久深情也就是这么来的。vs编程软件
呵呵先看几个数据类型定义吧
typedef float FLOAT;
typedef long LONG;
typedef short SHORT
typedef int INT;
typedef char CHAR;
float,long,short,int,char这几个数据类型都是大家熟悉的C/C++的数据类型吧,微软将他们重新定义了一下,很简单,就是改变名字为大写了,这样做的目的大概是微软为了编码的方便吧,输入法大小写都不用切换了,多人性化呀呵呵。。
再看几个数据类型定义的例子
typedef unsigned int UINT;
typedef unsigned int UINT32;
typedef signed int INT32;
typedef unsigned long DWORD;
typedef unsigned short WORD;
这些数据类型的定义就稍微有实质性作用一些了,注意观察,他们都比较短了,不用写那么长了,而且也还比较直观,如果我要定义一个无符号整形,我就不用写unsigned int a;
这么长了,只需UINT a;多简单,多明了,所以我说其实不烦人吧。
其中DWORD算是SDK程序中可以经常看见的一个数据类型了,经常被使用,很多新手也就不明白,这是什么数据类型啊,现在看到了吧,其实就是无符号长整形unsigned long,给他取了个外号而已··没什么技术含量,所以不用怕,程序中究竟是写unsigned long还是DWORD都看你自己心情,因为他们都代表同一种数据类型。
下面再介绍2个很重要的,经常被使用到的,无处不在的数据类型WPARAM,LPARAM
先看看他们定义吧
typedef LONG_PTR LPARAM;
typedef UINT_PTR WPARAM;
先告诉你,这2个数据类型很重要,不是危言耸听,以后你写SDK程序就知道了,看他们的定义如上,有些迷糊?别,我们一步一步分析,我们分析LPARAM。首先定义LPARAM为LONG_PTR也就是用LPARAM的地方也就可以写成LONG_PTR,LONG_PTR又是被定义成什么的呢?
typedef long LONG_PTR;
看到了吗?也就是long所以归根结底,LPARAM就是long型,所有LPARAM型的变量,你都可以直接使用long数据类型代替。不过不推荐这样,至于为什么,各位思考思考呢~~
以上这些数据类型是参考MSDN中的说明,或者可以查看WinDef.h这个头文件查看这些Windows数据类型的定义,那么也请各位自己推推看LARAM和WPARAM的真面目吧~
各位朋友在推导的过程中可能发现LONG_PTR的定义是这样写的
#if defined(_WIN64)
typedef__int64LONG_PTR;
#else
typedef long LONG_PTR;
#endif
这是什么意思呢,能看懂英文都能知道这在定义些什么,如果定义了_WIN64这个宏那么就定义LONG_PTR为__int64,否则定义LONG_PTR为long。很简单吧也就是说如果_WIN64这个宏在前面被
定义了,那么这里的LONG_PTR就被定义为__int64这个在64位编程下的数据类型,否则就定义为long型,这样说应该比较好理解了吧。在这里,各位就不必深究__int64了,在目前的主流32位编程下很少使用它啦。理解就ok了。这样定义是微软为了程序员编写的程序能在32位与64位下都能编译而采用的伎俩。
有关这些Windows的数据类型,想查看他们的真面目,其实很简单,在VC6.0,VS2008这些集成开发环境里面,你只需要在一个数据类型上面点击右键,在弹出菜单中选择‘Goto Defination’或者是‘查看定义’就可以看到了,如果看到的还不是最终面目,在继续上面步骤。直到看到它的本质数据类型为止。通过这样,新手对于Windows的这些复杂的数据类型定义也就有了根本的认识,不再是迷迷糊糊,在以后的编程中也就不会出现不知道用哪种数据类型或者哪些数据类型之间可以相互转换的情况了。不过还需要多多观察与练习才是啊
~~
下面再来看一看windows中定义的一些宏
#define VOID void
#define CONST const
2个最简单的宏,也是只变成大写而已,难道又是为了方便程序员不切换输入法?还真的人性化呀。
Windows SDK中的宏定义是最庞大的,最复杂的,但也是最灵活的,为什么这样说,先不告诉你,我会在以后的系列文章中一点一点的讲解,累积,因为太多了,也比较复杂,我们就采取在需要用到的时候才讲解它,目前看来还没这个必要了解那么多,就了解上面2个很简单的好了,像其他如:WINAPI CALLBACK GetWindowText这些宏现在讲了不但记不住还会增加你们的负担。,我们就在以后要用到的时候再做讲解。
到这里第一篇系列文章的内容也就差不多了。新手朋友们哪些地方迷惑的,提出来,我可以考虑是否加在后续的文章中进行解说。本SDK系列入门教程需要你们的支持。谢谢。
今天,开始第二篇文章,这章我准备介绍一下Windows平台下编程中Unicode编码和ASCII 编码的相关问题。
不知道各位新手朋友们遇到这样的问题没有呢,新建一个Windows应用程序,调用MessageBox这个函数,准备让它弹出一段提示文本,可是编译器在编译的时候却报错说,不能将const char*或者const char[]转换为const wchar_t*之类的提示呢,很多刚接触Windows API编程的朋友们在这里可能就卡住了,不知如何下手解决了,其实,这就是Unicode编码和ASCII编码的问题了。我下面就会一一道来
关于Unicode和ASCII具体的编码是怎么的,我这里就不详细介绍了,也介绍不了,如果需要深入了解,网上有很多这方面的专门文章,我这里就只对Unicode编码和ASCII编码在Windows平台下的编程相关的内容进行介绍。
我们都知道Unicode和ASCII最大的区别就是Unicode采用2个字节来存储一个字符,不管是英文,汉字,还是其他国家的文字,都有能用2个字节来进行编码,而ASCII采用一个字节存储一个字符,所以对于英文的编码,那是足够的了,可是对于汉字的编码,则必须采用一些特殊的方法,用2个ASCII字符来表示一个汉字。
我们在写程序的过程中,势必要和字符打交道,要输入,获取,显示字符,到底是选用Unicode 字符呢还是ASCII字符呢,这都是各位自己的权利。但为了程序的通用性和符合目前操作系统的主流趋势,Unicode编码是被推荐的。由于Unicode字符要比ASCII字符占用的空间大一倍,编译出来的程序在体积上和占用的内存上必定要大一些,不过这并不是什么很大的问题。所以微软目前的SDK中保留了2套API,一套用于采用Unicode编码处理字符的程序的编写,一套用于采用ASCII编码处理字符的程序的编写。例如,我们上面提到的MessageBox,它其实不是一个函数名,而是一个宏定义,我们先来看看它是怎么被定义的,再来讨论它。
#ifdef UNICODE
#define MessageBox MessageBoxW
#else
#define MessageBox MessageBoxA
#endif
看到了吗?很简单是不是,如果定义了UNICODE这个宏那么就定义MessageBox为MessageBoxW,如果没有定义UNICODE这个宏,那么就定义MessageBox为MessageBoxA,MessageBox后面的W和A就是代表宽字节(Unicode)和ASCII,这样,其实存在于SDK中的函数是MessageBoxW和MessageBoxA这两个函数.
MessageBox只是一个宏而已。所以在程序中,这3个名字你都可以使用,只不过需要注意的是,使用MessageBoxA的话,那么你要注意传给它的参数,字符都必须是单字节,也就是ASCII,在程序中就是char,如果使用MessageBoxW的话,那么,字符都必须使用Unicode,程序中就是wchar_t。但是这样有个非常不方便的地方那就是,如果你使用W后缀系列的函数的话,那么你的程序使用的字符就是Unicode字符编码的,但是如果你需要用这个程序的源代码编译出字符采用ASCII编码的程序,那么需要改动的地方就太大了。凡是涉及到字符操作的地方都需要改变。那么,有没有比较好的办法不做更改就可以用同样的代码编译出ASCII版本的程序呢。
当然有,就是我们在编程的时候尽量使用不带后缀的宏定义,如上例,就使用MessageBox,其中的参数也不明确使用char还是wchar_t而是使用微软给我们定义的TCHAR字符数据类型,它的定义和上面MessageBox函数的定义差不多,都是根据是否定义了UNICODE这个宏来判断是将TCHAR定义为char还是wchar_t,所以这样一来,这个TCHAR的数据类型就是可变的了,它根据工程的设置而定义为相应的最终字符类型,这样我们的程序就可以不做任何更改就可以轻松的编译出另外一个版本的了。是不是非常方便。
前面2篇文章纯文字的介绍比较多,因为很多是概念性的,需要理解,后面的文章我准备配合一些小示例程序,使用一些简单的API函数,遇到的相关的概念在一并介绍的方法进行。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。