概述:

CQsEdit 继承CEdit而来,CQsEdit 没有太多的绘制,只是对背景和边框线进行了绘制,并且对输入字符进行处理。

代码实现如下:

#pragma once
#include "UserMessage.h"
#include "QsInclude.h"
#include <atlmisc.h>#define ES_COMBO        (0x00000200)   /* Undocumented. Parent is a combobox */#define ES_AUTOSUGGEST ES_COMBO#define EN_QUERY_SUGGETST_DROP      (0x8000)    // is suggest dropped
#define EN_SUGGETST_DROP_HIDE           (0x8001)
#define EN_SUGGETST_DROP_SHOW           (0x8002)
#define EN_SUGGETST_DROP_SHOW_NEXT      (0x8003)
#define EN_SUGGETST_DROP_SHOW_PRE       (0x8004)//#define WINDOW_CUSTOM_STYLE_MASK      (0xFFFF)
#define EDIT_STYLE_MASK                 WINDOW_CUSTOM_STYLE_MASKtypedef bool (*CharFilter)(wchar_t wch);/* CQsEdit class */class CQsEdit : public CWindowImpl<CQsEdit, CEdit>,public CImageMgrCtrlBase< CQsEdit>
{typedef CWindowImpl< CQsEdit, CEdit > theBaseClass;typedef CImageMgrCtrlBase< CQsEdit> theImageCtrlBaseClass;BOOL          m_bBtnFlag;                     //是否启用清除内容按钮CRect           rcButton;                       //清除内容按钮区域Image         *m_pImage;                      //清除按钮图片volatile bool   m_bDrawBorder;                  //绘制边框标志volatile bool   m_bPassword;                    //密码框标志CString          m_strBkText;                    //输入提示文字WTL::CFont      m_editfont;                     //输入提示文字字体public:DECLARE_WND_SUPERCLASS(_T("QsEdit"), CEdit::GetWndClassName())BEGIN_MSG_MAP( CQsEdit )MESSAGE_HANDLER( WM_KILLFOCUS, OnFocusChanged )MESSAGE_HANDLER( WM_SETFOCUS, OnFocusChanged )MESSAGE_HANDLER( WM_PAINT, OnPaint )MESSAGE_HANDLER( WM_ERASEBKGND, OnEraseBKGnd )//MESSAGE_HANDLER( WM_KEYDOWN, OnKeyDown )MESSAGE_HANDLER( WM_CHAR, OnChar )//MESSAGE_HANDLER( WM_GETDLGCODE, OnGetDlgCode )MESSAGE_HANDLER( WM_KEYDOWN, OnKeydown )CHAIN_MSG_MAP( theImageCtrlBaseClass )DEFAULT_REFLECTION_HANDLER()END_MSG_MAP()/***@method   CQsEdit*@brief    CQsEdit's default constructor.*    *@return   */CQsEdit():m_bBtnFlag( FALSE ),m_bDrawBorder( True ),m_bPassword( false ),m_fnCharFilter(NULL){}/***@method   ~CQsEdit*@brief    CQsEdit's destructor.*    *@return   */virtual ~CQsEdit(){DeleteQSFont();}/***@method   Create*@brief    *    *@param    HWND hWndParent*@param    ATL::_U_RECT rect = NULL*@param    LPCTSTR szWindowName = NULL*@param    DWORD dwStyle = 0*@param    DWORD dwExStyle = 0*@param    ATL::_U_MENUorID MenuOrID = 0U*@param    LPVOID lpCreateParam = NULL*@return   HWND*/HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,DWORD dwStyle = 0, DWORD dwExStyle = 0, ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL){        theBaseClass::Create(hWndParent, rect, szWindowName, dwStyle, dwExStyle, MenuOrID, lpCreateParam);CRect rtClient;//CRect textRect;GetClientRect(&rtClient);rtClient.MoveToXY( 2 * GetEditBorder(), 2 * GetEditBorder() );//GetRect( &textRect );//SetWindowPos( NULL, -1, -1, textRect.Width() + 8, textRect.Height() + 8, SWP_NOMOVE|SWP_NOZORDER );//SetWindowPos( NULL, -1, -1, textRect.Width() , textRect.Height() , SWP_NOMOVE|SWP_NOZORDER );//textRect.MoveToXY( 2, 2 );SetRect( &rtClient );GetRect( &rtClient );return m_hWnd;}/***@method   SubclassWindow*@brief    Use this function to subclass one window*    *@param    HWND hWnd    subclass binding window handle*@return   BOOL success return TRUE, failed return FALSE*/BOOL SubclassWindow( HWND hWnd ){BOOL bRet = theBaseClass::SubclassWindow( hWnd );CRect rtClient;//CRect textRect;GetClientRect(&rtClient);rtClient.MoveToXY( 2 * GetEditBorder(), 2 * GetEditBorder() );//GetRect( &textRect );//SetWindowPos( NULL, -1, -1, textRect.Width() + 8, textRect.Height() + 8, SWP_NOMOVE|SWP_NOZORDER );//SetWindowPos( NULL, -1, -1, textRect.Width() , textRect.Height() , SWP_NOMOVE|SWP_NOZORDER );//textRect.MoveToXY( 2, 2 );SetRect( &rtClient );GetRect( &rtClient );return bRet;}/***@method   EnabledBorder*@brief    Call this function to enable edit's border*    *@param    bool bFlag   True to enable border, false disable border*@return   bool Current flag*/bool EnabledBorder( bool bFlag ){if( m_bDrawBorder != bFlag ){m_bDrawBorder = bFlag;}return m_bDrawBorder;}/***@method   EnabledPassword*@brief    Call this function to enable edit's password mode*    *@param    bool bFlag   True to password mode, false disable password mode*@return   bool*/bool EnabledPassword( bool bFlag ){if( m_bPassword != bFlag ){m_bPassword = bFlag;}return m_bPassword;}/***@method   SetBkText*@brief    Set default text of background*    *@param    LPCTSTR pszText  the text string to set*@return   void*/void SetBkText( LPCTSTR pszText ){m_strBkText = pszText;}/***@method   SetCharFilter*@brief    Set character filter callback function to mask not accept chars*    *@param    CharFilter   NewFilter Callback function to set*@return   CharFilter   Old char filter*/CharFilter SetCharFilter(CharFilter NewFilter){CharFilter oldFilter = m_fnCharFilter;m_fnCharFilter = NewFilter;return oldFilter;}/***@method   DeleteQSFont*@brief       删除字体对象*    *@return   void*/void DeleteQSFont(){if (NULL != m_editfont.m_hFont){m_editfont.DeleteObject();}}/***@method   SetQSFont*@brief     设置文字的大小*    *@param    TCHAR * fontName  字体名称 不得大小32*@param    int lfHeight  字体大小*@param    int lfWeight*@param    BYTE fCharSet*@return   void*/void SetQsFont(LPCTSTR fontName,int lfHeight,int lfWeight = FW_BOLD,BYTE fCharSet = DEFAULT_CHARSET){DeleteQSFont();LOGFONT itemFont;itemFont.lfCharSet = fCharSet;itemFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;itemFont.lfEscapement = 0;memset(itemFont.lfFaceName, 0, LF_FACESIZE);memcpy_s(itemFont.lfFaceName, LF_FACESIZE, fontName, LF_FACESIZE);itemFont.lfHeight = lfHeight;itemFont.lfItalic = FALSE;itemFont.lfOrientation = 0;itemFont.lfOutPrecision = OUT_DEFAULT_PRECIS;itemFont.lfPitchAndFamily = DEFAULT_PITCH | FF_SWISS;itemFont.lfQuality = CLEARTYPE_NATURAL_QUALITY;itemFont.lfStrikeOut = FALSE;itemFont.lfUnderline = FALSE;itemFont.lfWeight = lfWeight;itemFont.lfWidth = 0;m_editfont = ::CreateFontIndirect( &itemFont);SetFont(m_editfont);}/***@method   SetEditStyle*@brief    Set edit control style*    *@param    DWORD    dwNewStyle New edit style*@return   DWORD    Old edit style*/DWORD SetEditStyle(DWORD dwNewStyle){DWORD dwOldStyle = GetStyle();BOOL bSucc;//dwOldStyle = dwNewStyle & EDIT_STYLE_MASK;bSucc = ModifyStyle(dwNewStyle, dwOldStyle);ATLASSERT(bSucc);//dwOldStyle = dwOldStyle & EDIT_STYLE_MASK;return dwOldStyle;}static int GetEditBorder(){return 1;}protected:/***@method   OnChar*@brief    WM_CHAR message handle function*    *@param    UINT uMsg    Message id*@param    WPARAM wParam    word param*@param    LPARAM lParam    LParam*@param    BOOL& bHandled   if message is handled*@return   LRESULT      whether function call is success*/LRESULT OnChar( UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled ){bool bAccept;wchar_t wCh;wCh = wchar_t(wParam);//If is not visible char, always accept it.if (wCh <= ' '){bHandled = FALSE;return 0;}//If have filter, call it firstif (m_fnCharFilter){bAccept = m_fnCharFilter(wchar_t(wParam));if ( !bAccept ){return TRUE;}else{bHandled = FALSE;return FALSE;}}else{bHandled = FALSE;}return 0;}/***@method   OnKeyDown*@brief    WM_KEYDOWN message handle function*    *@param    UINT uMsg    Message id*@param    WPARAM wParam    word VK_*@param    LPARAM lParam    LParam*@param    BOOL& bHandled   if message is handled*@return   LRESULT  whether function call is success*/LRESULT OnKeyDown( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ){bHandled = FALSE;CWindowImpl<CQsEdit, CEdit>* pEdit = this;TCHAR tchKey = (TCHAR)wParam;if ( ( 'A' == tchKey ) || ( 'a' == tchKey ) ){SHORT sCtrlState = GetKeyState( VK_CONTROL );if ( sCtrlState & 0X8000 ){int nLen = GetWindowTextLength( );SetSel( 0, nLen, FALSE );Invalidate();pEdit = NULL;}}if ( VK_RETURN == tchKey ){::SendMessage( GetParent().m_hWnd, WM_EDITRETURN, 0, 0 );pEdit = NULL;}return pEdit != NULL? pEdit->DefWindowProc(uMsg, wParam, lParam): 0;}/***@method   OnFocusChanged*@brief    WM_SETFOCUS message handle function*    *@param    UINT uMsg    Message id*@param    WPARAM wParam    word param*@param    LPARAM lParam    LParam*@param    BOOL& bHandled   if message is handled*@return   LRESULT  whether function call is success*/LRESULT OnFocusChanged( UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled ){Invalidate();bHandled = FALSE;return 0;}/***@method   OnPaint*@brief    WM_PAINT message handle function*    *@param    UINT uMsg    Message id*@param    WPARAM wParam    word param*@param    LPARAM lParam    LParam*@param    BOOL& bHandled   if message is handled*@return   LRESULT  whether function call is success*/LRESULT OnPaint( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/ ){HWND hwnd = GetFocus();int len = GetWindowTextLength();if( ( len > 0 ) || ( hwnd == m_hWnd ) || ( m_strBkText.GetLength() <= 0 ) ){if( !m_bPassword ){return DefWindowProc( uMsg, wParam, lParam );}}WTL::CPaintDC paintDC( m_hWnd );paintDC.SetBkMode( TRANSPARENT );CRect rc;GetRect( rc );//创建内存作图对象WTL::CDC memDC;memDC.CreateCompatibleDC( paintDC.m_hDC );WTL::CBitmap memBitmap;memBitmap.CreateCompatibleBitmap( paintDC.m_hDC, rc.Width(), rc.Height() );HBITMAP hOldBmp = memDC.SelectBitmap( memBitmap );//获得控件当前使用的字体HFONT hFont = GetDefaultFont();//HFONT hFont = m_bkTxtFont.m_hFont;HFONT hOldFont = memDC.SelectFont( hFont );//还原背景memDC.BitBlt( 0, 0, rc.Width(), rc.Height(), paintDC.m_hDC, rc.left, rc.top, SRCCOPY );CRect textRect( 0, 0, rc.Width(), rc.Height() );memDC.SetTextColor( RGB( 128, 128, 128 ) );memDC.DrawText( m_strBkText, m_strBkText.GetLength(), &textRect, DT_LEFT | DT_VCENTER | DT_SINGLELINE);//提交图像paintDC.BitBlt( rc.left, rc.top, rc.Width(), rc.Height(), memDC.m_hDC, 0, 0, SRCCOPY );CFont font = hFont;memDC.SelectFont( hOldFont );memDC.SelectBitmap( hOldBmp );memDC.DeleteDC();memBitmap.DeleteObject();//::DeleteObject( hFont );return 0;}/***@method   OnEraseBKGnd*@brief    WM_ERASEBKGND message handle function*    *@param    UINT uMsg    Message id*@param    WPARAM wParam    word param*@param    LPARAM lParam    LParam*@param    BOOL& bHandled   if message is handled*@return   LRESULT  whether function call is success*/LRESULT OnEraseBKGnd( UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/ ){WTL::CDCHandle bkdc( ( HDC ) wParam );//如果需要绘制边框if( m_bDrawBorder ){CRect rc;GetClientRect( rc );//创建内存作图对象WTL::CDC dc;dc.CreateCompatibleDC( bkdc.m_hDC );WTL::CBitmap memBitmap;memBitmap.CreateCompatibleBitmap( bkdc.m_hDC, rc.Width(), rc.Height() );HBITMAP hOldBmp = dc.SelectBitmap( memBitmap );//还原背景dc.BitBlt( 0, 0, rc.Width(), rc.Height(), bkdc.m_hDC, 0, 0, SRCCOPY );WTL::CPen pen;pen.CreatePen( PS_SOLID, 1, RGB( 255, 255, 255 ) );//画一个淡蓝色的边框HPEN hOldPen = dc.SelectPen( pen );dc.RoundRect( 0, 0, rc.Width(), rc.Height(), 0, 0 );dc.SelectPen( hOldPen );//提交图像bkdc.BitBlt( 0, 0, rc.Width(), rc.Height(), dc.m_hDC, 0, 0, SRCCOPY );dc.SelectBitmap( hOldBmp );dc.DeleteDC();memBitmap.DeleteObject();pen.DeleteObject();}return 0;}/***@method   OnGetDlgCode*@brief    *    *@param    UINT uMsg*@param    WPARAM wParam*@param    LPARAM lParam*@param    BOOL& bHandled*@return   LRESULT*/LRESULT OnGetDlgCode( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/ ){LRESULT lRes;BOOL bDropped;if (lParam && (((LPMSG)lParam)->message == WM_KEYDOWN)){WPARAM wNotify;int vk = (int)((LPMSG)lParam)->wParam;if ( (GetStyle() & ES_AUTOSUGGEST ) && !(GetStyle() & ES_MULTILINE ) && (vk == VK_RETURN || vk == VK_ESCAPE || vk == VK_UP || vk == VK_DOWN) ){bDropped = (BOOL)SendMessageW(GetParent(), WM_COMMAND, EN_QUERY_SUGGETST_DROP, 0);if(vk == VK_UP || vk == VK_DOWN){if (FALSE == bDropped){wNotify = MAKEWPARAM(GetWindowLong(GWL_ID), EN_SUGGETST_DROP_SHOW);}else if( TRUE == bDropped  && vk == VK_DOWN ){wNotify = MAKEWPARAM(GetWindowLong(GWL_ID), EN_SUGGETST_DROP_SHOW_NEXT);}else if( TRUE == bDropped  && vk == VK_UP ){wNotify = MAKEWPARAM(GetWindowLong(GWL_ID), EN_SUGGETST_DROP_SHOW_PRE);}}if(vk == VK_RETURN || vk == VK_ESCAPE){wNotify = MAKEWPARAM(GetWindowLong(GWL_ID), EN_SUGGETST_DROP_HIDE);}SendMessage(GetParent(), WM_COMMAND, wNotify, (LPARAM)m_hWnd);lRes = DLGC_WANTARROWS;}else{lRes = DefWindowProc( uMsg,  wParam,  lParam);}}else{lRes = DefWindowProc( uMsg,  wParam,  lParam);lRes |= DLGC_WANTARROWS | DLGC_WANTTAB | DLGC_WANTALLKEYS | DLGC_WANTMESSAGE | DLGC_HASSETSEL;}return lRes;}/***@method   OnKeydown*@brief    *    *@param    UINT uMsg*@param    WPARAM wParam*@param    LPARAM lParam*@param    BOOL& bHandled*@return   LRESULT*/LRESULT OnKeydown( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ){LRESULT lRes = 0;BOOL bDropped;int nVirtKey = (int) wParam;    // virtual-key code //int lKeyData = lParam;          // key data WPARAM wNotify = 0;int vk = nVirtKey;if ( (GetStyle() & ES_AUTOSUGGEST ) && !(GetStyle() & ES_MULTILINE ) && (vk == VK_RETURN || vk == VK_ESCAPE || vk == VK_UP || vk == VK_DOWN) ){bDropped = (BOOL)SendMessageW(GetParent(), WM_COMMAND, EN_QUERY_SUGGETST_DROP, 0);if(vk == VK_UP || vk == VK_DOWN){if (FALSE == bDropped){wNotify = MAKEWPARAM(GetWindowLong(GWL_ID), EN_SUGGETST_DROP_SHOW);}else if( TRUE == bDropped  && vk == VK_DOWN ){wNotify = MAKEWPARAM(GetWindowLong(GWL_ID), EN_SUGGETST_DROP_SHOW_NEXT);}else if( TRUE == bDropped  && vk == VK_UP ){wNotify = MAKEWPARAM(GetWindowLong(GWL_ID), EN_SUGGETST_DROP_SHOW_PRE);}}if(vk == VK_RETURN || vk == VK_ESCAPE){wNotify = MAKEWPARAM(GetWindowLong(GWL_ID), EN_SUGGETST_DROP_HIDE);}::PostMessage(GetParent(), WM_COMMAND, wNotify, (LPARAM)m_hWnd);bHandled = FALSE;}else{return DefWindowProc( uMsg, wParam, lParam );}return lRes;}private:/***@method   GetEditTextFormat*@brief    Get edit control align style, used by DrawText()*    *@param    const LONG lStyle    The style of edit*@return   UINT text align style*/UINT GetEditTextFormat(const LONG lStyle){UINT uFormat = DT_SINGLELINE;//button上的字必须是一行//x方向if ( (lStyle & ES_CENTER)==ES_CENTER )//x方向,中uFormat |= DT_CENTER;else if ( (lStyle & ES_RIGHT)==ES_RIGHT )//x方向,右uFormat |= DT_RIGHT;else if ( (lStyle & ES_LEFT) == ES_LEFT )//x方向,左uFormat |= DT_LEFT;else//缺省,x中uFormat |= DT_CENTER;return uFormat;}private:CharFilter m_fnCharFilter;         /**< char filter callback function, WM_CHAR handle function will callback to filter chars */CRect        m_rtBkText;
};

