本文较为详细的分析了一个Win32程序的组成、结构、实现方法及运行原理,对于进行Windows程序设计有很好的借鉴参考价值。分享给大家供大家参考之用。具体分析如下:

一、Windows程序与普通C或C++程序的不同

学过C或C++等语言的人都知道,我们写的程序都一个入口,main函数,但是在Win32程序里,我们的入口函数又是什么呢?它是怎么样运行的,跟我们用C或C++写的控制台程序又有什么不同呢?

我们先说Win32程序跟我们控制台的程序的一个很重要的不同点,就是Win32程序是一个消息响应程序,例如点击了一个按钮,就会产生一个消息onButoon,然后会这个消息会进入我们程序所维护的一个消息队列,程序运行过程中不断地取出队列中的消息,并作出相应的处理。直到取出的是结束程序的消息。

二、了解MSG的结构和组成

首先,既然Windows的程序是基于消息触发的,那么Windows是如何定义一个消息的呢?下面是在MSDN上说明文档上的定义:

typedef struct tagMSG { // msg

HWND hwnd;

UINT message;

WPARAM wParam;

LPARAM lParam;

DWORD time;

POINT pt;

} MSG;

下面我们来分析一下这个结构体:

HWND hwnd:hwnd是一个窗口的句柄,用来唯一标识一个窗口资源;至于什么是一个句柄,它有点类似对C或C++中的指针,句柄是资源的标识,根据资源的类型,又可将句柄细分成图标句柄(HICON),光标句柄(HCURSOR),窗口句柄(HWND),应用程序实例句柄(HINSTANCE)等等各种类型的句柄。操作系统给每一个窗口指定的一个唯一的标识号即窗口句柄。

UINT message:message是一个UINT(即C或C++中的unsign int)类型的变量,它用来标识一个具体的消息,如按键盘的消息。message用一个整数来表示,但是一个整数通常不好记忆,所以在VC++中就用微软给我们定义的一些宏来表示,如WM_KEYDOWN。

WPARAM wParam:整型参数,用来指示message的附加信息。

LPARAM lParam:跟wParam一样,是一个整型参数,用来指示message的附加信息。与wParam一样,多用来区分同一个消息的不同情况。

DWORD time:DWORD其实是C或C++中的unsigned long类型,time标识了一个消息产生时的时间。

POINT pt:POINT是一个结构体,表示现实世界里的一个点,里面有两个LONG类型的成员x和y,用来表示产生这个消息产时光标或鼠标的坐标。

由此可知一个MSG的变量所包含的信息是相当多和详细的。

三、了解WinMain函数

然后,像C或C++控制台程序的入口是main函数一样,Win32程序的入口也是main函数,不过它叫WinMain函数,它的定义如下:

int WINAPI WinMain(

HINSTANCE hInstance, // handle to current instance

HINSTANCE hPrevInstance, // handle to previous instance

LPSTR lpCmdLine, // command line

int nCmdShow // show state

);

下面我们来分析一下这个函数:

HINSTANCE hInstance:hInstance是一个指向当前应用程序实例的一个句柄。实例就是一个运行中的程序。

HINSTANCE hPrevInstance:hPrevInstance是一个指向之前应用程序实例的一个句柄。

LPSTR lpCmdLine:lpCmdLine是一个指向字符串的指针,表示一个命令行参数,什么是命令行参数呢?就是我们C或C++中的main函数中的参数char *argv[]。

int nCmdShow:用来表示一个窗口的显示,表示它是要最大化显示,最小化显示,正常大小显示还是隐藏显示。

WinMain与main函数一样,是由操作系统进行调用的,所以这些参数也是由操作系统来赋值。

WINAPI是什么呢?其实它是一个宏,它代表的是__stdcall,表示的是参数传递的顺序,但是在VC中,参数的默认传递顺序为__cdecl。

四、创建一个窗口

那我们应该怎样设计一个窗口呢?要设计一个窗口,实际上是要设计一个窗口类,用来标记一个窗口的各种属性,在VC中已经有这样类(更正确地说是一个结构体)WNDCLASS。它的定义如下,后面的注释说明了它们的用处:

typedef struct _WNDCLASS {

UINT style; //用于指定类的类型,即窗口类的类型

WNDPROC lpfnWndProc; //指定一个窗口回调函数,是一个函数的指针

int cbClsExtra; //类的附加内存,通常数情况下为0

int cbWndExtra; //窗口附加内存,通常情况下为0

HANDLE hInstance; //当前实例句柄,用WinMain中的形参给它赋值

HICON hIcon; //图标句柄,用于指示应用程序所用的是什么图标,用函数LoadIcon进行赋值

HCURSOR hCursor; //光标句柄,用于指示鼠标进入应用程序窗口区域时的显示,用函数LoadCursor进行赋值

HBRUSH hbrBackground; //用于指示程序的背景颜色,用函数(HBRUSH)GetStockObject赋值。

LPCTSTR lpszMenuName; //指定菜单的名字

LPCTSTR lpszClassName; //指定类的名字

} WNDCLASS;

注:类型窗口的过程函数,也称回调函数,原理是,当应用程序收到给某一窗口的消息时,就应该调用某一函数来处理这条消息。这一调用过程不用应用程序自己来实施,而由操作系统来完成,但是,回调函数本身的代码必须由应用程序自己完成。对于一条消息,操作系统调用的是接受消息的窗口所属的类型中的lpfnWndProc成员指定的函数。每一种不同类型的窗口都有自己专用的回调函数,该函数就是通过lpfnWndProc成员指定的。

在VC里或写Windows程序时,我们会经常用到一类变量,这个变量里的每一位(bit)都对应某一种特性。当该变量的某位为1时,表示有该位对应的那种特性,当该位为0时,即没有该位所对应的特性。当变量中的某几位同时为1时,就表示同时具有几种特性的组合。一个变量中的哪一位代表哪种意义,不容易记忆,所以我们经常根据特征的英文拼写的大写去定义一些宏,该宏所对应的数值中仅有与该特征相对应的那一位(bit)为1,其余的bit都为0。其实这些宏是一个UINT类型的一个数值,所以我们可以用|运算符来把多个特性结合在一起,用&~来去掉一个特性。

所以要创建一个窗口,首先我们在WinMain函数中创建一个WNDCLASS变量,并对WNDCLASS变量中的成员赋值之后,就可以注册这个窗口,可调用函数RegisterClass(&wndcls)来注册一个窗口,它需要一个WNDCLASS类型变量的地址。然后定义一个窗口的句柄HWND hwnd;然后调用函数CreateWindow,把返回值赋给hwnd。最后调用函数ShowWindow(hwnd,SW_SHOWNORMAL);UpdateWindow(hwnd);来显示窗口。

五、建立消息循环

现在窗口是创建出来了,但是之前我们就说过,Windows程序是基于消息触发和处理的程序,那么我们如何让程序让系统知道我们的操作呢?例如点击了一下鼠标,按了一下键盘,那就要建立我们的消息循环了,建立方法如下。

首先,我们定义一个MSG类型的变量,如MSG msg;

然后执行如下的循环:

while(GetMessage(&msg,NULL,0,0)) {

TranslateMessage(&msg);

DispatchMessage(&msg);

}

解释:

GetMessage函数从我们的消息队列中取出消息,第一个参数为MSG变量,它出会自动帮我们填充msg中的成员变量;第二个参数是一个窗口句柄,NULL表示接受属于调用线程的所有消息;第三个参数指定消息的最小值;第四个参数指定消息的最大值。这两个参数若设为0,则获取所有在消息队列中的消息。它的返回值为BOOL型,只有在取出的消息为WM_QUIT时,返回FALSE;即除非关闭程序,否则将是一个死循环,一直对我们的操作进行处理。

TranslateMessage函数,用于翻译、处理和转换消息并把新消息投放到消息队列中,并且此过程不会影响原来的消息队列。

DispatechMessage函数,用于把收到的消息传到窗口回调函数进行分析和处理。即将消息传递给操作系统,让操作系统调用窗口回调函数,来对信息进行处理。

六、回调函数(窗口过程函数)

首先来看看它的定义:

LRESULT CALLBACK WinSunProc(

HWND hwnd, // 窗口句柄

UINT uMsg, // 消息标志符

WPARAM wParam, // MSG第一附加参数

LPARAM lParam // MSG第二附加参数

);

CALLBACK是一个宏表示前面所说的_stdcall,LRESULT是一个long型参数。

调用时,把窗口类WNDCLASS的参数传递过来,里面有一个switch语句,用来判断要处理的消息类型,并作出相应的处理,注意switch语句里一定有一个default:return DefWindowProc(hwnd,uMsg,wParam,lParam);表示没有在case中出现的消息将按默认处理方式来处理,不然窗口运行会出错,连窗口都不能创建和显示出来。

通过上述分析还原了一个Win32应用程序的完整执行流程,相信本文所述对大家的Windows应用程序设计有一定的借鉴价值。

