如何在我的子类控件paint方法中在默认的paint结果之上绘制一些东西



我目前正在尝试在应用程序中对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消息,我正在处理它,然后它就完成了。我没有经过默认的例程,例如将背景漆成白色。

然而,我实际上希望它是这样的:

  1. 执行默认绘制例程,如果我没有指定自定义绘制例程,就会发生这种情况
  2. FileEdit::OnPaint-方法画出我要求的东西

我仍然想要通常的绘画程序,但我只想在之后"顶部"添加一些东西。

有什么办法可以做到这一点吗?也许我可以把PAINTSTRUCT传递给一个基本方法?

提前感谢

自定义WM_PAINT处理程序的最干净的方法是找到一种将代码插入BeginPaintEndPaint对中间的方法。标准控件处理程序有自己的调用,所以当存在这样的机会时,最好在这些调用之间进行回调。例如,像listview和treeview这样的常见控件确实通过发送NM_CUSTOMDRAW通知来提供这种机会,但是编辑控件并没有那么灵活。

当然,如果您完全处理绘画,那么任务会容易得多,在这种情况下,您只需自己处理消息,而无需过多考虑标准处理程序。

一个运行良好的编辑特定解决方案(意味着它与标准控制实现兼容,这对其他控制不一定是正确的;它也适用于简单的编辑控制,而不是丰富的编辑控制)是:

  1. 提供您自己的WM_PAINT处理程序
  2. 调用DefWindowProc,让控件使用自己的BeginPaintEndPaint进行标准绘制
  3. 然后在处理程序中继续,使用GetDCReleaseDC(与BeginPaintEndPaint相反)获取HDC,并使用自定义更新获得的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;
}

另请参阅:

  • Win32:如何自定义绘制Edit控件
  • WTL中的自定义编辑控件完全不调用DefWindowProc进行绘画

最新更新