关于CEdit控件的透明(重绘)

Posted 朝闻道

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于CEdit控件的透明(重绘)相关的知识,希望对你有一定的参考价值。

摘自:http://www.jcwcn.com/html/VC/10_19_51_12.htm

 

 

做一个透明的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的方法。我用的是后者。

 

 

[cpp] view plain copy
 
 print?
  1. class CTESTDLG : public CDialog   
  2.   
  3. {   
  4.   
  5. ......   
  6.   
  7. //声明一个CTpEdit的成员变量   
  8.   
  9. private:   
  10.   
  11. CTpEdit m_tpedit;   
  12.   
  13. };   
  14.   
  15.     
  16.   
  17. //在OnInitDialog中Subclass对话框模板中的Edit控件   
  18.   
  19. BOOL CTESTDLG::OnInitDialog()   
  20.   
  21. {   
  22.   
  23. CDialog::OnInitDialog();   
  24.   
  25. m_tpedit.SubclassDlgItem(IDC_EDIT,this);   
  26.   
  27. return TRUE;   
  28.   
  29. }   
  30.   
  31.     
  32.   
  33. //在OnCtlColor中设置背景的透明,要改变Edit控件字体的颜色也在这里   
  34.   
  35.     
  36.   
  37. HBRUSH CTESTDLG::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)   
  38.   
  39. {   
  40.   
  41. HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);   
  42.   
  43.     
  44.   
  45. if((nCtlColor == CTLCOLOR_EDIT) && (pWnd->GetDlgCtrlID()==IDC_EDIT))   
  46.   
  47. {   
  48.   
  49. pDC->SetBkMode(TRANSPARENT); //设置背景透明,这样,输出字符的时候就   
  50.   
  51. //是所谓的空心字,而不是有白的底色   
  52.   
  53. pDC->SetTextColor(RGB(255,0,0)); //改变字体的颜色   
  54.   
  55. return HBRUSH(GetStockObject(HOLLOW_BRUSH));   
  56.   
  57. }   
  58.   
  59.     
  60.   
  61. return hbr;   
  62.   
  63. }   
  64.   
  65.     
  66.   
  67. //CTpEdit对象   
  68.   
  69.     
  70.   
  71. #ifndef _CCOLOR_EDIT_H_   
  72.   
  73. #define _CCOLOR_EDIT_H_   
  74.   
  75.     
  76.   
  77. class CTpEdit : public CEdit   
  78.   
  79. {   
  80.   
  81. public:   
  82.   
  83. //m_mousedown用来记录鼠标左键是否按下   
  84.   
  85. BOOL m_mousedown;   
  86.   
  87. protected:   
  88.   
  89. //响应如下的消息   
  90.   
  91. //{{AFX_MSG(CTpEdit)   
  92.   
  93. afx_msg BOOL OnEraseBkgnd(CDC* pDC);   
  94.   
  95. afx_msg void OnMouseMove(UINT nFlags, CPoint point);   
  96.   
  97. afx_msg void OnLButtonDown(UINT nFlags, CPoint point);   
  98.   
  99. afx_msg void OnLButtonUp(UINT nFlags, CPoint point);   
  100.   
  101. afx_msg UINT OnGetDlgCode();   
  102.   
  103. //}}AFX_MSG   
  104.   
  105. DECLARE_MESSAGE_MAP()   
  106.   
  107. };   
  108.   
  109.     
  110.   
  111. //{{AFX_INSERT_LOCATION}}   
  112.   
  113.     
  114.   
  115. #endif   
  116.   
  117. //CTpEdit的消息响应函数如下   
  118.   
  119. #include "stdafx.h"   
  120.   
  121. #include "ColorEdit.h"   
  122.   
  123. //画背景图   
  124.   
  125. BOOL CTpEdit::OnEraseBkgnd(CDC* pDC)   
  126.   
  127. {   
  128.   
  129. //得到Edit控件的外框,即背景区域   
  130.   
  131. RECT updatarect;   
  132.   
  133. GetClientRect(&updatarect);   
  134.   
  135. //画背景,我画的是一个黄色的矩形   
  136.   
  137. CBrush newBrush;   
  138.   
  139. newBrush.CreateSolidBrush(RGB(255,255,200));   
  140.   
  141. CBrush * oldBrush = pDC->SelectObject(&newBrush);   
  142.   
  143. pDC->Rectangle(&updatarect);   
  144.   
  145. pDC->SelectObject(oldBrush);   
  146.   
  147. return TRUE;   
  148.   
  149. }   
  150.   
  151.     
  152.   
  153. //强迫Edit控件擦除背景,重写字符   
  154.   
  155. UINT CTpEdit::OnGetDlgCode()   
  156.   
  157. { RedrawWindow(NULL, NULL,RDW_INVALIDATE | RDW_ERASE );   
  158.   
  159. return CEdit::OnGetDlgCode();   
  160.   
  161. }   
  162.   
  163. //记录鼠标左键是否按下   
  164.   
  165. void CTpEdit::OnLButtonDown(UINT nFlags, CPoint point)   
  166.   
  167. {   
  168.   
  169. m_mousedown = TRUE;   
  170.   
  171. SetCapture();   
  172.   
  173. CEdit::OnLButtonDown(nFlags, point);   
  174.   
  175. }   
  176.   
  177.     
  178.   
  179. void CTpEdit::OnLButtonUp(UINT nFlags, CPoint point)   
  180.   
  181. {   
  182.   
  183. if(m_mousedown)   
  184.   
  185. ReleaseCapture();   
  186.   
  187. m_mousedown = FALSE;   
  188.   
  189. CEdit::OnLButtonUp(nFlags, point);   
  190.   
  191. }   
  192.   
  193.     
  194.   
  195. //如果左键按下并且拖动鼠标就要刷新显示   
  196.   
  197. void CTpEdit::OnMouseMove(UINT nFlags, CPoint point)   
  198.   
  199. {   
  200.   
  201. if(m_mousedown)   
  202.   
  203. RedrawWindow(NULL, NULL,RDW_INVALIDATE | RDW_ERASE );   
  204.   
  205. CEdit::OnMouseMove(nFlags, point);   
  206.   
  207. }   
  208.   
  209. //初始化成员变量   
  210.   
  211. CTpEdit::CTpEdit()   
  212.   
  213. {   
  214.   
  215. m_mousedown=FALSE;   
  216.   
  217. }    
 
http://blog.csdn.net/witch_soya/article/details/6889970

以上是关于关于CEdit控件的透明(重绘)的主要内容,如果未能解决你的问题,请参考以下文章

自行实现透明的控件如Panel GroupBox(使用不需要重绘父控件的效果,一切都因为窗口有了WS_EX_TRANSPARENT属性)

单击控件时在MFC中选择CEdit控件的内容

CEdit控件[转]

小 CEdit 控件的 CSpinButtonCtrl 绘图问题

CEdit控件的相关用法

WinForm里的用户自定义控件如何半透明(急急)