程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> 關於VC++ >> 關於CEdit控件的透明

關於CEdit控件的透明

編輯:關於VC++

前幾天和風在這裡討論關於CEdit控件的透明問題。主要的目的就是要做一個有圖形背景的Edit控件,經過一番努,終於做出了一個還算象樣的Edit控件。

做一個透明的Edit控件的主要問題是字符的輸出,在Edit裡輸出的刷新有幾個時機,一個是在接收到鍵盤或鼠標消息的時候 ,還有就是在接收到WM_PAINT消息。刷新的時候也不是全部重畫,所以想通過在繼承的Edit類中處理WM_PAINT消息是行不通的。但是Edit控件自己總是知道怎麼去刷新,因此只要給控件發消息,讓其自己來刷新就可以了。通過使用spy++的得知需要刷新有幾個時機,一個是按鍵的時候,內容變化,另一個是選擇變化的時候,前者Edit控件會接收到GetCtlCode和KeyUp 消息,後者會接收到GetCtlCode和CaptureChange消息或KeyUp消息,因此在GetCtlCode裡調用ReDrawWindow來強迫Edit刷新 整個控件。在ReDrawWindow中通過使用參數RDW_ERASE可以使控件重畫背景,即調用OnEraseBkgnd(CDC* pDC),在該函數中重 畫背景。比較特殊的情況是按住鼠標左鍵並來回拖動鼠標的時候,這時候選擇要改變,接收的消息是MouseMove,為了正 確響應也要處理該消息,但是在每一個MouseMove中都刷新顯示的開銷太大,而且不可避免地有閃爍感,因此只有在鼠標左 鍵按下的時候才刷新顯示。

大概的代碼如下,主要是繼承了一個CEdit的對象CTpEdit,使用的時候可以動態創建,或者采用SubClass的方法。我用的是後者。

class CTESTDLG : public CDialog
{
......
//聲明一個CTpEdit的成員變量
private:
CTpEdit m_tpedit;
};
//在OnInitDialog中Subclass對話框模板中的Edit控件
BOOL CTESTDLG::OnInitDialog()
{
CDialog::OnInitDialog();
m_tpedit.SubclassDlgItem(IDC_EDIT,this);
return TRUE;
}
//在OnCtlColor中設置背景的透明,要改變Edit控件字體的顏色也在這裡
HBRUSH CTESTDLG::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
if((nCtlColor == CTLCOLOR_EDIT) && (pWnd->GetDlgCtrlID()==IDC_EDIT))
{
pDC->SetBkMode(TRANSPARENT); //設置背景透明,這樣,輸出字符的時候就
//是所謂的空心字,而不是有白的底色
pDC->SetTextColor(RGB(255,0,0)); //改變字體的顏色
return HBRUSH(GetStockObject(HOLLOW_BRUSH));
}
return hbr;
}
//CTpEdit對象
class CTpEdit : public CEdit
{
public:
//m_mousedown用來記錄鼠標左鍵是否按下
BOOL m_mousedown;
protected:
//響應如下的消息
//{{AFX_MSG(CTpEdit)
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg UINT OnGetDlgCode();
/

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved