c++ - 如何在默认绘制结果之上的子类控件绘制方法中绘制某些内容?

标签 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. 绘制我在 FileEdit::OnPaint 方法中请求的东西。

我仍然想要通常的绘画程序,但我只想在之后“在上面”添加一些东西。

有什么办法可以实现吗?也许我可以将 PAINTSTRUCT 传递给基本方法?

提前致谢

最佳答案

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

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

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

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

相关文章:

c++ - 如何获取小部件窗口句柄以传递给 Qt 中的 win32 api MessageBox

c++ - Const 变量随 C 中的指针改变

c++ - wstringstream 到 LPCWSTR

c++ - VB6 GUI 在多线程 COM 环境中不工作

c++ - 使用 ATL 覆盖 QueryInterface

c++ - if-else语句无法正常工作的怪异错误

c++ - “Setter”方法不更改属性,但是测试方法输出“test”吗? (以最少的可复制示例重新提交)

c - Windows 虚拟按键代码的所有标识符都以 VK_ 为前缀吗?

c++ - 显示如何向 Opera/Firefox 4 等 Vista 窗框的玻璃部分添加按钮/菜单的示例

asp.net - 在 IIS 上运行的 aspx 代码隐藏中连接到 COM 接口(interface)?