作为 Win32 的初学者,我需要创建一个带有按钮的网格。所以基本上对于网格中的每个单元格,我都创建按钮,如下消息:
DrawFrameControl(gdc,&rect,DFC_BUTTON,DFCS_BUTTONPUSH|DFCS_FLAT);
现在我需要为按钮设置颜色。我怎样才能做到。
您无法使用
DrawFrameControl
执行此操作。它始终使用系统颜色进行绘制。当然,用户可以在个性化控制面板中配置它们,但默认情况下它们设置为单调灰色。
更糟糕的是,
DrawFrameControl
是一个旧的 API,不考虑主题(也称为“视觉样式”)。它绘制的按钮看起来像 Windows 95 中的经典按钮控件。您必须使用 theming APIs 之一来选择这些样式。
为了获得自定义颜色,您需要自己处理所有绘图。没有捷径。
如果您想要一个 actual 按钮控件,您可以使用
BUTTON
窗口类和 BS_OWNERDRAW
窗口样式创建一个新窗口。这将导致按钮控件将 WM_DRAWITEM
消息发送到其父窗口,您将在其中编写所有自定义绘图代码。
如果您只是想要一些看起来像按钮的东西(这就是您在这里想要的),则不需要创建实际的控件。您只需处理父窗口的
WM_PAINT
消息并绘制伪按钮即可。我认为这就是您已经尝试用 DrawFrameControl
做的事情。但是,正如我提到的,DrawFrameControl
总是用自己的颜色进行绘制,并且是在善意的评论者建议您先绘制的彩色框之上绘制。您可以使用 DrawFrameControl
函数来模拟
DrawEdge
的效果。这基本上只是绘制按钮的边框,让你可以用任何你想要的东西填充中间——颜色、图案、图像等。示例代码:
case WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint(hWnd, &ps);
RECT rcButton;
rcButton.left = 50;
rcButton.top = 50;
rcButton.right = rcButton.left + 75;
rcButton.bottom = rcButton.top + 23;
// Set the DC's background color to whatever color we want the button to be.
// In this case, we use a nice orange. You can use anything you want.
// Or even fill the background with an image.
COLORREF clrOriginal = SetBkColor(ps.hdc, RGB(255, 128, 0));
if (clrOriginal != CLR_INVALID)
{
// Fill the button's rectangle with a solid color.
ExtTextOut(ps.hdc, 30, 30, ETO_OPAQUE, &rcButton, NULL, 0, NULL);
// Draw the button's border.
DrawEdge(ps.hdc, &rcButton, EDGE_RAISED, BF_TOPLEFT | BF_BOTTOMRIGHT);
// Restore the DC's original background color.
SetBkColor(ps.hdc, clrOriginal);
}
EndPaint(hWnd, &ps);
break;
}
结果:
它可以工作,但不太漂亮,因为它不尊重系统主题。为此,您将需要
DrawThemeEdge
函数。并且需要花费更多的时间来学习视觉样式 API。
这是它的实现方式。
void CDC::Draw3dRect(int x, int y, int cx, int cy,
COLORREF clrTopLeft, COLORREF clrBottomRight)
{
FillSolidRect(x, y, cx - 1, 1, clrTopLeft);
FillSolidRect(x, y, 1, cy - 1, clrTopLeft);
FillSolidRect(x + cx, y, -1, cy, clrBottomRight);
FillSolidRect(x, y + cy, cx, -1, clrBottomRight);
}