【发布时间】:2019-11-29 11:22:57
【问题描述】:
我使用以下模式录制增强的元文件以供以后播放:
POINT pts[] = {
//.....
};
::SelectObject(hEnhDC, ::GetStockObject(LTGRAY_BRUSH));
::Polygon(hEnhDC, pts, _countof(pts));
现在我不得不使用 GDI+ 来提供抗锯齿功能,因此我正在尝试转换该代码示例:
Gdiplus::Point pts[] = {
//...
};
Gdiplus::Graphics grx(hEnhDC);
Gdiplus::Pen pen(Gdiplus::Color(255, GetRValue(clrPen), GetGValue(clrPen), GetBValue(clrPen)), PEN_THICKNESS);
grx.FillPolygon(&brush, pts, _countof(pts));
grx.DrawPolygon(&pen, pts, _countof(pts));
问题是如何将股票对象 HBRUSH 从 ::GetStockObject(LTGRAY_BRUSH) 转换为 GDI+ Brush 对象?
编辑:伙计们,感谢您提出的所有建议。我很抱歉没有提供更多细节。这个问题不是关于从股票刷中获得RGB 颜色三元组。我可以使用GetSysColor 函数或LOGBRUSH 来完成所有这些操作,如下所示。
诀窍在于上面的第一句话。我正在录制一个可以在单独的计算机上播放的增强元文件,因此我无法将颜色硬编码到其中。
让我解释一下。比如说,第一个 GDI 示例(让我们将其简化为一个灰色填充的三角形):
POINT pts[] = {
{100, 100,},
{100, 120,},
{120, 100,},
};
::SelectObject(hEnhDC, ::GetStockObject(LTGRAY_BRUSH));
::Polygon(hEnhDC, pts, _countof(pts));
如果我随后对该元文件调用GetEnhMetaFileBits,我将获得以下数据:
因此,正如您在记录的元文件中看到的 EMR_SELECTOBJECT 对象指定了 LTGRAY_BRUSH = 0x80000001,当目标系统上的 meta-file is played 时,它将正确替换颜色。
这就是我想要通过 GDI+ 实现的目标。出于某种原因,它似乎只支持其Brush 类中的硬编码颜色三元组。这就是我问的原因。
否则,一种解决方案是解析增强元文件的原始数据。 (但对于 GDI+,它是一个更复杂的结构,还涉及解析EMR_GDICOMMENT 对象。)然后在播放 GDI+ 元文件之前在目标系统上替换所需的颜色。但它涉及编写大量代码,我在这个阶段试图避免这些......
【问题讨论】:
-
你为什么特别想使用股票对象?为什么不直接选择浅灰色并用它制作画笔?
-
@JonathanPotter:因为
GetStockObject(LTGRAY_BRUSH)在您的计算机上可能是“浅灰色”,但在选择high contrast配色方案的其他人的计算机上可能是亮黄色。 -
LOGBRUSH lb; GetObjectW(GetStockObject(LTGRAY_BRUSH), sizeof(lb), &lb); Color clr; clr.SetFromCOLORREF(lb.lbColor); Pen pen(&SolidBrush(clr)); -
@c00000fd 颜色方案会影响 GetSysColor 和 GetSysColorBrush API 调用的结果。 GetStockObject 不同。
-
我认为你过度设计了一些东西。与窗口边框和其他与主题相关的东西不同,库存画笔不会改变。几十年来,MS 已经在docs.microsoft.com/en-us/openspecs/windows_protocols/ms-emf/… 那里记录了它们。规范说
#C0C0C0,而且一直都是。毕竟这是一种数据交换格式。