搞了一天终于弄了个完整的编辑框控件出来了,
哎,,,搞界面开发还是有点复杂的。
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 }else117 {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/ms645604191 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才会认为HOVER199 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 }else245 {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.aspx300 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, // nHeight310 nWidth, // nWidth311 0, // nEscapement312 0, // nOrientation313 FW_NORMAL, // nWeight314 FALSE, // bItalic315 FALSE, // bUnderline316 0, // cStrikeOut317 ANSI_CHARSET, // nCharSet318 OUT_DEFAULT_PRECIS, // nOutPrecision319 CLIP_DEFAULT_PRECIS, // nClipPrecision320 DEFAULT_QUALITY, // nQuality321 DEFAULT_PITCH | FF_SWISS, // nPitchAndFamily322 lpszFaceName);323 324 this->SetFont(m_pTextFont);325 return TRUE;326 }