【问题标题】:Win32 to set color for Push ButtonWin32 为按钮设置颜色
【发布时间】:2014-07-31 07:26:31
【问题描述】:

作为 Win32 的初学者,我需要创建一个带有按钮的网格。所以基本上对于网格中的每个单元格,我都在创建按钮,如下消息:

DrawFrameControl(gdc,&rect,DFC_BUTTON,DFCS_BUTTONPUSH|DFCS_FLAT);

现在我需要为按钮设置颜色。我该怎么做。

【问题讨论】:

  • HBRUSH hBrush = ::CreateSolidBrush(...) 后跟 ::FillRect(&rect, hBrush)::SetBkColor(...) 后跟 ::ExtTextOut(...)。第二个选项性能更好,但不太容易理解。
  • 试过了... HBRUSH hBrush = CreateSolidBrush(RGB(102, 255, 192)); FillRect(gdc, &rect, hBrush); DrawFrameControl(gdc,&rect,DFC_BUTTON,DFCS_BUTTONPUSH|DFCS_FLAT);不工作。
  • -1 “不工作”还不够好。如果您无法清楚地展示您的尝试,并详细解释它如何未能达到您的期望,那么没有人可以帮助您。
  • :) 我正在使用这个示例link 创建一个网格,现在在 BabyGrid.cpp 的 DisplayColumn(...) 中,它正在使用 DrawFrameControl(gdc,&rect,DFC_BUTTON,DFCS_BUTTONPUSH| 创建按钮DFCS_FLAT); (更改为按钮)。现在按照上面的建议:我试过 ...HBRUSH hBrush = CreateSolidBrush(RGB(102, 255, 192)); FillRect(gdc, &rect, hBrush);其次是 DrawFrameControl(...)。但是 Button 的颜色没有改变,还是灰色的……现在还有什么其他的选择(我只使用 Win32)……
  • 虽然通过上面建议的其他方式,SetBkColor(...) 后跟 ExtTextOut(...),但我需要 ExtTextOut(...) 的 X、Y 坐标,根据文档 [链接] (msdn.microsoft.com/en-us/library/windows/desktop/…)。我需要在网格的单元格中绘制一个按钮。通过 LVITEMA 的子项,我如何获得每个子项的 X/Y 坐标。

标签: winapi button colors


【解决方案1】:

DrawFrameControl 无法做到这一点。它总是使用系统颜色绘制。当然,用户可以在个性化控制面板中配置它们,但默认情况下它们设置为单调的灰色。

更糟糕的是,DrawFrameControl 是一个不考虑主题(也称为“视觉样式”)的旧 API。它绘制的按钮看起来像 Windows 95 中的经典按钮控件。您必须使用theming APIs 之一来选择这些样式。

为了获得自定义颜色,您需要自己处理所有绘图。没有捷径。

如果您想要一个实际的按钮控件,您将创建一个具有BUTTON 窗口类和BS_OWNERDRAW 窗口样式的新窗口。这将导致按钮控件将WM_DRAWITEM 消息发送到其父窗口,您将在其中编写所有自定义绘图代码。

如果您只想要一个看起来 像按钮的东西(这就是您在此处想要的样子),您不需要创建实际的控件。您可以只处理父窗口的WM_PAINT 消息并绘制伪按钮。我认为这就是您已经尝试使用DrawFrameControl 做的事情。但是——正如我所提到的——DrawFrameControl 总是用自己的颜色来绘制,并且在善意的评论者建议你先绘制的彩色框的顶部进行绘制。你可以做的是使用DrawEdge function模拟DrawFrameControl的效果。这基本上只是绘制按钮的边框,让你在中间填充任何你想要的东西——颜色、图案、图像等。示例代码:

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 function。还有 很多 时间花在学习 Visual Styles API 上。

【讨论】:

  • 让我试试,我有一些周末学习材料(DrawThemeEdge)。
  • 非常感谢,这是一个解决方案。
猜你喜欢
  • 2011-09-12
  • 2013-08-30
  • 2011-04-07
  • 1970-01-01
  • 2017-01-12
  • 1970-01-01
  • 2023-03-11
  • 1970-01-01
  • 2013-11-29
相关资源
最近更新 更多