共用同一WndProc的多个窗口如何获取自身专属序号
问题根源
你两次代码出错的核心原因都是:窗口过程中的static变量是全局共享的,所有使用同一个窗口过程的窗口都会读写同一块内存,不存在每个窗口独立的static变量,因此会出现所有窗口读取到同一个值的问题。
实现方案
Win32 提供了GWLP_USERDATA窗口专属存储字段,你可以把每个窗口的独立序号绑定在这个字段上,完全满足需求:
步骤1:创建窗口时传入对应序号
调用CreateWindowEx创建窗口时,把当前要分配的序号作为最后一个参数lpParam传入,修改你的CreateTestWindow函数逻辑:
int CreateTestWindow() { Num += 1; // 原有CreateWindowEx调用逻辑不变,仅修改最后一个参数 CreateWindowEx( // 其他参数保持你原来的配置不变 (LPVOID)Num // 最后一个参数传入当前窗口的序号 ); return 0; }
步骤2:WM_CREATE阶段绑定序号到窗口
在窗口过程的WM_CREATE消息里拿到传入的序号,绑定到当前窗口的专属存储字段:
case WM_CREATE: { // 从lParam中提取创建窗口时传入的序号 CREATESTRUCT* pCreate = (CREATESTRUCT*)lParam; int windowIdx = (int)pCreate->lpCreateParams; // 把序号绑定到当前窗口的专属存储字段 SetWindowLongPtrW(hWnd, GWLP_USERDATA, (LONG_PTR)windowIdx); // 这里可以直接读取对应配置初始化窗口坐标大小 Data& cfg = UserData[windowIdx]; SetWindowPos(hWnd, NULL, cfg.x, cfg.y, cfg.width, cfg.height, SWP_NOZORDER); // 原有分层窗口逻辑保留 SetWindowLong(hWnd, GWL_EXSTYLE, GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_LAYERED); SetLayeredWindowAttributes(hWnd, RGB(255, 255, 255), 220, LWA_ALPHA); break; }
步骤3:任意消息中读取窗口序号
后续在任何消息处理逻辑里,都可以直接读取当前窗口的专属序号:
case WM_LBUTTONUP: { // 读取当前窗口绑定的序号 int windowIdx = (int)GetWindowLongPtrW(hWnd, GWLP_USERDATA); wchar_t meChar[20] = L""; _itow(windowIdx, meChar, 10); MessageBox(0, meChar, meChar, 0); break; // 注意你原来的代码这里缺了break,会落到WM_SIZE逻辑执行 }
步骤4:关闭窗口时写入配置
在关闭窗口的逻辑中读取序号,把当前窗口状态写回配置即可:
case WM_CLOSE: { int windowIdx = (int)GetWindowLongPtrW(hWnd, GWLP_USERDATA); RECT winRc; GetWindowRect(hWnd, &winRc); // 更新配置 UserData[windowIdx].x = winRc.left; UserData[windowIdx].y = winRc.top; UserData[windowIdx].width = winRc.right - winRc.left; UserData[windowIdx].height = winRc.bottom - winRc.top; // 可选择此时写文件,或者所有窗口关闭后统一写文件 Num -= 1; DestroyWindow(hWnd); break; }
补充说明
如果每个窗口需要存储的不止序号,可以直接把自定义结构体的指针绑定到GWLP_USERDATA上,注意自行管理结构体的内存分配和释放即可。
内容的提问来源于stack exchange,提问作者末影小末EnderMo
相关产品推荐
相关产品推荐

