www.pudn.com > SkinTest_demo.rar > SkinWin.cpp
// SkinWin.cpp: implementation of the CSkinWin class.
//
// A class to enable draw windows-blind style window
//
// ToDo:
// how to popup system menu by my program??
//
// History:
// 2002.11.24
// CAN WORK NOW.
// 2002.11.23 intial version
//
//
//
// AUthor:
// szhao00@mails.tsinghua.edu.cn
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "SkinWin.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CSkinWin::CSkinWin()
{
m_bInit = FALSE;
m_winstate = 0;
m_barcolor = RGB(207,207,207);
m_menucolor = RGB(207,207,207);
}
CSkinWin::~CSkinWin()
{
}
CString GetPathName( const char * filename );
CString GetFileName( const char * filename, int ext = 0);
char *next_token( char *buf, char *token, char *stopchars );
COLORREF ReadColor( CString section, CString key, CString file, COLORREF defcolor )
{
char buf[1000];
GetPrivateProfileString( section, key, "", buf, 1000, file );
if ( *buf )
{
char token[255];
char *p = buf;
int r, g, b;
p = next_token( p, token, NULL );
r = atoi(token);
p = next_token( p, token, NULL );
g = atoi(token);
p = next_token( p, token, NULL );
b = atoi(token);
return RGB(r, g, b );
}
else
return defcolor;
}
BOOL CSkinWin::LoadSkin( const char * skinfile )
{
static const char * ps = "Personality";
char buf[1000];
CString path = GetPathName( skinfile );
if ( m_bInit )
{
m_bmpDlg.DeleteObject();
m_bmpTitle.DeleteObject();
m_bmpLeft.DeleteObject();
m_bmpRight.DeleteObject();
m_bmpBottom.DeleteObject();
m_bmpMaxBtn.DeleteObject();
m_bmpRestoreBtn.DeleteObject();
m_bmpMinBtn.DeleteObject();
m_bmpCloseBtn.DeleteObject();
//set deafult
m_barcolor = RGB(207,207,207);
m_menucolor = RGB(207,207,207);
m_bInit = FALSE;
}
GetPrivateProfileString( ps, "DialogBmp", "", buf, 1000, skinfile );
if ( *buf != 0 )
m_bmpDlg.LoadBitmap( path + "/" + GetFileName( buf,1 ));
GetPrivateProfileString( ps, "Top", "", buf, 1000, skinfile );
if ( *buf == 0 || !m_bmpTitle.LoadBitmap( path + "/" + GetFileName( buf,1 )) )
return FALSE;
GetPrivateProfileString( ps, "Left", "", buf, 1000, skinfile );
if ( *buf == 0 || !m_bmpLeft.LoadBitmap( path + "/" + GetFileName( buf,1 ) ))
return FALSE;
GetPrivateProfileString( ps, "Right", "", buf, 1000, skinfile );
if ( *buf == 0 || !m_bmpRight.LoadBitmap( path + "/" + GetFileName( buf,1 ) ))
return FALSE;
GetPrivateProfileString( ps, "Bottom", "", buf, 1000, skinfile );
if ( *buf == 0 || !m_bmpBottom.LoadBitmap( path + "/" + GetFileName( buf,1 ) ))
return FALSE;
m_TitleHeight = m_bmpTitle.Height()/2;
m_BorderLeftWidth = m_bmpLeft.Width()/2;
m_BorderRightWidth = m_bmpRight.Width()/2;
m_BorderBottomHeight = m_bmpBottom.Height()/2;
m_titleoff1 = GetPrivateProfileInt( ps, "TopTopHeight", 0, skinfile );
m_titleoff2 = m_bmpTitle.Width() - GetPrivateProfileInt( ps, "TopBotHeight", 0, skinfile );
if ( m_titleoff2 <= m_titleoff1 )
m_titleoff2 = m_titleoff1 + 1;
m_leftoff1 = GetPrivateProfileInt( ps, "LeftTopHeight", 0, skinfile );
m_leftoff2 = m_bmpLeft.Height() - GetPrivateProfileInt( ps, "LeftBotHeight", 0, skinfile );
if ( m_leftoff2 <= m_leftoff1 )
m_leftoff2 = m_leftoff1 + 1;
m_rightoff1 = GetPrivateProfileInt( ps, "RightTopHeight", 0, skinfile );
m_rightoff2 = m_bmpRight.Height() - GetPrivateProfileInt( ps, "RightBotHeight", 0, skinfile );
if ( m_rightoff2 <= m_rightoff1 )
m_rightoff2 = m_rightoff1 + 1;
m_bottomoff1 = GetPrivateProfileInt( ps, "BottomTopHeight", 0, skinfile );
m_bottomoff2 = m_bmpBottom.Width() - GetPrivateProfileInt( ps, "BottomBotHeight", 0, skinfile );
if ( m_bottomoff2 <= m_bottomoff1 )
m_bottomoff2 = m_bottomoff1 + 1;
//load buttons
int count = GetPrivateProfileInt( ps, "ButtonCount", 0, skinfile );
int icount = GetPrivateProfileInt( ps, "ButtonImgCount", 3, skinfile );
for ( int i = 0; i < count; i++ )
{
CString sec;
sec.Format( "Button%d", i );
GetPrivateProfileString( sec, "ButtonImage", "", buf, 1000, skinfile );
int action = GetPrivateProfileInt( sec, "Action", 0, skinfile );
int x = GetPrivateProfileInt( sec, "XCoord", 0, skinfile );
int y = GetPrivateProfileInt( sec, "YCoord", 0, skinfile );
int state = icount;
if ( action == 0 )
{
//close
if ( !m_bmpCloseBtn.LoadBitmap( path + "/" + GetFileName( buf,1 )) )
return FALSE;
//state = m_bmpCloseBtn.Width()/m_bmpCloseBtn.Height();
m_rectCloseBtn = CRect( x-m_bmpCloseBtn.Width()/state, y, x , y + m_bmpCloseBtn.Height() );
}
if ( action == 2 )
{
//min
if ( !m_bmpMinBtn.LoadBitmap( path + "/" + GetFileName( buf,1 )) )
return FALSE;
//state = m_bmpMinBtn.Width()/m_bmpMinBtn.Height();
m_rectMinBtn = CRect( x-m_bmpMinBtn.Width()/state, y, x, y + m_bmpMinBtn.Height() );
}
if ( action == 1 )
{
if ( !m_bmpMaxBtn.GetSafeHandle() )
{
//max
if ( !m_bmpMaxBtn.LoadBitmap( path + "/" + GetFileName( buf,1 )) )
return FALSE;
//state = m_bmpMaxBtn.Width()/m_bmpMaxBtn.Height();
m_rectMaxBtn = CRect( x-m_bmpMaxBtn.Width()/state, y, x , y + m_bmpMaxBtn.Height() );
}
else
{
//restore
if ( !m_bmpRestoreBtn.LoadBitmap( path + "/" + GetFileName( buf,1 )) )
return FALSE;
//state = m_bmpRestoreBtn.Width()/m_bmpRestoreBtn.Height();
m_rectRestoreBtn = CRect( x-m_bmpRestoreBtn.Width()/state, y, x , y + m_bmpRestoreBtn.Height() );
}
}
if ( action == 4 )
{
}
}
m_textShift = GetPrivateProfileInt( ps, "TextShift", 0, skinfile );
m_textShiftVer = GetPrivateProfileInt( ps, "TextShiftVert", 0, skinfile );
char * colours = "Colours";
m_colTitle1 = ReadColor(colours, "TitleText", skinfile, GetSysColor(COLOR_CAPTIONTEXT) );
m_colTitle2 = ReadColor(colours, "InactiveTitleText", skinfile, GetSysColor(COLOR_CAPTIONTEXT) );
m_bTrans = GetPrivateProfileInt( ps, "UsesTran", 0, skinfile );
if ( m_bTrans )
m_colTrans = ReadColor(colours, "TransColor", skinfile, RGB(255,0,255) );
m_barcolor = ReadColor(colours, "BarColor", skinfile, RGB(207,207,207) );
m_menucolor = ReadColor(colours, "MenuColor", skinfile, RGB(207,207,207) );
m_btnbgcolor = ReadColor(colours, "ButtonFace", skinfile, GetSysColor(COLOR_BTNFACE) );
m_btntextcolor = ReadColor(colours, "ButtonText", skinfile, GetSysColor(COLOR_BTNTEXT));
m_btnhovercolor = ReadColor(colours, "ButtonHilight", skinfile, GetSysColor(COLOR_BTNFACE) );
m_btnfocuscolor = ReadColor(colours, "ButtonFocus", skinfile, GetSysColor(COLOR_BTNFACE) );
m_bInit = TRUE;
return TRUE;
}
BOOL CSkinWin::DrawTitle(CDC *pDC, int x, int y, int w, int state)
{
int padding;
int ox = x;
padding = ( w - m_bmpTitle.Width() )/( m_titleoff2 - m_titleoff1 ) + 1 ;
if ( padding < 0 ) padding = 0;
RECT sr;
if ( state == 0 )
sr = CRect( 0, 0, m_titleoff1, m_TitleHeight );
else
sr = CRect( 0, m_TitleHeight, m_titleoff1, m_bmpTitle.Height() );
m_bmpTitle.Draw( pDC, x, y, &sr );
x += m_titleoff1;
if ( state == 0 )
sr = CRect( m_titleoff1, 0, m_titleoff2, m_TitleHeight );
else
sr = CRect( m_titleoff1, m_TitleHeight, m_titleoff2, m_bmpTitle.Height() );
for ( int i = 0; i <= padding; i++, x += m_titleoff2 - m_titleoff1 )
{
int d = ( x + m_titleoff2 - m_titleoff1 - ox - w);
if ( d > 0 )
sr.right = sr.right - d;
m_bmpTitle.Draw( pDC, x, y, &sr );
}
x = ox + w - ( m_bmpTitle.Width() - m_titleoff2 ) + 1 ;
if ( state == 0 )
sr = CRect( m_titleoff2, 0, m_bmpTitle.Width()-1, m_TitleHeight);
else
sr = CRect( m_titleoff2, m_TitleHeight, m_bmpTitle.Width()-1, m_bmpTitle.Height() );
m_bmpTitle.Draw( pDC, x, y, &sr );
return TRUE;
}
BOOL CSkinWin::DrawBottom(CDC *pDC, int x, int y, int w, int state)
{
int padding;
int ox = x;
padding = ( w - m_bmpBottom.Width() )/( m_bottomoff2 - m_bottomoff1 ) + 1 ;
if ( padding < 0 ) padding = 0;
RECT sr;
if ( state == 0 )
sr = CRect( 0, 0, m_bottomoff1, m_BorderBottomHeight);
else
sr = CRect( 0, m_BorderBottomHeight, m_bottomoff1, m_bmpBottom.Height() );
m_bmpBottom.Draw( pDC, x, y, &sr );
x += m_bottomoff1;
if ( state == 0 )
sr = CRect( m_bottomoff1, 0, m_bottomoff2, m_BorderBottomHeight );
else
sr = CRect( m_bottomoff1, m_BorderBottomHeight, m_bottomoff2, m_bmpBottom.Height() );
for ( int i = 0; i <= padding; i++, x += m_bottomoff2 - m_bottomoff1 )
{
int d = ( x + m_bottomoff2 - m_bottomoff1 - ox - w);
if ( d > 0 )
sr.right = sr.right - d;
m_bmpBottom.Draw( pDC, x, y, &sr );
}
x = ox + w - ( m_bmpBottom.Width() - m_bottomoff2 );
if ( state == 0 )
sr = CRect( m_bottomoff2, 0, m_bmpBottom.Width()-1, m_BorderBottomHeight );
else
sr = CRect( m_bottomoff2, m_BorderBottomHeight, m_bmpBottom.Width()-1, m_bmpBottom.Height() );
m_bmpBottom.Draw( pDC, x, y, &sr );
return TRUE;
}
BOOL CSkinWin::DrawLeft(CDC *pDC, int x, int y, int h, int state)
{
int padding;
int oy = y;
padding = ( h - m_bmpLeft.Height() )/( m_leftoff2 - m_leftoff1 ) + 1 ;
if ( padding < 0 ) padding = 0;
RECT sr;
if ( state == 0 )
sr = CRect( 0, 0, m_BorderLeftWidth, m_leftoff1 );
else
sr = CRect( m_BorderLeftWidth, 0, m_bmpLeft.Width(), m_leftoff1 );
m_bmpLeft.Draw( pDC, x, y, &sr );
y += m_leftoff1;
if ( state == 0 )
sr = CRect( 0, m_leftoff1, m_BorderLeftWidth, m_leftoff2 );
else
sr = CRect( m_BorderLeftWidth, m_leftoff1, m_bmpLeft.Width(), m_leftoff2 );
for ( int i = 0; i <= padding; i++, y += m_leftoff2 - m_leftoff1 )
{
int d = ( y + m_leftoff2 - m_leftoff1 - oy - h);
if ( d > 0 )
sr.bottom = sr.bottom - d;
m_bmpLeft.Draw( pDC, x, y, &sr );
}
y = oy + h - ( m_bmpLeft.Height() - m_leftoff2 ) ;
if ( state == 0 )
sr = CRect( 0, m_leftoff2, m_BorderLeftWidth, m_bmpLeft.Height());
else
sr = CRect( m_BorderLeftWidth, m_leftoff2, m_bmpLeft.Width(), m_bmpLeft.Height() );
m_bmpLeft.Draw( pDC, x, y, &sr );
return TRUE;
}
BOOL CSkinWin::DrawRight(CDC *pDC, int x, int y, int h, int state)
{
int padding;
int oy = y;
padding = ( h - m_bmpRight.Height() )/( m_rightoff2 - m_rightoff1 ) + 1 ;
if ( padding < 0 ) padding = 0;
RECT sr;
if ( state == 0 )
sr = CRect( 0, 0, m_BorderRightWidth, m_rightoff1 );
else
sr = CRect( m_BorderRightWidth, 0, m_bmpRight.Width(), m_rightoff1 );
m_bmpRight.Draw( pDC, x, y, &sr );
y += m_rightoff1;
if ( state == 0 )
sr = CRect( 0, m_rightoff1, m_BorderRightWidth, m_rightoff2 );
else
sr = CRect( m_BorderRightWidth, m_rightoff1, m_bmpRight.Width(), m_rightoff2 );
for ( int i = 0; i <= padding; i++, y += m_rightoff2 - m_rightoff1 )
{
int d = ( y + m_rightoff2 - m_rightoff1 - oy - h);
if ( d > 0 )
sr.bottom = sr.bottom - d;
m_bmpRight.Draw( pDC, x, y, &sr );
}
y = oy + h - ( m_bmpRight.Height() - m_rightoff2 ) ;
if ( state == 0 )
sr = CRect( 0, m_rightoff2, m_BorderRightWidth, m_bmpRight.Height());
else
sr = CRect( m_BorderRightWidth, m_rightoff2, m_bmpRight.Width(), m_bmpRight.Height() );
m_bmpRight.Draw( pDC, x, y, &sr );
return TRUE;
}
BOOL CSkinWin::DrawFrame(CDC *pDC, int x, int y, int w, int h, int state, int title )
{
if ( title )
DrawTitle( pDC, x + m_BorderLeftWidth , y,
w - m_BorderRightWidth - m_BorderLeftWidth + 1, state );
DrawLeft( pDC, x, y, h, state );
DrawRight( pDC, x + w - m_BorderRightWidth , y, h, state );
DrawBottom( pDC, x + m_BorderLeftWidth,
y + h - m_BorderBottomHeight, w - m_BorderRightWidth - m_BorderLeftWidth, state );
return TRUE;
}
BOOL CSkinWin::InstallSkin(CWnd *wnd)
{
if ( !wnd || !m_bInit ) return FALSE;
HookWindow( (HWND)NULL);
int r = HookWindow( wnd );
DWORD style = GetWindowLong( m_hWnd, GWL_STYLE );
m_sizable = style & WS_SIZEBOX;
m_minable = style & WS_MINIMIZEBOX;
m_maxable = style & WS_MAXIMIZEBOX;
//m_sysmenu = style & WS_MAXIMIZEBOX;
style &= ~(WS_MINIMIZEBOX);
style &= ~WS_MAXIMIZEBOX;
style &= ~WS_SYSMENU;
SetWindowLong( m_hWnd, GWL_STYLE, style );
return r;
}
LRESULT CSkinWin::WindowProc(UINT msg, WPARAM wp, LPARAM lp)
{
if ( !IsWindow(m_hWnd) )
return 0;
if ( !m_bInit )
return Default();
switch ( msg )
{
case WM_SHOWWINDOW:
//call setwindowpos to force OnNcCalcSize when hWnd is a dialog
if ( wp )
SetWindowPos( m_hWnd, 0, 0, 0, 400, 400, SWP_NOSIZE|SWP_NOMOVE|SWP_FRAMECHANGED );
Default();
return 0;
break;
//case WM_ERASEBKGND:
case WM_INITMENUPOPUP:
Default();
return 0;
// return OnEraseBkgnd(CDC::FromHandle((HDC)wp) );
/*
case WM_INITMENU:
//a hack, when popup sysmenu, redraw title bar
HMENU h;
h = (HMENU)wp;
int c;
h = GetSubMenu(h, 0);
c = GetMenuItemID( h, 0 );
if ( c == SC_RESTORE )
{
CRect r;
GetClientRect( m_hWnd, r );
OnNcPaint(0);
r.bottom = GetSystemMetrics(SM_CYCAPTION);
InvalidateRect( m_hWnd, r, TRUE );
UpdateWindow( m_hWnd );
}
Default();
return 0;
*/
case WM_SYSCOMMAND:
OnSysCommand( wp, lp );
//Default();
return 0;
case WM_SETTEXT:
return OnSetText( wp, lp );
case WM_NCPAINT:
OnNcPaint( (HRGN)wp );
return 0;
case WM_NCCALCSIZE:
OnNcCalcSize( (BOOL)wp, (NCCALCSIZE_PARAMS *)lp );
return 0;
case WM_SIZE:
OnSize( wp, LOWORD(lp), HIWORD(lp) );
return 0;
case WM_NCACTIVATE:
return OnNcActivate( (BOOL)wp );
case WM_NCHITTEST:
return OnNcHitTest(CPoint(LOWORD(lp), HIWORD(lp)));
case WM_NCLBUTTONUP:
OnNcLButtonUp(wp, CPoint(LOWORD(lp), HIWORD(lp)));
return 0;
case WM_NCLBUTTONDOWN:
OnNcLButtonDown(wp, CPoint(LOWORD(lp), HIWORD(lp)));
return 0;
case WM_NCLBUTTONDBLCLK:
OnNcLButtonDblClk(wp, CPoint(LOWORD(lp), HIWORD(lp)));
return 0;
case WM_NCRBUTTONUP:
OnNcRButtonUp(wp, CPoint(LOWORD(lp), HIWORD(lp)));
return 0;
case WM_NCRBUTTONDOWN:
OnNcRButtonDown(wp, CPoint(LOWORD(lp), HIWORD(lp)));
return 0;
case WM_NCMOUSEMOVE:
OnNcMouseMove( wp,CPoint(LOWORD(lp), HIWORD(lp)));
return 0;
case WM_GETMINMAXINFO:
OnGetMinMaxInfo( (MINMAXINFO *)lp );
return 0;
case WM_WINDOWPOSCHANGING:
OnWindowPosChanging((WINDOWPOS *)lp);
return 0;
case WM_SIZING:
OnSizing( wp, (LPRECT)lp );
return 0;
case WM_ACTIVATE:
OnActivate( wp, CWnd::FromHandle((HWND)lp), 0 );
return 0;
case WM_COMMAND:
if ( !HandleSysCommand( wp, lp ) )
Default();
return 0;
default:
return Default();
}
}
void CSkinWin::OnNcPaint(HRGN rgn1)
{
CWnd *pWnd = CWnd::FromHandle(m_hWnd);
CDC * pDC = pWnd->GetWindowDC();
CRect wr;
pWnd->GetWindowRect( wr );
//f ( (DWORD)rgn)
//pDC->SelectClipRgn( CRgn::FromHandle(rgn) );
//m_bActive = GetActiveWindow() == m_hWnd;
int state = 0;
if ( m_bActive)
state = 0;
else state = 1;
pDC->ExcludeClipRect(0, 0, wr.Width(), m_TitleHeight );
DrawFrame( pDC, 0, 0, wr.Width(), wr.Height(), state, 0 );
pDC->SelectClipRgn( NULL );
CDC memDC, *pNewDC;
CMyBitmap bmp;
CBitmap *obmp;
memDC.CreateCompatibleDC( pDC );
bmp.CreateCompatibleBitmap( pDC, wr.Width(), m_TitleHeight );
obmp = memDC.SelectObject(&bmp);
pNewDC = &memDC;
DrawTitle( pNewDC, m_BorderLeftWidth , 0,
wr.Width() - m_BorderRightWidth - m_BorderLeftWidth + 1, state );
DrawLeft( pNewDC, 0, 0, m_bmpLeft.Height(), state );
DrawRight( pNewDC, wr.Width() - m_BorderRightWidth , 0, m_bmpRight.Height(), state );
CRgn newrgn;
newrgn.CreateRectRgn( 0, 0, wr.Width(), wr.Height() );
if ( m_bTrans )
{
CRgn rgn;
rgn.CreateRectRgn( 0, m_TitleHeight, wr.Width(), wr.Height() );
HRGN hrgn = bmp.CreateRgnFromFile( m_colTrans );
newrgn.CombineRgn( &rgn, CRgn::FromHandle(hrgn), RGN_XOR );
pDC->SelectClipRgn( &newrgn );
}
else
SetWindowRgn( m_hWnd, newrgn, FALSE );
if ( m_downHitTest == HTCLOSE )
DrawButton( pNewDC, 0, 1 );
else if ( m_moveHitTest == HTCLOSE)
DrawButton( pNewDC, 0, 2 );
else
DrawButton( pNewDC, 0, 0 );
if ( m_downHitTest == HTMINBUTTON )
DrawButton( pNewDC, 2, 1 );
else if ( m_moveHitTest == HTMINBUTTON)
DrawButton( pNewDC, 2, 2 );
else
DrawButton( pNewDC, 2, 0 );
if ( m_downHitTest == HTMAXBUTTON )
DrawButton( pNewDC, 1, 1 );
else if ( m_moveHitTest == HTMAXBUTTON)
DrawButton( pNewDC, 1, 2 );
else
DrawButton( pNewDC, 1, 0 );
int cx = GetSystemMetrics(SM_CXSMICON);
int cy = GetSystemMetrics(SM_CYSMICON);
HICON hi = (HICON)SendMessage( m_hWnd, WM_GETICON, ICON_SMALL, 0);
if ( !hi )
{
#ifdef IDR_MAINFRAME
hi = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
#endif
}
//draw icon
::DrawIconEx( pNewDC->GetSafeHdc(), m_BorderLeftWidth, 5, (HICON)
CopyImage( hi, IMAGE_ICON,
cx, cy, 0), cx, cy, 0, 0, DI_NORMAL);
//draw text
if ( m_title.IsEmpty() )
pWnd->GetWindowText(m_title);
if (m_bActive)
pNewDC->SetTextColor( m_colTitle1 );
else
pNewDC->SetTextColor( m_colTitle2 );
CFont font, *ofont;
font.CreatePointFont( GetSystemMetrics(SM_CYSMCAPTION), "System" );
ofont = pNewDC->SelectObject(&font);
pNewDC->SetBkMode(TRANSPARENT);
pNewDC->DrawText( m_title, CRect( m_textShift, m_textShiftVer, wr.Width() - m_bmpTitle.Width() + m_titleoff2,
m_TitleHeight ), DT_SINGLELINE | DT_LEFT | DT_VCENTER | DT_WORD_ELLIPSIS );
pNewDC->SelectObject(&font);
pDC->BitBlt( 0, 0, wr.Width(),
m_TitleHeight, pNewDC, 0, 0, SRCCOPY );
memDC.SelectObject(obmp);
pDC->SelectClipRgn(NULL);
}
void CSkinWin::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS *lpncsp)
{
if ( bCalcValidRects )
{
lpncsp->rgrc[0].left = lpncsp->rgrc[0].left + m_BorderLeftWidth;
lpncsp->rgrc[0].right = lpncsp->rgrc[0].right - m_BorderRightWidth;
lpncsp->rgrc[0].top = lpncsp->rgrc[0].top + m_TitleHeight;
lpncsp->rgrc[0].bottom = lpncsp->rgrc[0].bottom - m_BorderBottomHeight;
lpncsp->rgrc[1] = lpncsp->rgrc[0];
}
else
{
Default();
}
}
void CSkinWin::OnSizing(UINT nSide, LPRECT lpRect)
{
//Default();
CWnd *pWnd = CWnd::FromHandle(m_hWnd);
CRect wr(lpRect);
/*
if ( m_bTrans )
SetWindowRgn( m_hWnd, GetRegion(wr.Width(), wr.Height() ), TRUE );
else
SetWindowRgn( m_hWnd, NULL, TRUE );
*/
}
void CSkinWin::OnSize(UINT nType, int cx, int cy)
{
//Default();
CWnd *pWnd = CWnd::FromHandle(m_hWnd);
CRect wr;
Default();
pWnd->GetWindowRect(wr);
pWnd->Invalidate();
OnNcPaint(0);
if ( m_bTrans )
SetWindowRgn( m_hWnd, GetRegion(wr.Width(), wr.Height() ), TRUE );
else
SetWindowRgn( m_hWnd, NULL, TRUE );
}
HRGN CSkinWin::GetRegion(int w, int h)
{
CWnd *pWnd = CWnd::FromHandle(m_hWnd);
CRect wr;
pWnd->GetWindowRect(wr);
CRgn rgn;
if ( m_bTrans )
{
CDC *pDC = pWnd->GetDC();
CDC memDC;
CMyBitmap bmp;
CBitmap *obmp;
memDC.CreateCompatibleDC(pDC);
bmp.CreateCompatibleBitmap( pDC, w, m_TitleHeight );
obmp = memDC.SelectObject(&bmp);
/*
memDC.FillSolidRect( 0, 0, w, h, 0 );
DrawFrame( &memDC, 0, 0, w, h, 0 );
*/
DrawTitle( &memDC, m_BorderLeftWidth , 0,
wr.Width() - m_BorderRightWidth - m_BorderLeftWidth + 1, 0 );
DrawLeft( &memDC, 0, 0, m_bmpLeft.Height(), 0 );
DrawRight( &memDC, wr.Width() - m_BorderRightWidth , 0, m_bmpRight.Height(), 0 );
memDC.SelectObject(obmp);
pWnd->ReleaseDC( pDC );
rgn.CreateRectRgn( 0, m_TitleHeight, wr.Width(), wr.Height() );
HRGN hrgn = bmp.CreateRgnFromFile( m_colTrans );
CRgn newrgn;
newrgn.CreateRectRgn( 0, m_TitleHeight, wr.Width(), wr.Height() );
newrgn.CombineRgn( &rgn, CRgn::FromHandle(hrgn), RGN_XOR );
return (HRGN)newrgn.Detach();
}
else
rgn.CreateRectRgn( 0, 0, wr.Width(), wr.Height() );
return (HRGN)rgn.Detach();
}
BOOL CSkinWin::OnNcActivate(BOOL bActive)
{
m_bActive = bActive;
OnNcPaint(0);
if ( !bActive )
{
return 1;
}
else
return 0;
}
UINT CSkinWin::OnNcHitTest(CPoint point)
{
CWnd *pWnd = CWnd::FromHandle(m_hWnd);
CRect wr;
pWnd->GetWindowRect(wr);
point.x -= wr.left;
point.y -= wr.top;
if ( PtInRect( GetButtonRect(0), point ) )
return HTCLOSE;
if ( PtInRect( GetButtonRect(2), point ) && m_minable )
return HTMINBUTTON;
if ( PtInRect( GetButtonRect(1), point ) && m_maxable )
return HTMAXBUTTON;
CRect r;
int cx = GetSystemMetrics(SM_CXSMICON);
int cy = GetSystemMetrics(SM_CYSMICON);
if ( PtInRect( CRect(m_BorderLeftWidth, 5, m_BorderLeftWidth + cx, cy + 5), point ) )
return HTSYSMENU;
r = CRect( 0, 0, m_BorderLeftWidth, m_TitleHeight );
if ( PtInRect( r, point ) && m_sizable && m_winstate != 1 ) //!IsZoomed(m_hWnd) )
return HTTOPLEFT;
r = CRect( wr.Width() - m_BorderLeftWidth, 0, wr.Width(), m_TitleHeight );
if ( PtInRect( r, point ) && m_sizable && m_winstate != 1 ) //!IsZoomed(m_hWnd) )
return HTTOPRIGHT;
r = CRect( 0, wr.Height() - m_BorderBottomHeight, m_BorderLeftWidth, wr.Height() );
if ( PtInRect( r, point ) && m_sizable && m_winstate != 1 ) //!IsZoomed(m_hWnd) )
return HTBOTTOMLEFT;
r = CRect( wr.Width()-m_BorderRightWidth, wr.Height() - m_BorderBottomHeight, wr.Width(), wr.Height() );
if ( PtInRect( r, point ) && m_sizable && m_winstate != 1 ) //!IsZoomed(m_hWnd) )
return HTBOTTOMRIGHT;
r = CRect( 0, m_TitleHeight, m_BorderLeftWidth, wr.Height() - m_BorderBottomHeight );
if ( PtInRect( r, point ) && m_sizable && m_winstate != 1 ) //!IsZoomed(m_hWnd) )
return HTLEFT;
r = CRect( wr.Width()-m_BorderRightWidth, m_TitleHeight, wr.Width(), wr.Height() - m_BorderBottomHeight );
if ( PtInRect( r, point ) && m_sizable && m_winstate != 1 ) //!IsZoomed(m_hWnd) )
return HTRIGHT;
r = CRect( m_BorderLeftWidth, wr.Height() - m_BorderBottomHeight, wr.Width()-m_BorderRightWidth, wr.Height() );
if ( PtInRect( r, point ) && m_sizable && m_winstate != 1 ) //!IsZoomed(m_hWnd) )
return HTBOTTOM;
r = CRect( m_BorderLeftWidth, 0, wr.Width()-m_BorderRightWidth, m_BorderBottomHeight );
if ( PtInRect( r, point ) && m_sizable && m_winstate != 1 ) //!IsZoomed(m_hWnd) )
return HTTOP;
//set to boder 5
r = CRect( m_BorderLeftWidth, 5 , wr.Width()-m_BorderRightWidth, m_TitleHeight );
if ( PtInRect( r, point ) )
return HTCAPTION;
return HTCLIENT;
}
void CSkinWin::OnNcLButtonDblClk(UINT nHitTest, CPoint point)
{
if ( nHitTest == HTCAPTION && m_sizable )
{
if ( m_winstate == 1 )
Restore();
else
Maximize(); //ShowWindow(m_hWnd, SW_MAXIMIZE);
m_downHitTest = 0;
m_moveHitTest = 0;
OnNcPaint(0);
}
}
void CSkinWin::OnNcLButtonDown(UINT nHitTest, CPoint point)
{
m_downHitTest = nHitTest;
m_moveHitTest = m_downHitTest;
OnNcPaint(0);
if ( nHitTest >= HTLEFT && nHitTest <= HTBOTTOMRIGHT ||
nHitTest == HTCAPTION && m_winstate != 1 ) //!IsZoomed(m_hWnd) )
Default();
else if ( nHitTest == HTSYSMENU )
{
PopupSysMenu(point);
/*
CWnd * pWnd = CWnd::FromHandle(m_hWnd);
//a tricky hack
pWnd->ModifyStyle( 0, WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX );
Default();
pWnd->ModifyStyle( WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, 0 );
*/
}
}
void CSkinWin::OnNcLButtonUp(UINT nHitTest, CPoint point)
{
if ( nHitTest == HTCLOSE )
{
SendMessage(m_hWnd, WM_CLOSE, 0, 0);
return;
}
else if ( nHitTest == HTMINBUTTON )
Minimize();
else if ( nHitTest == HTMAXBUTTON )
{
if ( m_winstate == 1 ) // IsZoomed(m_hWnd) )
Restore(); //ShowWindow(m_hWnd, SW_RESTORE);
else
Maximize(); //ShowWindow(m_hWnd, SW_MAXIMIZE);
}
else
return;
m_downHitTest = 0;
m_moveHitTest = 0;
OnNcPaint(0);
}
void CSkinWin::OnNcMouseMove(UINT nHitTest, CPoint point)
{
if ( nHitTest >= HTLEFT && nHitTest <= HTBOTTOMRIGHT ||
nHitTest == HTCAPTION && m_winstate != 1 ) //!IsZoomed(m_hWnd) )
Default();
m_moveHitTest = nHitTest;
m_downHitTest = 0;
if ( m_oldHitTest != nHitTest )
{
/*
CRect r;
r = GetButtonRect(0);
r.UnionRect( r, GetButtonRect(1) );
r.UnionRect( r, GetButtonRect(2) );
CRgn rgn;
rgn.CreateRectRgn( r.left, r.top, r.right, r.bottom );
*/
OnNcPaint(0);
m_oldHitTest = nHitTest;
}
}
void CSkinWin::OnNcRButtonDown(UINT nHitTest, CPoint point)
{
if ( nHitTest == HTCAPTION )
{
/*
CWnd * pWnd = CWnd::FromHandle(m_hWnd);
pWnd->ModifyStyle( 0, WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX );
Default();
pWnd->ModifyStyle( WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, 0 );
*/
PopupSysMenu(point);
}
}
void CSkinWin::OnNcRButtonUp(UINT nHitTest, CPoint point)
{
}
CRect CSkinWin::GetButtonRect(int i)
{
CWnd *pWnd = CWnd::FromHandle(m_hWnd);
CRect wr;
pWnd->GetWindowRect(wr);
CRect r;
if ( i == 0 && m_bmpCloseBtn.GetSafeHandle() )
{
//close
r = m_rectCloseBtn;
r.left = wr.Width() - m_rectCloseBtn.right;
r.right = wr.Width() - m_rectCloseBtn.left;
}
if ( i == 1 && m_bmpMaxBtn.GetSafeHandle())
{
//max
if ( m_winstate != 1 || !m_bmpRestoreBtn.GetSafeHandle() )
{
r = m_rectMaxBtn;
r.left = wr.Width() - m_rectMaxBtn.right;
r.right = wr.Width() - m_rectMaxBtn.left;
}
else
{
r = m_rectRestoreBtn;
r.left = wr.Width() - m_rectRestoreBtn.right;
r.right = wr.Width() - m_rectRestoreBtn.left;
}
}
if ( i == 2 && m_bmpMinBtn.GetSafeHandle())
{
//min
r = m_rectMinBtn;
r.left = wr.Width() - m_rectMinBtn.right;
r.right = wr.Width() - m_rectMinBtn.left;
}
return r;
}
BOOL CSkinWin::DrawButton( CDC * pDC, int i, int state)
{
if ( i == 0 )
{
if ( m_bmpCloseBtn.GetSafeHandle() )
{
CRect r = GetButtonRect(0);
m_bmpCloseBtn.Draw( pDC, r.left, r.top,
CRect( state * r.Width(), 0, (state + 1 ) * r.Width(), m_bmpCloseBtn.Height() ), m_colTrans, m_bTrans );
}
}
if ( i == 1 )
{
CRect r = GetButtonRect(1);
if ( m_maxable && m_bmpMaxBtn.GetSafeHandle() )
if ( m_winstate == 1&& m_bmpRestoreBtn.GetSafeHandle() )
m_bmpRestoreBtn.Draw( pDC, r.left, r.top,
CRect( state * r.Width(), 0, (state + 1 ) * r.Width(), m_bmpCloseBtn.Height() ), m_colTrans, m_bTrans );
else
m_bmpMaxBtn.Draw( pDC, r.left, r.top,
CRect( state * r.Width(), 0, (state + 1 ) * r.Width(), m_bmpCloseBtn.Height() ) , m_colTrans, m_bTrans);
}
if ( i == 2 )
{
if ( m_minable && m_bmpMinBtn.GetSafeHandle() )
{
CRect r = GetButtonRect(2);
m_bmpMinBtn.Draw( pDC, r.left, r.top,
CRect( state * r.Width(), 0, (state + 1 ) * r.Width(), m_bmpCloseBtn.Height() ) , m_colTrans, m_bTrans);
}
}
return TRUE;
}
void CSkinWin::OnGetMinMaxInfo(MINMAXINFO *lpMMI)
{
lpMMI->ptMinTrackSize = CPoint( m_bmpTitle.Width() + m_bmpLeft.Width() +
m_bmpRight.Width(), m_bmpLeft.Height() + 20 );
}
void CSkinWin::OnWindowPosChanging(WINDOWPOS *lpwndpos)
{
}
BOOL CSkinWin::OnEraseBkgnd(CDC *pDC)
{
if ( m_bmpDlg.GetSafeHandle() )
{
CRect r;
GetClientRect( m_hWnd, r);
for ( int i = 0; i < r.Width()/m_bmpDlg.Width() + 1; i++ )
for ( int j = 0; j < r.Height()/m_bmpDlg.Height() + 1; j++ )
{
m_bmpDlg.Draw( pDC, CRect( i * m_bmpDlg.Width(), j * m_bmpDlg.Height(),
i * m_bmpDlg.Width() + m_bmpDlg.Width(), j * m_bmpDlg.Height() + m_bmpDlg.Height() ) );
}
return TRUE;
}
else
return FALSE;
}
CRect CSkinWin::GetMaximizeRect()
{
CRect r;
SystemParametersInfo(SPI_GETWORKAREA, 0, r, 0);
return r;
}
BOOL CSkinWin::Maximize()
{
CRect r = GetMaximizeRect();
GetWindowRect( m_hWnd, m_rectRestoreWin );
m_winstate = 1;
::MoveWindow( m_hWnd, r.left, r.top, r.Width(), r.Height(), TRUE );
UpdateWindow( m_hWnd );
return TRUE;
}
BOOL CSkinWin::Minimize()
{
m_oldwinstate = m_winstate;
m_winstate = 2;
ShowWindow(m_hWnd, SW_MINIMIZE);
return TRUE;
}
BOOL CSkinWin::Restore()
{
if ( m_winstate == 1 )
{
::MoveWindow( m_hWnd, m_rectRestoreWin.left, m_rectRestoreWin.top,
m_rectRestoreWin.Width(), m_rectRestoreWin.Height(), TRUE );
m_winstate = 0;
UpdateWindow( m_hWnd );
}
return TRUE;
}
//void OnActivate(UINT nState,CWnd* pWndOther, BOOL bMinimized );
void CSkinWin::OnActivate(UINT nState, CWnd *pWndOther, BOOL bMinimized)
{
//Default();
m_bActive = ( nState == WA_ACTIVE || nState == WA_CLICKACTIVE );
OnNcActivate(m_bActive);
}
LRESULT CSkinWin::OnSetText(WPARAM wp, LPARAM lp)
{
char * str = ( char *)lp;
Default();
m_title = str;
OnNcPaint(0);
return 0;
}
void CSkinWin::OnSysCommand(UINT nID, LPARAM lParam)
{
if ( nID == SC_MAXIMIZE )
Maximize();
else if ( nID == SC_RESTORE && m_winstate == 1 )
Restore();
else if ( nID == SC_RESTORE && m_winstate == 2 )
{
ShowWindow( m_hWnd, SW_RESTORE );
m_winstate = m_oldwinstate;
OnNcPaint(0);
}
else
Default();
}
BOOL CSkinWin::PopupSysMenu(CPoint point)
{
CWnd * pWnd = CWnd::FromHandle(m_hWnd);
CMenu SysMenu;
SysMenu.Attach( GetSystemMenu(m_hWnd, FALSE) );
/*
when gray menuitem, a strange line appears!!
if ( m_winstate == 0 )
{
SysMenu.EnableMenuItem( SC_MINIMIZE, MF_BYCOMMAND|MF_ENABLED );
SysMenu.EnableMenuItem( SC_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED );
SysMenu.EnableMenuItem( SC_RESTORE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED );
}
else if ( m_winstate == 1 )
{
SysMenu.EnableMenuItem( SC_MAXIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED );
SysMenu.EnableMenuItem( SC_RESTORE, MF_BYCOMMAND|MF_ENABLED );
}
else if ( m_winstate == 2 )
{
SysMenu.EnableMenuItem( SC_MINIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED );
SysMenu.EnableMenuItem( SC_RESTORE, MF_BYCOMMAND|MF_ENABLED );
}
*/
SysMenu.TrackPopupMenu( 0, point.x, point.y, pWnd );
SysMenu.Detach();
return TRUE;
}
BOOL CSkinWin::HandleSysCommand(WPARAM wp, LPARAM lp)
{
if ( lp == 0 )
{
CMenu SysMenu;
SysMenu.Attach( GetSystemMenu(m_hWnd, FALSE) );
int count = SysMenu.GetMenuItemCount();
for( int i = 0; i < count ; i++ )
if ( SysMenu.GetMenuItemID(i) == wp )
break;
SysMenu.Detach();
if ( i >= count )
return FALSE;
if ( wp == SC_MAXIMIZE )
Maximize();
else if ( wp == SC_MINIMIZE )
Minimize();
else if ( wp == SC_RESTORE && m_winstate == 1 )
Restore();
else if ( wp == SC_RESTORE && m_winstate == 2 )
{
ShowWindow( m_hWnd, SW_RESTORE );
m_winstate = m_oldwinstate;
OnNcPaint(0);
}
else
SendMessage( m_hWnd, WM_SYSCOMMAND, wp, lp );
return TRUE;
}
return FALSE;
}