Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

Metafile to clipboard, then read

Posted on 1998-06-17
7
Medium Priority
?
1,557 Views
Last Modified: 2013-12-03
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();
  //}
}
0
Comment
Question by:gaohong
  • 4
  • 3
7 Comments
 
LVL 22

Expert Comment

by:nietod
ID: 1408099
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?
0
 
LVL 3

Author Comment

by:gaohong
ID: 1408100
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.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1408101
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.
0
Get your Conversational Ransomware Defense e‑book

This e-book gives you an insight into the ransomware threat and reviews the fundamentals of top-notch ransomware preparedness and recovery. To help you protect yourself and your organization. The initial infection may be inevitable, so the best protection is to be fully prepared.

 
LVL 3

Author Comment

by:gaohong
ID: 1408102
In fact, you can not set clipboard data as CF_ENHMETAFILE. It
would not set.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1408103
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);
0
 
LVL 3

Author Comment

by:gaohong
ID: 1408104
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 ?
0
 
LVL 22

Accepted Solution

by:
nietod earned 400 total points
ID: 1408105
This should fix the SetClipboardData().  But does it fix the GetClipboardData() problem?  make sure this works totally before accepting my answer.  I am ussually happy to help out after an answer has been accepted, but this is an area where I probably can't help out (I was lucky so far).
0

Featured Post

Vote for the Most Valuable Expert

It’s time to recognize experts that go above and beyond with helpful solutions and engagement on site. Choose from the top experts in the Hall of Fame or on the right rail of your favorite topic page. Look for the blue “Nominate” button on their profile to vote.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article shows how to make a Windows 7 gadget that accepts files dropped from the Windows Explorer.  It also illustrates how to give your gadget a non-rectangular shape and how to add some nifty visual effects to text displayed in a your gadget.…
With most software applications trying to cater to multiple user needs nowadays, the focus is to make them as configurable as possible. For e.g., when creating Silverlight applications which will connect to WCF services, the service end point usuall…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Is your data getting by on basic protection measures? In today’s climate of debilitating malware and ransomware—like WannaCry—that may not be enough. You need to establish more than basics, like a recovery plan that protects both data and endpoints.…

783 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question