Windows 程序设计是一种完全不同于传统的 DOS 方式的程序设计方法。它是一种事件驱动方式的程序设计模式,主要是基于消息的。
每一个 Windows 应用程序开始执行后, 系统都会为该程序创建一个消息队列, 这个消息队列用来存放该程序创建的窗口的消息。
例如,当用户在窗口中画图的时候,按下鼠标左键,此时,操作系统会感知到这一事件,于是将这个事件包装成一个消息,投递到应用程序的消息队列中,等待应用程序的处理。
然后应用程序通过一个消息循环不断地从消息队列中取出消息,并进行响应。
每一个 Windows 应用程序开始执行后, 系统都会为该程序创建一个消息队列, 这个消息队列用来存放该程序创建的窗口的消息。
例如,当用户在窗口中画图的时候,按下鼠标左键,此时,操作系统会感知到这一事件,于是将这个事件包装成一个消息,投递到应用程序的消息队列中,等待应用程序的处理。
然后应用程序通过一个消息循环不断地从消息队列中取出消息,并进行响应。
在这个处理过程中,操作系统也会给应用程序“ 发送消息”。所谓“ 发送消息”,实际上是操作系统调用程序中一个专门负责处理消息的函数,这个函数称为窗口过程。
#include <windows.h>
//win32程序创建一共需要以下几个步骤
// 设计窗口
//注册窗口
//创建窗口
//显示和更新
//通过循环取消息
//处理消息(窗口过程)
//6处理窗口过程
//CALLBACK 代表__stdcall 参数的传递顺序:从右到左 以此入栈,并且在函数返回前 清空堆栈
LRESULT CALLBACK WindowProc(
HWND hwnd, //消息所属的窗口句柄
UINT uMsg, //具体消息名称 WM_XXXX 消息名
WPARAM wParam, //键盘附加消息
LPARAM lParam //鼠标附加消息
)
{
switch (uMsg)
{
case WM_CLOSE:
//所有xxxWindow为结尾的方法 ,都不会进入到消息队列中,而是直接执行
DestroyWindow(hwnd); //DestroyWindow 发送另一个消息 WM_DESTROY
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_LBUTTONDOWN: //鼠标左键按下
{
int xPos = LOWORD(lParam);
int yPos = HIWORD(lParam);
char buf[1024];
wsprintf(buf, TEXT("x = %d,y = %d"), xPos, yPos);
MessageBox(hwnd, buf, TEXT("鼠标左键按下"), MB_OK);
break;
}
case WM_KEYDOWN: //键盘
MessageBox(hwnd, TEXT("键盘按下"), TEXT("键盘按下"), MB_OK);
break;
case WM_PAINT: //绘图
{
PAINTSTRUCT ps; //绘图结构体
HDC hdc = BeginPaint(hwnd, &ps);
TextOut(hdc, 100, 100, TEXT("HELLO"), strlen("HELLO"));
EndPaint(hwnd, &ps);
}
break;
}
//返回值用默认处理方式
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
//程序入口函数
int WinMain(
_In_ HINSTANCE hInstance,//应用程序实例句柄
_In_opt_ HINSTANCE hPrevInstance, //上一个应用程序句柄,在win32下为NULL
_In_ LPSTR lpCmdLine, //参数数组
_In_ int nShowCmd) //显示命令,最大化 最小化 正常
{
//1 设计窗口
WNDCLASS wc;
wc.cbClsExtra = 0;//类的额外的内存
wc.cbWndExtra = 0;//窗口的额外内存
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);//设置背景
wc.hCursor = LoadCursor(NULL, IDC_HAND);//设置光标,如果第一个参数为null,代表使用系统提供的光标
wc.hIcon = LoadIcon(NULL,IDI_ERROR);//图标第一个参数为NULL代表使用系统提供的光标
wc.hInstance = hInstance;//应用程序实例句柄
wc.lpfnWndProc = WindowProc;//回调函数,窗口过程
wc.lpszClassName = TEXT("WIN");//指定窗口类名称
wc.lpszMenuName = NULL;//菜单名称
wc.style = 0;//显示风格,0代表默认风格
//2注册窗口
RegisterClass(&wc);
/*
lpClassName, 类名
lpWindowName,标题名
dwStyle,风格WS_OVERLAPPEDWINDOW
x,显示坐标
y,
nWidth,宽
nHeight,高
hWndParent,父窗口句柄
hMenu, 菜单句柄
hInstance,实例句柄
lpParam 附加值
*/
//3创建窗口
HWND hwnd = CreateWindow(wc.lpszClassName, TEXT("windows"),
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
//显示更新
ShowWindow(hwnd, SW_SHOWNORMAL);
UpdateWindow(hwnd);
//通过循环取消息
MSG msg;
/*
_Out_ LPMSG lpMsg,消息
_In_opt_ HWND hWnd,捕获的窗口,填null代表捕获所有窗口
_In_ UINT wMsgFilterMin,最小或最大过滤的消息,一般填0
_In_ UINT wMsgFilterMax
*/
while (GetMessage(&msg, NULL, 0, 0))
{
//翻译消息
TranslateMessage(&msg);
//分发消息
DispatchMessage(&msg);
}
return 0;
}