www.pudn.com > SDKSkin.rar > SkinButton.h
/****************************************************
** Fujitsu Copyright (C) 2006 - 2007
** 功 能: SkinButton封装了Button的相关处理。
** 文件名称: SkinButton
** 文件基类:
** 扩 展 名: h
** 创建日期: 2006-8-19 15:25
** 作 者: 汪荣
*****************************************************/
#ifndef _SKINBUTTON_ONCE_
#define _SKINBUTTON_ONCE_
#define WM_MOUSEHOVER 0x02A1
#define WM_MOUSELEAVE 0x02A3
#define ODS_HOTLIGHT 0x0040
#include "../SkinBase.h"
void CALLBACK TimerProc(HWND hwnd,UINT uMsg,UINT idEvent,DWORD dwTime)
{
POINT pt;
::GetCursorPos(&pt);
RECT rcClnt;
ScreenToClient(hwnd,&pt);
GetClientRect(hwnd,&rcClnt);
if(::PtInRect(&rcClnt,pt) == TRUE)
{
//m_bOver = true;
//if(bPaint == false)
{
//InvalidateRect(hwnd,&rcClnt,TRUE);
//bPaint = true;
}
}
else
{
KillTimer(hwnd,idEvent);
//m_bOver = false;
InvalidateRect(hwnd,&rcClnt,TRUE);
//bPaint = false;
}
}
class SkinButton : public SkinBase
{
public:
SkinButton()
{
}
static void SetOver(HWND _hWnd,bool bOver)
{
if(bOver)
{
SkinResList::GetWndFlag(_hWnd)->wnMOver = 1;
}
else SkinResList::GetWndFlag(_hWnd)->wnMOver = 0;
}
static void SetLDown(HWND _hWnd,bool bLDown)
{
if(bLDown)
{
SkinResList::GetWndFlag(_hWnd)->wnLBDown = 1;
}
else SkinResList::GetWndFlag(_hWnd)->wnLBDown = 0;
}
static void SetPainted(HWND _hWnd,bool bPainted)
{
if(bPainted)
{
SkinResList::GetWndFlag(_hWnd)->wnPainted = 1;
}
else SkinResList::GetWndFlag(_hWnd)->wnPainted = 0;
}
static bool IsOver(HWND _hWnd)
{
return (SkinResList::GetWndFlag(_hWnd)->wnMOver == 1);
}
static bool IsLDown(HWND _hWnd)
{
return (SkinResList::GetWndFlag(_hWnd)->wnLBDown == 1);
}
static bool IsPainted(HWND _hWnd)
{
return (SkinResList::GetWndFlag(_hWnd)->wnPainted == 1);
}
LRESULT BTNMMove(HWND _hWnd,UINT fwKeys,POINT curPos)
{
//SetTimer(_hWnd,1,10,TimerProc);
if(::GetCapture() != _hWnd)
{
SetCapture(_hWnd);
}
RECT rcClnt;
GetClientRect(_hWnd,&rcClnt);
if(::PtInRect(&rcClnt,curPos))
{
if(!IsPainted(_hWnd))
{
SetPainted(_hWnd,true);
InvalidateRect(_hWnd,&rcClnt,TRUE);
}
SetOver(_hWnd,true);
}
else
{
if(::GetCapture() == _hWnd)
{
::ReleaseCapture();
}
SetOver(_hWnd,false);
SetLDown(_hWnd,false);
InvalidateRect(_hWnd,&rcClnt,TRUE);
SetPainted(_hWnd,false);
}
return 0L;
}
LRESULT TransMsg(SKINMSG &skMsg)
{
LRESULT lr = 0;
BOOL bCurState = FALSE;
switch(skMsg._msg)
{
case WM_SETFOCUS:
case WM_KILLFOCUS:
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case BM_SETCHECK:
if(WM_LBUTTONDOWN == skMsg._msg)
{
SetLDown(skMsg._hWnd,true);
SetPainted(skMsg._hWnd,false);
SetOver(skMsg._hWnd,false);
}
if(WM_LBUTTONUP == skMsg._msg)
{
SetLDown(skMsg._hWnd,false);
}
SkinWndState::SetRedraw(skMsg._hWnd,FALSE);
lr = SkinResList::CallDefWndProc(skMsg);
SkinWndState::SetRedraw(skMsg._hWnd,TRUE);
SkinWndState::InvalidRect(skMsg._hWnd,TRUE);
UpdateWindow(skMsg._hWnd);
return lr;
case BM_SETSTATE:
bCurState = (SendMessage(skMsg._hWnd,BM_GETSTATE,0,0) & BST_PUSHED);
if((skMsg._wPm && bCurState) ||
(!skMsg._wPm && !bCurState))
{
break;
}
SkinWndState::SetRedraw(skMsg._hWnd,FALSE);
lr = SkinResList::CallDefWndProc(skMsg);
SkinWndState::SetRedraw(skMsg._hWnd,TRUE);
SkinWndState::InvalidRect(skMsg._hWnd,TRUE);
UpdateWindow(skMsg._hWnd);
return lr;
}
return SkinResList::CallDefWndProc(skMsg);
}
LRESULT CALLBACK SkinButtonProc(SKINMSG &skMsg)
{
if(WM_MOUSEMOVE == skMsg._msg)
{
POINT pt = {LOWORD(skMsg._lPm),HIWORD(skMsg._lPm)};
BTNMMove(skMsg._hWnd,(UINT)skMsg._wPm,pt);
}
/*else if(skMsg._msg == WM_PAINT)
{
PAINTSTRUCT ps;
HDC hDc = BeginPaint(skMsg._hWnd,&ps);
PaintButton(hDc,ps,skMsg);
EndPaint(skMsg._hWnd,&ps);
return TRUE;
}*/
return TransMsg(skMsg);
}
HBITMAP DrawRadio(HDC hDc,RNHBitmap bmDraw,bool bCheck,bool bEnable,RECT &rcBm,COLORREF clr)
{
int iRadioWid = bmDraw.Width() / 4;
int iHei = bmDraw.Height() + 1;
rcBm.right = rcBm.left + iRadioWid;
RNHDC memDc(CreateCompatibleDC(hDc));
RNHBitmap bmp(CreateCompatibleBitmap(hDc,rcBm.right - rcBm.left,rcBm.bottom - rcBm.top));
HBITMAP obmp = (HBITMAP)SelectObject(memDc,bmp);
HBRUSH hb = CreateSolidBrush(clr);
FillRect(memDc,&rcBm,hb);
DeleteObject(hb);
int idx = 0;
if(bCheck)
{
idx = 1;
if(!bEnable) idx = 3;
}
else
{
if(!bEnable) idx = 2;
}
RECT rcDraw = rcBm;
int iOffset = max(0,rcBm.bottom-rcBm.top-iHei);
rcDraw.left = 0;
rcDraw.top += iOffset/2;
if(iOffset > 0)
{
rcDraw.bottom = rcDraw.top + iHei;
}
else
{
rcDraw.bottom = rcDraw.top + rcBm.bottom-rcBm.top;
}
//rcBm = rcDraw;
SkinDraw::DrawStretch(memDc,rcDraw,bmDraw,
iRadioWid * idx,0,iRadioWid,iHei,false);
SelectObject(memDc,obmp);
return bmp.Detach();
}
LRESULT BTNTimerFunc(HWND _hWnd)
{
return 0;
}
static LRESULT BTNLButtonDown()
{
return 0L;
}
static LRESULT BTNLButtonUp()
{
return 0L;
}
LRESULT PaintButton(HDC hDc,PAINTSTRUCT &ps,SKINMSG &skMsg)
{
bool m_bSelected,m_bFocus,m_bOver;
m_bSelected = m_bFocus = false;
m_bOver = IsOver(skMsg._hWnd);
RECT rcDraw = ps.rcPaint;
GetClientRect(skMsg._hWnd,&rcDraw);
RNHDC _hDc(hDc,false);
TCHAR strText[MAX_PATH + 1] = {0};
::GetWindowText(skMsg._hWnd,strText,MAX_PATH);
//获取按钮的状态
if(GetFocus() == skMsg._hWnd)
{
m_bFocus = true;
m_bSelected = true;
}
else
{
m_bFocus = false;
m_bSelected = false;
}
if(IsLDown(skMsg._hWnd))
{
m_bFocus = true;
}
RNHBitmap bmBtn(SkinIni::Instance()->GetBTNImg());
int iBtnWid = bmBtn.Width()/5;
WNDSTATE wState = SKIN_NORMAL;
if(IsLDown(skMsg._hWnd))
{
wState = SKIN_DOWN;
}
else if(m_bFocus)
{
wState = SKIN_FOCUS;
}
else if(m_bSelected && !m_bOver)
{
wState = SKIN_DOWN;
}
else if(SkinWndState::GetWndStyle(skMsg._hWnd) & WS_DISABLED)
{
wState = SKIN_DISABLE;
}
else if(m_bOver)
{
wState = SKIN_HOT;
}
BTNPOS btPos = SkinIni::Instance()->GetBtnPos();
RNHBitmap bmp;
bmp.Attach(DrawBtn(_hDc,bmBtn,rcDraw,wState));
HRGN wnRgn = SkinRgn::ImageToRgn(_hDc,bmp,btPos.clrTran);
SetWindowRgn(skMsg._hWnd,wnRgn,TRUE);
HRGN hRgn = CreateRectRgn(0,0,0,0);
GetWindowRgn(skMsg._hWnd,hRgn);
::SelectClipRgn(_hDc,hRgn);
RECT dsRc = {0,0,bmp.Width(),bmp.Height()};
RNHDC memDc(CreateCompatibleDC(_hDc));
HBITMAP obmp = (HBITMAP)SelectObject(memDc,bmp);
SkinDraw::DrawStretch(_hDc,memDc,rcDraw,dsRc);
SelectClipRgn(_hDc,NULL);
DeleteObject(hRgn);
SelectObject(memDc,obmp);
//显示按钮的文本
if(_tcslen(strText) > 0)
{
HFONT hFont = (HFONT)SendMessage(skMsg._hWnd,WM_GETFONT,0,0);
HFONT hOldFont = (HFONT)SelectObject(_hDc,hFont);
SIZE szExtent;
GetTextExtentPoint32(_hDc,strText, _tcslen(strText),&szExtent);
int nCenterPointX = rcDraw.left + (rcDraw.right-rcDraw.left)/2;
int nCenterPointY = rcDraw.top + (rcDraw.bottom-rcDraw.top)/2;
POINT pt = {nCenterPointX - szExtent.cx/2,nCenterPointY-szExtent.cy/2};
if(IsLDown(skMsg._hWnd))
{
pt.x += 1;
pt.y += 1;
}
int nMode = SetBkMode(_hDc,TRANSPARENT);
RECT rcDr = rcDraw;
rcDr.left = pt.x;rcDr.top = pt.y;
rcDr.right = pt.x + szExtent.cx;
rcDr.bottom = pt.y + szExtent.cy;
if(SkinWndState::GetWndStyle(skMsg._hWnd) & WS_DISABLED)
{
DrawText(_hDc,strText,_tcslen(strText),&rcDr,DT_SINGLELINE);//|DT_CENTER|DT_VCENTER);
}
else
{
DrawText(_hDc,strText,_tcslen(strText),&rcDr,DT_SINGLELINE);
}
SelectObject(_hDc,hOldFont);
SetBkMode(_hDc,nMode);
}
return TRUE;
}
static HBITMAP DrawBtn(RNHDC &hDc,RNHBitmap &bmBtn,RECT rcDraw,WNDSTATE wState)
{
int iBtnWid = bmBtn.Width()/5;
BTNPOS btPos = SkinIni::Instance()->GetBtnPos();
int iBegPos = 0;
if(wState == SKIN_NORMAL)
{
iBegPos = 0;
}
else if(wState == SKIN_FOCUS)
{
iBegPos = iBtnWid*3;
}
else if(wState == SKIN_DOWN)
{
iBegPos = iBtnWid*1;
}
else if(wState == SKIN_HOT)
{
iBegPos = iBtnWid*3;
}
else if(wState == SKIN_DISABLE)
{
iBegPos = iBtnWid*2;
}
int iLFWid = max(btPos.iLTLen,btPos.iLBLen);
int iRFWid = max(btPos.iRTLen,btPos.iRBLen);
int iTFHei = max(btPos.iLTHei,btPos.iRTHei);
int iBFHei = max(btPos.iLBHei,btPos.iRBHei);
RECT rcTmp = {0,0,rcDraw.right,rcDraw.bottom};
if(rcTmp.right < (iLFWid + iRFWid))
{
//rcTmp.right = iLFWid + iRFWid;
}
if(rcTmp.bottom < (iTFHei + iBFHei))
{
//rcTmp.bottom = iTFHei + iBFHei;
}
RNHDC memDc(CreateCompatibleDC(hDc));
RNHBitmap bmp(CreateCompatibleBitmap(hDc,rcTmp.right-rcTmp.left,rcTmp.bottom-rcTmp.top));
HBITMAP obmp = (HBITMAP)SelectObject(memDc,bmp);
// 画左上角
RECT drTmp = rcDraw;
int iHei = rcDraw.bottom-rcDraw.top;
int iWid = rcDraw.right-rcDraw.left;
drTmp.bottom = btPos.iLTHei;
drTmp.right = btPos.iLTLen;
SkinDraw::Draw(memDc,bmBtn,drTmp,iBegPos,0,btPos.iLTLen,btPos.iLTHei);
drTmp.left = iWid - btPos.iRTLen;
drTmp.bottom = btPos.iRTHei;
drTmp.right = iWid;
SkinDraw::Draw(memDc,bmBtn,drTmp,iBegPos+(iBtnWid-btPos.iRTLen),0,
btPos.iRTLen,btPos.iRTHei);
drTmp.left = 0;
drTmp.top = iHei-btPos.iLBHei;
drTmp.right = btPos.iLBLen;
drTmp.bottom = iHei;
SkinDraw::Draw(memDc,bmBtn,drTmp,iBegPos,bmBtn.Height()-btPos.iLBHei,btPos.iLBLen,btPos.iLBHei);
drTmp.left = iWid - btPos.iRBLen;
drTmp.right = iWid;
drTmp.top = iHei - btPos.iRBHei;
SkinDraw::Draw(memDc,bmBtn,drTmp,iBegPos+(iBtnWid-btPos.iRTLen),bmBtn.Height()-btPos.iRBHei,
btPos.iRBLen,btPos.iRBHei);
drTmp.left = 0;
drTmp.top = btPos.iLTHei;
drTmp.bottom = iHei - btPos.iLBHei;
drTmp.right = iLFWid;
if(iHei > (btPos.iLTHei+btPos.iLBHei))
{
int iMid = (drTmp.bottom - drTmp.top) / 2;
drTmp.bottom = drTmp.top + iMid;
SkinDraw::Draw(memDc,bmBtn,drTmp,iBegPos,btPos.iLTHei+1,iLFWid,1);
drTmp.top = drTmp.bottom;
drTmp.bottom = iHei - btPos.iLBHei;
SkinDraw::Draw(memDc,bmBtn,drTmp,iBegPos,bmBtn.Height()-iBFHei-1,iLFWid,1);
}
drTmp.left = drTmp.right;
drTmp.top = 0;
drTmp.bottom = iTFHei;
drTmp.right = iWid - iLFWid;
SkinDraw::Draw(memDc,bmBtn,drTmp,iBegPos+iLFWid,0,
iBtnWid-iLFWid-iRFWid,iTFHei);
drTmp.left = iWid - iRFWid;
drTmp.top = btPos.iRTHei;
drTmp.bottom = iHei - btPos.iRBHei;
drTmp.right = iWid;
if(iHei > (btPos.iRTHei+btPos.iRBHei))
{
int iMid = (drTmp.bottom - drTmp.top) / 2;
drTmp.bottom = drTmp.top + iMid;
SkinDraw::Draw(memDc,bmBtn,drTmp,iBegPos+(iBtnWid-iRFWid),iTFHei+1,
iRFWid,1);
drTmp.top = drTmp.bottom;
drTmp.bottom = iHei - btPos.iRBHei;
SkinDraw::Draw(memDc,bmBtn,drTmp,iBegPos+(iBtnWid-iRFWid),
bmBtn.Height()-iBFHei-1,iRFWid,1);
}
drTmp.left = iLFWid;
drTmp.top = iHei - iBFHei;
drTmp.bottom = iHei;
drTmp.right = iWid - iRFWid;
SkinDraw::Draw(memDc,bmBtn,drTmp,iBegPos+iLFWid,bmBtn.Height()-iBFHei,
iBtnWid-iLFWid-iRFWid,iBFHei);
drTmp.left = iLFWid;
drTmp.top = iTFHei;
drTmp.bottom = iHei - iBFHei;
drTmp.right = iWid - iRFWid;
if(iHei > (btPos.iRTHei+btPos.iRBHei))
{
int iMid = (drTmp.bottom - drTmp.top) / 2;
drTmp.bottom = drTmp.top + iMid;
SkinDraw::Draw(memDc,bmBtn,drTmp,iBegPos+iLFWid,iTFHei + 1,
iBtnWid-iLFWid-iRFWid,1);
drTmp.top = drTmp.bottom;
drTmp.bottom = iHei - btPos.iRBHei;
SkinDraw::Draw(memDc,bmBtn,drTmp,iBegPos+iLFWid,bmBtn.Height()-iBFHei-1,
iBtnWid-iLFWid-iRFWid,1);
}
SelectObject(memDc,obmp);
return bmp.Detach();
}
LRESULT DrawCtrlItem(UINT idCtrl,LPDRAWITEMSTRUCT lpdis)
{
//return 0L;
bool m_bSelected,m_bFocus,m_bOver;
m_bSelected = m_bFocus = false;
m_bOver = IsOver(lpdis->hwndItem);
RECT rcDraw = lpdis->rcItem;
RNHDC _hDc(lpdis->hDC,false);
int nSaveDC= SaveDC(_hDc);
UINT uState = lpdis->itemState;
TCHAR strText[MAX_PATH + 1];
::GetWindowText(lpdis->hwndItem,strText,MAX_PATH);
RNHBitmap bmBtn(SkinIni::Instance()->GetBTNImg());
int iBtnWid = bmBtn.Width()/5;
WNDSTATE wState = SKIN_NORMAL;
if(IsLDown(lpdis->hwndItem))
{
wState = SKIN_DOWN;
}
else if(uState & ODS_FOCUS)
{
wState = SKIN_FOCUS;
}
else if(SkinWndState::GetWndStyle(lpdis->hwndItem) & WS_DISABLED)
{
wState = SKIN_DISABLE;
}
else if(m_bOver)
{
wState = SKIN_HOT;
}
BTNPOS btPos = SkinIni::Instance()->GetBtnPos();
RNHBitmap bmp;
bmp.Attach(DrawBtn(_hDc,bmBtn,rcDraw,wState));
HRGN wnRgn = SkinRgn::ImageToRgn(_hDc,bmp,btPos.clrTran);
SetWindowRgn(lpdis->hwndItem,wnRgn,TRUE);
HRGN hRgn = CreateRectRgn(0,0,0,0);
GetWindowRgn(lpdis->hwndItem,hRgn);
::SelectClipRgn(_hDc,hRgn);
RECT dsRc = {0,0,bmp.Width(),bmp.Height()};
RNHDC memDc(CreateCompatibleDC(_hDc));
HBITMAP obmp = (HBITMAP)SelectObject(memDc,bmp);
SkinDraw::DrawStretch(_hDc,memDc,rcDraw,dsRc);
SelectClipRgn(_hDc,NULL);
DeleteObject(hRgn);
//显示按钮的文本
if(_tcslen(strText) > 0)
{
HFONT hFont = (HFONT)SendMessage(lpdis->hwndItem,WM_GETFONT,0,0);
HFONT hOldFont = (HFONT)SelectObject(_hDc,hFont);
SIZE szExtent;
GetTextExtentPoint32(_hDc,strText, _tcslen(strText),&szExtent);
int nCenterPointX = rcDraw.left + (rcDraw.right-rcDraw.left)/2;
int nCenterPointY = rcDraw.top + (rcDraw.bottom-rcDraw.top)/2;
POINT pt = {nCenterPointX - szExtent.cx/2,nCenterPointY-szExtent.cy/2};
if(uState & ODS_SELECTED)
{
pt.x += 1;
pt.y += 1;
}
int nMode = SetBkMode(_hDc,TRANSPARENT);
RECT rcDr = rcDraw;
rcDr.left = pt.x;rcDr.top = pt.y;
rcDr.right = pt.x + szExtent.cx;
rcDr.bottom = pt.y + szExtent.cy;
if(uState & ODS_DISABLED ||
!IsWindowEnabled(lpdis->hwndItem))
{
SKinDrawState(_hDc,pt, szExtent, strText, DSS_DISABLED, TRUE, 0, (HBRUSH)NULL);
//DrawText(_hDc,strText,_tcslen(strText),&rcDr,DT_SINGLELINE);//|DT_CENTER|DT_VCENTER);
}
else
{
SKinDrawState(_hDc,pt, szExtent, strText, DSS_NORMAL, TRUE, 0, (HBRUSH)NULL);
//DrawText(_hDc,strText,_tcslen(strText),&rcDr,DT_SINGLELINE);
}
SelectObject(_hDc,hOldFont);
SetBkMode(_hDc,nMode);
}
RestoreDC(_hDc,nSaveDC);
return TRUE;
}
};
#endif