win32c语言编程实例,实例分析一个简单的Win32程序相关推荐

  1. Win32 程序开发:一个简单的Win32程序

    1)什么是Win32 Win32是指Microsoft Windows操作系统的32位环境,与Win64 都为Windows常见环境.如今的Win32操作系统可以一边听音乐,一边编程,一边打印文档.W ...

  2. 从头学C语言——(1)编写一个简单的C程序

    编写一个简单的C程序 编译器安装完成之后,我们就可以用它来编写代码了. 这里用Dev C++作为示例,我的是5.11的版本(后续版本是其他人开发的分支版本). 1.双击打开软件, 2.点击左上角工具栏 ...

  3. c语言二级编程实例,二级C语言编程_-实例.doc

    二级C语言编程_-实例.doc 编程实例 ? 1.???????? 1.2.3.4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?1.程序分析:可填在百位.十位.个位的数字都是1.2.3. ...

  4. c语言调用子程序的例子,几个C语言编程应用实例.DOC

    PAGE PAGE 290 第13章 几个C语言编程应用实例 13.1 TMS320LF2407与图形液晶显示模块接口及应用 源程序代码: 所需的复位和中断向量定义文件"vectors.as ...

  5. c语言12之编程设计一个简单的计算器程序,要求根据用户从键盘输入的表达式:操作数1 运算符op 操作数2 计算表达式的值,指定的运算符为加减乘除。

    题目: 设计一个简单的计算器程序,要求根据用户从键盘输入的表达式: 操作数1 运算符op 操作数2 计算表达式的值,指定的运算符为加减乘除. 源代码: #include<stdio.h> ...

  6. c语言编程效率的分析,C语言编程效率的分析.pdf

    信息管理 年第 期 青海科技 2006 5 C语言编程效率的分析 卫 良 青海师范大学数学与信息科学系,青海 西宁 ) ( 810008 摘 要:文章结合实例探讨了 语言编程中的执行效率问题,并提出了 ...

  7. 通信软件基础B-重庆邮电大学-Java-编程实现一个简单的聊天程序-多线程编程实现

    实验任务六 编程实现一个简单的聊天程序-多线程编程实现 1. 系统设计要求 编程实现一个简单的聊天程序,实现两台计算机间的信息交互,使用多线程编程实现:可同时连接多个客户端,服务器收到客户端发送的消息 ...

  8. 通过汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的

    实验目的: 通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的 实验过程: 通过vi程序进行编程: int g(int x) { return x + 3; } int f(int x) ...

  9. 分析一个简单的汇编代码

    分析一个简单的汇编代码 部分常见的寄存器 寄存器 16位 32位 64位 累加寄存器 AX EAX RAX 基址寄存器 BX EBX RBX 计数寄存器 CX ECX RCX 数据寄存器 DX EDX ...

最新文章

  1. JavaScript写XML
  2. linux 预加载 动态链接库rootkit 简介
  3. Learn Python The Hard Way(20)
  4. 随机数的产生可用于的场景验证码 密码
  5. ifix如何设画面大小_ifix5.1环境下的ifix服务器、客户端配置
  6. Linux上创建一个用户,并给该用户指定目录的权限,修改时区
  7. 作者:鄂世嘉,男,同济大学博士生,CCF学生会员。
  8. 力扣18. 四数之和(JavaScript)
  9. Linux GPIO键盘驱动开发记录_OMAPL138
  10. 爬取嘉兴市人才网即时招聘信息并写入文本TXT完整案例
  11. Eclipse SVN 忽略文件或文件夹
  12. matlab中怎么使用数组,matlab中数组的基本使用
  13. 亮温模型--相关概念
  14. 如何建立一套完整的DCS系统?
  15. 深入理解Java虚拟机(四)Eden、Survivor、老年代、GC日志
  16. iOS开发学无止境 - 6个iOS图片文本设计的小技巧
  17. Unable to ping server at localhost:1099
  18. 粒子背景php,html5+canvas圆形粒子移动背景动画特效
  19. 听起来你的咕噜功能虽然您当前的赚取加盟文凭在线
  20. 中文自然语言处理测评数据集、基准模型、语料库、排行榜整理分享

热门文章

  1. 流量卡之家: 运营商共享5G网络基础设施 建设成本大幅降低
  2. 2022怎么开个人淘宝网店?星志远电商
  3. C++类和对象:友元内部类
  4. 新寻仙霸下boss击杀方法及掉落物品刷新时间图文介绍
  5. c语言数组形式,c定义数组_C语言定义数组的几种形式
  6. 清除ajax缓存的方法
  7. html css画小猪佩琪,【前端切图】用css画一个卡通形象-小猪佩奇
  8. 记一次亚索模拟器入门——小哥大一作品
  9. 学会origin这20个操作,作图快速又完美
  10. 用python画雨滴_Python使用Matplotlib实现雨点图动画效果的方法