Link to home
Start Free TrialLog in
Avatar of gaohong
gaohong

asked on

Metafile to clipboard, then read

I am trying to draw my app to clipboard as metafile records,
then let other apps to paste what's on the clipboard.
I am quite sure the data is writen to clipboard, but I could
not get it from clipboard.

I will list sending clipboard code first, then retrive part.
The other question is does the application who retrieve the
clipboard will deallocating the resource ? There is no
documentation on this issue.

When I write METAFILE to file (enhanced metafile format),
I can retrieve without any missing. But when I write metafile with windows metafile format (for Win3.x) and I
retrieve with corresponding old format function, then I missing all the drawing (lines), only flood fill and text.

Under both formats, I could not retrieve from clipboard.
Could somebody help me and notify me with email when you
give an answer.

gaohong@electro.psi.vcu.edu


Write to clipboard part

void writeToClipboard()
   {
    HDC hDCMeta;
    HENHMETAFILE   hMeta;
    //HMETAFILE   hMeta;

    TRect rect = VClientRect;
    rect.left *= 0;
    rect.top  *= 0;
    rect.right *= 100*200;
    rect.bottom *= 100*150;

  //Create the metafile with output going to the disk.

    //hDCMeta = CreateEnhMetaFile(DrawAttr->CurrentDC, "sample.emf", 0, 0);
    hDCMeta = CreateEnhMetaFile(DrawAttr->CurrentDC, 0, 0, 0);
    //hDCMeta = CreateMetaFile("sample.wmf");
    DrawAttr->SetAttribute(hDCMeta);
    DrawData->draw(DrawData->getDrawBound(0), *DrawAttr, 1);
    hMeta = CloseEnhMetaFile(hDCMeta);
    //hMeta = CloseMetaFile(hDCMeta);

    HGLOBAL hmfp = ::GlobalAlloc(GHND, sizeof(METAFILEPICT));
    if(hmfp)
      {
  METAFILEPICT far *mfp = (METAFILEPICT far *) GlobalLock(hmfp);

       mfp->mm   = MM_ANISOTROPIC;
       //mfp->xExt = 1;
       //mfp->yExt = 1;
       mfp->hMF  = (HMETAFILE) hMeta;
       ::GlobalUnlock(hmfp);

       if(::OpenClipboard(HWindow))
         {
          ::EmptyClipboard();
          hmfp = ::SetClipboardData(CF_METAFILEPICT, hmfp);
         if(hmfp)
            {
              ::MessageBox(NULL, "clipboard data set OK", "Good", MB_OK);
              enablePaste = 1;
            }
         else
            ::MessageBox(NULL, "clipboard data not set", "warning", MB_OK);
          ::CloseClipboard();
         }
      }
  }



My test Retrieve clipboard part

void  getClipboardData()
  {
 if(::OpenClipboard(HWindow))
   {
  HGLOBAL hmfp = ::GetClipboardData(CF_ENHMETAFILE);
//*****  the failure is hmfp is NULL *******
  METAFILEPICT far* mfp = (METAFILEPICT far*)::GlobalLock(hmfp);

  if (mfp) {
    //Mm = mfp->mm;
    //Extent = TSize(mfp->xExt, mfp->yExt);
    Handle = (HENHMETAFILE) mfp->hMF;
    ::GlobalUnlock(hmfp);
    }
    ::CloseClipboard();
  }
  else
    {
    Handle = 0;
    ::MessageBox(NULL, "warning", "No metafile in clipboard", MB_OK);
    }
    // Force redraw
    //
    Invalidate();
  //}
}
Avatar of nietod
nietod

On a whim I decided to check back on this and I noticed something.  You set the clipboard data as MATAFILEPICT but try to obtain it back as ENHMETAFILE.  Does that fix the problem?
Avatar of gaohong

ASKER

Nietod:

I have tried set clipboard data as CF_ENHMETAFILE, then the return value tells me that it is not set. Only CF_METAFILEPICT
can be set to clipboard.

On get clipboard data, both CF_ENHMETAFILE and CF_METAFILEPICT
returns NULL handle.

If you look the documentation of CF format, it looks like there
is some conversion.  However, I suspect MS did messed up here
some how.
Not that this explains why you can't retrieve the data from the clipboard, but when you set the data using CF_ENHMETAFILE I suspect you are supposed to specify the handle to the metafile directly, that is, you don't specify a METAFILEPICT structure.  That may explain why you couldn't set the clipboard data.
Avatar of gaohong

ASKER

In fact, you can not set clipboard data as CF_ENHMETAFILE. It
would not set.
Did you try that specifying a handle to an enhanced meta file, rather than specifying a handle to  a METAFILEPICT?  For example,

          hmfp = ::SetClipboardData(CF_ENHMETAFILE, hMeta);

instead of

          hmfp = ::SetClipboardData(CF_ENHMETAFILE, hmfp);
Avatar of gaohong

ASKER

Beatiful. It works. This way also removes the problem who takes
care of GlobalLocked handle, no such problem then.

Nice exchange with you Nietod. Could you mark the answer to get
grade ?
ASKER CERTIFIED SOLUTION
Avatar of nietod
nietod

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial