Win32 基本程序设计原理总结

本文深入探讨了Windows程序设计的基础,包括Windows系统的基本原理、所需函数库和头文件、程序运行本质、窗口类注册、消息处理机制、线程与进程的概念。重点介绍了窗口函数作为窗口生命中枢的角色,以及消息队列和消息循环的重要性。通过对对话框窗口、资源描述文件(.RC)以及C Runtime多线程版本的理解,揭示了Windows程序的生命周期和内部工作原理。

目录

1. Windows系统 基本原理

2. 需要什么函数库(.LIB)

2.1 C Runtimes:

2.2 Windows API

3. 需要什么头文件(.H)

4. Windows 程序运行的本质

5. 窗口类的注册与窗口的诞生

6.消息

6.1 消息分类:

7. 消息队列

8. 消息循环

9. 窗口的生命中枢:窗口函数(窗口过程)

10. 对话框窗口的运作

11. 资源描述文件(.RC)

12. Windows 程序的生与死

13. 闲置时间的处理:OnIdle

14. 什么是 C Runtime 函数库的多线程版本

15. 进程与线程(Process and Thread)

15.1 核心对象

15.2 一个进程的诞生与死亡

15.3 产生子进程

15.4 一个线程的诞生与死亡

15.5 以 _beginthreadex 取代 CreateThread

15.6 线程优先权(Priority)

16. 问答


参考:侯杰的书,感谢JJ深入浅出的介绍! 
第1章 Win32 基本程序观念 | 深入浅出MFC (gitbooks.io)

1. Windows系统 基本原理

    Windows 操作系统本身,主要是 Windows 三大模块 GDI32.DLL 和 USER32.DLL 和 KERNEL32.DLL提供的。    
   下图是Windows SDK程序(Win32)的开发流程图:

我们基于Windows编程,肯定不是从零开始搭建,是基于Windows函数库,以及微软封装的其他功能函数库开发的。

2. 需要什么函数库(.LIB)

编译器驱动程序读取源程序文件.c,并把它翻译成一个可执行目标文件exe。这个翻译过程分为四个阶段:预处理(Preprocessing)、编译(Compilation)、汇编(Assembly)、链接(Linking)。执行这四个阶段的程序(预处理器、编译器、汇编器、和链接器)一起构成了编译系统。
参考: 程序详细编译过程(预处理、编译、汇编、链接) - 知乎 (zhihu.com)

在链接时期,链接器仍需先为调用者(应用程序本身)准备一些适当的资讯,才能够在运行时顺利「跳」到 DLL 执行。
Windows支持静态链接库lib(链接时期),和动态链接库dll(运行时期)。

文件名为 .dll 者是动态链接函数库(DLL,Dynamic Link Library),事实上.exe、.dll、.fon、.mod、.drv、.ocx 都是所谓的动态链接函数库。

Windows 程序调用的函数可分为 C Runtimes 以及 Windows API 两大部分。
c运行库、c标准库、windows API的区别和联系 - 任智康 - 博客园 (cnblogs.com)

2.1 C Runtimes:

  • LIBC.LIB - 这是C Runtime 函数库的静态链接版本。

  • MSVCRT.LIB - 这是C Runtime 函数库动态链接版本(MSVCRT40.DLL)的 import 函数库。如果链接此一函数库,你的程序执行时必须有 MSVCRT40.DLL 在场。

更详细的介绍: C/C++中CRT表示什么意思?转载-CSDN博客

2.2 Windows API

  • Windows 的三大模块所对应的 import 函数库分别为 GDI32.LIB 和 USER32.LIB 和 KERNEL32.LIB,动态库对应的是 GDI32.DLL 和 USER32.DLL 和 KERNEL32.DLL。

3. 需要什么头文件(.H)

所有Windows程序都必须含入WINDOWS.H,不过,WINDOWS.H 只照顾三大模块所提供的API 函数。如果你用到其它 system DLLs,就得含入对应的头文件。

4. Windows 程序运行的本质

Windows 程序运行的本质是以消息为基础,以事件为驱动。Windows程序的事件驱动特性,包括消息的产生、获得、分派、判断、处理

Windows 程序的进行系依靠外部发生的事件来驱动。换句话说,程序不断等待(利用一个 while 循环),等待任何可能的输入,然后做判断,然后再做适当的处理。上述的「输入」是由操作系统捕捉到之后,以消息形式(一种数据结构)进入程序之中。操作系统如何捕捉外围设备(如键盘和鼠标)所发生的事件呢?噢,USER 模块掌管各个外围的驱动程序,它们各有侦测循环。

如果把应用程序获得的各种「输入」分类,可以分为由硬件装置所产生的消息(如鼠标移动或键盘被按下),放在系统队列(system queue)中,以及由 Windows 系统或其它Windows 程序传送过来的消息,放在程序队列(application queue)中。以应用程序的眼光来看,消息就是消息,来自哪里或放在哪里其实并没有太大区别,反正程序调用GetMessage API就取得一个消息,程序的生命靠它来推动。所有的GUI系统,包括UNIX的X Window 以及OS/2的Presentation Manager,都像这样,是以消息为基础的事件驱动系统。 

Windows 程序的本体与操作系统之间的关系图:

WinMain 则是Windows 程序的进入点:

nt CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine,     int nCmdShow)
{
...
} // 在 Win32 中 CALLBACK 被定义为 __stdcall,是一种函数调用习惯,关系到参数挤压到堆栈的次序,以及处理堆栈的责任归属。其它的函数调用习惯还有_pascal和_cdecl


当Windows的「外壳」(shell,例如 Windows 3.1的程序管理员或Windows 95的文件总管)侦测到使用者意欲执行一个 Windows 程序,于是调用加载器把该程序加载,然后调用C startup code,后者再调用WinMain,开始执进程序。

5. 窗口类的注册与窗口的诞生

一开始,Windows 程序必须做些初始化工作,为的是产生应用程序的工作舞台:窗口。这没有什么困难,因为API函数CreateWindow完全包办了整个巨大的工程。但是窗口产生之前,其属性必须先设定好。所谓属性包括窗口的「外貌」和「行为」,一个窗口的边框、颜色、标题、位置等等就是其外貌,而窗口接收消息后的反应就是其行为(具体地说就是指窗口函数本身)。程序必须在产生窗口之前先利用 API 函数 RegisterClass设定属性(我们称此动作为注册窗口类)。RegisterClass 需要一个大型数据结构WNDCLASS 做为参数,CreateWindow 则另需要11个参数。

RegisterClass与CreateWindow关系图

可以清楚看出一个窗口类牵扯的范围多么广泛,其中wc.lpfnWndProc所指定的函数就是窗口的行为中枢,也就是所谓的窗口函数。注意,CreateWindow只产生窗口,并不显示窗口,所以稍后我们必须再利用 ShowWindow 将之显示在屏幕上。又,我们希望先传送个WM_PAINT给窗口,以驱动窗口的绘图动作,所以调用UpdateWindow

6.消息

消息,就是指Windows发出的一个通知,告诉应用程序某个事情发生了。例如,单击鼠标、改变窗口尺寸、按下键盘上的一个键都会使Windows发送一个消息给应用程序,它被定义为:

typedef struct {
HWND hwnd; //窗口句柄, 发生在哪个窗口上
UINT message; //消息标识号 ( WM_MOUSEMOVE, WM_LBUTTONDOWN, ... )
WPARAM wParam; //消息参数1
LPARAM lParam; //消息参数2
DWORD time;
POINT pt;
} MSG, *PMSG;

其中的成员变量 message 是 WM_SIZE 、 WM_COMMAND 、 WM_QUIT 等等消息标识。hwnd 中是这个消息所在的窗口句柄。time和pt由系统生成这个消息时填充。
一个消息结构体包含了该事件 所有完备信息,当应用程序收到该消息时,就可以做出相应处理了。

6.1 消息分类:

<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值