概述:
CQsCheckBox基础与 CButton,通过自绘来实现 实现check Box的效果,通过BST_CHECKED 属性来实现。
代码实现如下:
#pragma once;
#include "QsInclude.h"
#define TXTMAX 512
#define QS_CHK_SYSYSTEM 0x00000001
#define QS_CHK_OWNERDRAW 0x00000002
class CQsCheckBox:
public CWindowImpl<CQsCheckBox, CButton>,
public CImageMgrCtrlBase< CQsCheckBox>,
public COwnerDraw< CQsCheckBox >
{
typedef CWindowImpl< CQsCheckBox, CButton > theBaseClass;
typedef CImageMgrCtrlBase< CQsCheckBox> theImageCtrlBaseClass;
Image *m_pCurImage;
Image *m_pLastImage;
volatile int m_nCheck;
volatile bool m_bMouseDown;
StringAlignment m_eAlignment;
Color m_enableColor;
Color m_unenableColor;
DWORD m_dwStyle;
BOOL m_bunifyfont;
public:
BEGIN_MSG_MAP( CQsCheckBox )
MESSAGE_HANDLER( WM_ERASEBKGND, OnEraseBKGnd )
MESSAGE_HANDLER( WM_LBUTTONUP, OnLButtonUp )
MESSAGE_HANDLER( WM_MOUSELEAVE, OnMouseLeave )
MESSAGE_HANDLER( WM_MOUSEMOVE, OnMouseMove )
MESSAGE_HANDLER( BM_SETCHECK, OnSetCheck )
MESSAGE_HANDLER( BM_GETCHECK, OnGetCheck )
CHAIN_MSG_MAP_ALT( COwnerDraw< CQsCheckBox >, 1 )
CHAIN_MSG_MAP( theImageCtrlBaseClass )
DEFAULT_REFLECTION_HANDLER()
END_MSG_MAP()
CQsCheckBox():
m_bMouseDown( false ),
m_pCurImage( NULL ),
m_pLastImage( NULL ),
m_enableColor(255, 0, 0, 0),
m_unenableColor(255, 128, 128, 128),
m_nCheck( 0 )
{
m_uFirstPos = CONTROL_CHK_FIRST;
m_uLastPos = CONTROL_CHK_LAST;
SetAlignment( StringAlignmentNear );
m_dwStyle = QS_CHK_OWNERDRAW;
m_bunifyfont = FALSE;
}
virtual ~CQsCheckBox()
{
}
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)
{
return theBaseClass::Create( hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
}
void SetBtnUnifFont(BOOL bunifyfont)
{
m_bunifyfont = bunifyfont;
}
void SetAlignment( StringAlignment align )
{
m_eAlignment = align;
}
StringAlignment GetAlignment( void )
{
return m_eAlignment;
}
void SetQSWindowsStyle(DWORD dwstyle)
{
m_dwStyle = dwstyle;
}
BOOL SubclassWindow( HWND hWnd )
{
m_nCheck = (int)::SendMessage( hWnd, BM_GETCHECK, 0, 0 );
BOOL bRet = theBaseClass::SubclassWindow( hWnd );
if(m_dwStyle&QS_CHK_OWNERDRAW)
{
UINT nBS = GetButtonStyle();
SetButtonStyle( nBS | BS_OWNERDRAW );
}
return bRet;
}
UINT GetState( void )
{
LONG lStyle = GetWindowLong( GWL_STYLE );
BOOL bIsDisabled = ( ( lStyle & WS_DISABLED ) != 0 );
BOOL bIsChecked = ( GetCheck() == BST_CHECKED );
UINT uStateFont = CONTROL_BTN_NORMAL;
BOOL bIsFocused = ( ::GetFocus() == m_hWnd );
if( bIsDisabled )
{
if( bIsChecked)
{
uStateFont = CONTROL_CHK_DISCHECKED;
}
else
{
uStateFont = CONTROL_CHK_DISUNCHECK;
}
}
else
{
if( bIsChecked )
{
if(bIsFocused)
{
uStateFont = CONTROL_CHK_FOUCS_CHECKED;
}
else
{
uStateFont = CONTROL_CHK_CHECKED;
}
}
else
{
if(bIsFocused)
{
uStateFont = CONTROL_CHK_FOUCS_UNCHECK;
}
else
{
uStateFont = CONTROL_CHK_UNCHECK;
}
}
}
return uStateFont;
}
UINT GetCheckStateFont( void )
{
LONG lStyle = GetWindowLong( GWL_STYLE );
BOOL bIsDisabled = ( ( lStyle & WS_DISABLED ) != 0 );
BOOL bIsChecked = ( GetCheck() == BST_CHECKED );
UINT uStateFont = CONTROL_CHK_CHECKED;
BOOL bIsFocused = ( ::GetFocus() == m_hWnd );
if(m_bunifyfont == TRUE)
{
return uStateFont;
}
if( bIsDisabled )
{
if( bIsChecked)
{
uStateFont = CONTROL_CHK_DISCHECKED;
}
else
{
uStateFont = CONTROL_CHK_DISUNCHECK;
}
}
else
{
if( bIsChecked )
{
if(bIsFocused)
{
uStateFont = CONTROL_CHK_CHECKED;
}
else
{
uStateFont = CONTROL_CHK_CHECKED;
}
}
else
{
if(bIsFocused)
{
uStateFont = CONTROL_CHK_UNCHECK;
}
else
{
uStateFont = CONTROL_CHK_UNCHECK;
}
}
}
return uStateFont;
}
HFONT GetTextFont( void )
{
return GetStateFont( GetCheckStateFont() );
}
void SetEnableColor(Color enableColor)
{
m_enableColor = enableColor;
}
void SetUnEnableColor(Color unenableColor)
{
m_unenableColor = unenableColor;
}
public:
void GetTextImageRect( RECT* lpTextRect, RECT* lpImageRect )
{
CRect rtCtrl;
GetClientRect( &rtCtrl );
Image *pImg = GetCurrentImage( );
HFONT hFont = GetTextFont( );
HDC hDC = ::GetDC( m_hWnd );
Graphics graph( hDC );
Gdiplus::Font fnt( hDC, hFont );
RectF rtfText( 0, 0,(REAL)rtCtrl.Width(), (REAL)rtCtrl.Height() );
RectF boundText( 0.0, 0.0, 0.0, 0.0 );
TCHAR szTxt[TXTMAX] = {'0'};
GetWindowText( szTxt, TXTMAX );
StringFormat strfmtText;
StringAlignment align = GetAlignment();
strfmtText.SetAlignment( align );
strfmtText.SetLineAlignment( StringAlignmentNear );
if( szTxt[0] != 0 )
{
graph.MeasureString( szTxt, (int)_tcslen(szTxt),&fnt, rtfText, &strfmtText,&boundText );
}
int nImgWidth = 0;
int nImgHeight = 0;
if ( pImg != NULL )
{
nImgWidth = pImg->GetWidth();
nImgHeight = pImg->GetHeight();
}
if( StringAlignmentFar == GetAlignment() )
{
lpTextRect->left = (LONG)(rtCtrl.Width() - boundText.Width);
lpTextRect->top = 0;
lpTextRect->right = rtCtrl.Width();
lpTextRect->bottom = rtCtrl.Height();
int ytmp = rtCtrl.Height() - nImgHeight;
lpImageRect->left = lpTextRect->left - nImgWidth - 5 ;
lpImageRect->top = ( ytmp < 0 ? 0 : ytmp ) / 2;
lpImageRect->right = lpImageRect->left + nImgWidth;
lpImageRect->bottom = lpImageRect->top + nImgHeight;
}
else if( StringAlignmentCenter == GetAlignment() )
{
int nTotalWidth = (int)(nImgWidth + 10 + boundText.Width);
int nLeft = ( rtCtrl.Width() - nTotalWidth ) / 2;
nLeft = nLeft < 0 ? 0: nLeft;
int ytmp = rtCtrl.Height() - nImgHeight;
lpImageRect->left = nLeft;
lpImageRect->top = ( ytmp < 0 ? 0 : ytmp ) / 2;
lpImageRect->right = lpImageRect->left + nImgWidth;
lpImageRect->bottom = lpImageRect->top + nImgHeight;
lpTextRect->left = lpImageRect->right + 5;
lpTextRect->top = 0;
lpTextRect->right = (LONG)(lpTextRect->left + boundText.Width + 2);
lpTextRect->bottom = rtCtrl.Height();
}
else
{
int ytmp = (int)(rtCtrl.Height() - nImgHeight);
lpImageRect->left = 0;
lpImageRect->top = ( ytmp < 0 ? 0 : ytmp ) / 2;
lpImageRect->right = lpImageRect->left + nImgWidth;
lpImageRect->bottom = lpImageRect->top + nImgHeight;
lpTextRect->left = lpImageRect->right + 5;
lpTextRect->top = 0;
lpTextRect->right = (LONG)rtCtrl.right;
lpTextRect->bottom = rtCtrl.Height();
}
graph.ReleaseHDC( hDC );
ReleaseDC( hDC );
DeleteObject( hFont );
}
void DrawItem( LPDRAWITEMSTRUCT lpdis )
{
if(m_dwStyle&QS_CHK_SYSYSTEM)
{
return ;
}
int width = lpdis->rcItem.right - lpdis->rcItem.left;
int height = lpdis->rcItem.bottom - lpdis->rcItem.top;
WTL::CDC memDC;
memDC.CreateCompatibleDC( lpdis->hDC );
WTL::CBitmap memBitmap;
memBitmap.CreateCompatibleBitmap( lpdis->hDC, width, height );
HBITMAP hOldBmp = memDC.SelectBitmap( memBitmap );
memDC.SetBkMode( TRANSPARENT );
::SendMessage( GetParent(), WM_DRAWBKGNDUI, ( WPARAM )memDC.m_hDC, ( LPARAM )lpdis->hwndItem );
DrawButton( memDC.m_hDC, lpdis->rcItem );
::BitBlt( lpdis->hDC, 0, 0, width, height, memDC.m_hDC, 0, 0, SRCCOPY );
memDC.SelectBitmap( hOldBmp );
memBitmap.DeleteObject();
memDC.DeleteDC();
}
protected:
LRESULT OnSetCheck( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& )
{
if(m_dwStyle&QS_CHK_SYSYSTEM)
{
return DefWindowProc(uMsg, wParam, lParam);
}
switch( wParam )
{
case BST_CHECKED:
case BST_INDETERMINATE:
m_nCheck = BST_CHECKED;
break;
default:
m_nCheck = BST_UNCHECKED;
break;
}
Invalidate();
return 0;
}
LRESULT OnGetCheck( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& )
{
if(m_dwStyle&QS_CHK_SYSYSTEM)
{
return DefWindowProc(uMsg, wParam, lParam);
}
return m_nCheck;
}
LRESULT OnLButtonDown( UINT , WPARAM , LPARAM , BOOL& bHandled )
{
m_bMouseDown = true;
bHandled = FALSE;
return 0;
}
LRESULT OnMouseMove( UINT , WPARAM , LPARAM , BOOL& bHandled )
{
if(m_dwStyle&QS_CHK_SYSYSTEM)
{
return TRUE;
}
if( m_pCurImage != GetImage( CONTROL_BTN_MOUSEIN ) )
{
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.hwndTrack = m_hWnd;
tme.dwFlags = TME_LEAVE;
TrackMouseEvent(&tme);
}
bHandled = FALSE;
return 0;
}
LRESULT OnMouseLeave( UINT , WPARAM , LPARAM , BOOL& bHandled )
{
if(m_dwStyle&QS_CHK_SYSYSTEM)
{
return TRUE;
}
bHandled = FALSE;
return 0;
}
LRESULT OnLButtonUp( UINT , WPARAM , LPARAM , BOOL )
{
m_bMouseDown = false;
SendMessage(WM_KILLFOCUS,0,0);
int nCtrlID = GetDlgCtrlID( );
SetCheck( !GetCheck() );
Invalidate();
::SendMessage( GetParent(), WM_COMMAND, (WPARAM)nCtrlID,LPARAM(m_hWnd));
return 0;
}
LRESULT OnEraseBKGnd( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& )
{
if(m_dwStyle&QS_CHK_SYSYSTEM)
{
return DefWindowProc(uMsg, wParam, lParam);
}
return 0;
}
LRESULT OnClicked(WORD , WORD , HWND , BOOL& )
{
if(m_dwStyle&QS_CHK_SYSYSTEM)
{
return 0;
}
SetCheck( !GetCheck() );
Invalidate();
return 0;
}
private:
UINT GetButtonTextFormat(const LONG lStyle)
{
UINT uFormat = DT_SINGLELINE;
if ( (lStyle & BS_CENTER)==BS_CENTER )
uFormat |= DT_CENTER;
else if ( (lStyle & BS_RIGHT)==BS_RIGHT )
uFormat |= DT_RIGHT;
else if ( (lStyle & BS_LEFT) == BS_LEFT )
uFormat |= DT_LEFT;
else
uFormat |= DT_LEFT;
if ( (lStyle & BS_VCENTER ) == BS_VCENTER )
uFormat |= DT_VCENTER;
else if ( (lStyle & BS_TOP)==BS_TOP )
uFormat |= DT_TOP;
else if ( (lStyle & BS_BOTTOM)==BS_BOTTOM )
uFormat |= DT_BOTTOM;
else
uFormat |= DT_VCENTER;
return uFormat;
}
Image* GetCurrentImage( void )
{
Image *pImg = NULL;
UINT uStateFont = GetState();
pImg = GetImage( uStateFont );
if( pImg == NULL )
{
if( m_pCurImage != NULL )
{
pImg = m_pCurImage;
}
else
{
pImg = GetImage( CONTROL_BTN_NORMAL );
}
}
return pImg;
}
void DrawButton( HDC hDC, RECT )
{
HDC hdc = hDC;
SetBkMode( hdc, TRANSPARENT );
LONG lStyle = GetWindowLong( GWL_STYLE );
BOOL bIsDisabled = ( ( lStyle & WS_DISABLED ) != 0 );
CRect rc;
GetWindowRect( rc );
POINT pt;
GetCursorPos( &pt );
Image *pImg = GetCurrentImage( );
if( m_pCurImage != pImg )
{
if( m_pCurImage != NULL)
{
m_pLastImage = m_pCurImage;
}
else
{
m_pLastImage = pImg;
}
m_pCurImage = pImg;
}
CRect rtImage, rtText;
GetTextImageRect( rtText, rtImage );
if( m_pCurImage != NULL )
{
Graphics graph( hDC );
graph.SetPageScale( 1.0 );
graph.SetPageUnit( UnitPixel );
graph.SetSmoothingMode( SmoothingModeNone );
graph.DrawImage( m_pCurImage, rtImage.left, rtImage.top, rtImage.Width(), rtImage.Height() );
graph.ReleaseHDC( hDC );
}
TCHAR szTxt[TXTMAX] = {0};
GetWindowText( szTxt, TXTMAX );
HFONT hFont = GetTextFont( );
WTL::CDCHandle dc( hDC );
Graphics graph(dc.m_hDC);
Gdiplus::Font fnt( dc.m_hDC, hFont );
StringFormat strfmt;
strfmt.SetAlignment(StringAlignmentCenter);
strfmt.SetLineAlignment(StringAlignmentCenter);
CRect rtf( rtText.left,rtText.top,rtText.right,rtText.Height());
if( bIsDisabled )
{
HFONT hOldFont = dc.SelectFont( hFont );
dc.SetTextColor(m_unenableColor.ToCOLORREF());
dc.DrawText( szTxt, -1, &rtf, GetButtonTextFormat( lStyle ) );
dc.SelectFont( hOldFont );
}
else
{
HFONT hOldFont = dc.SelectFont( hFont );
dc.SetTextColor(m_enableColor.ToCOLORREF());
dc.DrawText( szTxt, -1, &rtf, GetButtonTextFormat( lStyle ) );
dc.SelectFont( hOldFont );
}
graph.ReleaseHDC(dc.m_hDC);
DeleteObject( hFont );
}
};
|