回 帖 发 新 帖 刷新版面

主题:[讨论]《白手起家Win32SDK应用程序》第一篇 预备知识

第一篇 预备知识
                      白云小飞

[b]1 说在前面[/b]
    由于VC6及MFC的特点,我们许多人从标准C++学习到VC6MFC应用程序的编程学习的过度会有一个很大的夸跃,从而感到非常的吃力。
    究其原因之一:MFC类库设计虽然精巧,但我们在使用MFC设计程序时,会发现MFC到处是API函数的影子。MFC并没有象Delphi的VCL类库,VB的控件库一样封装得让人几乎完全不用知道还有Win32API函数及其操作原理,所以要想利用VC6的MFC编程,我认为就一定要先学习如何直接用Win32API函数来编程。对API编程中的一些关键的概念和原理要有一定认识,这样才会有一个比较平滑的过渡。以上就是我写这个系列的初衷。

[b]2 我假设你已有的知识:[/b]
    这里我假设你已经掌握了如下的知识,如果你在如下方面知识有点不太清楚,那要去补一补罗,否则你看到相关的内容时会有麻烦的。
    下面说是我对你知识的假设:
2.1 Windows系统的文件、文件夹、路径的概念
2.2 C语言的基本知识(基本以等级考试二级C语言为准,还要有所扩充)
  2.2.1 指针的概念。
  2.2.2 函数指针概念。
  2.2.3 各种自定义类型(最重要的是struct类型)的概念。
  2.2.4 要知道函数的各种参数传递形式(值、地址、引用传递)。
  2.2.5 typedef及其应用。
  2.2.6 #include及其应用。
  2.2.7 十进制、二进制、十六进制。
  2.2.8 按位与、或、非运算的实质。
  2.2.9 宏定义概念、使用及意义。
  (每个人总是学完了C或C++语法后才会开始用VC6进行Windows编程学习的。但是你的基础又是如何呢?这是一个关键。因此我对你的C知识做了具体的假设。)
2.3 会安装VC6.0并安装到一台机上
2.4 VC6编译界面的各组成部分及基本操作(至少会用VC6写控制台程序)。
2.5 VC6调试中至少要会设置断点哦。
  (呵呵!我的要求不过份吧!)

[b]3 还必须预备的知识:[/b]
    以上知识是你看本系列的前提,不过我还要给你预备一下我们再这个阶段学习中会遇到的新东西。
[b]3.1 你将会接触到的Win32API函数库:[/b]
    以前的DOS下或Windows的控制台程序下,你要在显示器上输出文字,要用printf(),或cout的函数对象来完。但如果你要显示一个图形或图象或为你的程序设计一个图形化的操作界面等等的,那可就惨了,一切都要你自已完成。复杂得很了!(唉!谁叫DOS是字符界面的操作系统呢!)
    现在好了,在Windows下编程你可就轻松得多了。因为Windows操作系统都为我们准备好了,它提供给我们多达数千个函数(啊!我要昏倒了。这么多的函数要学。),我们通过这些函数来操作Windows系统提供给我们的各种功能。比如我要在桌面上创建并显示一个窗口。就只要调用几个相关的被称为API的函数,让Windows来帮助我们完成这些事。我们是通过这些函数与Windows系统交互的,所以这些函数被称作Win32应用程序接口函数,简称Win32API函数。
    请不用害怕哟!其实,这么多的函数我们不必都马上一一学过,只要掌握了不多的具有代表性的函数的使用方法,并知道大体API函数都提供了哪些功能就可以了。以后要用时再去查。
    Window拥有现成的各种各样的系统功能,供我们的程序调用。那么又是通过什么方式来调用这些系统功能呢?原来,Window还现成提供一个接口,好让我们的程序来使用这些系统功能,这个结口就是Win32API函数了(注:API是应用程序接口的英文缩写)。Win32API函数是我们的应用程序与Windows系统交互的唯一途径。
    我并不打算这时就介绍任何一个具体的API函数。你现在只要知道你又要接触一个函数库了——被称为Win32API的函数库,如同你以前所学的C/C++函数库。
    哈哈,这真是太好了,我们不用再象DOS一样,自已来完成程序界面的绘制了。我们现在又增加一个全新的函数库,只要调用几个相关API函数,剩下的一切由Windows来完成就可以啦!(当然还有很多其它功能。)

[b]3.2  “新”的数据类型:[/b]
    学完C、C++之后,我们就可以开始进入VC6的Windows编程学习了。但是在接下来的学习中我们会发现在Windows编程中有许多“新”的数据类型。看下面:
    BOOL、BYTE、INT、UINT、WORD、DWORD、FLOAT、CHAR、LPSTR、HINSTANCE、HWND、HMENU、HICON等等。
    你看这些大写的数据类型,你以前有见过吗?还有很多哦!我们以后的学习过程中还会见到的。(呵呵!你可要有思想准备了!)
    这真是让我们初学者迷惑呀!难道VC6中对C/C++的基本数据类型又有重大的扩充了吗?
    其实不用害怕,只是用新瓶装旧酒而已了。在VC6的windef.h头文件中已有这些定义:
typedef int                 BOOL;
typedef unsigned char       BYTE;
typedef int                 INT;
typedef unsigned int        UINT;
typedef unsigned short      WORD;
typedef unsigned long       DWORD;
typedef float               FLOAT;
在winnt.h中有
typedef long LONG;
[b]typedef char CHAR;[/b]
typedef CHAR *LPSTR, *PSTR;
    你看其中(粗体字)CHAR只不过是char 的别名而已,也就是说它们是等价的。只要你包含了相关的头文件,然后你就可以这样申明一个变量:
INT i;    //等同于int i;
CHAR a;   //等同于char a;
LPSTR pa;   //等同于char *pa;
    明白了吗?
    我想你一定会问:为什么要这样转义呢?我们直接用int 、unsighed int、char等等不就行了吗?我一句两句也说不清,你只要知道,微软这样做一定是要道理的。
    哦!还有这些HINSTANCE、HWND、HMENU、HICON我没说呢!今后你还会见到许多这样以H为开头的数据类型,下面就让我在下一节的“句柄”概念中说给你听。

[b]3.3 “句柄”概念[/b]
    由windows系统创建出来的或加载的对象(如应用程序进程、线程、窗口、菜单、图标、光标等等的对象),windows系统都会分配给它们一个唯一的标识值,作为这些对象的标志,称之为句柄。我们程序中对这些对象的操作其实就是对其句柄的操作。请记住,句柄就是这些对象的“代号”了。
    在编程序中,我们需要用相应的句柄变量来保存这些句柄值,那么用什么类型的句柄变量呢?
    就是我们前面提到过的HINSTANCE、HWND。
    像其它变量一样(如:int a;)申明句柄变量,如下:
HINSTANCE  hst;  //hst变量可以保存某个应用程序实例(即一个进程)的句柄。
HWND  hwFirst;  //hwFrist变量可以保存某个窗体句柄。
HMENU hMenu;   //hMenu变量可以保存某个菜单句柄。
HICON hIcon;     //hIcon变量可以保存某个图标句柄。
    具体的使用让我以后再慢慢与你道来啦。
    那么这些类型的实质又是什么?
    目前,它们都只是一个int类型(小语:我听说微软也许以后会改变它的类型)。不过不管怎样,你现在只要把HINSTANCE、HWND、HMENU、HICON当做是一个独立的数据类型就可以了。

[b]3.4 消息标识[/b]
    Windows系统是一个基于消息的系统。这样的机制导致我们的程序与以往DOS下的程序流程会有很大的不同。(这可是很考我们的智慧喽!)
    
    [b]从软件使用者角度看一个Win32窗口程序运行的过程:[/b]
    1) 我们运行一个应用程序,程序创建并显示一个我们想要的程序窗口。
    2) 当我们对窗口进行操作时(如单击、双击、右击、按下键盘、最大化、最小化、关闭窗口等等),程序会完成特定的操作,如:单击最大化、最小化按钮时,窗口会最大化、最小化操作;对窗口中菜单项的选取时,会完成该菜单的相应功能。

[b]    从程序员的角度看一个Win32窗口程序运行的过程:[/b]
    1) 我们运行一个应用程序,程序中我们通过Win32API函数创建并显示一个我们想要的程序窗口。(由我们的程序来调用函数实现)
    2) 当我们对窗口进行操作时(如单击、双击、右击、按下键盘、最大化、最小化、关闭窗口等等),窗口会自动产生一系列相应的消息(这是由操作系统实现的)。
    3) 具体地讲:当我们改变窗口大小时,会产生WM_SIZE消息;单击关闭按钮关闭窗口时,会产生WM_CLOSE消息;选取某一菜单项时,会产生WM_COMMAND消息;按下键盘时,会产生WM_CHAR、WM_KEYDOWN、WM_KEYUP消息;单击鼠标左键时,会产生WM_LBUTTONUP、WM_LBUTTONDOWN消息等等。啊,很多很多,我也不必全部罗列出来了。(我说过了,这些都是由操作系统实现的)
    4) windows系统会将这些消息排入我们窗口所在线程的消息队列中(你会明白线程是什么吗?)(也由Window操作系统实现),这样我们的程序才有机会获取并处理这些产生的消息。
    5) 我们的程序可以通过Window操作系统提供的API函数来获取这些消息及相关的信息。然后通过我们学过的条件判断语句来判断是什么消息及其相关的操作信息并可编写相应的程序代码,从而实现对窗口操作的不同反应。(由我们的程序来实现)
    看上述的过程描述,你可能要有点的抽象思维能力了。你现在只要有对程序流程有如上的大体认知就可以了。慢慢地我会将上述流程变成确实的程序代码噢!
    (等等,还是有个问题:这些WM_CLOSE、WM_COMMAND、WM_CHAR、WM_KEYDOWN、WM_KEYUP、WM_LBUTTONUP、WM_LBUTTONDOWN等等的以WM_开头的消息到底又是什么东西呢?)
    看VC6的头文件winuser.h中的片段:
……
#define WM_CLOSE                        0x0010
……
#define WM_LBUTTONDOWN                  0x0201
#define WM_LBUTTONUP                    0x0202
#define WM_LBUTTONDBLCLK                0x0203
#define WM_RBUTTONDOWN                  0x0204
……
#define WM_KEYDOWN                      0x0100
#define WM_KEYUP                        0x0101
#define WM_CHAR                         0x0102
……
#define WM_INITDIALOG                   0x0110
#define WM_COMMAND                      0x0111
#define WM_SYSCOMMAND                   0x0112
……
    哦!这些WM_开头的所谓的消息只不过是一系列16进制整型数值的符号常量而已。每一个不同的整型数值代表着一个窗口某一操作的标识,因此我们将这些数值或者说以WM_开头的符号常量称之为消息了。
    也就说,我们在窗口中作各种不同的操作,Windows系统会产生各种相应的数值。我们就是通过条件语句比较这些数值来判断我们在窗口中所做的操作的。

[b]3.5 资源标识[/b]
    (你看我没完没了地介绍一个个概念,觉得烦不烦?不用你说,我自已也有点烦了。唉!不过这些似乎是必要的,所以我不得不坚持下去。不过,还好,剩下的不多了。)
    那么VC6中资源是什么一种概念呢?
    我们的程序中可能要用到各种图标(*.ico文件)、各种形状的鼠标(*.cur文件)、各种图像(*.bmp/*.gif等等)、各种声音(*.wav等)、各种菜单……,这些就是我们这里所说的资源了。
    每一个要用到资源,我们都要给它分配一个编号或名称,作为这个资源的标识。之后我们的程序只是通过这个编号或名称来访问这些资源了。所以这些编号或名称我们称之为资源标识。好了,现在你也只要有了一个大体的映象就可以了,具体的形式和应用让我慢慢再与你说了。
    (各位可以提出你的疑问,白云小飞一定会尽力回复的。)
   啊!终于结束冗长的概念解说了,看到这里,请先回顾一下我们前面讲的东西。然后嘛——我们可以开工啦!。

回复列表 (共12个回复)

沙发

真是辛苦楼主了。。。支持楼主!~~

板凳

好贴啊。。顶~~你。。期待下篇

3 楼

楼主写的很好啊
希望能看到下篇
请楼主继续!!!!!!!!!!!!!!
谢谢

4 楼

总算对windows有个大概的了解了
希望楼主继续
呵呵 ~`

5 楼

dddddddddddddddddddddddddd

6 楼

楼主好人,我顶

7 楼

楼主写得真好
要是哪些VC++书也都能向楼主这样写得通俗易懂得话 那真是好书了^_^

8 楼

我还以为是新帖呢~~~~没想到是那么老远的了。。。。

9 楼

写那么多不容易啊。顶下。

10 楼

VC6编译界面的各组成部分及基本操作(至少会用VC6写控制台程序)。
请教楼主,要做到上面那点,有什么相关的好书可以推荐下!!!

我来回复

您尚未登录,请登录后再回复。点此登录或注册