采用 DrawThemeBackground API函数可以给ThemeButton加上图标,类似以前Delphi风格的按钮。代码及界面效果如下,不难,就不多解释了
LRESULT CSkinWnd::ButtonWindowProc(HWND hRealWnd, UINT msg, WPARAM wp, LPARAM lp)
{
switch (msg)
{
case WM_PAINT:
{
DWORD style = (UINT)GetWindowLong(hRealWnd, GWL_STYLE) & 0xff;
if ( style != BS_PUSHBUTTON && style != BS_DEFPUSHBUTTON )
return CSubclassWnd::WindowProc(hRealWnd, msg,wp, lp);
CPaintDC dc(GetCWnd());
CRect rc;
CWnd* pWnd = CWnd::FromHandle(hRealWnd);
pWnd->GetClientRect(rc);
CDC xDC;
xDC.CreateCompatibleDC(&dc);
CBitmap xbmp;
xbmp.CreateCompatibleBitmap(&dc, rc.Width(), rc.Height());
xDC.SelectObject(&xbmp);
int state = (int)::SendMessageW(hRealWnd, BM_GETSTATE, 0, 0);
HTHEME hTheme=OpenThemeData(hRealWnd, L"Button");
if(hTheme)
{
int drawState;
if(::IsWindowEnabled(hRealWnd))
{
if(state & BST_PUSHED)
drawState = PBS_PRESSED;
else if(state & BST_HOT)
drawState = PBS_HOT;
else if(state & BST_FOCUS)
drawState = PBS_DEFAULTED;
else drawState = PBS_NORMAL;
}
else drawState = PBS_DISABLED;
::DrawThemeParentBackground(hRealWnd, xDC.m_hDC, rc);
DrawThemeBackground (hTheme,xDC.m_hDC, BP_PUSHBUTTON, drawState,&rc,NULL);
CloseThemeData (hTheme);
}
else
{
int nState;
if(!::IsWindowEnabled(hRealWnd))
nState = DFCS_BUTTONPUSH|DFCS_INACTIVE;
else if(state & BST_PUSHED)
nState = DFCS_BUTTONPUSH|DFCS_PUSHED;
else if (state & BST_HOT)
nState = DFCS_BUTTONPUSH|DFCS_HOT;
else
nState = DFCS_BUTTONPUSH;
::DrawFrameControl(xDC.m_hDC, rc, DFC_BUTTON, nState);
}
LONG l = ::GetWindowLong(hRealWnd, DWL_USER);
UINT nID = ::GetDlgCtrlID(hRealWnd);
int k = 0, j = 0;
if (IDOK == nID || IDYES == nID || IDCANCEL == nID || IDNO == nID)
{
CDC bDC;
CBitmap bmpx;
bmpx.LoadBitmapW((IDCANCEL == nID || IDNO == nID) ? IDB_CANCEL_ICO: IDB_OK_ICO);
bDC.CreateCompatibleDC(&xDC);
bDC.SelectObject(bmpx);
BITMAP bm;
bmpx.GetBitmap(&bm);
int l = 4;
int t = (rc.Height() - bm.bmHeight) / 2;
::TransparentBlt(xDC.m_hDC, l, t, bm.bmWidth, bm.bmHeight, bDC.m_hDC, 0, 0, bm.bmWidth, bm.bmHeight, RGB(255, 255, 255));
k = l; j = bm.bmWidth;
}
if (::IsWindowEnabled(hRealWnd))
::SetTextColor(xDC, RGB(255, 64, 64));
else
::SetTextColor(xDC, RGB(128, 128, 128));
xDC.SetBkMode(TRANSPARENT);
xDC.SelectObject(pWnd->GetFont());
int old = rc.left;
rc.left += k + j;
wchar_t lpsz[256];
::GetWindowText(hRealWnd, lpsz, 256);
::DrawText(xDC.m_hDC, lpsz, _tcslen(lpsz), rc, DT_CENTER | DT_VCENTER|DT_SINGLELINE);
rc.left = old;
::BitBlt(dc.m_hDC, rc.left, , rc.Width(), rc.Height(), xDC.m_hDC, rc.left, , SRCCOPY);
return 0L;
}
}
// We don't handle it: pass along
return CSubclassWnd::WindowProc(hRealWnd, msg, wp, lp);
}