扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
使用MFC的CBitmapButton或者CButtonST等类很容易在按钮上画出位图+文字的Button。但是如果不使用MFC该怎么画呢?下面就是纯粹的SDK做的位图+文字的Button:
// OwnerDrawBtn.cpp : Defines the entry point for the application. #include "stdafx.h" #define ICON_HEIGHT 32 static HINSTANCE hInst; // current instance static void InitializeDialog(HWND hwnd); LRESULT CALLBACK DialogFunc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); int APIENTRY WinMain(HINSTANCE hInstance, while (GetMessage(&msg, NULL, 0, 0)) LRESULT CALLBACK DialogFunc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_CREATE: case WM_COMMAND: if(lpDIS->CtlID != IDC_BMPBTN) HDC dc = lpDIS->hDC; // button state RECT itemRect = lpDIS->rcItem; ::SetBkMode(dc, TRANSPARENT); if (bIsFocused) COLORREF crColor = GetSysColor(COLOR_BTNFACE); HBRUSH brBackground = CreateSolidBrush(crColor); ::FillRect(dc, &itemRect, brBackground); ::DeleteObject(brBackground); // Draw pressed button ::DrawFrameControl(dc, &itemRect, DFC_BUTTON, uState); // Read the button's title RECT captionRect = lpDIS->rcItem; BOOL bHasTitle = (sTitle[0] != '\0'); if (bHasTitle) ::SetBkMode(dc, TRANSPARENT); if (bIsDisabled) // Draw the focus rect return (TRUE); break; void InitializeDialog(HWND hwnd) ::SetFocus(::GetDlgItem(hwnd, IDC_BMPBTN)); static void DrawTheIcon(HWND hButtonWnd, HDC* dc, BOOL bHasTitle, RECT* rpItem, RECT* rpTitle, BOOL bIsPressed, BOOL bIsDisabled) // Ole'! static void PrepareImageRect(HWND hButtonWnd, BOOL bHasTitle, RECT* rpItem, RECT* rpTitle, BOOL bIsPressed, DWORD dwWidth, DWORD dwHeight, RECT* rpImage) ::CopyRect(rpImage, rpItem); ::GetClientRect(hButtonWnd, &rBtn); 关键点:必须在BUTTON的属性中设置:Owner draw,这样才会产生WM_DRAWITEM消息
//
#include "resource.h"
#define ICON_WIDTH 32
static HICON hIcon = NULL;
static void DrawTheIcon(HWND hButtonWnd, HDC* dc, BOOL bHasTitle, RECT* rpItem, RECT* rpTitle, BOOL bIsPressed, BOOL bIsDisabled);
static void PrepareImageRect(HWND hButtonWnd, BOOL bHasTitle, RECT* rpItem, RECT* rpTitle, BOOL bIsPressed, DWORD dwWidth, DWORD dwHeight, RECT* rpImage);
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
static char szAppName[] = "OWNERDRAWBUTTON";
HWND hwnd;
MSG msg;
WNDCLASSEX wndclass;
wndclass.cbSize = sizeof(WNDCLASSEX);
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = DialogFunc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = DLGWINDOWEXTRA;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wndclass.lpszMenuName = (LPCSTR)szAppName;
wndclass.lpszClassName = szAppName;
wndclass.hIconSm = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
RegisterClassEx(&wndclass);
hInst = hInstance; // get current instance.
hwnd = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), GetDesktopWindow(), (DLGPROC)DialogFunc);
ShowWindow(hwnd, nCmdShow);
{
if (!IsWindow(hwnd) || !IsDialogMessage(hwnd, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
{
switch(message)
{
case WM_INITDIALOG:
InitializeDialog(hwnd);
break;
break;
switch (LOWORD(wParam))
{
case IDOK:
::EndDialog(hwnd, LOWORD(wParam));
::PostQuitMessage(0);
break;
default:
break;
}
break;
case WM_DRAWITEM:
{
// draw the owner draw button
LPDRAWITEMSTRUCT lpDIS = (LPDRAWITEMSTRUCT) lParam;
{
return (0);
}
BOOL bIsPressed = (lpDIS->itemState & ODS_SELECTED);
BOOL bIsFocused = (lpDIS->itemState & ODS_FOCUS);
BOOL bIsDisabled = (lpDIS->itemState & ODS_DISABLED);
{
HBRUSH br = CreateSolidBrush(RGB(0,0,0));
::FrameRect(dc, &itemRect, br);
::InflateRect(&itemRect, -1, -1);
::DeleteObject(br);
}
if (bIsPressed)
{
HBRUSH brBtnShadow = CreateSolidBrush(GetSysColor(COLOR_BTNSHADOW));
::FrameRect(dc, &itemRect, brBtnShadow);
::DeleteObject(brBtnShadow);
}
else // ...else draw non pressed button
{
UINT uState = DFCS_BUTTONPUSH | ((bIsPressed) ? DFCS_PUSHED : 0);
}
char sTitle[100];
::GetWindowText(::GetDlgItem(hwnd, IDC_BMPBTN), sTitle, 100);
DrawTheIcon(::GetDlgItem(hwnd, IDC_BMPBTN), &dc, bHasTitle, &lpDIS->rcItem, &captionRect, bIsPressed, bIsDisabled);
{// Draw the button's title
// Center text
RECT centerRect = captionRect;
::DrawText(dc, sTitle, -1, &captionRect, DT_WORDBREAK | DT_CENTER | DT_CALCRECT);
LONG captionRectWidth = captionRect.right - captionRect.left;
LONG captionRectHeight = captionRect.bottom - captionRect.top;
LONG centerRectWidth = centerRect.right - centerRect.left;
LONG centerRectHeight = centerRect.bottom - centerRect.top;
::OffsetRect(&captionRect, (centerRectWidth - captionRectWidth)/2, (centerRectHeight - captionRectHeight)/2);
{
::OffsetRect(&captionRect, 1, 1);
::SetTextColor(dc, ::GetSysColor(COLOR_3DHILIGHT));
::DrawText(dc, sTitle, -1, &captionRect, DT_WORDBREAK | DT_CENTER);
::OffsetRect(&captionRect, -1, -1);
::SetTextColor(dc, ::GetSysColor(COLOR_3DSHADOW));
::DrawText(dc, sTitle, -1, &captionRect, DT_WORDBREAK | DT_CENTER);
}
else
{
::SetTextColor(dc, ::GetSysColor(COLOR_BTNTEXT));
::SetBkColor(dc, ::GetSysColor(COLOR_BTNFACE));
::DrawText(dc, sTitle, -1, &captionRect, DT_WORDBREAK | DT_CENTER);
}
if (bIsFocused)
{
RECT focusRect = itemRect;
::InflateRect(&focusRect, -3, -3);
::DrawFocusRect(dc, &focusRect);
}
} // End if
}
case WM_DESTROY:
::PostQuitMessage(0);
return FALSE;
}
return FALSE;
}
{
hIcon = ::LoadIcon(hInst, MAKEINTRESOURCE(IDI_ICON1));
}
{
RECT rImage;
PrepareImageRect(hButtonWnd, bHasTitle, rpItem, rpTitle, bIsPressed, ICON_WIDTH, ICON_HEIGHT, &rImage);
::DrawState(*dc,
NULL,
NULL,
(LPARAM)hIcon,
0,
rImage.left,
rImage.top,
(rImage.right - rImage.left),
(rImage.bottom - rImage.top),
(bIsDisabled ? DSS_DISABLED : DSS_NORMAL) | DST_ICON);
}
{
RECT rBtn;
if (bHasTitle == FALSE)
{
// Center image horizontally
LONG rpImageWidth = rpImage->right - rpImage->left;
rpImage->left += ((rpImageWidth - (long)dwWidth)/2);
}
else
{
// Image must be placed just inside the focus rect
LONG rpTitleWidth = rpTitle->right - rpTitle->left;
rpTitle->right = rpTitleWidth - dwWidth - 30;
rpTitle->left = 30;
rpImage->left = rBtn.right - dwWidth - 30;
// Center image vertically
LONG rpImageHeight = rpImage->bottom - rpImage->top;
rpImage->top += ((rpImageHeight - (long)dwHeight)/2);
}
}
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者