入门指南
本教程是关于什么的
本教程的目的是向你介绍使用win32 API编写程序的基础知识(和通用的写法)。使用的语言是C,但大多数C++编译器也能成功编译,事实上,教程中的绝大多数内容都适用于任何可以连接API的语言,包括Java、Assembly和Visual Basic;我不会向你呈现任何跟这些语言相关的代码,这需要你在本教程的指导下自己去完成,有一些人在本API的基础上使用其他语言进行编程取得了相当的成功。
本教程不会教你C语言,也不会告诉你怎样去运行你特定的编译器(Borland C++,Visual C++,LCC-Win32等)然而我将花一些时间在附录中提供一些使用编译器的知识的笔记。
如果你不知道宏或类型定义是什么或者一个开关语句时如何工作的,那么现在回头,先找一本关于C语言的好书或教程好好研究学习。
注意事项
在整个教程中,有时我会确切地指出某些很重要的地方,这些地方的内容需要你好好研读。因为这些地方让很多人搞砸了,如果你没有好好研读的话,那你也很可能搞砸。
第一个地方是:
在ZIP压缩文件中提供的代码是必看的!我没有在教程中提供所有的代码,只包含与我正在讨论部分相关的代码,为了了解这段代码如何嵌入程序中,你必须看一看在ZIP文件中的源码。
第二个方面是:
完整地看完所有的内容!如果你在本教程的某个小节中产生疑问,请保持耐心阅读,你的疑问可能会在接下来的内容中被解决。如果你无法忍受带着疑问阅读,那么在向我发来邮件之前,至少浏览和搜索文档中的剩余内容。
还有一件事情需要记住的是,你关于主题A的一些疑问可能会在对B或C甚至L的讨论中被回答,所以遇到问题时多读读文档寻找答案。
OK,上面就是一些在教程正式开始之前需要说明白的东西和注意事项,现在让我们来尝试一些实际的代码。
最简单的Win32程序
如果你是一个彻彻底底的菜鸟,那么请保证至少你能编译这个最基本的窗口应用。把一下的代码复制到你的编译器中,如果没出现什么问题,你应该会看到一个最简单的窗口。
记住把代码当成C编译,而不是C++,这可能没什么关系,但因为这里所有的代码都是C的代码,我们应该有个合理正确的开始。在大多数情况下,你应该把你的代码加入到.c文件中而不是.cpp文件中,如果你感觉很蛋疼,把代码放到test.c文件中然后编译它就完了。
1 #include <windows.h>
2 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
3 LPSTR lpCmdLine, int nCmdShow)
4 {
5 MessageBox(NULL, "Goodbye, cruel world!", "Note", MB_OK);
6 return 0;
7 }
如果代码无法正常运行,先看看都有哪些报错然后把它解决,如果你不明白报错的内容,请查阅适用于你的编译器的帮助或任何其他文档。确保你新建一个Win32 GUI项目(不是控制台应用程序),不管你用的是什么编译器,关于这一块,很遗憾我无法提供更多帮助,因为不同编译器的标准是不一样的。
你可能得到了一些警告,告诉你没有使用适用于WinMain()的参数,这没关系,能编译通过就好。现在我们已经建立了一个可以通过编译的最简单的程序,让我们对这段代码做进一步的讲解。
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
WinMain()相当于DOS或UNIX程序的main(),这是你的程序开始执行的地方,参数列表如下:
HINSTANCE hInstance
程序可执行模块(在内存中的可执行文件)的句柄
官方API(处理程序的可执行模块) 一般用来加载资源和执行其他任务的基础模块(加载到你程序中的exe或dll模块) dll: dynamic link library
(PS.关于句柄:句柄(handle)是一种资源的标识; 操作系统要管理这些资源,都是通过句柄来找到对应的资源。 句柄有点类似于指针, 资源都会占用一定的内存,当我们需要使用这些资源的时候,就需要获得这些内存中的资源,通过句柄就可以访问这些内存。
按资源的类型,可以将句柄细分成 图标句柄(HICON),光标句柄(HCURSOR),窗口句柄(HWND),应用程序实例句柄(HINSTANCE))
HINSTANCE hPrevInstance
对于win32程序来说通常是NULL,对win16程序有用,对win32无用
LPSTR lpCmdLine
一个字符串的命令行参数,不包括程序名,跟打开文件的路径有关,默认为空
int nCmdShow
一个可能会传递给ShowWindow()方法的一个整数值,在接下来的内容中我们会讲到
hInstance用于加载资源和其他基于单个窗口模块的任务,这里所有的模块是加载进你的程序中的EXE或DLL,对本教程中的大部分内容来说,我们只需要关注一个模块,那就是EXE。
hPrevInstance只用在Win16程序中,作为程序实例化之前的一个预处理的句柄,在Win32中不再使用这个参数,在这里你可以忽略它。
调用的惯例
WINAPI指定了参数调用的惯例,这个惯例被定义为_stdcall的标准。如果你不知道这是什么意思,不用担心,这对我们接下来的教程没有什么影响,你只需要知道在这里需要这样指定。
Win32的数据类型
你会发现很多通用的关键字或类型在win32中有指定的定义,在win32中,我们用UINT来表示unsigned int,用LPSTR来表示char*等。。。要选择哪种表达方式取决于你,如果你感觉使用char*比用LPSTR更舒服,那就用char*吧!你只需要确保替换之前明白是哪种类型
记住一些特定的定义,它很容易被解释说明!一个LP的前缀代表Long Pointer,在Win32中Long是被废弃的所以我们无需担心指针加不加Long的问题,但如果你连指针都不懂,你可以选择:1)找本C的书或教程看看 2)继续看本教程,接着一脸懵逼吧。我建议不懂的人选择1,但大多数不懂的人选择2,接下来的东西没看懂的话别怪我没提醒你。
接着在LP后面的C表示这是个常量指针,所以LPCSTR表示一个指向常量字符串的指针,它不可改变;以此类推LPSTR表示一个非常量指针,它是可改变的。
你可能会看到一个T混杂在里面,我们现在不需要关心这个,除非你是使用Unicode编码,否则T不代表什么。
之所以想把它翻译过来是因为这个教程很好,而网上又没有找到对应的翻译,由于本人英文水平所限,只能翻译到这个程度了,有纰漏还望多多指出,附上本篇翻译的英文原版教程地址:http://www.winprog.org/tutorial/start.html