1、Windows是事件驱动方式的程序设计
Windows程序设计是一种事件驱动方式的程序设计,主要是基于消息的。当用户进行某些操作时,操作系统会感知到这一事件,并将该事件包装成一个消息,投递到应用程序的队列中,然后应用程序从消息队列中取出消息并响应。
2、消息队列
操作系统为每个应用程序都建立一个消息队列,消息队列是一个先进先出的缓冲区,其中每个元素都是一个消息,操作系统将由事件产生的消息先后放进消息队列中,应用程序总是取走当前队列第一个消息,并对该消息进行处理即消息响应。消息结构:
typedef struct tagMSG {
HWND hwnd; //接收消息的窗口句柄
UINT message; //消息标识
WPARAM wParam; //消息附加信息,取决具体消息
LPARAM lParam; //消息附加信息,取决具体消息
DWORD time; //消息投递时间
POINT pt; //消息投递时,光标在屏幕上的坐标
} MSG, *PMSG, *LPMSG;
3、WinMain函数
WinMain是Windows程序的入口函数,与DOS程序的入口函数main的作用相同,当WinMain函数结束或返回时,Windows应用程序结束。
int WINAPI WinMain(
HINSTANCE hInstance, //当前实例句柄
HINSTANCE hPrevInstance, //先前实例句柄,32位系统中此值为NULL
LPSTR lpCmdLine, //命令行指针
int nCmdShow //窗口显示状态
);
4、创建一个窗口
4.1 设计窗口类
Windows提供的窗口结构体WNDCLASS wndcls。用于设计窗口。
typedef struct _WNDCLASS {
UINT style;// 窗口类型
WNDPROC lpfnWndProc;//窗口处理函数
int cbClsExtra;//窗口扩展
int cbWndExtra;//窗口实例扩展
HINSTANCE hInstance;//实例句柄
HICON hIcon;//窗口的最小化图标
HCURSOR hCursor;//窗口鼠标光标
HBRUSH hbrBackground;//窗口背景色
LPCTSTR lpszMenuName;//窗口菜单
LPCTSTR lpszClassName;// 窗口类名
} WNDCLASS, *LPWNDCLASS;
4.2 注册窗口类
RegisterClass(CONST WNDCLASS *lpWndClass)。向系统注册该窗口。
4.3 创建窗口
设计好窗口并将其完成注册之后,就可以调用CreateWindows()函数产生这种类型的窗口了。
HWND CreateWindow(
LPCTSTR lpClassName,.//窗口类名称
LPCTSTR lpWindowName,//窗口的名称
DWORD dwStyle,//创建窗口的样式
int x,//窗口左上角坐标x
int y,//窗口左上角坐标y
int nWidth,//窗口的宽度
int nHeight,//窗口高度
HWND hWndParent,//窗口的父窗口句柄
HMENU hMenu,//窗口菜单句柄
HANDLE hlnstance,//窗口所属应用程序实例的句柄
LPVOID lpParam//消息的附加参数
);
4.4 显示及更新窗口
BOOL ShowWindows(HWND hWnd, int nCmdShow);
窗口创建后,用于显示窗口。
hWnd:窗口句柄
nCmdShow:窗口显示状态,常用的有以下几种。
- SW_HIDE:隐藏窗口并激活其他窗口。
- SW_SHOW:在窗口原来的位置以原来的尺寸激活和显示窗口。
- SW_SHOWMAXIMIZED:激活窗口并将其最大化显示。
- SW_SHOWMIXIMIZED:激活窗口并将其最小化显示。
- SW_SHOWNORMAL:激活并显示窗口。
BOOL UpdateWindows(WHND hWnd);
直接发送一个WM_PAINT消息给窗口过程函数进行处理。
4.5 消息循环
BOOL GetMessage(
LPMSG lpMsg,//指向消息结构体
WWND hWnd,//窗口句柄,NULL表示接收属于调用线程的所有窗口的窗口消息。
UINT wMsgFilterMin,//获取的消息的最小值。
UINT wMsgFilterMax);//获取的消息的最大值。
编写消息循环:
MSG msg;
While(GetMessage(&msg, NULL, 0, 0))//从消息队列中取出一条消息
{
TranslateMessage(&msg);//进行消息转换
DispatchMessage(&msg);//分派消息到窗口的回调函数处理
}
4.6 调用约定
__stdcall 与 __cdecl是两种不同的函数调用约定,定义了函数参数入栈的顺序,由调用函数还是被调用函数将参数弹出栈,以及产生函数修饰名的方法。
Win32的API函数都遵循__stdcall调用约定。在VC++开发环境中,默认的编译选项是 __cdecl,对于那些需要__stdcall调用约定的函数,在声明时必须显示地加上__stdcall。
5、变量的命名约定
前缀 | 含义 |
---|---|
a | 数组 |
b | 布尔值(int) |
by | 无符号字符(字节) |
c | 字符 |
rgb | 保存RGB颜色值的长整型 |
cx,cy | 短整型 |
dw | 无符号长整型 |
fn | 函数 |
h | 句柄 |
i | 整数 |
m_ | 类的数据成员 |
n | 短整型或整型 |
np | 近指针 |
p | 指针 |
l | 长整型 |
lp | 长指针 |
s | 字符串 |
sz | 以零结尾的字符串 |
tm | 正文大小 |
w | 无符号整形 |
x,y | 无符号整形(表示 x 或 y 的坐标) |