一直觉得MFC太麻烦,而QT如果写界面又带又很多的库文件,所以很想利用windows api来写图形界面,看起来比较复杂,但是了解原理后也看起来十分简单了。
流程
其中重点在于:
1)创建窗口类(WNDCLASS*,*表示后面可能有其他后缀,至于各个后缀不同含义见后面“注意”)并注册(RegisterClass*())
2)编写窗口类的事件处理函数
3)创建窗口(CreateWindow*())并显示(ShowWindow())
4)消息循环分发(TranslateMessage(),DispatchMessage())
例子,可以直接在vs中编译运行,不用附加什么东西
#include <Windows.h> // 2)窗口事件处理函数 LRESULT CALLBACK WinProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){ switch (uMsg) { case WM_DESTROY: PostQuitMessage(0); break; default: break; } // 注意!!下面这句是必须的,否则CreateWidow返回NULL return DefWindowProc(hWnd, uMsg, wParam, lParam); } int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ){ // 1)窗口类设计 WNDCLASSEXW wcx; wcx.cbSize = sizeof(WNDCLASSEXW); wcx.style = CS_HREDRAW | CS_VREDRAW; wcx.cbClsExtra = 0; wcx.cbWndExtra = 0; wcx.hInstance = hInstance; wcx.hIcon = NULL; wcx.hCursor = LoadCursor(NULL, IDC_ARROW); wcx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wcx.lpszMenuName = NULL; wcx.hIconSm = NULL; // 小图标 wcx.lpszClassName = L"MainWinClass"; // 窗口类名称 wcx.lpfnWndProc = WinProc; // 2)窗口事件处理函数 // 1)注册窗口类 ATOM win = RegisterClassExW(&wcx); HWND hWnd; // 3)创建窗口 hWnd = CreateWindowW( L"MainWinClass", L"我是标题党", WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_POPUPWINDOW , CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, (HWND)NULL, (HMENU)NULL, hInstance, (LPVOID)NULL ); if (!hWnd){ MessageBox(NULL, L"fuck", L"Error!", 0); return 0; } // 3)显示窗口 ShowWindow(hWnd, SW_SHOW); UpdateWindow(hWnd); // 4)消息处理 MSG msg; while (GetMessage(&msg,NULL,NULL,NULL)){ TranslateMessage(&msg); DispatchMessage(&msg); } return 0; }
下面的代码简单演示了过程,里面大部分无关的细节都忽略了,注意下面编号:
注意
1)如果你发现CreateWindow返回NULL的话,很大可能性是窗口消息处理函数最后一句不是return DefWindowProc(hWnd, uMsg, wParam, lParam);
2)函数带Ex后缀与不带Ex后缀参数的不同。
3)函数带W后缀和A后缀的不同,W表示宽字符,即UNICODE,A表示ASCII。如CreateWindowW是传入宽字符的函数,而CreateWindowA是ASCII传入的,不同后缀时,参数里字符串的形式要注意匹配。