Reputation: 49
As beginner to Win32, I need to create a grid with buttons. So basically for every cell within grid I am creating button as following message:
DrawFrameControl(gdc,&rect,DFC_BUTTON,DFCS_BUTTONPUSH|DFCS_FLAT);
Now I need to set color to the button. How I can do it.
Upvotes: 0
Views: 3688
Reputation: 1
MFC has CDC::Draw3dRect, which lets you specify the colors to use for the 3D effect. You still have to calculate the colors, though.
Here is how it's implemented.
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);
}
Upvotes: 0
Reputation: 244692
You cannot do this with DrawFrameControl
. It always draws with the system colors. They are, of course, configurable by the user in the Personalization control panel, but they are set to a drab gray by default.
Worse, DrawFrameControl
is an old API that does not take theming (also known as "visual styles") into account. The buttons it draws will look like the classic button controls in Windows 95. You have to use one of the theming APIs to pick up these styles.
In order to get a custom color, you will need to handle all of the drawing yourself. There is no shortcut.
If you wanted an actual button control, you would create a new window with the BUTTON
window class and the BS_OWNERDRAW
window style. That would cause the button control to send WM_DRAWITEM
messages to its parent window, where you would write all of the custom drawing code.
If you just want something that looks like a button (which is what it seems like you want here), you don't need to create actual controls. You can just handle the parent window's WM_PAINT
message and draw the pseudo-buttons. I think this is what you were trying to do already with DrawFrameControl
. But—as I mentioned—DrawFrameControl
always draws with its own colors, and is drawing on top of the colored boxes that the well-meaning commenters have suggested that you draw first. What you can do is simulate the effect of DrawFrameControl
by using the DrawEdge
function. That will basically just draw the border of the button, letting you fill in the middle with whatever you want—a color, a pattern, an image, etc. Sample code:
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;
}
Result:
It works, but it's not pretty, since it doesn't respect the system theme. You will need the DrawThemeEdge
function for that. And a lot more time to invest learning the Visual Styles API.
Upvotes: 1