- A+
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
#include "windows.h" //#pragma comment(lib,"kernel32.dll") LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd) { //MessageBox(NULL, L"hello world", L"first哈哈", 0); //1.设置窗口 WNDCLASSEX wndclass = {0}; wndclass.cbSize = sizeof(WNDCLASSEX); wndclass.lpszClassName = L"myclass"; wndclass.hInstance = hInstance; wndclass.lpfnWndProc = WndProc;//消息循环函数 //2.注册窗口 if (RegisterClassEx(&wndclass) == 0) { return -1; } //3.创建窗口 HWND hwnd = CreateWindow(L"myclass", L"吃丨菜", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, NULL, NULL, hInstance, NULL); //4.显示窗口 ShowWindow(hwnd, nShowCmd); UpdateWindow(hwnd); HDC hdc = GetDC(hwnd); HDC mdc = CreateCompatibleDC(hdc); HBITMAP siz = CreateCompatibleBitmap(hdc, 800, 600); SelectObject(mdc, siz); HDC bufdc = CreateCompatibleDC(hdc); HBITMAP bg = (HBITMAP)LoadImage(NULL, L"image/background.bmp", IMAGE_BITMAP, 480, 852, LR_LOADFROMFILE); SelectObject(bufdc, bg); BitBlt(mdc, 0, 0, 480, 852, bufdc, 0, 0, SRCCOPY); BitBlt(mdc, 480, 0, 480, 852, bufdc, 0, 0, SRCCOPY); //TransparentBlt(mdc, 0, 0, 480, 852, bufdc, 0, 0, 480, 852, RGB(0, 0, 0)); BitBlt(hdc, 0, 0, 800, 600, mdc, 0, 0, SRCCOPY); //5.处理消息 MSG msg = { 0 }; while (msg.message != WM_QUIT) { if (PeekMessage(&msg, 0, NULL, NULL, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } } ReleaseDC(hwnd,hdc); DeleteDC(mdc); UnregisterClass(L"myclass", hInstance); return 0; } LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, message, wParam, lParam); } return 0; } |
创建空白的Win32应用程序,添加一个cpp文件
在开头引入windows库文件 #include "windows.h"
然后就是Windows的入口函数WinMain了,它是整个应用程序的入口点
1 2 3 4 |
int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd) { return 0; } |
定义如上,VAssisX可以快速提示写出来,不需要死记硬背
下面就开始自定义窗口了
首先,1.设置窗口
1 2 3 4 5 6 |
//1.设置窗口 WNDCLASSEX wndclass = {0}; wndclass.cbSize = sizeof(WNDCLASSEX); wndclass.lpszClassName = L"myclass"; wndclass.hInstance = hInstance; wndclass.lpfnWndProc = WndProc;//消息循环函数 |
WNDCLASSEX是一个结构体,定义窗口的相关属性
图片上的只是结构体的部分属性,基本上不需要怎么变
需要自定义相关属性时,可以查看相关的文档,vs按F1
其中lpszClassName是类的名字,用于识别这个结构体
lpfnWndProc是消息循环函数
1 2 3 4 5 6 7 8 9 10 11 12 |
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, message, wParam, lParam); } return 0; } |
如图所示,这个函数是固定的
在Windows中每个应用程序都有着这么一个消息函数
用于接收用户的相关的交互事件,例如:鼠标点击事件,键盘按下事件等
其中default是让操作系统处理DefWindowProc(hwnd, message, wParam, lParam)
2.注册窗口
if (RegisterClassEx(&wndclass) == 0) {
return -1;
}
如果注册不成功就返回-1,表示不正常退出
wndclass就是第一布定义的结构体
3.创建窗口
HWND hwnd = CreateWindow(L"myclass", L"吃丨菜", WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,
800, 600, NULL, NULL, hInstance, NULL);
第一个参数就是第一步定义的结构体类名
第二个参数是窗口的标题
800,600分别是窗口的宽和高
其他的属性是一些Windows事先定义好的宏和NULL空
相关的参数功能看文档吧!
4.显示窗口
ShowWindow(hwnd, nShowCmd);
UpdateWindow(hwnd);
这两句就不说了,一看就知道是什么意思了
5.处理消息
MSG msg = { 0 };//消息结构体,自动保存相关消息的信息
while (msg.message != WM_QUIT)
{
if (PeekMessage(&msg, 0, NULL, NULL, PM_REMOVE)) {
TranslateMessage(&msg);//翻译消息
DispatchMessage(&msg);//让消息函数处理
}
}
PeekMessage(&msg, 0, NULL, NULL, PM_REMOVE)
从队列中取出一条消息,并从消息队列中移除PM_REMOVE
结束的时候需要注销定义的窗口结构体释放资源
UnregisterClass(L"myclass", hInstance);
这样,一个基本自定义的窗口就做好了!