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

时间:2017-02-11 12:48:27

标签: c++ winapi atl wtl

我目前正在尝试在我的应用程序中继承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. ,请浏览默认的绘图程序
  3. FileEdit::OnPaint - 方法。
  4. 中绘制我要求的内容

    我仍然想要通常的绘画例程,但我只是想在之后添加一些“on top”。

    有没有办法实现这个目标?也许我可以将PAINTSTRUCT传递给基本方法?

    提前致谢

1 个答案:

答案 0 :(得分:1)

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

如果你完全处理这个画面,那么任务当然要容易得多,在这种情况下你只需要自己处理这个消息而不必过多考虑标准处理程序。

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

  1. 提供您自己的WM_PAINT处理程序
  2. 致电DefWindowProc让控件使用自己的BeginPaintEndPaint
  3. 进行标准绘画
  4. 然后使用HDCGetDC(而不是ReleaseDCBeginPaint)获取EndPaint并使用您的更新获得的DC,继续使用您的处理程序自定义。
  5. 子类编辑控件的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;
    }
    

    另见: