Winapi 渲染到设备上下文时的资源管理(CDC/HDC)
我有一些关于在MFC中绘制笔划的问题。假设预先声明了类CStroke。示例代码如下所示Winapi 渲染到设备上下文时的资源管理(CDC/HDC),winapi,mfc,gdi,Winapi,Mfc,Gdi,我有一些关于在MFC中绘制笔划的问题。假设预先声明了类CStroke。示例代码如下所示 BOOL CStroke::DrawStroke(CDC* pDC) { CPen penStroke; if ( !penStroke.CreatePen(PS_SOLID, m_nPenWidth, m_color) ) return FALSE; CPen *pOldPen = pDC->SelectObject(&penStroke); p
BOOL CStroke::DrawStroke(CDC* pDC)
{
CPen penStroke;
if ( !penStroke.CreatePen(PS_SOLID, m_nPenWidth, m_color) )
return FALSE;
CPen *pOldPen = pDC->SelectObject(&penStroke);
pDC->MoveTo(m_pointArray[0]);
for( int i = 0; i < m_pointArray.GetSize(); i++ )
{
pDC->LineTo(m_pointArray[i]);
}
pDC->SelectObject(pOldPen);
return TRUE;
}
boolcstroke::DrawStroke(CDC*pDC)
{
CPen-penStroke;
如果(!penStroke.CreatePen(PS_实体、m_nPenWidth、m_颜色))
返回FALSE;
CPen*pOldPen=pDC->SelectObject(&penStroke);
pDC->MoveTo(m_pointArray[0]);
对于(int i=0;iLineTo(m_pointArray[i]);
}
pDC->选择对象(pOldPen);
返回TRUE;
}
我的问题是:
pDC->SelectObject(pOldPen)
来选择pOldPen李>
简短答复:
pOldPen
因为你欠打电话的人的。这不是礼物pDC->SelectObject(pOldPen)
来选择pOldPen
因为在DC中选择另一个资源是从DC中选择当前资源的唯一方法当通过调用将GDI资源选择到DC中时,设备上下文代表您使用GDI资源。在任何时候,DC中每种类型(笔、画笔、位图等)都有一种被选中。但是,它不会为您管理资源。资源管理由应用程序负责 不幸的是,上面的MFC实现隐藏了关于资源管理的一个重要细节。将代码转换为普通的WinAPI实现将使隐藏的内容更加明显:
BOOL CStroke::DrawStroke(HDC hDC)
{
// Create a new pen resource
HPEN penStroke = CreatePen(PS_SOLID, m_nPenWidth, m_color);
if ( penStroke == NULL )
return FALSE;
// Select it into the device context
HPEN oldPen = static_cast<HPEN>( SelectObject(hDC, &penStroke) );
// Render strokes
if ( m_pointArray.GetSize() > 0 ) // bugfix *
{
pDC->MoveTo(m_pointArray[0]);
for( int i = 1; i < m_pointArray.GetSize(); i++ ) // bugfix **
{
pDC->LineTo(m_pointArray[i]);
}
}
// Select pen out of DC
HPEN penCreatedAbove = static_cast<HPEN>( SelectObject(hDC, oldPen) );
// Clean up our resource (this is what CPen::~CPen() hides)
DeleteObject(penCreatedAbove)
return TRUE;
}
为完整起见,并将此实现与MFC代码对齐,以下是相关的MFC实现:
CPen::CreatePen(int nPenStyle, int nWidth, COLORREF crColor)
{ return Attach(::CreatePen(nPenStyle, nWidth, crColor)); }
CPen penStroke
是一个自动变量,因此当控件离开封闭块时(即drawstrope
返回时),它的析构函数运行。析构函数调用它的基类实现CGdiObject::DeleteObject
,如下所示:
BOOL CGdiObject::DeleteObject()
{
if (m_hObject == NULL)
return FALSE;
return ::DeleteObject(Detach());
}
bugfix*不再访问空序列的第一个元素 错误修复**第一个元素已用于
MoveTo
简短回答:
pOldPen
因为你欠打电话的人的。这不是礼物pDC->SelectObject(pOldPen)
来选择pOldPen
因为在DC中选择另一个资源是从DC中选择当前资源的唯一方法当通过调用将GDI资源选择到DC中时,设备上下文代表您使用GDI资源。在任何时候,DC中每种类型(笔、画笔、位图等)都有一种被选中。但是,它不会为您管理资源。资源管理由应用程序负责 不幸的是,上面的MFC实现隐藏了关于资源管理的一个重要细节。将代码转换为普通的WinAPI实现将使隐藏的内容更加明显:
BOOL CStroke::DrawStroke(HDC hDC)
{
// Create a new pen resource
HPEN penStroke = CreatePen(PS_SOLID, m_nPenWidth, m_color);
if ( penStroke == NULL )
return FALSE;
// Select it into the device context
HPEN oldPen = static_cast<HPEN>( SelectObject(hDC, &penStroke) );
// Render strokes
if ( m_pointArray.GetSize() > 0 ) // bugfix *
{
pDC->MoveTo(m_pointArray[0]);
for( int i = 1; i < m_pointArray.GetSize(); i++ ) // bugfix **
{
pDC->LineTo(m_pointArray[i]);
}
}
// Select pen out of DC
HPEN penCreatedAbove = static_cast<HPEN>( SelectObject(hDC, oldPen) );
// Clean up our resource (this is what CPen::~CPen() hides)
DeleteObject(penCreatedAbove)
return TRUE;
}
为完整起见,并将此实现与MFC代码对齐,以下是相关的MFC实现:
CPen::CreatePen(int nPenStyle, int nWidth, COLORREF crColor)
{ return Attach(::CreatePen(nPenStyle, nWidth, crColor)); }
CPen penStroke
是一个自动变量,因此当控件离开封闭块时(即drawstrope
返回时),它的析构函数运行。析构函数调用它的基类实现CGdiObject::DeleteObject
,如下所示:
BOOL CGdiObject::DeleteObject()
{
if (m_hObject == NULL)
return FALSE;
return ::DeleteObject(Detach());
}
bugfix*不再访问空序列的第一个元素
错误修复**第一个元素已用于
移动到非常简单:将笔更改回原来的状态。在绘图过程中笔是否更改了?是:-->penStroke.CreatePen(PS_SOLID,m_nPenWidth,m_color)因此,pOldPen记录penStroke替换的笔?完成后,需要将先前选择的资源重新选择到设备上下文中,以便进行适当的资源管理。考虑一个场景,其中<代码> cHe::拖拽是更复杂的渲染的一部分,并且调用<代码> DrawStroke < /CODE>的代码本身已经创建并选择了一个钢笔到设备上下文中。当DrawStroke
返回时,调用代码需要能够管理其资源,因此它需要在设备上下文中选择相同的笔。非常简单:将笔更改回以前的状态。笔在绘图过程中是否更改了?是:-->penStroke.CreatePen(PS_SOLID,m_nPenWidth,m_color)因此,pOldPen记录penStroke替换的笔?完成后,需要将先前选择的资源重新选择到设备上下文中,以便进行适当的资源管理。考虑一个场景,其中<代码> cHe::拖拽是更复杂的渲染的一部分,并且调用<代码> DrawStroke < /CODE>的代码本身已经创建并选择了一个钢笔到设备上下文中。当drawstrope
返回时,调用代码需要能够管理其资源,因此需要在设备上下文中选择相同的笔。