一、windows程序消息处理机制
二、创建win32应用程序过程
- 编写WinMain函数
- 设计窗口类
- 注册窗口类
- 创建窗口类
- 显示和更新窗口类
- 编写消息循环
- 编写窗口过程函数
三、实现
#include <windows.h>
#include <stdio.h>
//声明回调函数
LRESULT CALLBACK WinSunProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter,消息的附加参数
LPARAM lParam // second message parameter
);
//入口点函数,该函数是由操作系统调用,并由操作系统赋值
int WINAPI WinMain(
HINSTANCE hInstance, // handle to current instance
HINSTANCE hPrevInstance, // handle to previous instance
LPSTR lpCmdLine, // command line para
int nCmdShow // show window state 比如放大缩小等等
)
{
//设计窗口类
WNDCLASS wndcls;
wndcls.cbClsExtra=0;//通常用不上,设置为0
wndcls.cbWndExtra=0;//通常这个参数用不上,设置为0
wndcls.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);//HBRUSH句柄,利用GetStockObject函数,(HBRUSH)是强制类型转换,参数WHITE_BRUSH白色画刷,即白色背景,参数可参看MSDN
wndcls.hCursor=LoadCursor(NULL,IDC_UPARROW);//光标句柄,类似图标句柄
wndcls.hIcon=LoadIcon(NULL,IDI_APPLICATION );//图表句柄,通过LoadIcon函数赋值,要用微软标准图表,第一个参数需要设置为空,第二个参数图标的选择
wndcls.hInstance=hInstance;//用形参赋值
wndcls.lpfnWndProc=WinSunProc;//参数lpfnWndProc指向窗口过程回调函数
wndcls.lpszClassName="sunxin2006";//创建窗口的类名
wndcls.lpszMenuName=NULL;//设置菜单名字
wndcls.style=CS_HREDRAW | CS_VREDRAW;//水平或垂直位置发生变化的时候要求窗口重画
//注册窗口
RegisterClass(&wndcls);//参数要求是窗口类结构体指针
//创建窗口
HWND hwnd;//先创建一个句柄,通过句柄去保存我们创建窗口的一个标识(句柄相当于指针)
hwnd=CreateWindow("sunxin2006","http://www.sunxin.org",WS_OVERLAPPEDWINDOW /*& ~WS_MAXIMIZEBOX*/,
0,0,600,400,NULL,NULL,hInstance,NULL);//CreateWindow创建窗口,参数2可查看定义
//显示窗口
ShowWindow(hwnd,SW_SHOWNORMAL);
//更新窗口
UpdateWindow(hwnd);
//消息循环
MSG msg;//用MSG结构体定义消息变量
while(GetMessage(&msg,NULL,0,0))//GetMessage从消息队列中取出消息
{
TranslateMessage(&msg);//比如可将按键消息转换为w_char消息
DispatchMessage(&msg);//将收到的消息传到窗口过程函数中,即将消息给操作系统,操作系统再调用窗口过程函数
}
return msg.wParam;
}
//窗口过程函数,即回调函数 可在MSDN中查看WindowProc,与消息结构体前四个参数一致
//CALLBACK调用约定
LRESULT CALLBACK WinSunProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
//判断具体有哪些消息
switch(uMsg)
{
//该消息是按键
case WM_CHAR:
char szChar[20];
sprintf(szChar,"char code is %d",wParam);
MessageBox(hwnd,szChar,"char",0);//0其实就是代表MB_OK
break;
//鼠标左键消息
case WM_LBUTTONDOWN:
MessageBox(hwnd,"mouse clicked","message",0);
HDC hdc;
hdc=GetDC(hwnd);
TextOut(hdc,0,50,"程序员之家",strlen("程序员之家"));//利用得到的DC句柄在指定位置处输出一行文字
ReleaseDC(hwnd,hdc);//释放DC,否则容易造成内存泄漏
break;
//窗口重绘消息
case WM_PAINT:
HDC hDC;
PAINTSTRUCT ps;
hDC=BeginPaint(hwnd,&ps);
TextOut(hDC,0,0,"http://www.sunxin.org",strlen("http://www.sunxin.org"));
EndPaint(hwnd,&ps);//不能与DC混用,它们只能在WM_PAINT使用
break;
//窗口关闭消息
case WM_CLOSE:
if(IDYES==MessageBox(hwnd,"是否真的结束?","message",MB_YESNO))//判断时习惯将常量放在前面
{
DestroyWindow(hwnd);//该函数销毁窗口,但是不会退出退出程序,该函数会发出一个WM_DESTROY消息
}
break;
case WM_DESTROY:
PostQuitMessage(0);//退出程序
break;
default:
return DefWindowProc(hwnd,uMsg,wParam,lParam);//对不感兴趣的消息提供缺省消息
}
return 0;
}
善于利用MSDN,对于不懂的函数利用MSDN查看
参考:VC++深入详解(孙鑫)