WinAPI使用GDI运行时更新窗口矩形颜色重绘不生效问题
问题原因及修复方案
核心错误点
- 你调用
InvalidateRect时传入的wnd是输入框的句柄,只会触发输入框自身重绘,而绘制颜色矩形的是主窗口,需要给主窗口发无效区域通知才能触发对应的WM_PAINT逻辑 - 代码存在GDI资源泄漏、内存泄漏的潜在问题
- 如果输入的颜色码带
#前缀,当前的sscanf_s格式符会读取失败,导致颜色值无法正确更新
具体修改点
- 把
subEditProc里的InvalidateRect(wnd, NULL, TRUE);替换为调用主窗口的InvalidateRect:
// 用GetParent获取输入框的父窗口(也就是你绘制矩形的主窗口)句柄 InvalidateRect(GetParent(wnd), NULL, TRUE);
- 修复WM_PAINT中的GDI资源泄漏,创建的画刷用完后要释放:
case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); HBRUSH newBrush = CreateSolidBrush(RGB(floor(current_color.r * 255), floor(current_color.g * 255), floor(current_color.b * 255))); HGDIOBJ oldBrush = SelectObject(hdc, newBrush); Rectangle(hdc, 10, 10, 200, 200); SelectObject(hdc, oldBrush); DeleteObject(newBrush); // 新增这行释放画刷资源 EndPaint(hWnd, &ps); } break;
- 优化输入读取逻辑的内存泄漏问题,不需要动态分配字符串,同时兼容带
#前缀的输入:
case VK_RETURN: { std::string color_text = read_textInput(hColorInput); int r, g, b; // 直接用c_str()不需要额外拷贝,格式符适配带#前缀的输入 if (sscanf_s(color_text.c_str(), "%02x%02x%02x", &r, &g, &b) != 3) { sscanf_s(color_text.c_str(), "#%02x%02x%02x", &r, &g, &b); } current_color.r = r / 255.; current_color.g = g / 255.; current_color.b = b / 255.; InvalidateRect(GetParent(wnd), NULL, TRUE); } break;
验证逻辑
修改完成后,输入六位十六进制颜色码(比如FF0000对应红色)按下回车,主窗口就会触发重绘,用新的颜色值绘制矩形。调整窗口大小触发重绘时也会使用最新的current_color值。
内容的提问来源于stack exchange,提问作者Yaroslav Rodionov
相关产品推荐
相关产品推荐

