搞了一天终于弄了个完整的编辑框控件出来了,
哎,,,搞界面开发还是有点复杂的。
1 #pragma once 2 3 #include "AdvEdit.h" 4 // CBkgEditBox 5 6 class CBkgEditBox : public CEdit 7 { 8 DECLARE_DYNAMIC(CBkgEditBox) 9 10 public: 11 CBkgEditBox(); 12 virtual ~CBkgEditBox(); 13 14 protected: 15 DECLARE_MESSAGE_MAP() 16 public: 17 afx_msg BOOL OnEraseBkgnd(CDC* pDC); 18 afx_msg void OnSetFocus(CWnd* pOldWnd); 19 afx_msg void OnMouseHover(UINT nFlags, CPoint point); 20 afx_msg void OnMouseLeave(); 21 afx_msg void OnMouseMove(UINT nFlags, CPoint point); 22 afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor); 23 afx_msg HBRUSH CtlColor(CDC* pDC, UINT nCtlColor); 24 afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags); 25 afx_msg void OnKillFocus(CWnd* pNewWnd); 26 27 private: 28 BOOL m_bFirstDraw; // 第一次绘制背景标识 29 Gdiplus::Image *m_pPngBg; // 背景位图资源 30 BOOL m_bHover; // 鼠标是否在编辑框上标识 31 BOOL m_bAllowMouseTrack; // 鼠标移动时是否允许追踪鼠标移动 32 COLORREF m_clrBkgnd; // 默认背景Hover颜色 33 COLORREF m_clrHoverBkgnd; // 默认背景UnHover颜色 34 COLORREF m_clrText; // 字体颜色 35 CString m_strTipStr; // 输入提示信息 36 CBrush m_brhNull; // 空画刷对象 37 CFont* m_pTextFont; // 编辑框字体 38 39 public: 40 BOOL SetBackgndRes( UINT nResourceID, LPCTSTR lpszType=_T("PNG")); 41 void SetGrayTipString(LPCTSTR lpszTipString); 42 void SetTextColor(COLORREF clrText); 43 BOOL SetTextFont(int nHeight = 18, int nWidth = 10, LPCTSTR lpszFaceName = _T("宋体")); 44 BOOL IsEditEmpty(); 45 };
1 // MyEditBox.cpp : 实现文件 2 // 3 4 #include "stdafx.h" 6 #include "BkgEditBox.h" 7 8 9 // CBkgEditBox 10 11 IMPLEMENT_DYNAMIC(CBkgEditBox, CEdit) 12 13 CBkgEditBox::CBkgEditBox() 14 { 15 m_bFirstDraw = TRUE; 16 m_pPngBg = NULL; 17 m_bHover = FALSE; 18 m_bAllowMouseTrack = TRUE; 19 20 m_clrBkgnd = RGB(255,255,255); 21 m_clrHoverBkgnd = RGB(255,255,255); 22 m_clrText = RGB(0,0,0); 23 m_strTipStr = _T(""); 24 25 m_brhNull.CreateStockObject(NULL_BRUSH); 26 m_pTextFont = NULL; 27 } 28 29 CBkgEditBox::~CBkgEditBox() 30 { 31 if (NULL != m_pTextFont) 32 { 33 delete m_pTextFont; 34 m_pTextFont = NULL; 35 } 36 } 37 38 39 BEGIN_MESSAGE_MAP(CBkgEditBox, CEdit) 40 ON_WM_ERASEBKGND() 41 ON_WM_SETFOCUS() 42 ON_WM_MOUSEHOVER() 43 ON_WM_MOUSELEAVE() 44 ON_WM_MOUSEMOVE() 45 ON_WM_CTLCOLOR() 46 ON_WM_CTLCOLOR_REFLECT() 47 ON_WM_CHAR() 48 ON_WM_KILLFOCUS() 49 END_MESSAGE_MAP() 50 51 52 53 // CBkgEditBox 消息处理程序 54 55 56 57 58 BOOL CBkgEditBox::OnEraseBkgnd(CDC* pDC) 59 { 60 // 图片背景与编辑框的距离顶点 61 int nLeftStep,nTopStep,nWidthStep,nHeightStep; 62 nLeftStep = 1; 63 nTopStep = 5; 64 nWidthStep = 2; 65 nHeightStep = 8; 66 CDC* pOldDC = pDC; 67 if (NULL != m_pPngBg) 68 { 69 pDC = GetParent()->GetDC(); 70 CRect rect; 71 GetWindowRect(&rect); 72 this->GetParent()->ScreenToClient(&rect); 73 74 int nWidth = m_pPngBg->GetWidth(); 75 int nHeight = m_pPngBg->GetHeight(); 76 77 // 不是第一次绘制时需要调整位置 78 if (!m_bFirstDraw) 79 { 80 rect.left -= nLeftStep; 81 rect.top -= nTopStep; 82 }else 83 { 84 MoveWindow(rect.left + nLeftStep, rect.top + nTopStep, 85 nWidth - nWidthStep, nHeight - nHeightStep); 86 } 87 88 89 CDC MemDc; 90 MemDc.CreateCompatibleDC(pDC); 91 92 CBitmap bitMemMap; 93 bitMemMap.CreateCompatibleBitmap(pDC, nWidth, nHeight); 94 MemDc.SelectObject(&bitMemMap); 95 96 Gdiplus::Graphics graphics(MemDc.m_hDC); 97 graphics.DrawImage(m_pPngBg, 0, 0, nWidth, nHeight); 98 pDC->BitBlt(rect.left, rect.top, nWidth,nHeight, &MemDc, 0, 0,SRCCOPY); 99 100 bitMemMap.DeleteObject(); 101 MemDc.DeleteDC(); 102 m_bFirstDraw = FALSE; 103 104 pDC = pOldDC; 105 } 106 107 108 109 { 110 111 // 内阴影 112 CBrush brhInnerShadow; 113 if (!m_bHover) 114 { 115 brhInnerShadow.CreateSolidBrush(m_clrBkgnd); 116 }else 117 { 118 brhInnerShadow.CreateSolidBrush(m_clrHoverBkgnd); 119 } 120 121 122 CBrush* pOldBrh = pDC->SelectObject(&brhInnerShadow); 123 pDC->SelectStockObject(NULL_PEN); 124 CRect rcShadow; 125 GetClientRect(&rcShadow); 126 if (NULL != m_pPngBg) 127 { 128 rcShadow.right = rcShadow.left + m_pPngBg->GetWidth() - nWidthStep; 129 rcShadow.bottom = rcShadow.top + m_pPngBg->GetHeight() - nHeightStep; 130 } 131 pDC->Rectangle(&rcShadow); 132 if(NULL!=pOldBrh) 133 { 134 pDC->SelectObject(pOldBrh); 135 } 136 brhInnerShadow.DeleteObject(); 137 this->UpdateWindow(); 138 139 } 140 141 return CEdit::OnEraseBkgnd(pDC); 142 } 143 144 BOOL CBkgEditBox::SetBackgndRes( UINT nResourceID, LPCTSTR lpszType/*=_T("PNG")*/ ) 145 { 146 return G_ImageFromIDResource(nResourceID, lpszType, m_pPngBg); 147 } 148 149 150 void CBkgEditBox::OnMouseHover(UINT nFlags, CPoint point) 151 { 152 m_bHover = TRUE; 153 Invalidate(); 154 155 CEdit::OnMouseHover(nFlags, point); 156 } 157 158 159 void CBkgEditBox::OnMouseLeave() 160 { 161 // Hover结束 162 m_bHover = FALSE; 163 // 重绘背景 164 Invalidate(); 165 166 // 鼠标离开,继续追踪HOVER消息 167 m_bAllowMouseTrack = TRUE; 168 169 //CWnd* pWnd =this->GetParent(); 170 171 //CRect rcTmp; 172 //GetClientRect(rcTmp); 173 //rcTmp.OffsetRect(3, 3); 174 ////InvalidateRect(rcTmp); 175 //this->ClientToScreen(&rcTmp); 176 //pWnd->ScreenToClient(&rcTmp); 177 //pWnd->InvalidateRect(&rcTmp); 178 //pWnd->UpdateWindow(); 179 180 181 182 CEdit::OnMouseLeave(); 183 } 184 185 186 void CBkgEditBox::OnMouseMove(UINT nFlags, CPoint point) 187 { 188 // 默认情况下,窗口是不响应 WM_MOUSELEAVE 和 WM_MOUSEHOVER 消息的, 189 // 所以要使用 _TrackMouseEvent 函数来激活这两个消息 190 // https://msdn.microsoft.com/en-us/library/ms645604 191 192 if (m_bAllowMouseTrack) 193 { 194 TRACKMOUSEEVENT tme; 195 tme.cbSize = sizeof(TRACKMOUSEEVENT); 196 tme.dwFlags = TME_HOVER|TME_LEAVE; 197 tme.hwndTrack = m_hWnd; 198 tme.dwHoverTime = 10; // 超过10ms才会认为HOVER 199 200 _TrackMouseEvent(&tme); 201 m_bAllowMouseTrack = FALSE; 202 } 203 204 CEdit::OnMouseMove(nFlags, point); 205 } 206 207 BOOL CBkgEditBox::IsEditEmpty() 208 { 209 CString strText; 210 GetWindowText(strText); 211 if (strText.IsEmpty()) 212 { 213 return TRUE; 214 } 215 if (strText == m_strTipStr) 216 { 217 return TRUE; 218 } 219 return FALSE; 220 } 221 222 223 HBRUSH CBkgEditBox::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 224 { 225 HBRUSH hbr = CEdit::OnCtlColor(pDC, pWnd, nCtlColor); 226 227 // TODO: 在此更改 DC 的任何特性 228 229 // TODO: 如果默认的不是所需画笔,则返回另一个画笔 230 231 return hbr; 232 } 233 234 HBRUSH CBkgEditBox::CtlColor( CDC* pDC, UINT nCtlColor ) 235 { 236 // 设置透明背景 237 pDC->SetBkMode(TRANSPARENT); 238 239 CString sText; 240 GetWindowText(sText); 241 if (sText == m_strTipStr) 242 { 243 pDC->SetTextColor(RGB(150,150,150)); 244 }else 245 { 246 pDC->SetTextColor(m_clrText); 247 } 248 249 return m_brhNull; 250 } 251 252 253 void CBkgEditBox::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 254 { 255 Invalidate(TRUE); 256 257 CEdit::OnChar(nChar, nRepCnt, nFlags); 258 } 259 260 261 void CBkgEditBox::OnSetFocus(CWnd* pOldWnd) 262 { 263 CEdit::OnSetFocus(pOldWnd); 264 265 CString sText; 266 GetWindowText(sText); 267 if (sText == m_strTipStr) 268 { 269 SetWindowText(_T("")); 270 } 271 Invalidate(TRUE); 272 return ; 273 274 } 275 void CBkgEditBox::OnKillFocus(CWnd* pNewWnd) 276 { 277 CEdit::OnKillFocus(pNewWnd); 278 279 CString sText; 280 GetWindowText(sText); 281 if (_T("") == sText) 282 { 283 SetWindowText(m_strTipStr); 284 } 285 } 286 287 void CBkgEditBox::SetGrayTipString( LPCTSTR lpszTipString ) 288 { 289 m_strTipStr = lpszTipString; 290 291 SetWindowText(lpszTipString); 292 } 293 294 void CBkgEditBox::SetTextColor( COLORREF clrText ) 295 { 296 m_clrText = m_clrText; 297 } 298 299 // https://msdn.microsoft.com/zh-tw/library/vstudio/2ek64h34.aspx 300 BOOL CBkgEditBox::SetTextFont( int nHeight /*= 20*/, int nWidth /*= 12*/, LPCTSTR lpszFaceName /*= _T("宋体")*/ ) 301 { 302 if (NULL != m_pTextFont) 303 { 304 delete m_pTextFont; 305 m_pTextFont = NULL; 306 } 307 m_pTextFont = new CFont; 308 m_pTextFont->CreateFont( 309 nHeight, // nHeight 310 nWidth, // nWidth 311 0, // nEscapement 312 0, // nOrientation 313 FW_NORMAL, // nWeight 314 FALSE, // bItalic 315 FALSE, // bUnderline 316 0, // cStrikeOut 317 ANSI_CHARSET, // nCharSet 318 OUT_DEFAULT_PRECIS, // nOutPrecision 319 CLIP_DEFAULT_PRECIS, // nClipPrecision 320 DEFAULT_QUALITY, // nQuality 321 DEFAULT_PITCH | FF_SWISS, // nPitchAndFamily 322 lpszFaceName); 323 324 this->SetFont(m_pTextFont); 325 return TRUE; 326 }