【问题标题】:creating a bitmap pattern for a window's HBRUSH为窗口的 HBRUSH 创建位图模式
【发布时间】:2009-06-12 23:03:01
【问题描述】:

嗯,我有点想在窗户上有一种淡淡的条纹图案……只是,因为它看起来不错。无论如何,我知道我可以制作一个阴影画笔,如下所示:

window with red stripes on white background http://www.cityaftersix.ca/uploads/windowpattern.png

但是,我只能设置前景色,不知道如何使背景不为白色(只使用默认的窗口颜色)。我在 MSDN 上四处寻找,试图弄清楚如何绘制一个位图,它使用默认背景颜色和稍暗的前景色来穿过窗口的背景。我该怎么做?请注意,我在 emacs 中工作,在 C 中——我没有像资源编辑器或类似的东西......我将在纯 C 中添加它。

有人知道这是怎么做到的吗?

我希望我可以用代码绘制一个简单的 5x5 位图——这样每次绘制时都使用COLOR_BACKGROUND。有没有办法得到COLOR_BACKGROUND,把那个颜色变暗,然后复制成新的颜色?


好的,好的,我做到了

稍后我会重新发布我的解决方案作为答案,但问题有点奇怪: 我对GetSysColor(COLOR_BTNFACE); 的调用以0x00BBGGRR 的格式返回COLORREF,而CreateBitmap(); 将其解释为0x00RRGGBB... 我的意思是,我只是交换了红色和蓝色字节,但有什么办法是为了避免这种字节顺序混乱还是只是 Windows 的一个怪癖?

另外,如何将这个画笔绘制到静态控件上?

【问题讨论】:

  • 英特尔是小端平台,你是来自大端的环境吗?也许这解释了混乱?
  • 不,这一切都只是在我的 Windows XP 笔记本电脑上......似乎一个函数将 RGB 值的顺序与另一个函数读取它们的顺序不同。如果这是系统字节序的问题,不是 0x00RRGGBB 还是 0xBBGGRR00?或 0x00BBGGRR / 0xRRGGBB00
  • 我认为 CreateBitmap 创建了一个依赖于设备的位图 - 位在内存中的布局格式取决于设备驱动程序。您可能想使用 CreateDIBSection 创建一个与设备无关的位图 - 您可以安全地编辑 DIB,而无需了解实现细节
  • 感谢您的提示,我会调查一下——但是使用 CreateBitmap 会遇到什么麻烦?我只是创建一次然后在各处绘制它......虽然我认为一个实现细节是位图数据必须是字对齐的......这在某些系统上可能会有所不同吗?嗯……

标签: c user-interface winapi


【解决方案1】:

您可以将CreateHatchBrush 用于简单的内置模式。要创建自己的,请使用 CreatePatternBrush.

引用 MSDN:

使用单色(每像素 1 位)位图创建的画笔具有绘制它的设备上下文的文本和背景颜色。由 0 位表示的像素用当前文本颜色绘制;用当前背景颜色绘制 1 位表示的像素。

我相信你想要做什么?

【讨论】:

  • 嗯,基本上。但是我真的不知道设备上下文是什么,我仍然不知道如何获取窗口的背景颜色,然后更改该值以创建前景色
  • 设备上下文是您在 GDI 中绘制的东西。它代表内存、屏幕、打印机之类的东西。
【解决方案2】:

您可以使用GetBkColor 获得设备上下文的当前背景颜色。您可以使用GetDC 获得与窗口兼容的设备上下文。要将它们放在一起,请使用以下内容:

HDC dc=GetDC(hWnd);
COLORREF backColour=GetBkColor(dc);

// do something...

ReleaseDC(dc);

【讨论】:

  • 这看起来容易多了,但是,我在一个函数中创建画笔,它在窗口类中使用(它尚未注册或创建)。
【解决方案3】:

好的,所以我想通了,一切正常。 为了创建图案,我首先创建了一个位图,如下所示:

   COLORREF bg = GetSysColor(COLOR_BTNFACE);
    bg = RGB(GetBValue(bg), GetGValue(bg), GetRValue(bg));
    COLORREF fg = bg - 0x00151515; //slightly darker than the background color
    COLORREF bits[30] = {          //would be problematic I guess if the color
      bg, bg, bg, bg, fg,          //was originally less than 0x00151515
      bg, bg, bg, fg, bg,
      bg, bg, fg, bg, bg,
      bg, fg, bg, bg, bg,
      fg, bg, bg, bg, bg
    };
    HBITMAP hbm = CreateBitmap(5, 5, 1, sizeof(COLORREF) * 8, bits);

GetSysColor() 返回格式为 0x00BBGGRR(蓝色、绿色、红色)的颜色,但 CreateBitmap() 想要格式为 0x00RRGGBB 的颜色。所以我只是交换了bg 中的蓝色和红色值。我把它变成了这样的 HBRUSH:

hbr = CreatePatternBrush(hbm);

无论如何,这很好用,只是 STATIC 控件超出了它的顶部,并且使它变得非常丑陋(文本后面的所有空白区域,以及在控件中根本没有任何文本的部分) .

为了使STATIC 控件透明,我处理了WM_CTLCOLORSTATIC 消息(以前我试图向控件发送某种消息,以更改背景,就像我使用WM_SETTEXT 更改文本一样)。所以我这样做了:

HBRUSH main_st_color_ev(HWND hwnd, HDC hdc, HWND hwndChild, int type){

  return stripes;

}

(条纹是一个全局 HBRUSH,我将之前制作的位图画笔分配给它)
这将控件中所有丑陋的空白空间更改为我创建的画笔。然而,文本后面的空间变成了白色。在搜索了互联网和 MSDN 之后,我做了以下补充:

SetBkMode(hdc, TRANSPARENT);

【讨论】:

  • 我认为这段代码可能很脆弱——经过一番研究,似乎 CreateBitmap 创建了一个 DDB(设备相关位图)——你不应该用它来编辑。 DDB 中的位布局取决于设备驱动程序。您应该改为创建 DIB。我希望不要太混乱
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多