对GetLogPen()
和GetExtLogPen()
的调用都失败了。它们返回零......
CBrush Brush;
Brush.CreateSolidBrush( COLOR_MINORSELECTION );
Brush.GetLogBrush( &lBrush );
DWORD Style[] = { 3, 1 };
CPen CustomPen;
CustomPen.CreatePen( PS_USERSTYLE, 1, &lBrush, 2, Style );
CPen *pOldPen = pDC->SelectObject( &CustomPen );
LOGPEN LogPen;
if( CustomPen->GetLogPen( &LogPen ) == 0 )
{
EXTLOGPEN ExtLogPen;
if( CustomPen->GetExtLogPen( &ExtLogPen ) == 0 )
return;
}
失败似乎是因为笔式使用了PS_USERSTYLE
。如果我使用PS_SOLID
笔执行此操作,则会按预期填充LogPen
结构。
有什么想法吗?
答案 0 :(得分:2)
这是CPen::GetExtLogPen实施中的错误:
int CPen::GetExtLogPen(EXTLOGPEN* pLogPen) { return ::GetObject(m_hObject, sizeof(EXTLOGPEN), pLogPen); }
该实现忽略了EXTLOGPEN结构中DWORD
的尾随变量大小的数组。该结构定义为:
typedef struct tagEXTLOGPEN { DWORD elpPenStyle; DWORD elpWidth; UINT elpBrushStyle; COLORREF elpColor; ULONG_PTR elpHatch; DWORD elpNumEntries; DWORD elpStyleEntry[1]; } EXTLOGPEN, *PEXTLOGPEN;
如果 elpStyleEntry 数组最多只有一个元素,则对CPen::GetExtLogPen
的调用会成功。除了那些具有PS_USERSTYLE
笔样式的笔外,所有笔都适用。使用PS_USERSTYLE
笔样式时, elpStyleEntry 条目将至少包含2个条目。
使用PS_USERSTYLE
笔样式的笔的解决方法是使用Windows API GetObject调用,并绕过MFC实现:
// Query for required buffer size
int sizeRequired = ::GetObject(CustomPen.m_hObject, 0, nullptr);
// Allocate buffer (may not be properly aligned)
std::vector<byte> buffer(sizeRequired);
// Retrieve the entire EXTLOGPEN structure
int ret = ::GetObject(CustomPen.m_hObject, static_cast<int>(buffer.size()), buffer.data());
assert(ret == static_cast<int>(buffer.size());
// Cast to const ref for convenient access
const EXTLOGPEN& elp = *reinterpret_cast<const EXTLOGPEN*>(buffer.data());
不幸的是,solution posted by Mark Ransom无法解决问题,因为CPen::GetExtLogPen
将sizeof(EXTLOGPEN)
传递给GetObject
调用,而不是其参数的真实大小。
<小时/> 注意:bug report已提交给Microsoft Connect。
答案 1 :(得分:0)
EXTLOGPEN
结构仅为一个样式参数定义空间,但最多允许16个。目前还不清楚GetExtLogPen
如何确定可用空间的大小。试试这个,看看它是否有帮助。
struct EXTLOGPEN16 : public EXTLOGPEN
{
DWORD elpStyleMore[15];
public:
EXTLOGPEN16()
{
elpNumEntries = 16;
}
};
EXTLOGPEN16 ExtLogPen;
if (CustomPen->GetExtLogPen(&ExtLogPen) == 0)
// ...