WTL 自绘控件库 (CQsEdit)相关推荐

  1. WTL 自绘控件库 (CQsTabCtrl)

    概述: CQsTabCtrl 继承与 CTabCtrl,通过自绘来背景的绘制,以及各种选中状态的的绘制,以及选中和非选中字体的颜色等一些属性. 代码实现如下: #pragma once; #inclu ...

  2. WTL 自绘控件库 (CQSProgressBar)

    概述: CQSProgressBar 进度条,是显示进度控制.但是需要添加自绘属性. 代码实现如下: #pragma once; #pragma warning(disable:4995 4819)# ...

  3. winform checkbox要点击两次_开源C# Winform控件库SunnyUI强力推荐

    本站(https://dotnet9.com)曾介绍过一款Winform开源控件库<HZHControls>,文章发布后不少朋友热情的咨询相关控件库信息,由此看来Winform在大家心中的 ...

  4. 开源C# Winform控件库《SunnyUI》强力推荐

    本站(https://dotnet9.com)曾介绍过一款Winform开源控件库<HZHControls>,文章发布后不少朋友热情的咨询相关控件库信息,由此看来Winform在大家心中的 ...

  5. Github 开源:升讯威 Winform 开源控件库( Sheng.Winform.Controls)

    Github 地址:https://github.com/iccb1013/Sheng.Winform.Controls 本控件库中的代码大约写于10年前(2007年左右),难免有不成熟与欠考虑之处, ...

  6. 如何在WPF中调用C#控件库(HexEdit)

    1 编写一个Hex Edit控件,使用VS2010建立一个类控件库,分别增加两个类文件,一个命名为HexEdit.cs, 一个命名为TextEditControl.cs,具体内容如下所示: 1)Hex ...

  7. MFC自绘控件系列-按钮PNG贴图(GDI+)

    常规的GDI自绘控件仅支持BMP图片,不支持png图片.png图片体积小,支持透明色,可以做圆角界面.自绘控件想要支持PNG图片,需要在MFC工程引入GDI+.需要注意的是MFC工程默认是不支持GDI ...

  8. UI控件库分享:DWZ(j-UI)、LigerUI、Linb

    DWZ(j-UI): 在线演示地址:http://demo.dwzjs.com 在线文档:http://demo.dwzjs.com/doc/dwz-user-guide.pdf DWZ框架Ajax开 ...

  9. 虚拟桌面模拟查找点击自绘控件

    // VDesktopClick.cpp : 定义控制台应用程序的入口点. //#include "stdafx.h" #include <string> #inclu ...

  10. [原创]基于Extjs的开源控件库 - http://extaspnet.codeplex.com/

    ExtAspNet   ExtAspNet - ExtJS based ASP.NET Controls with Full AJAX Support     ExtAspNet是一组专业的Asp.n ...

最新文章

  1. 探索JAVA并发 - 如何减少锁的竞争
  2. px、em、rem、vw、vh、vm、rpx这些单位的
  3. 音视频技术开发周刊 | 216
  4. otl oracle存储过程,OTL调用存储过程/函数及注意事项
  5. 电子书下载:MySQL5权威指南(第3版)
  6. c++歌手类代码_安卓资源ID修改-游戏发行-切包过程中的R类和Public.xml
  7. eureka 客户端服务启动了又失败了_SpringCloud-Eureka(2)
  8. 软件评测师-13.软件测试技术与应用
  9. ubuntu安装中文输入法fcitx
  10. P1957 口算练习题[c++版]
  11. 复试21天Day 20
  12. 12款绝赞的Windows软件,让你的电脑再好用10倍
  13. 学生计算机编程比赛获奖感言,学生技能大赛获奖感言
  14. Windows命令提示符窗口操作命令
  15. 民间文学【0006】
  16. 数据库范式:1NF、2NF、3NF、BCNF
  17. 安全狗获聘福建省网络与信息安全信息通报中心技术支撑单位
  18. 1月初.wang域名总量15强:易名西数阿里云稳居三甲
  19. 计算机组成--PC和IP的区别
  20. 彼岸夏花(一个爱与救赎的凄美故事)

热门文章

  1. k64 datasheet学习笔记1---概述
  2. 关于雨林木风版的linux操作系统ymlf_os_3.0
  3. android 支付宝快捷支付
  4. html获取当前ip地址_IP地址精准查询
  5. 关于SQL server 2012无法打开物理文件“某某某”,操作系统错误5 :(拒绝访问)。(Microsoft SQL Server,错误 5120)
  6. 锂电池充电——充电保护电路
  7. 使用USB充电的5号电池
  8. 父级fixed_子元素使用position:fixed,导致他的宽度不能和父元素保持一致的解决方案...
  9. 武大2020/4/15-关于选派全日制在校生2020/2021学年秋季赴部分欧洲高校交流学习的通知(三)
  10. Flutter 2.8 更新详解