window内部运行机制
- 窗口的使用
- 注册窗口类
WNDCLASS 窗口类
wcex.cbSize = sizeof(WNDCLASSEX); //结构体大小
wcex.style = CS_HREDRAW | CS_VREDRAW;
//当横向和竖向发生拉伸就会发生重绘事件
wcex.lpfnWndProc = WndProc; //窗口回调函数
wcex.cbClsExtra = 0; //窗口类关联额外的空间
wcex.cbWndExtra = 0; //窗口关联的额外空间
wcex.hInstance = hInstance; //当前程序实例
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WIN32PROJECT1));
//图标
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
//光标,图形光标和等待光标
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
//窗口的背景 画刷
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_WIN32PROJECT1);
//菜单
wcex.lpszClassName = szWindowClass;
//应用程序类名,FindWindow就是通过类名和窗口名获取
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
//小图标的使用
* 这里需要注册窗口类
RegisterClassEx();
相当于主题应用,什么风格的窗口
2. 创建窗口
创建窗口类有12个
CreateWindow(szWindowClass, szTitle, WS_MINIMIZEBOX | WS_SYSMENU,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
3. 显示更新窗口
ShowWindow(hWnd, nCmdShow); //显示窗口
UpdateWindow(hWnd); //更新窗口
4. 消息循环
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
5. 处理消息
* 窗口处理函数就可以处理了
* window窗口消息
* 进队消息
* 进队消息是用户输入的结果,如键盘点击,鼠标移动,鼠标单击,时钟消息,刷新消息,退出消息
* postMessage,将信息传入到队列
* 不进队消息
* 调用特定的window函数
* CreateWindow 发送WM_CREATE
* Invaildate 发送WM_PAINT
* GetWindowText 发送WM_GETTEXT
* sendMessage发送消息
* 入口函数
WINAPI WinMain(
HINSTANCE hInstance,HINSTANCE hPreInstance,
LPSTR lpCmdLine, int showCmd)
- 注意
- 表示没有使用下面的参数
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
* 避免窗口大小改变
case WM_NCHITTEST:
//该消息避免屏幕大小的变化
break;
这个消息的原理就是在窗口外的点击放置到窗口内,那么你就无法通过拖动和拉伸来改变窗口的大小了
* 移动窗口到正中央
GetWindowRect(hWnd, &rect);
//获取窗口的大小,原因坐标系在左上方
wndx = rect.right - rect.left;
//矩形右边-矩形左边==窗口的长度
wndy = rect.bottom - rect.top;
//矩形下边-矩形上边 == 窗口的高度
//获取系统屏幕大小也就是我们的分辨率
screenx = GetSystemMetrics(SM_CXSCREEN);
screeny = GetSystemMetrics(SM_CYSCREEN);
MoveWindow(hWnd, (screenx - wndx) / 2, (screeny - wndy) / 2, wndx, wndy, true);
实现原理:获取屏幕大小和窗口大小,将窗口的左上方放置到(屏幕-窗口)/2的位置上就可以了。
#include<windows.h>
#include<tchar.h>
#include "resource.h"
#define MAX 100
TCHAR className[MAX] = {0};
TCHAR wndTitle[MAX] = { 0 };
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
void initString(HINSTANCE hInstance)
{
LoadString(hInstance, IDS_CLASSNAME, className, MAX); //加载字符串
LoadString(hInstance, IDS_WNDNAME, wndTitle, MAX);
//MessageBox(NULL, className, wndTitle, MB_OK);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
initString(hInstance);
//窗口初始化
WNDCLASS wndc;
wndc.cbClsExtra = 0;
wndc.cbWndExtra = 0;
wndc.style = CS_HREDRAW | CS_VREDRAW;//可以横向和竖向拉伸
//背景图片
wndc.hbrBackground = (HBRUSH)LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP1));
//wndc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wndc.hCursor = LoadCursor(NULL, IDC_CROSS);
wndc.hIcon = LoadIcon(NULL, IDI_ASTERISK);
wndc.hInstance = hInstance;
wndc.lpfnWndProc = WndProc;
wndc.lpszClassName = className;
wndc.lpszMenuName = NULL;
//注册窗口类
if (!RegisterClass(&wndc))
{
return -1;
}
//创建窗口类获取句柄
HWND hwnd = CreateWindow(className, wndTitle, WS_VISIBLE | WS_OVERLAPPEDWINDOW, 0, 0, 500, 500, NULL, NULL, hInstance, NULL);
//判断是否创建成功
if (hwnd == NULL)
{
/*MessageBox(NULL, className, wndTitle, MB_OK);*/
return -1;
}
//显示更新窗口
ShowWindow(hwnd, SW_SHOWNORMAL);
UpdateWindow(hwnd);
/*MessageBox(NULL, className, wndTitle, MB_OK);*/
//下面是消息循环
MSG msg;
while (GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
RECT rect;
int wndx, wndy;
int clx, cly;
int screenx, screeny;
switch (message)
{
case WM_CREATE:
//获取窗口大小
GetWindowRect(hWnd, &rect);
//获取窗口的大小,原因坐标系在左上方
wndx = rect.right - rect.left; //矩形右边-矩形左边==窗口的长度
wndy = rect.bottom - rect.top; //矩形下边-矩形上边 == 窗口的高度
//获取客户区域
GetClientRect(hWnd, &rect);
clx = rect.right - rect.left;
cly = rect.bottom - rect.top;
//获取系统屏幕大小也就是我们的分辨率
screenx = GetSystemMetrics(SM_CXSCREEN);
screeny = GetSystemMetrics(SM_CYSCREEN);
MoveWindow(hWnd, (screenx - wndx) / 2, (screeny - wndy) / 2, wndx, wndy, true);
//SetWindowPos(hWnd, NULL, (screenx - wndx-900) / 2, (screeny - wndy-636) / 2, 900 + wndx - clx, 636 + wndy - cly, 0);
break;
case WM_SIZE:
break;
//case WM_CLOSE:
// ::DestoryWindow(hWnd);
// break;
case WM_NCHITTEST:
//该消息避免屏幕大小的变化
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}