https://m.toutiao.com/is/Btx2j4B/
当Windows操作系统启动一个程序时,它调用的就是该程序的WinMain函数( 实际是由插入到可执行文件中的启动代码调用的)。 WinMain是Windows程序的入口点函数,与DOS程序的入口点函数main的作用相同,当WinMain 函数结束或返回时,Windows应用程序结束。
int WINAPI WinMain( HINSTANCE hInstance, //应用程序实例 HINSTANCE hPrevInstance, //上一个应用程序实例 LPSTR lpCmdLine, //命令行参数 int nShowCmd //窗口显示的样式);
#include <Windows.h>#include <cstdio>#pragma comment(linker, '/subsystem:\'console\' /entry:\'WinMainCRTStartup\'')int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, int nCmdShow) { printf('%p %p %p\n', hInstance, hPrevInstance, GetModuleHandleA(NULL)); printf('%d %d\n', nCmdShow, SW_SHOWNORMAL); printf('%s\n', lpCmdLine); MessageBoxA(NULL, TEXT('第一个 Windows API 程序'), TEXT('黑猫编程'), MB_OK); return 0;}
#include <Windows.h>#include <cstdio>#include <cstring>#include <clocale>int main() { const char* str1 = 'Abc中国'; printf('%s %d\n', str1, strlen(str1)); _wsetlocale(LC_ALL, L'chs'); const wchar_t* str2 = L'ABC中国文字'; wprintf(L'%s %d\n', str2, wcslen(str2)); MessageBoxW(NULL, TEXT('hello cat.'), L'coding', MB_OK); return 0;}
一个完整的Win32程序(#include <windows.h>),该程序实现的功能是创建一个窗口,并在该窗口中响应键盘及鼠标消息,程序的实现步骤为:
#include <Windows.h>// 自定义窗口过程回调函数LRESULT CALLBACK MyWindowProc(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam) { switch (Msg) { case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProcA(hwnd, Msg, wParam, lParam);}int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { // 注册窗口类 WNDCLASS wnd; wnd.cbClsExtra = 0; wnd.cbWndExtra = 0; wnd.hbrBackground = (HBRUSH)(GetStockObject(WHITE_BRUSH)); wnd.hCursor = LoadIcon(NULL, IDC_ARROW); wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION); wnd.lpfnWndProc = MyWindowProc; wnd.lpszClassName = TEXT('blackcat'); wnd.lpszMenuName = NULL; wnd.style = CS_HREDRAW; wnd.hInstance = hInstance; RegisterClassA(&wnd); // 创建窗口 返回之前发送 VW_CREATE HWND hwnd = CreateWindowA( TEXT('blackcat'), TEXT('黑猫编程'), WS_OVERLAPPEDWINDOW, 100, 100, 300, 300, NULL, NULL, hInstance, NULL ); // 显示窗口 ShowWindow(hwnd, nShowCmd); // 更新窗口 UpdateWindow(hwnd); // 消息循环 收到 VM_QUIT 退出 MSG msg; while (GetMessageA(&msg, hwnd, 0, 0)) { TranslateMessage(&msg); DispatchMessageA(&msg); } return 0;}
在WIN32中,消息队列是与线程(Thread)相关的,一个线程只能有一个消息队列(queue)与之相对应。当一个线程里面首次调用User32.dll或GDI32.dll中的函数时,系统会为该线程创建一个消息队列,否则就没有消息队列。
在一个线程中可以产生多个窗口,所以每个窗口课共用一个线程消息队列,所有产生给某个窗口的消息,都先由创建这个窗口的线程处理,窗口在任何线程中都可以创建,但消息循环必须要和创建窗口在同一线程,否则窗口将无法从DispatchMessage()获取任何消息,为了使窗口接受这些消息,线程必须有自己的循环。
联系客服