InkStart 方法
InkStart、 InkDraw 和 InkStop 方法都使用 Win32 GUI 构造,例如设备上下文和笔对象。 这说明了为什么需要 CGuiPaper 作为单独的封装级别。 绘图纸的 GUI 方面在 CGuiPaper 中处理。 COPaper 对象仅发送墨迹数据。
CGuiPaper 封装级别的另一个设计原因是其 InkStart、 InkDraw 和 InkStop 方法的双重性质。 他们不仅调用 COPaper 在墨迹数据发生时记录墨迹数据,还会在墨迹发生时绘制绘图的视觉图像。 CGuiPaper 保留m_bInkSaving标志来管理这种双重性质。 当m_bInkSaving为 FALSE 时,将在屏幕上绘制图像,但不会将数据发送到 COPaper 进行记录。
当用户未移动鼠标,但 COPaper 的墨迹数据被重新提交到 CGuiPaper 进行自动重新绘制时,此方案用于重新绘制。 可以通过调用其 InkSaving 方法告知 CGuiPaper 设置m_bInkSaving标志。
以下示例代码片段演示 GUIPAPER 的 InkStart 方法。CPP 和接收器。Cpp。
InkStart 方法 (GUIPAPER。CPP)
HRESULT CGuiPaper::InkStart(
SHORT nX,
SHORT nY)
{
HRESULT hr = E_FAIL;
if (m_nLockKey || (!m_nLockKey && !m_bInkSaving))
{
// Start an ink drawing sequence only if one is not in progress.
if (!m_bInking)
{
// Remember start position.
m_OldPos.x = nX;
m_OldPos.y = nY;
// Delete old pen.
if (m_hPen)
DeleteObject(m_hPen);
// Create and select the new drawing pen.
m_hPen = CreatePen(PS_SOLID, m_nInkWidth, m_crInkColor);
SelectObject(m_hDC, m_hPen);
hr = NOERROR;
// Ask the Paper object to mark the start of the ink drawing
// sequence in the current ink color.
if (m_pIPaper && m_bInkSaving)
{
hr = m_pIPaper->InkStart(
m_nLockKey,
nX,
nY,
m_nInkWidth,
m_crInkColor);
// Capture the Mouse.
SetCapture(m_hWnd);
// We've modified the ink data--it is now "dirty" with
// respect to the compound file image. Set dirty flag.
m_bDirty = TRUE;
}
// Set inking flag to TRUE.
m_bInking = TRUE;
}
}
return hr;
}
InkStart 方法 (SINK。CPP)
StoClien 以调用其 COPaperSink 对象中连接的 IPaperSink 接口的形式接收绘图数据。 这些方法对应于 CGuiPaper 中类似的 InkStart、 InkDraw 和 InkStop 方法。
STDMETHODIMP COPaperSink::CImpIPaperSink::InkStart(
SHORT nX,
SHORT nY,
SHORT nWidth,
COLORREF crInkColor)
{
// Turn off ink saving to the COPaper object.
m_pBackObj->m_pGuiPaper->InkSaving(FALSE);
// Play the data back to the CGuiPaper for display only.
m_pBackObj->m_pGuiPaper->InkWidth(nWidth);
m_pBackObj->m_pGuiPaper->InkColor(crInkColor);
m_pBackObj->m_pGuiPaper->InkStart(nX, nY);
return NOERROR;
}
在接收器中调用 InkStart 时,它会调用 CGuiPaper 以关闭将墨迹保存到 COPaper。 COPaper 不需要接收其发送的数据的回显副本。 在接收器中调用 InkDraw 时,它只是将调用传递给 CGuiPaper::InkDraw。 在接收器中调用 InkStop 时,将调用 CGuiPaper 以重新打开墨迹保存。 结果是仅将 COPaper 的墨迹数据播放到 CGuiPaper 进行显示。
通过在“接收器”菜单上选择“断开连接”选项,可以测试 StoClien 在 IPaperSink 断开连接时的行为。 作为试验,断开接收器的连接后,从“帮助”菜单中选择“关于”。 此时将显示“关于”对话框,该对话框将涵盖 StoClien 绘图的一部分。 在“关于”对话框中单击“确定”。 请注意,所覆盖的绘图部分现在已消失。 绘图数据不会丢失,但图像的一部分已丢失。 客户端收到WM_PAINT消息并发出 IPaper::Redraw 方法。 但由于接收器未连接,因此它未收到 IPaperSink 调用以重新绘制绘图。
还可以通过最小化 StoClien 并还原它来测试此行为。 在这种情况下,整个绘图图像会丢失,需要重新绘制。 若要在这些测试之一之后重新绘制绘图图像,请使用“接收器”菜单重新连接,然后从“绘图”菜单中选择“ 重绘 ”。