1

I jumped into an old MFC application which has a problem when run under Windows 10 1703/Creators update. It works fine for XP to Windows 10/1607. After some investigation, it seems that in Windows 10/1703 the app cannot paste metafiles (wmf and emf) from the clipboard into an CRichTextView and save it. The graphics data is not embedded in the rtf file. Here is a stripped down example:

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");
}

This example pastes a enhanced metafile mit "ABC" and a line into the CRichTextView and saves the document as "abc.rtf"

  • From Windows XP to Windows 10/1607 this works fine
  • with the latest Creators update the file is smaller and the data is not saved

It is probably related to RichEditBox: picture and content after the picture disappear (Windows 10 1703 Creators Update)

Any ideas? Is there a way to get the metafile graphics in the document without the clipboard? Bitmaps still work.

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
Andreas
  • 11
  • 2
  • This is not a compiler issue. Run the very same exe file on Windows 7 and 10/1703 and you get different results. – Andreas Aug 24 '17 at 15:58
  • Which version of VS are you using? Which version of the richedit control is used by the `CRichEditView`? – zett42 Aug 25 '17 at 15:04
  • For _a way to get the metafile graphics in the document without the clipboard_ read [this answer](https://stackoverflow.com/a/1490785/7571258). It's C# but it shows the necessary RTF tags. – zett42 Aug 25 '17 at 15:20
  • @zett42 I am unsing VS2017. I also tested 2010 and 2015. It does not matter. I do not know the version of the richedit control. Where can I find it? – Andreas Aug 28 '17 at 06:20
  • Look for an `AfxInitRichEditN()` call where `N` is a number that gives a rough idea of the version of the control. You might replace it with `AfxInitRichEdit5()` to use the latest version of the control (msftedit.dll). You would also have to make sure that the MFC control uses `MSFTEDIT_CLASS` as the window class (instead of `RICHEDIT_CLASS`). – zett42 Aug 28 '17 at 08:12
  • The application and the wordpad example I used for investigating use 1.0. – Andreas Aug 28 '17 at 09:08
  • 1
    I think this is a bug in Windows 10. I will work around it by generating the RTF Data myself (as suggersted by zettl42) an insert it with the GetRichEditCtrl().StreamIn() function. – Andreas Aug 30 '17 at 06:10
  • Once you have 15+ reputation it would be great if you [answer your own question](https://stackoverflow.com/help/self-answer) with the verified workaround. – zett42 Aug 30 '17 at 09:03

1 Answers1

1

We had the same problem in our software after creators update. We also get our graphic via the clipboard. After some research on Google and SO I came up with this:

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();

We use this now to insert graphics into our document. I have not tried it as a standalone document.

dwo
  • 3,576
  • 2
  • 22
  • 39