2017-02-11 155 views
1

我目前正在嘗試在我的應用程序中繼承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); 
}; 

我paint方法是這樣的:

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到一個基本的方法?

在此先感謝

+0

可能的選項:處理'WM_PAINT'在你的子類處理程序中重建你需要的'PAINTSTRUCT'部分,然後調用超類的'OnPaint()'(我不確定如何用ATL/WTL,對不起),然後使用'GetDC()'做額外的繪圖?對於PAINTSTRUCT的字段,hdc來自GetDC(),rcPaint來自GetUpdateRect()。這個*不應該*有任何不良影響,除非'EndPaint()'在做一些魔術(除了刪除更新rect之外)...?有可能是一種鉤入WTL的方式,我不知道;如果沒有,這將是一個純粹的Win32最後的手段。 – andlabs

+0

也不確定是否應該在超類處理程序運行之前調用'GetDC()',因爲我的評論似乎表明。我個人不會,但是... – andlabs

回答

1

定製WM_PAINT處理最徹底的方法是找到一種方法來插入你的代碼中BeginPaintEndPaint對中間。標準控制處理程序有它自己的調用,所以當這種機會存在時,最好在這些調用之間進行回調。例如,諸如listview和treeview之類的常見控件通過發送NM_CUSTOMDRAW通知來提供此機會,但是編輯控件並不那麼靈活。

如果您完全處理繪畫,那麼這個任務當然會容易得多,在這種情況下,您只需自己處理消息,而不必過多地考慮標準處理程序。

的具體編輯解決方案,效果很好(這意味着它與標準控制實現,這並不一定是其他控件真正兼容;它也是簡單的編輯控件,而不是豐富的編輯控件)是:

  1. 提供自己WM_PAINT處理
  2. 呼叫DefWindowProc爲了讓控制標準做畫有自己的BeginPaintEndPaint
  3. 然後繼續在你的處理器使用越來越HDC 0和ReleaseDC(與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; 
} 

參見: