MFC自定义控件初始渲染时机咨询:子类化控件首次绘制位置
解决子类化控件初始绘制的时机问题
其实这个问题我之前也碰到过,构造函数里窗口句柄还没创建确实没法调用渲染逻辑,给你几个靠谱的触发时机,选适合你场景的就行:
1. 子类化完成后立刻触发重绘
这是最直接的方式,比如你在对话框的OnInitDialog里完成控件子类化,或者在代码里调用SetWindowSubclass/SetWindowLongPtr之后,马上执行:
InvalidateRect(m_hWnd, NULL, TRUE); UpdateWindow(m_hWnd);
InvalidateRect会标记整个控件区域为需要重绘,UpdateWindow会立刻发送WM_PAINT消息,强制你的绘制函数执行一次。
2. 在子类窗口过程里处理WM_SHOWWINDOW消息
如果你的控件可能一开始是隐藏状态,第一次显示时才需要绘制,那就在子类的窗口过程里加这个处理:
case WM_SHOWWINDOW: if (wParam == TRUE) { // 控件从隐藏变为显示 InvalidateRect(hWnd, NULL, TRUE); UpdateWindow(hWnd); } break;
这样能确保控件第一次出现在界面上时,一定会执行初始绘制。
3. MFC控件可以用PreSubclassWindow
如果你是用MFC写的子类化控件,重写PreSubclassWindow方法就行——这个方法是在控件完成子类化、窗口句柄已经存在后调用的,刚好适合做初始化操作:
void CMyCustomCtrl::PreSubclassWindow() { CWnd::PreSubclassWindow(); // 触发初始绘制 Invalidate(); UpdateWindow(); }
另外要注意:不管用哪个时机,你的WM_PAINT处理函数里必须包含完整的初始绘制逻辑——不能只在鼠标事件触发时才更新内容,要保证每次收到WM_PAINT都能画出控件的完整状态,这样初始触发的重绘才能显示正确的内容。
内容的提问来源于stack exchange,提问作者Swiss Frank
相关产品推荐
相关产品推荐

