如何将窗口绘制到内存设备上下文?

Posted

技术标签:

【中文标题】如何将窗口绘制到内存设备上下文?【英文标题】:How to draw a window to a memory device context? 【发布时间】:2009-06-12 22:04:09 【问题描述】:

在我的应用程序中,用户双击表格行以打开对话框窗口。问题是窗口会立即显示 - 我想让窗口看起来“跳出”表格行(就像窗口“跳出”任务栏一样)。为此,我需要将对话框窗口绘制到内存设备上下文中 - 如果不先将其绘制到屏幕上,我该如何做到这一点?

谢谢

------------------ 编辑 ----------------------

@bubbafat: 谢谢 - 是的,我需要使用 CreateCompatibleDC,然后将内存 DC 的大小设置为对话窗口的大小。但随后我需要将窗口的“图片”绘制到存储设备像素上。这将允许我绘制“弹出”动画的每一帧 - 即:

第 1 帧:从 以 10% 正常缓冲到屏幕 大小和 10% 的不透明度 第 2 帧:复制 图像从缓冲区到 屏幕以 20% 正常尺寸和 20% 不透明度 等

【问题讨论】:

【参考方案1】:

如果您尝试将窗口绘制到内存 DC,请考虑向其发送 WM_PRINT 消息。假设您的窗口过程在正常情况下没有做任何特别奇怪的事情,它应该将所有内容呈现到您的 DC 中。可以从那里获取动画。

【讨论】:

【参考方案2】:

DrawAnimatedRects 函数是为任务栏“跳出”的功能 - 无需自己渲染窗口动画。

编辑:除了在 Vista 上不起作用。这是一些等效的代码:

// DrawAnimatedRects(wnd->GetSafeHwnd(), IDANI_CAPTION, animateFrom, &rect);
const DWORD MILLIs = 500;
DWORD startTime = GetTickCount();
DWORD now = startTime;
CRect offset(rect.left - animateFrom->left, rect.top - animateFrom->top,
             rect.right - animateFrom->right, rect.bottom - animateFrom->bottom);
wnd->Invalidate();
while (now - MILLIs < startTime)

    int fraction100 = (int) (((now - startTime) * 100) / MILLIs);
    CRect step(animateFrom->left + (fraction100 * offset.left) / 100,
               animateFrom->top + (fraction100 * offset.top) / 100,
               animateFrom->right + (fraction100 * offset.right) / 100,
               animateFrom->bottom + (fraction100 * offset.bottom) / 100);
    wnd->SetWindowPos(0, step.left, step.top,
                      step.right - step.left, step.bottom - step.top,
                      SWP_NOZORDER);
    wnd->ShowWindow(SW_SHOWNORMAL);
    Sleep(5);
    now = GetTickCount();

【讨论】:

【参考方案3】:

听起来您的问题是“如何创建与我的屏幕兼容的内存设备上下文以便我可以绘制它?”在这种情况下,答案是使用 CreateCompatibleDC。如果这不是您的问题,那么请提供更多信息,以便更清楚您在流程中的确切位置遇到问题。

【讨论】:

详情请看原帖

以上是关于如何将窗口绘制到内存设备上下文?的主要内容,如果未能解决你的问题,请参考以下文章

设备上下文-CDC绘图细节

在 CImage 对象上使用设备上下文绘制线条

有时在绘图期间设备上下文大小会减小

如何在 WinAPI 中将 TrueType 字体绘制到像素数组中?

MFC-GDI和GDI+

从 XP 中的隐藏或剪切窗口复制内容?