概述:
CQsStatic 继承与CStatic,主要支持控件的自绘,文本的颜色、文本大小等属性,并且支持底图背景和鼠标进入与鼠标移出等相关操作等。
CQsStatic 实现如下:
#pragma once;
#include "QsInclude.h"
#include "UserMessage.h"
#include "UiPublicDefine.h"
typedef enum
{
E_SizeAdjustStyl_No = 0,
E_SizeAdjustStyl_Left,
E_SizeAdjustStyl_Center,
E_SizeAdjustStyl_Right
} enSizeAdjustStyle;
class CQsStatic :
public CWindowImpl<CQsStatic, CStatic>,
public CImageMgrCtrlBase< CQsStatic>
{
std::vector< Image* > m_vtImage;
volatile bool m_bMouseTrack;
Image* m_pImageMoseIn;
UINT m_nActiveFrameNo;
UINT m_nTotalFrames;
UINT m_nInterval;
UINT m_nDisTimer;
UINT m_uFormat;
BOOL m_isDrawEdge;
Color m_EdgeClr;
Color m_LineClr;
int m_leftspace;
int m_rightspace;
int m_topspace;
int m_bottomspace;
BOOL m_bReturn;
enSizeAdjustStyle m_eSizeAdjustStyle;
typedef CWindowImpl< CQsStatic, CStatic > theBaseClass;
typedef CImageMgrCtrlBase< CQsStatic> theImageCtrlBaseClass;
public:
BEGIN_MSG_MAP( CQsStatic )
MESSAGE_HANDLER( WM_PAINT, OnPaint )
MESSAGE_HANDLER( WM_TIMER, OnTimer )
MESSAGE_HANDLER( WM_TIMER, OnDestroy )
MESSAGE_HANDLER( WM_MOUSELEAVE, OnMouseLeave )
MESSAGE_HANDLER( WM_MOUSEMOVE, OnMouseMove )
CHAIN_MSG_MAP( theImageCtrlBaseClass )
DEFAULT_REFLECTION_HANDLER()
END_MSG_MAP()
CQsStatic() :
m_nActiveFrameNo( 0 ),
m_nTotalFrames( 0 ),
m_nInterval( 5000 ),
m_nDisTimer( 0 )
{
m_bMouseTrack = TRUE;
m_uFirstPos = CONTROL_STA_FIRST;
m_uLastPos = CONTROL_STA_LAST;
m_uFormat = DT_SINGLELINE|DT_LEFT;
m_isDrawEdge = FALSE;
m_EdgeClr = Color(128, 255, 255, 255);
m_LineClr = Color(200, 182, 164, 183);
m_pImageMoseIn = NULL;
m_leftspace = 0;
m_rightspace = 0;
m_topspace = 0;
m_bottomspace = 0;
m_eSizeAdjustStyle = E_SizeAdjustStyl_No;
m_bReturn = FALSE;
}
virtual ~CQsStatic()
{
if(m_pImageMoseIn != NULL)
{
delete m_pImageMoseIn;
}
}
BOOL SubclassWindow( HWND hWnd )
{
if( m_nDisTimer > 0 )
{
KillTimer( m_nDisTimer );
m_nDisTimer = 0;
}
BOOL bRet = theBaseClass::SubclassWindow( hWnd );
if( m_nTotalFrames > 1 )
{
m_nDisTimer = (UINT)SetTimer( 1001, m_nInterval );
}
ModifyStyleEx( 0, WS_EX_TRANSPARENT );
return bRet;
}
void SetWindowTextEx(LPCTSTR lpszString)
{
SetRedraw(FALSE);
SetWindowText(lpszString);
SetRedraw(TRUE);
Invalidate(FALSE);
}
void SetbReturn(BOOL bRetrun)
{
m_bReturn = bRetrun;
}
BOOL SetWindowText(LPCTSTR lpszString) throw()
{
ATLASSERT(::IsWindow(m_hWnd));
BOOL bRet = ::SetWindowText(m_hWnd, lpszString);
AdjustSize();
return bRet;
}
void SetSizeAdjustStyle( enSizeAdjustStyle eStyle )
{
m_eSizeAdjustStyle = eStyle;
}
void AdjustSize( void )
{
if ( E_SizeAdjustStyl_No == m_eSizeAdjustStyle )
{
return;
}
WTL::CDC paintDC( ::GetDC(m_hWnd) );
Graphics graph( paintDC.m_hDC);
CRect rtStatic;
GetWindowRect(&rtStatic);
GetParent().ScreenToClient( &rtStatic );
RectF rtfTitle( 0, 0, 10000, 10 );
HFONT hFont = GetStateFont( CONTROL_STA_NORMAL );
Font font( paintDC.m_hDC, hFont );
StringFormat strfmtTitle;
strfmtTitle.SetAlignment( StringAlignmentNear );
strfmtTitle.SetLineAlignment( StringAlignmentNear );
RectF boundTitle;
int nLength = GetWindowTextLength();
TCHAR* szText = new TCHAR[nLength+1];
memset( szText, 0, sizeof(TCHAR)*(nLength+1));
GetWindowText( szText, nLength+1 );
std::wstring strText = szText;
graph.MeasureString( strText.c_str(),
(INT)strText.length(),
&font,
rtfTitle,
&strfmtTitle,
&boundTitle );
int nNewWidth = (int)(boundTitle.Width) + m_leftspace + m_rightspace;
int nOldWidth = rtStatic.Width();
if ( E_SizeAdjustStyl_Left == m_eSizeAdjustStyle )
{
SetWindowPos( NULL, 0, 0, boundTitle.Width, rtStatic.Height(), SWP_NOMOVE|SWP_NOZORDER );
}
else if ( E_SizeAdjustStyl_Center == m_eSizeAdjustStyle )
{
SetWindowPos( NULL, rtStatic.left - (nNewWidth-nOldWidth)/2, rtStatic.top, nNewWidth, rtStatic.Height(), SWP_NOZORDER );
}
else if ( E_SizeAdjustStyl_Right == m_eSizeAdjustStyle )
{
SetWindowPos( NULL, rtStatic.left - (nNewWidth-nOldWidth), rtStatic.top, nNewWidth, rtStatic.Height(), SWP_NOZORDER );
}
else
{
}
}
void SetTextFormat(UINT uFormat)
{
m_uFormat = uFormat;
}
void SetTextSpace(int leftspace,int rightspace,int topspace,int bottomspace)
{
m_leftspace = leftspace;
m_rightspace = rightspace;
m_topspace = topspace;
m_bottomspace = bottomspace;
}
void SetEdgeStyle(BOOL bDrawEdge = FALSE,Color edgeClr = Color(128, 255, 255, 255), Color lineClr = Color(255, 128, 128, 128))
{
m_isDrawEdge = bDrawEdge;
m_EdgeClr = edgeClr;
m_LineClr = lineClr;
}
protected:
LRESULT OnTimer( UINT , WPARAM , LPARAM , BOOL& )
{
if( m_nTotalFrames <= 1 )
{
return 0;
}
m_nActiveFrameNo++;
if( m_nActiveFrameNo >= m_nTotalFrames )
{
m_nActiveFrameNo = 0;
}
Invalidate();
return 0;
}
LRESULT OnDestroy( UINT , WPARAM , LPARAM , BOOL& )
{
for( size_t i = 0; i < m_vtImage.size(); i++ )
{
delete m_vtImage[i];
}
m_vtImage.clear();
if( m_nDisTimer > 0 )
{
KillTimer( m_nDisTimer );
m_nDisTimer = 0;
}
return 0;
}
void DrawEdgeEx(HDC &hDC, CRect & rc, Color &edgeClr, Color &lineClr)
{
Pen mypen(edgeClr,10);
Pen mypen1(Color(64, 65,65, 65),1);
Pen mypen2(lineClr,3);
Graphics mygraph(hDC);
mygraph.DrawRectangle(&mypen,1,1,rc.Width()-2,rc.Height()-2);
mygraph.DrawRectangle(&mypen1,0,0,rc.Width()-1,rc.Height()-1);
Point startpoint(rc.right,0);
Point endpoint(rc.right,rc.bottom);
mygraph.DrawLine(&mypen2,startpoint,endpoint);
startpoint.X = 0;
startpoint.Y = rc.bottom;
endpoint.X = rc.right;
endpoint.Y = rc.bottom;
mygraph.DrawLine(&mypen2,startpoint,endpoint);
mygraph.ReleaseHDC(hDC);
}
public:
LRESULT OnMouseMove( UINT , WPARAM , LPARAM , BOOL& bHandled )
{
if ( m_bMouseTrack )
{
HWND hParent = GetParent();
if ( NULL != hParent )
{
WPARAM wParam = MAKELONG( ::GetWindowLong(m_hWnd, GWL_ID), STAT_MOUSEIN );
::PostMessage( hParent, WM_COMMANDEX, wParam, (LPARAM)m_hWnd );
}
}
if(m_bMouseTrack)
{
Invalidate();
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.hwndTrack = m_hWnd;
tme.dwFlags = TME_LEAVE|TME_HOVER;
TrackMouseEvent(&tme);
m_bMouseTrack = FALSE;
}
bHandled = FALSE;
return 0;
}
LRESULT OnMouseLeave( UINT , WPARAM , LPARAM , BOOL& bHandled )
{
if(!m_bMouseTrack)
{
Invalidate();
bHandled = FALSE;
m_bMouseTrack = TRUE;
HWND hParent = GetParent();
if ( NULL != hParent )
{
WPARAM wParam = MAKELONG( ::GetWindowLong(m_hWnd, GWL_ID), STAT_MOUSEOUT );
::PostMessage( hParent, WM_COMMANDEX, wParam, (LPARAM)m_hWnd );
}
}
return 0;
}
void SetImageMoseIn(Image* pImage)
{
m_pImageMoseIn = pImage->Clone();
}
int GetStrRow(CString& str)
{
int i=0;
int c=0;
do
{
i = str.Find(_T('\n'),i+1);
++c;
}while ((i != -1)&&i!= str.GetLength()-1);
return c;
}
void GetRowString(int nCount,CString str,vector<CString>& strVector)
{
for(int i =0;i<nCount;i++)
{
int nLeght = str.Find(_T('\n'));
CString strTemp;
if (nLeght > 0)
{
strTemp = str.Left(nLeght+1);
str.Delete(0,nLeght+1);
}
else
{
strTemp = str;
}
strVector.push_back(strTemp);
}
}
LRESULT OnPaint( UINT , WPARAM , LPARAM , BOOL& )
{
WTL::CPaintDC paintDC( m_hWnd );
paintDC.SetBkMode( TRANSPARENT );
CRect rc;
GetClientRect( rc );
WTL::CDC dc;
dc.CreateCompatibleDC( paintDC.m_hDC );
WTL::CBitmap memBitmap;
memBitmap.CreateCompatibleBitmap( paintDC.m_hDC, rc.Width(), rc.Height() );
HBITMAP hOldBmp = dc.SelectBitmap( memBitmap );
dc.SetBkMode( TRANSPARENT );
::SendMessage( GetParent(), WM_DRAWBKGNDUI, ( WPARAM )dc.m_hDC, ( LPARAM )m_hWnd );
int nLeft = 0;
int ntop = 0;
if (m_isDrawEdge)
{
DrawEdgeEx(dc.m_hDC,rc,m_EdgeClr,m_LineClr);
nLeft = ntop = 6;
}
POINT pt;
GetCursorPos( &pt );
BOOL bMouseIn =FALSE;
HWND hwnd = WindowFromPoint(pt);
if(hwnd==m_hWnd)
{
bMouseIn = TRUE;
}
if(bMouseIn == TRUE)
{
if(m_pImageMoseIn != NULL)
{
Image *pImage = m_pImageMoseIn;
Graphics graph( dc.m_hDC );
RectF rtfDest( (REAL)nLeft, (REAL)ntop, REAL(rc.Width()-2*nLeft), REAL(rc.Height()-2*ntop) );
StretchImageExceptCorner( graph, pImage, rtfDest, 5, 5, 5, 5 );
graph.ReleaseHDC( dc.m_hDC );
}
else
{
if( m_vtImage.size() > m_nActiveFrameNo )
{
Image *pImage = m_vtImage[m_nActiveFrameNo];
Graphics graph( dc.m_hDC );
RectF rtfDest( (REAL)nLeft, (REAL)ntop, REAL(rc.Width()-2*nLeft), REAL(rc.Height()-2*ntop) );
StretchImageExceptCorner( graph, pImage, rtfDest, 5, 5, 5, 5 );
graph.ReleaseHDC( dc.m_hDC );
}
}
}
else
{
if( m_vtImage.size() > m_nActiveFrameNo )
{
Image *pImage = m_vtImage[m_nActiveFrameNo];
Graphics graph( dc.m_hDC );
RectF rtfDest( (REAL)nLeft, (REAL)ntop, REAL(rc.Width()-2*nLeft), REAL(rc.Height()-2*ntop) );
StretchImageExceptCorner( graph, pImage, rtfDest, 5, 5, 5, 5 );
graph.ReleaseHDC( dc.m_hDC );
}
}
int len = GetWindowTextLength();
if( len > 0 )
{
len += 1;
CString strText;
GetWindowText( strText.GetBuffer( len ), len );
strText.ReleaseBuffer();
HFONT hFont = GetStateFont( CONTROL_STA_NORMAL );
HFONT hOldFont = dc.SelectFont( hFont );
dc.SetTextColor( GetFontColor( CONTROL_STA_NORMAL ) );
CRect rect(rc);
rect.left = rect.left+ m_leftspace;
rect.right = rect.right+ m_rightspace;
rect.top = rect.top+ m_topspace;
rect.bottom = rect.bottom+ m_bottomspace;
if(m_bReturn == TRUE)
{
int nCount = GetStrRow(strText);
int nLenght = rect.Height()/nCount;
vector<CString> verstring;
GetRowString(nCount,strText,verstring);
for (int i =0;i<nCount;i++)
{
rect.top = i*nLenght;
rect.bottom = (i+1)*nLenght;
dc.DrawText(verstring[i], -1, &rect, GetTextFormat( ) | DT_NOPREFIX);
}
}
else
{
dc.DrawText( strText, -1, &rect, GetTextFormat( ) | DT_NOPREFIX);
}
dc.SelectFont( hOldFont );
::DeleteObject( hFont );
}
paintDC.BitBlt( 0, 0, rc.Width(), rc.Height(), dc.m_hDC, 0, 0, SRCCOPY );
dc.SelectBitmap( hOldBmp );
memBitmap.DeleteObject();
dc.DeleteDC();
return 0;
}
private:
UINT GetTextFormat()
{
return m_uFormat;
}
public:
void DeleteImage()
{
for( size_t i = 0; i < m_vtImage.size(); i++ )
{
delete m_vtImage[i];
}
m_vtImage.clear();
}
BOOL SetImage( Image *pImg, UINT uInterval = 5000 )
{
m_nInterval = uInterval;
if( m_nDisTimer != 0 )
{
KillTimer( m_nDisTimer );
m_nDisTimer = 0;
}
if( m_vtImage.size() > 0 )
{
for( size_t i = 0; i < m_vtImage.size(); i++ )
{
delete m_vtImage[i];
}
m_vtImage.clear();
}
if( NULL == pImg )
{
return FALSE;
}
m_nActiveFrameNo = 0;
m_nTotalFrames = 0;
UINT count = pImg->GetFrameDimensionsCount();
GUID* pDimensionIDs = new GUID[count];
pImg->GetFrameDimensionsList( pDimensionIDs, count );
m_nTotalFrames = pImg->GetFrameCount( &pDimensionIDs[0] );
UINT i = 0;
int width = pImg->GetWidth();
int height = pImg->GetHeight();
while( true )
{
if( Ok == pImg->SelectActiveFrame( pDimensionIDs, i++ ) )
{
Bitmap bmp( width, height );
Graphics graph( &bmp );
graph.DrawImage( pImg, Rect( 0, 0, width, height ), 0, 0, width, height, UnitPixel );
m_vtImage.push_back( bmp.Clone( 0, 0, width, height, bmp.GetPixelFormat() ) );
}
else
{
break;
}
}
delete []pDimensionIDs;
if(m_vtImage.size()==0)
{
m_vtImage.push_back(pImg->Clone());
}
if( ( m_nTotalFrames > 1 ) && IsWindow() )
{
m_nDisTimer = (UINT)SetTimer( 1001, m_nInterval );
}
CRect rc;
GetWindowRect( rc );
ScreenToClient( rc );
InvalidateRect( rc, TRUE );
return TRUE;
}
BOOL SetImage( UINT uID, LPCTSTR sTR, UINT uInterval = 5000 )
{
Image *pImage = ImageFromIDResourceEx( uID, sTR );
if( NULL == pImage )
{
return FALSE;
}
BOOL bRet = SetImage( pImage, uInterval );
delete pImage;
return bRet;
}
BOOL SetImageEx( Image *pImg, int nX, int nY, int nWidth, int nHeigth, UINT uInterval = 5000 )
{
m_nInterval = uInterval;
if( m_nDisTimer != 0 )
{
KillTimer( m_nDisTimer );
m_nDisTimer = 0;
}
if( m_vtImage.size() > 0 )
{
for( size_t i = 0; i < m_vtImage.size(); i++ )
{
delete m_vtImage[i];
}
m_vtImage.clear();
}
if( NULL == pImg )
{
return FALSE;
}
m_nActiveFrameNo = 0;
m_nTotalFrames = 0;
UINT count = pImg->GetFrameDimensionsCount();
GUID* pDimensionIDs = new GUID[count];
pImg->GetFrameDimensionsList( pDimensionIDs, count );
m_nTotalFrames = pImg->GetFrameCount( &pDimensionIDs[0] );
UINT i = 0;
int width = pImg->GetWidth();
int height = pImg->GetHeight();
while( Ok == pImg->SelectActiveFrame( pDimensionIDs, i++ ) )
{
Bitmap bmp( width, height );
Graphics graph( &bmp );
graph.DrawImage( pImg, Rect( 0, 0, width, height ), nX, nY, nWidth, nHeigth, UnitPixel );
m_vtImage.push_back( bmp.Clone( 0, 0, width, height, bmp.GetPixelFormat() ) );
}
delete []pDimensionIDs;
if( ( m_nTotalFrames > 1 ) && IsWindow() )
{
m_nDisTimer = (UINT)SetTimer( 1001, m_nInterval );
}
CRect rc;
GetWindowRect( rc );
ScreenToClient( rc );
InvalidateRect( rc, TRUE );
return TRUE;
}
BOOL SetImageEx( UINT uID, LPCTSTR sTR, int nX, int nY, int nWidth, int nHeigth, UINT uInterval = 5000 )
{
Image *pImage = ImageFromIDResourceEx( uID, sTR );
if( NULL == pImage )
return FALSE;
BOOL bRet = SetImageEx( pImage, nX, nY, nWidth, nHeigth, uInterval );
delete pImage;
return bRet;
}
};
|