win32学习03.窗口程序
步骤:
- 写WinMain函数
- 定义窗口处理函数(处理消息)
- 注册窗口类(类似于先声明再使用)RegisterClass
- 创建窗口(内存中创建窗口)CreateWindow
- 显示窗口(根据内存绘制窗口)ShowWindow/UpdateWindow
- 消息循环(提取/翻译/派发 消息)GetMessage/TranslateMessage/DispatchMessage
消息处理
include
include
//声明窗口过程函数
LRESULT CALLBACK WinSunProc(HWND hwnd, //窗口句柄
UINT uMsg, //消息
WPARAM wParam, //附加参数1
LPARAM lParam //附加参数2
);
int WinMain(
__in HINSTANCE hInstance,//当前程序的实例句柄,找到本进程的内存
__in_opt HINSTANCE hPrevInstance, //前一个实例句柄,已经废弃,一般为NULL
__in LPSTR lpCmdLine, //命令行参数字符串
__in int nShowCmd //窗口的显示方式:最大化,最小化,原样。
)
{
const char* ClassName = "HappyTeemo";
//设计窗口类
WNDCLASS wndcls;
wndcls.style = CS_HREDRAW | CS_VREDRAW;
wndcls.lpfnWndProc = WinSunProc;
wndcls.cbClsExtra = 0;
wndcls.cbWndExtra = 0;
wndcls.hInstance = hInstance;
wndcls.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wndcls.hCursor = LoadCursor(NULL,IDC_CROSS);
wndcls.hIcon = LoadIcon(NULL,IDI_ERROR);
wndcls.lpszClassName = ClassName;
wndcls.lpszMenuName = NULL;
RegisterClass(&wndcls);//注册窗口类
//创建窗口
HWND hwnd;
hwnd = CreateWindow
(ClassName,"HappyTeemoFirstWindow",WS_OVERLAPPEDWINDOW,0,0,600,400,NULL,NULL,hInstance,NULL);
//显示和刷新窗口
ShowWindow(hwnd,SW_SHOWNORMAL);
UpdateWindow(hwnd);
//定义消息结构体,开始消息循环
MSG msg;
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
//窗口过程函数
LRESULT CALLBACK WinSunProc(HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
switch(uMsg)
{
case WM_CHAR: //按下字符键
char szChar[200];
sprintf(szChar,"char is %d",wParam);
MessageBox(hwnd,szChar,"HappyTeemo",0);
break;
case WM_LBUTTONDOWN://鼠标左键
MessageBox(hwnd,"mouse clicked","HappyTeemo",0);
HDC hdc;
hdc=GetDC(hwnd);
TextOut(hdc,0,50,"HappyTeemo",strlen("HappyTeemo"));
ReleaseDC(hwnd,hdc);
break;
case WM_PAINT: //重绘
HDC hDC;
PAINTSTRUCT ps;
hDC=BeginPaint(hwnd,&ps);
TextOut(hDC,0,0,"HappyTeemo",strlen("HappyTeemo"));
EndPaint(hwnd,&ps);
break;
case WM_CLOSE://关闭
if(IDYES==MessageBox(hwnd,"Close?","HappyTeemo",MB_YESNO))
{
DestroyWindow(hwnd);
}
break;
case WM_DESTROY://销毁
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
return 0;
}
/** 窗口类的结构体 typedef struct _WNDCLASS { UINT style;// 窗口样式 WNDPROC lpfnWndProc;//窗口处理函数,函数指针 int cbClsExtra;//附加内存,一般为0,为了开缓冲区 int cbWndExtra;//窗口附加内存,一般也为0,为了开缓冲区 HINSTANCE hInstance;//实例句柄 HICON hIcon;//窗口的图标句柄 HCURSOR hCursor;//窗口鼠标光标 HBRUSH hbrBackground;//窗口背景色 LPCTSTR lpszMenuName;//窗口菜单名 LPCTSTR lpszClassName;// 窗口类名 } WNDCLASS, LPWNDCLASS; **/
/** //MSG结构体: typedef struct tagMSG { HWND hwnd; //句柄,属于哪个窗口的 UINT message; //消息,不同数值表示不同消息 WPARAM wParam; //附加信息1 LPARAM lParam; //附加信息2 DWORD time; //时间 POINT pt; //鼠标位置 } MSG; */
/** HWND CreateWindow( LPCTSTR lpClassName, // registered class name,注册类的名字 LPCTSTR lpWindowName, // window name,标题栏名字 DWORD dwStyle, // window style,风格 int x, // horizontal position of window,窗口左上角x坐标 int y, // vertical position of window,窗口左上角y坐标 int nWidth, // window width,宽 int nHeight, // window height,高 HWND hWndParent, // handle to parent or owner window,父窗口句柄 HMENU hMenu, // menu handle or child identifier,菜单句柄 HINSTANCE hInstance, // handle to application instance,实例句柄 LPVOID lpParam // window-creation data,附加参数 ); */
窗口类的类别:
- 系统窗口类:系统定义好的,不需要注册就可以用,比如按钮(只要有形状的基本都可以算窗口)。
- 全局窗口类,当前应用程序所有模块可以用。
- 局部窗口类,本模块可以用。
注册全局的时候,需要加上CS_GLOBALCLASS风格。建议使用局部类(减少重名的麻烦)
窗口类的查找过程:
- 现在局部窗口类找,找到跳到2,没找到跳到3。
- 对比实力句柄:HINSTANCE hInstance。如果相同则表示一个进程模块,则创建返回。不相同跳到3。
- 全局窗口类中找,找到则创建返回。没找到则进行第四步。
- 系统窗口类中找,找到则创建放回。没找到则返回创建失败。
子窗口简介:
需要设置父类窗口句柄,风格增加WS_CHILD。
还没有评论,来说两句吧...