我目前正在尝试在我的应用程序中子类化 CRichEditCtrl
。这是子类:
class FileEdit : public CWindowImpl<FileEdit, CRichEditCtrl>
{
DECLARE_WND_CLASS(L"FileEdit");
public:
BEGIN_MSG_MAP_EX(FileEdit)
MSG_WM_PAINT(OnPaint)
MSG_WM_LBUTTONUP(OnLButtonUp)
END_MSG_MAP()
bool Init();
private:
void OnPaint(CDCHandle dc);
void OnLButtonUp(UINT nFlags, CPoint point);
};
我的绘画方法是这样的:
void FileEdit::OnPaint(CDCHandle dc)
{
PAINTSTRUCT ps;
if (!dc)
{
dc = BeginPaint(&ps);
}
POINT p[2];
p[0].x = 1;
p[0].y = 1;
p[1].x = 5;
p[1].y = 5;
Polygon(dc, p, 2);
EndPaint(&ps);
}
这确实绘制了我想要的多边形,但这也是它唯一绘制的东西。我很确定为什么会这样。我正在接受 Paint 消息,我正在处理它,然后它就完成了。例如,我不会执行将背景涂成白色的默认例程。
但是,我实际上想要这样:
- 执行默认的绘制例程,如果我不指定自定义绘制例程,就会发生这种情况
- 绘制我在
FileEdit::OnPaint
方法中请求的东西。
我仍然想要通常的绘画程序,但我只想在之后“在上面”添加一些东西。
有什么办法可以实现吗?也许我可以将 PAINTSTRUCT
传递给基本方法?
提前致谢
最佳答案
自定义 WM_PAINT
处理程序的最干净的方法是找到一种方法将您的代码插入到 BeginPaint
和 EndPaint
对的中间。标准控制处理程序有自己的调用,因此最好在存在此类机会时在这些调用之间进行回调。例如,listview 和 treeview 等常用控件确实通过发送 NM_CUSTOMDRAW
通知提供了这种机会,但是编辑控件并不那么灵活。
当然,如果您完全处理绘画,任务会容易得多,在这种情况下,您只需自己处理消息,而无需过多考虑标准处理程序。
一个运行良好的特定于编辑的解决方案(意味着它与标准控件实现兼容,这不一定适用于其他控件;它也适用于简单的编辑控件,而不是丰富的编辑控件)是:
- 提供您自己的
WM_PAINT
处理程序 - 调用
DefWindowProc
让控件用它自己的BeginPaint
和EndPaint
进行标准绘画 - 然后在您的处理程序中继续使用
GetDC
和ReleaseDC
获取HDC
(与BeginPaint
和EndPaint
) 并使用您的自定义更新获得的 DC。
子类编辑控件的 WTL 处理程序可能如下所示:
LRESULT OnPaint(CDCHandle)
{
if(!(GetStyle() & ES_READONLY)) // Just an example how to make custom draw optional
{
DefWindowProc();
CClientDC Dc(m_hWnd);
// TODO: Paint using Dc
} else
SetMsgHandled(FALSE);
return 0;
}
另见:
关于c++ - 如何在默认绘制结果之上的子类控件绘制方法中绘制某些内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42176041/