【问题标题】:Print preview in Visual Studio 6 vs. Visual Studio 2013Visual Studio 6 与 Visual Studio 2013 中的打印预览
【发布时间】:2014-11-08 23:40:14
【问题描述】:

我正在将旧的 MFC MDI(多文档界面)应用程序从 Visual Studio 6 迁移到 Visual Studio 2013。这个过程非常简单,但现在我遇到了一个关于打印预览的问题。

当我使用 Visual Studio 6 编译程序时,打印预览如下所示:

预览窗口接管主框架窗口,移除菜单和工具栏。

但是用 Visual Studio 2013 编译的同一个程序看起来像这样:

打印预览发生在视图的框架窗口中,由于各种原因,这种行为是不可接受的。 在单步执行 VS6 和 VS2013 上的 MFC 源代码时,我发现差异归结为 MFC 的 CView::DoPrintPreview 方法如何获取打印预览的框架窗口。

CView::DoPrintPreview(在viewprev.cpp中)的相关部分在这里:

Visual Studio 6

BOOL CView::DoPrintPreview(UINT nIDResource, CView* pPrintView,
    CRuntimeClass* pPreviewViewClass, CPrintPreviewState* pState)
{
    ASSERT_VALID_IDR(nIDResource);
    ASSERT_VALID(pPrintView);
    ASSERT(pPreviewViewClass != NULL);
    ASSERT(pPreviewViewClass->IsDerivedFrom(RUNTIME_CLASS(CPreviewView)));
    ASSERT(pState != NULL);

    CFrameWnd* pParent = STATIC_DOWNCAST(CFrameWnd, AfxGetMainWnd());
    ...

这里pParent 将只包含主框架窗口。

Visual Studio 2013

BOOL CView::DoPrintPreview(UINT nIDResource, CView* pPrintView,
    CRuntimeClass* pPreviewViewClass, CPrintPreviewState* pState)
{
    ASSERT_VALID_IDR(nIDResource);
    ASSERT_VALID(pPrintView);
    ASSERT(pPreviewViewClass != NULL);
    ASSERT(pPreviewViewClass->IsDerivedFrom(RUNTIME_CLASS(CPreviewView)));
    ASSERT(pState != NULL);

    CWnd* pMainWnd = GetParentFrame();
    if (DYNAMIC_DOWNCAST(CFrameWnd, pMainWnd) == NULL)
    {
        // if it's not a frame, we'll try the main window
        pMainWnd = AfxGetMainWnd();
    }

    CFrameWnd* pParent = STATIC_DOWNCAST(CFrameWnd, pMainWnd);
    ...

这里pParent 将包含视图的框架窗口(通过GetParentFrame() 获得)而不是主框架窗口。

备注

  • 此行为发生在 Visual Studio 6 以上的大多数(如果不是所有)Visual Studio 版本上。
  • 这只是 MDI 程序的问题,SDI 程序的行为保持不变,顺便说一句,这与 SDI 一样正常,视图的框架窗口实际上是主框架窗口。

有人知道我如何在不需要重新实现一半 MFC 的 CViewCPreviewView 类的情况下使用 Visual Studio 获得与使用 Visual Studio 6 相同的行为吗?

【问题讨论】:

  • 我在将 VC6 项目转换为 VS10 时遇到了一些相关的问题,但不一样,我的打印预览会崩溃。我不得不从 CView 派生出我自己的打印预览类——如果这能给你一个指针的话。尽管新模型更准确,因为它更像真正的 MDI。如果你能坚持下去,试着证明一下。
  • 如何创建自己的CFrameWnd 来充当CView 的临时父级?
  • @user1793036:你能提供更多细节吗?

标签: c++ visual-studio mfc porting visual-c++-6


【解决方案1】:

我不确定它是否有效,但您可以尝试使用 SetParent。

  • 遗憾的是 CView::DoPrintPreview 不是虚拟的。所以覆盖 CView::OnFilePrintPreview。实现很简单,只需调用 DoPrintPreview。
  • 现在使用 GetParent 并保存视图的旧 Parent。保存。
  • 使用 SetParent 并将视图附加到 AfxGetMainWnd
  • 调用 DoPrintPreview
  • DoPrintPreview 返回后使用 SetParent 并再次设置旧保存的父句柄。

应该可以,因为 Frame 和 view 的结构与应用程序的 SDI 形式不同。

【讨论】:

  • 看起来像this。此外,在调用DoPrintPreview 之后立即调用SetParent(savedparendhandle) 无论如何可能是错误的,我认为应该在预览完成后设置原始父级,可能在CPreviewView::OnPreviewClose() 中。我也尝试了您的建议,但在调用DoPrintPreview 后没有立即调用SetParent,但结果相似。
  • 在调用 DoPrintPreview 之前也获取当前的 MDI-Frame 窗口。
  • 不太清楚你的意思。我应该如何处理那个 MDI 框架窗口?
  • 在 CMDIFrameWnd 内部有一个 m_hWndMDIClient 包含所有子窗口。隐藏这个。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多