1

我跳进了一个旧的 MFC 应用程序,它在 Windows 10 1703/Creators 更新下运行时出现问题。它适用于 XP 到 Windows 10/1607。经过一番调查,似乎在 Windows 10/1703 中,该应用程序无法将元文件(wmf 和 emf)从剪贴板粘贴到 CRichTextView 并保存。图形数据未嵌入 rtf 文件中。这是一个精简的示例:

static void testFn(CRichEditView* View)
{
    // Minimal Example

    // Init MetaFileDC
    CMetaFileDC MetaFileDC;
    CClientDC DC(NULL);
    MetaFileDC.CreateEnhanced(NULL, NULL, NULL, NULL);
    CRect Recht(0, 0, 400, 300);
    MetaFileDC.SetAttribDC(DC.m_hDC);
    MetaFileDC.SetWindowOrg(0, 0);
    MetaFileDC.SetWindowExt(Recht.Size());

    // draw : "ABC" and a line
    MetaFileDC.TextOutA(0, 0, "ABC");
    MetaFileDC.MoveTo(0, 0);
    MetaFileDC.LineTo(Recht.right, Recht.bottom);

    // to clipboard
    View->OpenClipboard();
    EmptyClipboard();
    SetClipboardData(CF_ENHMETAFILE, MetaFileDC.CloseEnhanced());
    CloseClipboard();

    // paste from clipboard
    View->GetRichEditCtrl().Paste();

    // save rtf file
    View->GetDocument()->OnSaveDocument("abc.rtf");
}

此示例将增强的图元文件 mit "ABC" 和一行粘贴到 CRichTextView 并将文档保存为 "abc.rtf"

  • 从 Windows XP 到 Windows 10/1607 这工作正常
  • 使用最新的 Creators 更新,文件变小,数据未保存

大概和RichEditBox有关:图片消失后的图片和内容(Windows 10 1703 Creators Update)

有任何想法吗?有没有办法在没有剪贴板的情况下获取文档中的元文件图形?位图仍然有效。

4

1 回答 1

1

创作者更新后,我们的软件也遇到了同样的问题。我们还通过剪贴板获取我们的图形。在对 Google 和 SO 进行一些研究之后,我想出了这个:

HENHMETAFILE hMetafile = nullptr;

if(OpenClipboard(AfxGetMainWnd()->m_hWnd))
{
    if(EnumClipboardFormats(0) == CF_ENHMETAFILE)
        hMetafile = (HENHMETAFILE) GetClipboardData(CF_ENHMETAFILE);

    CloseClipboard();
}

Gdiplus::MetafileHeader header;
Gdiplus::Metafile::GetMetafileHeader(hMetafile,&header);

HDC hdc = AfxGetMainWnd()->GetDC()->GetSafeHdc();
UINT bufsize = GetWinMetaFileBits(hMetafile,0,0,MM_ANISOTROPIC,hdc);
BYTE* buffer = new BYTE[bufsize];
GetWinMetaFileBits(hMetafile,bufsize,buffer,MM_ANISOTROPIC,hdc);

std::stringstream ss;
ss << "{\\rtf1{\\pict\\wmetafile8";
ss << "\\picw" << (UINT)((header.Width / header.DpiX) * 2540) << "\\pich" << (UINT)((header.Height / header.DpiY) * 2540);
ss << "\\picwgoal" << (UINT)((header.Width / header.DpiX) * 1440) << "\\pichgoal" << (UINT)((header.Height / header.DpiY) * 1440);
ss << " " << std::endl;
ss << std::hex << std::setfill('0');

for(UINT i = 0;i < bufsize;++i)
    ss << std::setw(2) << static_cast<UINT>(buffer[i]);

delete[] buffer;
ss << "}}" << std::endl;
return ss.str().c_str();

我们现在使用它来将图形插入到我们的文档中。我还没有尝试将其作为独立文档。

于 2017-10-30T11:48:15.960 回答