其实上一篇已经给出窗口的创建过程,但是还不够具体,不够详细,今天就给出比较具体的流程。
一.窗口创建步骤
1.1 定义程序入口winmain函数
1.2 注册窗口
1.2.1 窗口类
typedef struct { UINT style; // 窗口类风格
WNDPROC lpfnWndProc; // 窗口过程函数指针
int cbClsExtra; // 窗口类附加数据缓冲区字节数
int cbWndExtra; // 窗口附加数据缓冲区字节数
HINSTANCE hInstance; // 当前应用程序实例句柄
HICON hIcon; // 图标句柄
HCURSOR hCursor; // 光标句柄
HBRUSH hbrBackground; // 刷子句柄
LPCTSTR lpszMenuName; // 菜单资源名
LPCTSTR lpszClassName; // 窗口类名 } WNDCLASS, *PWNDCLASS;
注意: WNDCLASSEX中多了一个 UINT cbSize; // 结构体字节数*
1.2.2 窗口类风格
CS_GLOBALCLASS - 应用程序全局窗口类
CS_BYTEALIGNCLIENT - 窗口客户区水平位置按8像素对齐
CS_BYTEALIGNWINDOW - 窗口水平位置按8像素对齐
CS_HREDRAW - 窗口水平变化时重绘
CS_VREDRAW - 窗口垂直变化时重绘
CS_DBLCLKS - 允许窗口接收鼠标双击消息
CS_NOCLOSE - 没有关闭按钮
1.2.3注册窗口函数
ATOM RegisterClass (CONST WNDCLASS* lpWndClass);
ATOM即unsigned short,成功返回所注册窗口类的唯一标识码(非0), 失败返回0。
1.3 消息处理
LRESULT CALLBACK WindowProc (
HWND hWnd, // 窗口句柄
UINT uMsg, // 消息标识
WPARAM wParam, // 消息参数
LPARAM lParam // 消息参数 )
LRESULT CALLBACK DefWindowProc (
HWND hWnd, // 窗口句柄
UINT uMsg, // 消息标识
WPARAM wParam, // 消息参数
LPARAM lParam // 消息参数 );
案例:DefWindowProc函数对WM_DESTROY消息的处理不会投递WM_QUIT消息,
导致消息循环不会结束,窗口虽然关闭,但进程仍然存在。
switch (uMsg) {
case WM_DESTROY:
PostQuitMessage (0);
break;
default:
return DefWindowProc (hWnd, uMsg, wParam, lParam); }
1.4 创建窗口:
1.4.1创建窗口函数:在内存中创建窗口对象,并不可见
HWND CreateWindow (
LPCTSTR lpClassName, // 窗口类名
LPCTSTR lpWindowName, // 窗口标题栏信息
DWORD dwStyle, // 窗口风格
int x, // 窗口左上角水平坐标
int y, // 窗口左上角垂直坐标
int nWidth, // 窗口宽度
int nHeight, // 窗口高度
HWND hWndParent, // 父窗口句柄
HMENU hMenu, // 菜单句柄
HINSTANCE hInstance, // 当前应用程序实例句柄
LPVOID lpParam // 附加数据 )
1.4.2 窗口风格
WS_OVERLAPPED:用于产生一个叠层窗口,都有标题栏和边框
WS_CAPTION:有标题栏的窗口
WS_SYSMENU:创建一个标题栏上具有系统菜单的窗口,需要ws_caption一起使用
WS_MINIMAZEBOX:创建具有最小化按钮窗口,必须有ws_system类型
WS_MAXIMIZBOX:创建具有最大化按钮的窗口,必须有ws_system类型。
WS_OVERLAPPEDWINDOW:创建有标题栏,系统菜单最大化最小化窗口
WS_POPUP - 弹出式
WS_POPUPWINDOW - 边框、弹出式、系统菜单
WS_SIZEBOX - 带尺寸框的粗边框
WS_SYSMENU - 系统菜单
1.5 窗口显示
BOOL ShowWindow ( //成功返回TRUE,失败返回FALSE。
HWND hWnd, // 窗口句柄
int nCmdShow // 显示方式 );
BOOL UpdateWindow( HWND hWnd // 窗口句柄 );//刷新
成功返回TRUE,失败返回FALSE。
1.6 消息循环
重复执行提取消息、翻译消息、派发消息三步
BOOL GetMessage ( //收到WM_QUIT返回FALSE,收到其它消息返回TRUE
LPMSG lpMsg, // 消息结构
HWND hWnd, // 窗口句柄
UINT wMsgFilterMin, // 起始消息
UINT wMsgFilterMax // 终止消息 );
BOOL TranslateMessage ( //将虚键消息翻译为字符消息。
const MSG* lpMsg // 消息结构 );
若消息被翻译则返回TRUE,否则返回FALSE。
LRESULT DispatchMessage ( //将消息派发到窗口过程函数。
const MSG* lpmsg // 消息结构 );
返回窗口过程函数的返回值
1.7 注销窗口
UnregisterClass。进程结束时,其所注册的全部窗口类都会被自动注销
完整代码演示如下:
基本的概念汇总
2.1句柄概念
在windows应用程序中,窗口都是通过句柄进行标识的,
当系统创建这些资源的时候会分配内存,并返回资源标志号—句柄
2.2加载图标
LoadImage(实例句柄,文件名,图片类型,指定图标或光标的宽度,高度,加载方式);
IMAGE_BITMAP:装载位图;
IMAGE_CURSOR:装载光标;
IMAGE_ICON:装载图标。
LR_DEFAULTSIZE ---默认大小
LR_DEFAULTCOLOR:缺省标志;它不作任何事情
LR_LOADFROMFILE---从文件中加载
2.3移动窗口
BOOL MoveWindow(
HWND hWnd, // 窗口句柄
int X, // 水平坐标
int Y, // 垂直坐标
int nWidth, // 窗口的宽
int nHeight, // 窗口的高
BOOL bRepaint // 是否擦除原来的);