对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
结构。有什么想法吗?
最佳答案
这是CPen::GetExtLogPen实现中的错误:
该实现将忽略EXTLOGPEN结构中尾随大小可变的DWORD
数组。此结构定义为:
如果elpStyleEntry数组的长度最多为1个元素,则对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。