Open lkm77 opened 1 year ago
以下是相关代码
ExMessage getmessage_win32(BYTE filter, HWND hWnd) { while (!IsNewMessage(filter, hWnd)) HpSleep(1); ExMessage msg = GetNextMessage(filter, hWnd); RemoveMessage(hWnd); return msg; } bool IsNewMessage(BYTE filter, HWND hWnd) { for (auto& element : GetMsgVector(hWnd)) if (filter & GetExMessageType(element)) return true; return false; } std::vector<ExMessage>& GetMsgVector(HWND hWnd) { static std::vector<ExMessage> vec; int index = GetWindowIndex(hWnd); if (IsAliveWindow(index)) { return g_vecWindows[index].vecMessage; } else { vec.clear(); return vec; } }
如果把窗口销毁,GetMsgVector会一直返回空的消息容器,getmessage_win32会一直循环,导致无法判断窗口存在,程序无法退出.
void RegisterExMessage(int indexWnd, UINT msg, WPARAM wParam, LPARAM lParam) { // 记录消息事件 switch (msg) { // EM_MOUSE case WM_MOUSEMOVE: case WM_MOUSEWHEEL: case WM_LBUTTONDOWN: case WM_LBUTTONUP: case WM_LBUTTONDBLCLK: case WM_MBUTTONDOWN: case WM_MBUTTONUP: case WM_MBUTTONDBLCLK: case WM_RBUTTONDOWN: case WM_RBUTTONUP: case WM_RBUTTONDBLCLK: { ExMessage msgMouse = {}; msgMouse.message = msg; msgMouse.x = GET_X_LPARAM(lParam); msgMouse.y = GET_Y_LPARAM(lParam); msgMouse.wheel = GET_WHEEL_DELTA_WPARAM(wParam); msgMouse.shift = LOWORD(wParam) & 0x04 ? true : false; msgMouse.ctrl = LOWORD(wParam) & 0x08 ? true : false; msgMouse.lbutton = LOWORD(wParam) & 0x01 ? true : false; msgMouse.mbutton = LOWORD(wParam) & 0x10 ? true : false; msgMouse.rbutton = LOWORD(wParam) & 0x02 ? true : false; // 有滚轮消息时,得到的坐标是屏幕坐标,需要转换 if (msgMouse.wheel) { POINT p = { msgMouse.x ,msgMouse.y }; ScreenToClient(g_vecWindows[indexWnd].hWnd, &p); msgMouse.x = (short)p.x; msgMouse.y = (short)p.y; } g_vecWindows[indexWnd].vecMessage.push_back(msgMouse); } break; // EM_KEY case WM_KEYDOWN: case WM_KEYUP: case WM_SYSKEYDOWN: case WM_SYSKEYUP: { // code from MSDN WORD vkCode = LOWORD(wParam); // virtual-key code WORD keyFlags = HIWORD(lParam); WORD scanCode = LOBYTE(keyFlags); // scan code BOOL isExtendedKey = (keyFlags & KF_EXTENDED) == KF_EXTENDED; // extended-key flag, 1 if scancode has 0xE0 prefix if (isExtendedKey) scanCode = MAKEWORD(scanCode, 0xE0); BOOL repeatFlag = (keyFlags & KF_REPEAT) == KF_REPEAT; // previous key-state flag, 1 on autorepeat WORD repeatCount = LOWORD(lParam); // repeat count, > 0 if several keydown messages was combined into one message BOOL upFlag = (keyFlags & KF_UP) == KF_UP; // transition-state flag, 1 on keyup // 功能键:不区分左右 // if we want to distinguish these keys: //switch (vkCode) //{ //case VK_SHIFT: // converts to VK_LSHIFT or VK_RSHIFT //case VK_CONTROL: // converts to VK_LCONTROL or VK_RCONTROL //case VK_MENU: // converts to VK_LMENU or VK_RMENU // vkCode = LOWORD(MapVirtualKeyW(scanCode, MAPVK_VSC_TO_VK_EX)); // break; //} ExMessage msgKey = {}; msgKey.message = msg; msgKey.vkcode = (BYTE)vkCode; msgKey.scancode = (BYTE)scanCode; msgKey.extended = isExtendedKey; msgKey.prevdown = repeatFlag; g_vecWindows[indexWnd].vecMessage.push_back(msgKey); // 给控制台发一份,支持 _getch() 系列函数 PostMessage(g_hConsole, msg, wParam, lParam); } break; // EM_CHAR case WM_CHAR: { ExMessage msgChar = {}; msgChar.message = msg; msgChar.ch = (TCHAR)wParam; g_vecWindows[indexWnd].vecMessage.push_back(msgChar); // 通知控制台 PostMessage(g_hConsole, msg, wParam, lParam); } break; // EM_WINDOW case WM_ACTIVATE: case WM_MOVE: case WM_SIZE: { ExMessage msgWindow = {}; msgWindow.message = msg; msgWindow.wParam = wParam; msgWindow.lParam = lParam; g_vecWindows[indexWnd].vecMessage.push_back(msgWindow); } break; } }
并且RegisterExMessage函数不会登记窗口销毁消息,无法通过处理销毁消息退出. 是否应该加一个判断窗口是否存在或是登记窗口销毁消息的操作呢?
以下是相关代码
如果把窗口销毁,GetMsgVector会一直返回空的消息容器,getmessage_win32会一直循环,导致无法判断窗口存在,程序无法退出.
并且RegisterExMessage函数不会登记窗口销毁消息,无法通过处理销毁消息退出. 是否应该加一个判断窗口是否存在或是登记窗口销毁消息的操作呢?