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