📄 buttonst.cpp
字号:
{
byIndex = (m_csIcons[1].hIcon == NULL ? 0 : 1);
}
}
CRect rImage;
PrepareImageRect(bHasTitle, rpItem, rpTitle, bIsPressed, m_csIcons[byIndex].dwWidth, m_csIcons[byIndex].dwHeight, rImage);
// Ole'!
pDC.DrawState(
rImage.TopLeft(), rImage.Size(),
m_csIcons[byIndex].hIcon,
(bIsDisabled ? DSS_DISABLED : DSS_NORMAL),
0);
}
void CButtonST::DrawItem(UINT ctrlID, LPDRAWITEMSTRUCT lpDIS)
{
CDCHandle pDC = lpDIS->hDC;
CPenHandle pOldPen;
// Checkbox or Radiobutton style ?
if (m_bIsCheckBox)
{
m_bIsPressed = (lpDIS->itemState & ODS_SELECTED) || m_nCheck;
}
// Normal button OR other button style ...
else
{
m_bIsPressed = (lpDIS->itemState & ODS_SELECTED);
}
m_bIsFocused = (lpDIS->itemState & ODS_FOCUS) != 0;
m_bIsDisabled = (lpDIS->itemState & ODS_DISABLED) != 0;
CRect itemRect = lpDIS->rcItem;
pDC.SetBkMode(TRANSPARENT);
if (!m_bIsFlat)
{
if (m_bIsFocused || GetDefault())
{
CBrush br;
br.CreateSolidBrush(RGB(0,0,0));
pDC.FrameRect(&itemRect, br);
itemRect.DeflateRect(1, 1);
}
}
// Prepare draw... paint button background
// Draw transparent?
if (m_bDrawTransparent)
{
PaintBk(pDC);
}
else
{
OnDrawBackground(pDC, &itemRect);
}
// Draw pressed button
if (m_bIsPressed)
{
if (m_bIsFlat)
{
if (m_bDrawBorder)
{
OnDrawBorder(pDC, &itemRect);
}
}
else
{
CBrush brBtnShadow;
brBtnShadow.CreateSolidBrush(GetSysColor(COLOR_BTNSHADOW));
pDC.FrameRect(&itemRect, brBtnShadow);
}
}
else // ...else draw non pressed button
{
CPen penBtnHiLight; // White
CPen pen3DLight; // Light gray
CPen penBtnShadow; // Dark gray
CPen pen3DDKShadow; // Black
penBtnHiLight.CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_BTNHILIGHT)); // White
pen3DLight.CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_3DLIGHT)); // Light gray
penBtnShadow.CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_BTNSHADOW)); // Dark gray
pen3DDKShadow.CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_3DDKSHADOW)); // Black
if (m_bIsFlat)
{
if (m_bMouseOnButton && m_bDrawBorder)
{
pDC.Draw3dRect(itemRect, ::GetSysColor(COLOR_BTNHILIGHT), ::GetSysColor(COLOR_BTNSHADOW));
}
}
else
{
// Draw top-left borders
// White line
pOldPen = pDC.SelectPen(penBtnHiLight);
pDC.MoveTo(itemRect.left, itemRect.bottom-1);
pDC.LineTo(itemRect.left, itemRect.top);
pDC.LineTo(itemRect.right, itemRect.top);
// Light gray line
pDC.SelectPen(pen3DLight);
pDC.MoveTo(itemRect.left+1, itemRect.bottom-1);
pDC.LineTo(itemRect.left+1, itemRect.top+1);
pDC.LineTo(itemRect.right, itemRect.top+1);
// Draw bottom-right borders
// Black line
pDC.SelectPen(pen3DDKShadow);
pDC.MoveTo(itemRect.left, itemRect.bottom-1);
pDC.LineTo(itemRect.right-1, itemRect.bottom-1);
pDC.LineTo(itemRect.right-1, itemRect.top-1);
// Dark gray line
pDC.SelectPen(penBtnShadow);
pDC.MoveTo(itemRect.left+1, itemRect.bottom-2);
pDC.LineTo(itemRect.right-2, itemRect.bottom-2);
pDC.LineTo(itemRect.right-2, itemRect.top);
//
pDC.SelectPen(pOldPen);
}
}
// Read the button's title
CString sTitle;
int nLen = GetWindowTextLength();
int nRetLen = GetWindowText(sTitle.GetBufferSetLength(nLen), nLen + 1);
CRect captionRect = lpDIS->rcItem;
// Draw the icon
if (m_csIcons[0].hIcon != 0)
{
DrawTheIcon(pDC, !sTitle.IsEmpty(), lpDIS->rcItem, captionRect, m_bIsPressed, m_bIsDisabled);
}
if (m_csBitmaps[0].hBitmap != 0)
{
pDC.SetBkColor(RGB(255,255,255));
DrawTheBitmap(pDC, !sTitle.IsEmpty(), lpDIS->rcItem, captionRect, m_bIsPressed, m_bIsDisabled);
}
// Write the button title (if any)
if (!sTitle.IsEmpty())
{
// Draw the button's title
// If button is pressed then "press" title also
if (m_bIsPressed && !m_bIsCheckBox)
{
captionRect.OffsetRect(1, 1);
}
// Center text
CRect centerRect = captionRect;
pDC.DrawText(sTitle, -1, captionRect, DT_WORDBREAK | DT_CENTER | DT_CALCRECT);
captionRect.OffsetRect((centerRect.Width() - captionRect.Width())/2, (centerRect.Height() - captionRect.Height())/2);
pDC.SetBkMode(TRANSPARENT);
if (m_bIsDisabled)
{
captionRect.OffsetRect(1, 1);
pDC.SetTextColor(::GetSysColor(COLOR_3DHILIGHT));
pDC.DrawText(sTitle, -1, captionRect, DT_WORDBREAK | DT_CENTER);
captionRect.OffsetRect(-1, -1);
pDC.SetTextColor(::GetSysColor(COLOR_3DSHADOW));
pDC.DrawText(sTitle, -1, captionRect, DT_WORDBREAK | DT_CENTER);
}
else
{
if (m_bMouseOnButton || m_bIsPressed)
{
pDC.SetTextColor(m_crColors[BTNST_COLOR_FG_IN]);
pDC.SetBkColor(m_crColors[BTNST_COLOR_BK_IN]);
}
else
{
pDC.SetTextColor(m_crColors[BTNST_COLOR_FG_OUT]);
pDC.SetBkColor(m_crColors[BTNST_COLOR_BK_OUT]);
}
pDC.DrawText(sTitle, -1, captionRect, DT_WORDBREAK | DT_CENTER);
}
}
if (!m_bIsFlat || (m_bIsFlat && m_bDrawFlatFocus))
{
// Draw the focus rect
if (m_bIsFocused)
{
CRect focusRect = itemRect;
focusRect.DeflateRect(3, 3);
pDC.DrawFocusRect(&focusRect);
}
}
}
void CButtonST::InitToolTip()
{
if (m_ToolTip.m_hWnd == 0)
{
// Create ToolTip control
m_ToolTip.Create(*this);
// Create inactive
m_ToolTip.Activate(false);
// Enable multiline
m_ToolTip.SetMaxTipWidth(400);
}
}
void CButtonST::SetTooltipText(LPCTSTR lpszText, bool bActivate)
{
// We cannot accept 0 pointer
if (lpszText == 0) { return; }
// Initialize ToolTip
InitToolTip();
// If there is no tooltip defined then add it
if (m_ToolTip.GetToolCount() == 0)
{
CRect rectBtn;
GetClientRect(rectBtn);
m_ToolTip.AddTool(*this, lpszText, rectBtn, 1);
}
// Set text for tooltip
m_ToolTip.UpdateTipText(lpszText, *this, 1);
m_ToolTip.Activate(bActivate);
}
void CButtonST::SetTooltipText(int nId, bool bActivate)
{
CString sText;
// load string resource
sText.LoadString(nId);
// If string resource is not empty
if (!sText.IsEmpty()) { SetTooltipText((LPCTSTR)sText, bActivate); }
}
void CButtonST::ActivateTooltip(bool bActivate)
{
// If there is no tooltip then do nothing
if (m_ToolTip.GetToolCount() == 0) { return; }
// Activate tooltip
m_ToolTip.Activate(bActivate);
}
LPARAM CButtonST::OnCtlColor(CDCHandle pDC, HWND button)
{
return (LPARAM)::GetStockObject(NULL_BRUSH);
}
void CButtonST::OnSysColorChange()
{
DefWindowProc();
m_dcBk.DeleteDC();
m_bmpBk.DeleteObject();
}
BOOL CButtonST::OnClicked(UINT wNotifyCode, int wID, HWND pWnd)
{
if (m_bIsCheckBox)
{
m_nCheck = !m_nCheck;
Invalidate();
}
else
{
// Handle the URL (if any)
if (::lstrlen(m_szURL) > 0)
{
::ShellExecute(0, _T("open"), m_szURL, 0,0, SW_SHOWMAXIMIZED);
return false;
}
}
return false;
}
void CButtonST::SetCheck(bool nCheck, bool bRepaint)
{
if (m_bIsCheckBox)
{
m_nCheck = nCheck;
if (bRepaint && IsWindow()) Invalidate();
}
}
bool CButtonST::GetCheck() const
{
return m_nCheck;
}
DWORD CButtonST::SetBitmaps(HBITMAP hBitmapIn, COLORREF crTransColorIn, HBITMAP hBitmapOut, COLORREF crTransColorOut)
{
int nRetValue;
BITMAP csBitmapSize;
// Free any loaded resource
FreeResources();
if (hBitmapIn != 0)
{
m_csBitmaps[0].hBitmap = hBitmapIn;
m_csBitmaps[0].crTransparent = crTransColorIn;
// Get bitmap size
nRetValue = ::GetObject(hBitmapIn, sizeof(csBitmapSize), &csBitmapSize);
if (nRetValue == 0)
{
FreeResources();
return BTNST_INVALIDRESOURCE;
}
m_csBitmaps[0].dwWidth = (DWORD)csBitmapSize.bmWidth;
m_csBitmaps[0].dwHeight = (DWORD)csBitmapSize.bmHeight;
// Create mask for bitmap In
m_csBitmaps[0].hMask = CreateBitmapMask(hBitmapIn, m_csBitmaps[0].dwWidth, m_csBitmaps[0].dwHeight, crTransColorIn);
if (m_csBitmaps[0].hMask == 0)
{
FreeResources();
return BTNST_FAILEDMASK;
}
if (hBitmapOut != 0)
{
m_csBitmaps[1].hBitmap = hBitmapOut;
m_csBitmaps[1].crTransparent = crTransColorOut;
// Get bitmap size
nRetValue = ::GetObject(hBitmapOut, sizeof(csBitmapSize), &csBitmapSize);
if (nRetValue == 0)
{
FreeResources();
return BTNST_INVALIDRESOURCE;
}
m_csBitmaps[1].dwWidth = (DWORD)csBitmapSize.bmWidth;
m_csBitmaps[1].dwHeight = (DWORD)csBitmapSize.bmHeight;
// Create mask for bitmap Out
m_csBitmaps[1].hMask = CreateBitmapMask(hBitmapOut, m_csBitmaps[1].dwWidth, m_csBitmaps[1].dwHeight, crTransColorOut);
if (m_csBitmaps[1].hMask == 0)
{
FreeResources();
return BTNST_FAILEDMASK;
}
}
}
RedrawWindow();
return BTNST_OK;
}
DWORD CButtonST::SetBitmaps(ATL::_U_STRINGorID nBitmapIn, COLORREF crTransColorIn, ATL::_U_STRINGorID nBitmapOut, COLORREF crTransColorOut, HMODULE rsrcModule)
{
HBITMAP hBitmapIn = 0;
HBITMAP hBitmapOut = 0;
HINSTANCE hInstResource = 0;
// Find correct resource handle
hInstResource = (rsrcModule != 0 ? rsrcModule : _Module.GetResourceInstance());
// Load bitmap In
hBitmapIn = (HBITMAP)::LoadImage(hInstResource, nBitmapIn.m_lpstr, IMAGE_BITMAP, 0, 0, 0);
// Load bitmap Out
hBitmapOut = (HBITMAP)::LoadImage(hInstResource, nBitmapOut.m_lpstr, IMAGE_BITMAP, 0, 0, 0);
return SetBitmaps(hBitmapIn, crTransColorIn, hBitmapOut, crTransColorOut);
}
HBITMAP CButtonST::CreateBitmapMask(HBITMAP hSourceBitmap, DWORD dwWidth, DWORD dwHeight, COLORREF crTransColor)
{
HBITMAP hMask = NULL;
HDC hdcSrc = NULL;
HDC hdcDest = NULL;
HBITMAP hbmSrcT = NULL;
HBITMAP hbmDestT = NULL;
COLORREF crSaveBk;
COLORREF crSaveDestText;
hMask = ::CreateBitmap(dwWidth, dwHeight, 1, 1, NULL);
if (hMask == NULL) return NULL;
hdcSrc = ::CreateCompatibleDC(NULL);
hdcDest = ::CreateCompatibleDC(NULL);
hbmSrcT = (HBITMAP)::SelectObject(hdcSrc, hSourceBitmap);
hbmDestT = (HBITMAP)::SelectObject(hdcDest, hMask);
crSaveBk = ::SetBkColor(hdcSrc, crTransColor);
::BitBlt(hdcDest, 0, 0, dwWidth, dwHeight, hdcSrc, 0, 0, SRCCOPY);
crSaveDestText = ::SetTextColor(hdcSrc, RGB(255, 255, 255));
::SetBkColor(hdcSrc,RGB(0, 0, 0));
::BitBlt(hdcSrc, 0, 0, dwWidth, dwHeight, hdcDest, 0, 0, SRCAND);
SetTextColor(hdcDest, crSaveDestText);
::SetBkColor(hdcSrc, crSaveBk);
::SelectObject(hdcSrc, hbmSrcT);
::SelectObject(hdcDest, hbmDestT);
::DeleteDC(hdcSrc);
::DeleteDC(hdcDest);
return hMask;
}
DWORD CButtonST::SetColor(ColorType byColorIndex, COLORREF crColor, bool bRepaint)
{
if (byColorIndex >= BTNST_MAX_COLORS) { return BTNST_INVALIDINDEX; }
// Set new color
m_crColors[byColorIndex] = crColor;
if (bRepaint && IsWindow()) { Invalidate(); }
return BTNST_OK;
}
DWORD CButtonST::GetColor(ColorType byColorIndex, COLORREF* crpColor)
{
if (byColorIndex >= BTNST_MAX_COLORS) { return BTNST_INVALIDINDEX; }
// Get color
*crpColor = m_crColors[byColorIndex];
return BTNST_OK;
}
bool CButtonST::SetURL(LPCTSTR lpszURL)
{
if (lpszURL != 0)
{
// Store the URL
::lstrcpyn(m_szURL, lpszURL, _MAX_PATH);
}
else
{
// Remove any existing URL
::ZeroMemory(&m_szURL, sizeof(m_szURL));
}
return true;
}
LRESULT CButtonST::OnCreate(LPCREATESTRUCT pCreateStruct)
{
UINT nBS = GetStyle();
// Be sure that we have an owner drawn button
ModifyStyle(0, BS_OWNERDRAW);
// Check if this is a checkbox
m_bIsCheckBox = (nBS & BS_CHECKBOX) != 0;
// Check if this is the default button
if (!m_bIsCheckBox)
{
m_bIsDefault = (nBS & BS_DEFPUSHBUTTON) != 0;
}
SetMsgHandled(false);
return 0;
}
BOOL CButtonST::SubclassWindow(HWND hWnd)
{
UINT nBS = ::GetWindowLong(hWnd, GWL_STYLE);
// Be sure that we have an owner drawn button
::SetWindowLong(hWnd, GWL_STYLE, (nBS | BS_OWNERDRAW));
// Check if this is a checkbox
m_bIsCheckBox = (nBS & BS_CHECKBOX) != 0;
// Check if this is the default button
if (!m_bIsCheckBox)
{
m_bIsDefault = (nBS & BS_DEFPUSHBUTTON) != 0;
}
return inherited::SubclassWindow(hWnd);
}
bool CButtonST::SetAutoRepeat(bool bSet, DWORD dwMilliseconds)
{
m_bAutoRepeat = bSet;
m_dwPeriodAutoRepeat = dwMilliseconds;
return true;
}
void CButtonST::DrawTransparent(bool bRepaint)
{
m_bDrawTransparent = true;
// Restore old bitmap (if any)
if (m_dcBk.m_hDC != 0 && m_pbmpOldBk != 0)
{
m_dcBk.SelectBitmap(m_pbmpOldBk);
}
if (m_bmpBk != 0) { m_bmpBk.DeleteObject(); }
if (m_dcBk != 0) { m_dcBk.DeleteDC(); }
// Repaint the button
if (bRepaint && IsWindow()) Invalidate();
}
WNDPROC CButtonST::GetWindowProc()
{
return WindowProc;
}
LRESULT CALLBACK CButtonST::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (uMsg == WM_LBUTTONDBLCLK)
{
uMsg = WM_LBUTTONDOWN;
}
return inherited::WindowProc(hWnd, uMsg, wParam, lParam);
}
// This function is called every time the button background needs to be painted.
// If the button is in transparent mode this function will NOT be called.
//
// Parameters:
// [IN] pDC
// Pointer to a CDC object that indicates the device context.
// [IN] pRect
// Pointer to a CRect object that indicates the bounds of the
// area to be painted.
//
// Return value:
// BTNST_OK
// Function executed successfully.
//
DWORD CButtonST::OnDrawBackground(CDCHandle pDC, LPCRECT pRect)
{
COLORREF crColor;
if (m_bMouseOnButton || m_bIsPressed)
{
crColor = m_crColors[BTNST_COLOR_BK_IN];
}
else
{
crColor = m_crColors[BTNST_COLOR_BK_OUT];
}
CBrush brBackground;
brBackground.CreateSolidBrush(crColor);
pDC.FillRect(pRect, brBackground);
return BTNST_OK;
} // End of OnDrawBackground
// This function is called every time the button border needs to be painted.
// If the button is in standard (not flat) mode this function will NOT be called.
//
// Parameters:
// [IN] pDC
// Pointer to a CDC object that indicates the device context.
// [IN] pRect
// Pointer to a CRect object that indicates the bounds of the
// area to be painted.
//
// Return value:
// BTNST_OK
// Function executed successfully.
//
DWORD CButtonST::OnDrawBorder(CDCHandle pDC, LPCRECT pRect)
{
if (m_bIsPressed)
{
pDC.Draw3dRect(pRect, ::GetSysColor(COLOR_BTNSHADOW), ::GetSysColor(COLOR_BTNHILIGHT));
}
else
{
pDC.Draw3dRect(pRect, ::GetSysColor(COLOR_BTNHILIGHT), ::GetSysColor(COLOR_BTNSHADOW));
}
return BTNST_OK;
} // End of OnDrawBorder
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -