PlayEnhMethaFile

hi fellows,
i encountered a strange problem i cannot solve that easy:

i want to do the following:
- read an enhanced metafile from disk
- create an new enhanced metafile device context in memory
- play the loaded emf on this context
   (therefore the bounding rectangles should match i think)
- now i can draw on the dc over the loaded emf
- store the new emf on disk
  (the old one is in the background, maybe some text/line is drawn above)

up to now i did in my member function of a class:

dword z = GetEnhMetaFileA(afilename);
if(z)
 {enhmetaheader h;
  if(GetEnhMetaFileHeader(z, sizeof(h), h))
    {
    m_bounds = h.frame;
    m_dc = CreateEnhMetaFileA(m_dc, 0, &m_bounds, IMAGE_NAME);
    if(m_dc)
      {
      if(PlayEnhMetaFile(m_dc, z, &m_bounds))
       {
       m_clip = CreateRectRgnIndirect(&m_bounds);
       if(m_clip)  SelectClipRgn(m_dc, m_clip);              
       }
     else IMAGE_ERROR;
     }
    else IMAGE_ERROR;
    if(!(retval)) Clear();
    }
  else IMAGE_ERROR;
  DeleteEnhMetaFile(z);
  }
else IMAGE_ERROR;

the datatypes, functionprototypes and the macro IMAGE_ERROR look maybe odd
but work definitely
m_bounds is of type rect, a member variable
m_dc and m_clip are also member variables

i had two cases of error:

in the first, a self drawn and stored emf was loaded
(which can be loaded correctly with any graphics software),
the PlayEnhMetaFile fails but GetLastError returnes NO_ERROR.
if i store the result again with CloseEnhMetaFile and CopyEnhMetaFile,
the picture is shrinked to a very small rectangle in a huge white area.

in the second i try to load an emf generated by a graphics suite,
here it works all fine (at the first glance),
but if i try to store the result again, it gives me an empty
picture.

the storing routine works all fine (since i can watch
self-generated and stored emfs)

so what's wrong?
can somebody help me?

the language is either c++ or dephi,
no MFC or predefined components can be used,
we work with directly imported win api

a short code sample would be nice

thanks in advance,
dr. nick
LVL 5
drnickAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

DanRollinsCommented:
>>PlayEnhMetaFile fails but GetLastError returnes NO_ERROR.

We saw this same 'false error' in this Q:
   http://www.experts-exchange.com/Programming/Programming_Languages/MFC/Q_20012402.html
   with no resolution.  Microsoft is mute about what is certainly a system error (but it may be driver related?)

>>the picture is shrinked to a very small rectangle in a huge white area.

Place a breakpoint and verify the correct values are in &m_bounds
-==-=-=-=-=-=-=-
On what platform are you developing/testing?  There are some distinct limitations to the PlayEnhMetaFile API when used on Win9x systems.

-- Dan
0
drnickAuthor Commented:
first of all, thanks

as far as i read the thread you posted,
i think i can ignore the faulty return value of playenhmetafile,
is that true?

we test on windows 2000 server

the coordinates in the header of the file are correct,
the smallest surrounding rectangle (bounds)
is (0,0,99,99) and the app-defined (frame) is
(0,0,100,100), so there's no special reason for the shrinking behaviour.

but however, i don't need to care about return values if
the picture is at least drawn correctly.
you know, i can load the thing by getenhmetafile and store it with copyenhmetafile again correctly, but i need to edit it.

if i use FengYuan's prog, i get (see below).
this looks quite correct, i think.
have you any other idea?

        hRegion = CreateRectRgn(0,0,100,100);
     ExtSelectClipRgn(hDC, hRegion, RGN_COPY);
     DeleteObject(hRegion);
     hObj[1]=CreateSolidBrush(RGB(0xFF,0,0));
     SelectObject(hDC, hObj[1]);
     SelectObject(hDC, hObj[1]);
     PatBlt(hDC,0,0,100,100,PATCOPY);
     SelectObject(hDC, hObj[1]);
     DeleteObject(hObj[1]);
     hObj[1]=CreateSolidBrush(RGB(0xFF,0xFF,0));
     SelectObject(hDC, hObj[1]);
     SelectObject(hDC, hObj[1]);
     PatBlt(hDC,25,25,51,51,PATCOPY);
     SelectObject(hDC, hObj[1]);
     DeleteObject(hObj[1]);
     SetTextColor(hDC, RGB(0,0,0xFF));
     hObj[1]=CreateFont(-20,0,0,0,700,1,0,0,1,0,0,0,0,"arial");
     SelectObject(hDC, hObj[1]);
     const int Dx_1[]={ 12, 11, 6, 6, 12, 6, 16, 11, 6, 7 };
     ExtTextOutW(hDC, 10,10,0,NULL,L"hallo welt",10,Dx_1);
     DeleteObject(hObj[1]);
     SetTextColor(hDC, RGB(0,0,0xFF));
     hObj[1]=CreateFont(-20,0,0,0,700,1,0,0,1,0,0,0,0,"symbol");
     SelectObject(hDC, hObj[1]);
     const int Dx_2[]={ 13, 14, 12, 12, 12, 6, 15, 10, 12, 10 };
     ExtTextOutW(hDC, 10,40,0,NULL,L"hallo welt",10,Dx_2);
     DeleteObject(hObj[1]);
     hObj[1]=CreateSolidBrush(RGB(0x51,0x93,3));
     SelectObject(hDC, hObj[1]);
     hObj[2]=CreatePen(PS_SOLID, 1, RGB(7,0xB2,1));
     SelectObject(hDC, hObj[2]);
     Chord(hDC, 20, 20, 79, 79, 80, 50, 50, 80);
     DeleteObject(hObj[2]);
     DeleteObject(hObj[1]);
     hObj[1]=CreateSolidBrush(RGB(0,0xFF,0));
     SelectObject(hDC, hObj[1]);
     hObj[2]=CreatePen(PS_SOLID, 1, RGB(0x4C,0,0));
     SelectObject(hDC, hObj[2]);
     Pie(hDC, 10, 20, 29, 39, 67, 54, 23, 56);
     DeleteObject(hObj[2]);
     DeleteObject(hObj[1]);
     hObj[1]=CreateSolidBrush(RGB(0,0x98,0x19));
     SelectObject(hDC, hObj[1]);
     hObj[2]=CreatePen(PS_SOLID, 1, RGB(0,0xF0,0xFF));
     SelectObject(hDC, hObj[2]);
     Ellipse(hDC, 40, 40, 89, 59);
     DeleteObject(hObj[2]);
     DeleteObject(hObj[1]);
     hObj[1]=CreateSolidBrush(RGB(0x62,0xB2,0));
     SelectObject(hDC, hObj[1]);
     hObj[2]=CreatePen(PS_SOLID, 1, RGB(0x3E,0xCA,0x23));
     SelectObject(hDC, hObj[2]);
     RoundRect(hDC, 50, 5, 79, 59, 10, 10);
     DeleteObject(hObj[2]);
     DeleteObject(hObj[1]);
     hObj[1]=CreatePen(PS_SOLID, 1, 0x4098C06);
     SelectObject(hDC, hObj[1]);
     MoveToEx(hDC, 0, 0, NULL);
     LineTo(hDC, 100, 100);
     DeleteObject(hObj[1]);
     hObj[1]=CreatePen(PS_SOLID, 1, RGB(0x20,0xD1,0x88));
     SelectObject(hDC, hObj[1]);
     MoveToEx(hDC, 100, 0, NULL);
     SetArcDirection(hDC, AD_CLOCKWISE);
     Arc(hDC, 0, 0, 99, 99, 20, 20, 90, 70);
     DeleteObject(hObj[1]);
     SetPixelV(hDC, 10, 10, RGB(0xFF,0,0));
     SetPixelV(hDC, 10, 11, RGB(0xFF,0,0));
     SetPixelV(hDC, 11, 11, RGB(0xFF,0,0));
     SetPixelV(hDC, 12, 11, RGB(0xFF,0,0));
     SetPixelV(hDC, 12, 12, RGB(0xFF,0,0));
     SetPixelV(hDC, 13, 13, RGB(0xFF,0,0));
     SetPixelV(hDC, 14, 14, RGB(0xFF,0,0));
     SetPixelV(hDC, 15, 15, RGB(0xFF,0,0));
     hObj[1]=CreateSolidBrush(RGB(0xFF,0,0));
     SelectObject(hDC, hObj[1]);
     SelectObject(hDC, hObj[1]);
     PatBlt(hDC,60,60,10,10,PATCOPY);
     SelectObject(hDC, hObj[1]);
     DeleteObject(hObj[1]);
0
drnickAuthor Commented:
first of all, thanks

as far as i read the thread you posted,
i think i can ignore the faulty return value of playenhmetafile,
is that true?

we test on windows 2000 server

the coordinates in the header of the file are correct,
the smallest surrounding rectangle (bounds)
is (0,0,99,99) and the app-defined (frame) is
(0,0,100,100), so there's no special reason for the shrinking behaviour.

but however, i don't need to care about return values if
the picture is at least drawn correctly.
you know, i can load the thing by getenhmetafile and store it with copyenhmetafile again correctly, but i need to edit it.

if i use FengYuan's prog, i get (see below).
this looks quite correct, i think.
have you any other idea?

        hRegion = CreateRectRgn(0,0,100,100);
     ExtSelectClipRgn(hDC, hRegion, RGN_COPY);
     DeleteObject(hRegion);
     hObj[1]=CreateSolidBrush(RGB(0xFF,0,0));
     SelectObject(hDC, hObj[1]);
     SelectObject(hDC, hObj[1]);
     PatBlt(hDC,0,0,100,100,PATCOPY);
     SelectObject(hDC, hObj[1]);
     DeleteObject(hObj[1]);
     hObj[1]=CreateSolidBrush(RGB(0xFF,0xFF,0));
     SelectObject(hDC, hObj[1]);
     SelectObject(hDC, hObj[1]);
     PatBlt(hDC,25,25,51,51,PATCOPY);
     SelectObject(hDC, hObj[1]);
     DeleteObject(hObj[1]);
     SetTextColor(hDC, RGB(0,0,0xFF));
     hObj[1]=CreateFont(-20,0,0,0,700,1,0,0,1,0,0,0,0,"arial");
     SelectObject(hDC, hObj[1]);
     const int Dx_1[]={ 12, 11, 6, 6, 12, 6, 16, 11, 6, 7 };
     ExtTextOutW(hDC, 10,10,0,NULL,L"hallo welt",10,Dx_1);
     DeleteObject(hObj[1]);
     SetTextColor(hDC, RGB(0,0,0xFF));
     hObj[1]=CreateFont(-20,0,0,0,700,1,0,0,1,0,0,0,0,"symbol");
     SelectObject(hDC, hObj[1]);
     const int Dx_2[]={ 13, 14, 12, 12, 12, 6, 15, 10, 12, 10 };
     ExtTextOutW(hDC, 10,40,0,NULL,L"hallo welt",10,Dx_2);
     DeleteObject(hObj[1]);
     hObj[1]=CreateSolidBrush(RGB(0x51,0x93,3));
     SelectObject(hDC, hObj[1]);
     hObj[2]=CreatePen(PS_SOLID, 1, RGB(7,0xB2,1));
     SelectObject(hDC, hObj[2]);
     Chord(hDC, 20, 20, 79, 79, 80, 50, 50, 80);
     DeleteObject(hObj[2]);
     DeleteObject(hObj[1]);
     hObj[1]=CreateSolidBrush(RGB(0,0xFF,0));
     SelectObject(hDC, hObj[1]);
     hObj[2]=CreatePen(PS_SOLID, 1, RGB(0x4C,0,0));
     SelectObject(hDC, hObj[2]);
     Pie(hDC, 10, 20, 29, 39, 67, 54, 23, 56);
     DeleteObject(hObj[2]);
     DeleteObject(hObj[1]);
     hObj[1]=CreateSolidBrush(RGB(0,0x98,0x19));
     SelectObject(hDC, hObj[1]);
     hObj[2]=CreatePen(PS_SOLID, 1, RGB(0,0xF0,0xFF));
     SelectObject(hDC, hObj[2]);
     Ellipse(hDC, 40, 40, 89, 59);
     DeleteObject(hObj[2]);
     DeleteObject(hObj[1]);
     hObj[1]=CreateSolidBrush(RGB(0x62,0xB2,0));
     SelectObject(hDC, hObj[1]);
     hObj[2]=CreatePen(PS_SOLID, 1, RGB(0x3E,0xCA,0x23));
     SelectObject(hDC, hObj[2]);
     RoundRect(hDC, 50, 5, 79, 59, 10, 10);
     DeleteObject(hObj[2]);
     DeleteObject(hObj[1]);
     hObj[1]=CreatePen(PS_SOLID, 1, 0x4098C06);
     SelectObject(hDC, hObj[1]);
     MoveToEx(hDC, 0, 0, NULL);
     LineTo(hDC, 100, 100);
     DeleteObject(hObj[1]);
     hObj[1]=CreatePen(PS_SOLID, 1, RGB(0x20,0xD1,0x88));
     SelectObject(hDC, hObj[1]);
     MoveToEx(hDC, 100, 0, NULL);
     SetArcDirection(hDC, AD_CLOCKWISE);
     Arc(hDC, 0, 0, 99, 99, 20, 20, 90, 70);
     DeleteObject(hObj[1]);
     SetPixelV(hDC, 10, 10, RGB(0xFF,0,0));
     SetPixelV(hDC, 10, 11, RGB(0xFF,0,0));
     SetPixelV(hDC, 11, 11, RGB(0xFF,0,0));
     SetPixelV(hDC, 12, 11, RGB(0xFF,0,0));
     SetPixelV(hDC, 12, 12, RGB(0xFF,0,0));
     SetPixelV(hDC, 13, 13, RGB(0xFF,0,0));
     SetPixelV(hDC, 14, 14, RGB(0xFF,0,0));
     SetPixelV(hDC, 15, 15, RGB(0xFF,0,0));
     hObj[1]=CreateSolidBrush(RGB(0xFF,0,0));
     SelectObject(hDC, hObj[1]);
     SelectObject(hDC, hObj[1]);
     PatBlt(hDC,60,60,10,10,PATCOPY);
     SelectObject(hDC, hObj[1]);
     DeleteObject(hObj[1]);
0
Cloud Class® Course: CompTIA Healthcare IT Tech

This course will help prep you to earn the CompTIA Healthcare IT Technician certification showing that you have the knowledge and skills needed to succeed in installing, managing, and troubleshooting IT systems in medical and clinical settings.

drnickAuthor Commented:
hm, this is odd:
when i try to open the newly saved (and thus, shrinked) emf with FengYuan, it fails completely.
the resulting screen is empty.
0
drnickAuthor Commented:
... and when i try it again, it works
... strange

... gives me:

        SaveDC(hDC);
      SetMetaRgn(hDC);
      SelectObject(hDC, GetStockObject(WHITE_BRUSH));
      SelectObject(hDC, GetStockObject(BLACK_PEN));
      SelectObject(hDC, GetStockObject(DEVICE_DEFAULT_FONT));
      SelectPalette(hDC, (HPALETTE)GetStockObject(DEFAULT_PALETTE), TRUE);
      SetBkColor(hDC, RGB(0xFF,0xFF,0xFF));
      SetTextColor(hDC, RGB(0,0,0));
      SetBkMode(hDC, OPAQUE);
      SetPolyFillMode(hDC, ALTERNATE);
      SetROP2(hDC, R2_COPYPEN);
      SetStretchBltMode(hDC, STRETCH_ANDSCANS);
      SetTextAlign(hDC, TA_NOUPDATECP | TA_LEFT | TA_TOP);
      SetBrushOrgEx(hDC, 0, 0, NULL);
      SetMiterLimit(hDC,  0.00000);
      MoveToEx(hDC, 0, 0, NULL);
      SetWorldTransform(hDC, 31.25000,  0.00000,  0.00000, 31.25000,  0.00000,  0.00000);
      ModifyWorldTransform(hDC, 31.25000,  0.00000,  0.00000, 31.25000,  0.00000,  0.00000, 0x4 /*Unknown*/);
      // GdiComment(100, GDIC, 0x2)
      hRegion = CreateRectRgn(0,0,3125,3125);
      ExtSelectClipRgn(hDC, hRegion, RGN_COPY);
      DeleteObject(hRegion);
      hObj[1]=CreateSolidBrush(RGB(0xFF,0,0));
      SelectObject(hDC, hObj[1]);
      SelectObject(hDC, hObj[1]);
      PatBlt(hDC,0,0,100,100,PATCOPY);
      SelectObject(hDC, hObj[1]);
      DeleteObject(hObj[1]);
      hObj[1]=CreateSolidBrush(RGB(0xFF,0xFF,0));
      SelectObject(hDC, hObj[1]);
      SelectObject(hDC, hObj[1]);
      PatBlt(hDC,25,25,51,51,PATCOPY);
      SelectObject(hDC, hObj[1]);
      DeleteObject(hObj[1]);
      SetTextColor(hDC, RGB(0,0,0xFF));
      hObj[1]=CreateFont(-20,0,0,0,700,1,0,0,1,0,0,0,0,"arial");
      SelectObject(hDC, hObj[1]);
      const int Dx_1[]={ 12, 11, 6, 6, 12, 6, 16, 11, 6, 7 };
      ExtTextOutW(hDC, 10,10,0,NULL,L"hallo welt",10,Dx_1);
      DeleteObject(hObj[1]);
      SetTextColor(hDC, RGB(0,0,0xFF));
      hObj[1]=CreateFont(-20,0,0,0,700,1,0,0,1,0,0,0,0,"symbol");
      SelectObject(hDC, hObj[1]);
      const int Dx_2[]={ 13, 14, 12, 12, 12, 6, 15, 10, 12, 10 };
      ExtTextOutW(hDC, 10,40,0,NULL,L"hallo welt",10,Dx_2);
      DeleteObject(hObj[1]);
      hObj[1]=CreateSolidBrush(RGB(0x51,0x93,3));
      SelectObject(hDC, hObj[1]);
      hObj[2]=CreatePen(PS_SOLID, 1, RGB(7,0xB2,1));
      SelectObject(hDC, hObj[2]);
      Chord(hDC, 20, 20, 79, 79, 80, 50, 50, 80);
      DeleteObject(hObj[2]);
      DeleteObject(hObj[1]);
      hObj[1]=CreateSolidBrush(RGB(0,0xFF,0));
      SelectObject(hDC, hObj[1]);
      hObj[2]=CreatePen(PS_SOLID, 1, RGB(0x4C,0,0));
      SelectObject(hDC, hObj[2]);
      Pie(hDC, 10, 20, 29, 39, 67, 54, 23, 56);
      DeleteObject(hObj[2]);
      DeleteObject(hObj[1]);
      hObj[1]=CreateSolidBrush(RGB(0,0x98,0x19));
      SelectObject(hDC, hObj[1]);
      hObj[2]=CreatePen(PS_SOLID, 1, RGB(0,0xF0,0xFF));
      SelectObject(hDC, hObj[2]);
      Ellipse(hDC, 40, 40, 89, 59);
      DeleteObject(hObj[2]);
      DeleteObject(hObj[1]);
      hObj[1]=CreateSolidBrush(RGB(0x62,0xB2,0));
      SelectObject(hDC, hObj[1]);
      hObj[2]=CreatePen(PS_SOLID, 1, RGB(0x3E,0xCA,0x23));
      SelectObject(hDC, hObj[2]);
      RoundRect(hDC, 50, 5, 79, 59, 10, 10);
      DeleteObject(hObj[2]);
      DeleteObject(hObj[1]);
      hObj[1]=CreatePen(PS_SOLID, 1, 0x4098C06);
      SelectObject(hDC, hObj[1]);
      MoveToEx(hDC, 0, 0, NULL);
      LineTo(hDC, 100, 100);
      DeleteObject(hObj[1]);
      hObj[1]=CreatePen(PS_SOLID, 1, RGB(0x20,0xD1,0x88));
      SelectObject(hDC, hObj[1]);
      MoveToEx(hDC, 100, 0, NULL);
      SetArcDirection(hDC, AD_CLOCKWISE);
      Arc(hDC, 0, 0, 99, 99, 20, 20, 90, 70);
      DeleteObject(hObj[1]);
      SetPixelV(hDC, 10, 10, RGB(0xFF,0,0));
      SetPixelV(hDC, 10, 11, RGB(0xFF,0,0));
      SetPixelV(hDC, 11, 11, RGB(0xFF,0,0));
      SetPixelV(hDC, 12, 11, RGB(0xFF,0,0));
      SetPixelV(hDC, 12, 12, RGB(0xFF,0,0));
      SetPixelV(hDC, 13, 13, RGB(0xFF,0,0));
      SetPixelV(hDC, 14, 14, RGB(0xFF,0,0));
      SetPixelV(hDC, 15, 15, RGB(0xFF,0,0));
      hObj[1]=CreateSolidBrush(RGB(0xFF,0,0));
      SelectObject(hDC, hObj[1]);
      SelectObject(hDC, hObj[1]);
      SelectObject(hDC, hObj[1]);
      DeleteObject(hObj[1]);
      // GdiComment(8, GDIC, 0x3)
      RestoreDC(hDC, -1);
0
drnickAuthor Commented:
... and when i try it again, it works
... strange

... gives me:

        SaveDC(hDC);
      SetMetaRgn(hDC);
      SelectObject(hDC, GetStockObject(WHITE_BRUSH));
      SelectObject(hDC, GetStockObject(BLACK_PEN));
      SelectObject(hDC, GetStockObject(DEVICE_DEFAULT_FONT));
      SelectPalette(hDC, (HPALETTE)GetStockObject(DEFAULT_PALETTE), TRUE);
      SetBkColor(hDC, RGB(0xFF,0xFF,0xFF));
      SetTextColor(hDC, RGB(0,0,0));
      SetBkMode(hDC, OPAQUE);
      SetPolyFillMode(hDC, ALTERNATE);
      SetROP2(hDC, R2_COPYPEN);
      SetStretchBltMode(hDC, STRETCH_ANDSCANS);
      SetTextAlign(hDC, TA_NOUPDATECP | TA_LEFT | TA_TOP);
      SetBrushOrgEx(hDC, 0, 0, NULL);
      SetMiterLimit(hDC,  0.00000);
      MoveToEx(hDC, 0, 0, NULL);
      SetWorldTransform(hDC, 31.25000,  0.00000,  0.00000, 31.25000,  0.00000,  0.00000);
      ModifyWorldTransform(hDC, 31.25000,  0.00000,  0.00000, 31.25000,  0.00000,  0.00000, 0x4 /*Unknown*/);
      // GdiComment(100, GDIC, 0x2)
      hRegion = CreateRectRgn(0,0,3125,3125);
      ExtSelectClipRgn(hDC, hRegion, RGN_COPY);
      DeleteObject(hRegion);
      hObj[1]=CreateSolidBrush(RGB(0xFF,0,0));
      SelectObject(hDC, hObj[1]);
      SelectObject(hDC, hObj[1]);
      PatBlt(hDC,0,0,100,100,PATCOPY);
      SelectObject(hDC, hObj[1]);
      DeleteObject(hObj[1]);
      hObj[1]=CreateSolidBrush(RGB(0xFF,0xFF,0));
      SelectObject(hDC, hObj[1]);
      SelectObject(hDC, hObj[1]);
      PatBlt(hDC,25,25,51,51,PATCOPY);
      SelectObject(hDC, hObj[1]);
      DeleteObject(hObj[1]);
      SetTextColor(hDC, RGB(0,0,0xFF));
      hObj[1]=CreateFont(-20,0,0,0,700,1,0,0,1,0,0,0,0,"arial");
      SelectObject(hDC, hObj[1]);
      const int Dx_1[]={ 12, 11, 6, 6, 12, 6, 16, 11, 6, 7 };
      ExtTextOutW(hDC, 10,10,0,NULL,L"hallo welt",10,Dx_1);
      DeleteObject(hObj[1]);
      SetTextColor(hDC, RGB(0,0,0xFF));
      hObj[1]=CreateFont(-20,0,0,0,700,1,0,0,1,0,0,0,0,"symbol");
      SelectObject(hDC, hObj[1]);
      const int Dx_2[]={ 13, 14, 12, 12, 12, 6, 15, 10, 12, 10 };
      ExtTextOutW(hDC, 10,40,0,NULL,L"hallo welt",10,Dx_2);
      DeleteObject(hObj[1]);
      hObj[1]=CreateSolidBrush(RGB(0x51,0x93,3));
      SelectObject(hDC, hObj[1]);
      hObj[2]=CreatePen(PS_SOLID, 1, RGB(7,0xB2,1));
      SelectObject(hDC, hObj[2]);
      Chord(hDC, 20, 20, 79, 79, 80, 50, 50, 80);
      DeleteObject(hObj[2]);
      DeleteObject(hObj[1]);
      hObj[1]=CreateSolidBrush(RGB(0,0xFF,0));
      SelectObject(hDC, hObj[1]);
      hObj[2]=CreatePen(PS_SOLID, 1, RGB(0x4C,0,0));
      SelectObject(hDC, hObj[2]);
      Pie(hDC, 10, 20, 29, 39, 67, 54, 23, 56);
      DeleteObject(hObj[2]);
      DeleteObject(hObj[1]);
      hObj[1]=CreateSolidBrush(RGB(0,0x98,0x19));
      SelectObject(hDC, hObj[1]);
      hObj[2]=CreatePen(PS_SOLID, 1, RGB(0,0xF0,0xFF));
      SelectObject(hDC, hObj[2]);
      Ellipse(hDC, 40, 40, 89, 59);
      DeleteObject(hObj[2]);
      DeleteObject(hObj[1]);
      hObj[1]=CreateSolidBrush(RGB(0x62,0xB2,0));
      SelectObject(hDC, hObj[1]);
      hObj[2]=CreatePen(PS_SOLID, 1, RGB(0x3E,0xCA,0x23));
      SelectObject(hDC, hObj[2]);
      RoundRect(hDC, 50, 5, 79, 59, 10, 10);
      DeleteObject(hObj[2]);
      DeleteObject(hObj[1]);
      hObj[1]=CreatePen(PS_SOLID, 1, 0x4098C06);
      SelectObject(hDC, hObj[1]);
      MoveToEx(hDC, 0, 0, NULL);
      LineTo(hDC, 100, 100);
      DeleteObject(hObj[1]);
      hObj[1]=CreatePen(PS_SOLID, 1, RGB(0x20,0xD1,0x88));
      SelectObject(hDC, hObj[1]);
      MoveToEx(hDC, 100, 0, NULL);
      SetArcDirection(hDC, AD_CLOCKWISE);
      Arc(hDC, 0, 0, 99, 99, 20, 20, 90, 70);
      DeleteObject(hObj[1]);
      SetPixelV(hDC, 10, 10, RGB(0xFF,0,0));
      SetPixelV(hDC, 10, 11, RGB(0xFF,0,0));
      SetPixelV(hDC, 11, 11, RGB(0xFF,0,0));
      SetPixelV(hDC, 12, 11, RGB(0xFF,0,0));
      SetPixelV(hDC, 12, 12, RGB(0xFF,0,0));
      SetPixelV(hDC, 13, 13, RGB(0xFF,0,0));
      SetPixelV(hDC, 14, 14, RGB(0xFF,0,0));
      SetPixelV(hDC, 15, 15, RGB(0xFF,0,0));
      hObj[1]=CreateSolidBrush(RGB(0xFF,0,0));
      SelectObject(hDC, hObj[1]);
      SelectObject(hDC, hObj[1]);
      SelectObject(hDC, hObj[1]);
      DeleteObject(hObj[1]);
      // GdiComment(8, GDIC, 0x3)
      RestoreDC(hDC, -1);
0
drnickAuthor Commented:
sorry for double posting, hit reload by accident
0
drnickAuthor Commented:
(had hit it twice, i think..)

hello again, i detected that the error (shrinking) also
occures when i do (with the purpose to store and keep on
editing my emf):

c_boolean     SC   CImage::Close                
(void)                             //VMT 3
  {boolean retval = true;
  if( (!(m_file)) || (m_changed) )
    {
    if(m_file)
      {
      retval = DeleteEnhMetaFile(m_file);
      if(!retval) IMAGE_ERROR;
      m_file = 0;
      }
    if(retval)
      {
      retval = false;

      if(m_dc)
        {
        m_file = CloseEnhMetaFile(m_dc);
        if(m_file)
          {
          p_rect boundsptr = 0;
          if( (m_bounds.bottom >  m_bounds.top) &&
              (m_bounds.right  > m_bounds.left) )
boundsptr = &m_bounds;
          m_dc = CreateEnhMetaFileA(0, 0, boundsptr,
IMAGE_NAME);
          if(m_dc)
            {          
            PlayEnhMetaFile(m_dc, m_file, boundsptr);
            m_changed = false;
            if(m_clip)
              {
              SelectClipRgn(m_dc, m_clip);
              }
            retval = true;
            }
          else IMAGE_ERROR;        
          }
        else IMAGE_ERROR;
        }
      else IMAGE_EMPTY;
      } }  
  return retval;
  }
0
DanRollinsCommented:
It looks like the sequence lines up after the first few records.  The first few records are setting the scaling options.  When you said...

>>- create an new enhanced metafile device context in memory

perhaps the reference hdc that you use is screwy or something.  What if you nullify or clear out the WorldTransform for the new metafile, the problem will go away.  Or maybe the mapping mode has been tweaked...

Show the code you use to create the metafile you use as the destination.

-- Dan
0
drnickAuthor Commented:
hm, the code is below.
the clip region is needed, because else the emf would
grow if i draw across the borders.
i use 0 as refDC, so it would use the screen by default,
so i do by loading.
if i replace the refdc by GetDC(0), i get the same result.
you're right, the world transform is somewhat strange.
but the 31.25 result from the proportion of screen pixel width to metric measures: ther're exactly 31.25 0.01 mm units per pixel says the calculator.
how can i nulify the worldtransform stuff?
what is it with mapping mode?
however, thanks for your effords so far.

c_boolean     SC   CImage::Create  (c_dword awidth, c_dword aheight)
  {
  boolean retval = false;
  if(Clear())
    {
    p_rect boundsptr = 0;
    if((awidth > 0) && (aheight > 0))
      {
      m_bounds.bottom = aheight;
      m_bounds.right  = awidth;
      boundsptr       = &m_bounds;
      m_clip          = CreateRectRgnIndirect(boundsptr);
      }
    m_dc = CreateEnhMetaFileA(0, 0, boundsptr, IMAGE_NAME);
    if(m_dc)
      {
      if(m_clip) SelectClipRgn(m_dc, m_clip);        
      retval = true;
      }
    else IMAGE_ERROR;
    }
  return retval;
  }
0
drnickAuthor Commented:
p.s. awidth and aheight are both 100 in my testing example
0
DanRollinsCommented:
Just a guess... Try using
    SetMapMode( hdcDestFroMetafile, MM_TEXT );

before playing the metafile.  Worth a try.

-- Dan
0
drnickAuthor Commented:
hm, you got me going:

without setmapmode, i get a very small image in the upper left corner, any subsequent drawing actions will also be shrinked and placed there

the same result with SetMapMode(... MM_TEXT), i think that's the default behaviour

but with SetMapMode(... MM_HIMETRIC) subsequent drawing actions appear with the right size at the right place.
the bad thing is, playenhmetafile does nothing...

but good idea, i'll keep working on that and report findings
0
drnickAuthor Commented:
aha, in the hi_metric case,
the bounds field of the emf-header is evaluated to
(0, -79, 99, 0) but it should be (0, 0, 99, 99).
0
drnickAuthor Commented:
nope, that helps nothing.
i can try to setworldtranform, but it changes anything.
the graphic is not drawn.
however, that thing with mapmode was not bad.
at least, i've now the proper size
0
DanRollinsCommented:
Glad to help.  I'd trot it back throud that FenYuan thing to see if you are getting closer to the desired settings.

-- Dan
0
drnickAuthor Commented:
already done: i get the same stuff like in last posting.
strange
0
drnickAuthor Commented:
any other ideas?
0
DanRollinsCommented:
What values are you sending in to CImage::Create  in the awidth and aheight partameters.  I see that you are createing a RECT directlry from these.  Recall that these are expected to be in metic units.  Thus, if you are sending in pixel units, for instance, (100,100), then you should convert to metric units.  I think that's a simple matter of multiplying awidth and aheight each by 31.25 (or whatever the pixel size is on your screen(?) )

There is a tip in the dox for the (obsolete) CreateMetafile fn in which they say you should use the MM_ANISOTROPIC mapping mode.  I think the idea is that no matter how small it looks, you can then scale it to a desired size later hen you play it back without losing resolution.

-- Dan
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
drnickAuthor Commented:
i give 'em 100 and 100.

i think i found one possible source of my problem:
(i started all up from the bottom again meanwhile)
right before playenhmetafile plays to a dc,
it SaveDC the dc, then it resets the
dc's mapping mode to MM_TEXT and also
initialized SetWorldTransform.
so whatever values i pass to SetMapMode and
SetViewPortExtEx and SetWorldTransform will be
overridden rightaway and 'll have no effect at all.
so that approach was nonsense.

now i'm going to test out now if i get the stuff working
when i set up the picture in proportions to my screen
resolution, as you suggested.
this is a way i'd rather liked to avoid,
because calculating of coordinates may lead to
incorrect values due to rounding and trucating,
but i give it a try.

thanks so far,
dr. nick
0
drnickAuthor Commented:
.. i take it all back and state the opposite:

 i _can_ draw the saved emfs to the new emfs by
 specifiying an projection with viewport and
 window.
 the savedc/restoredc in the playenhmetafile mean nothing.

 the solution was

if(SetMapMode(adc, MM_ANISOTROPIC))
 {
 SetWindowExtEx(adc, MM_X(m_bounds.right), MM_Y(m_bounds.bottom), 0);
 SetViewportExtEx(adc, (m_bounds.right), (m_bounds.bottom), 0);
 SetWindowOrgEx(adc, 0, 0, 0);
 SetViewportOrgEx(adc, 0, 0, 0);
 }

with

dword     MaxX_MM   = 0;
dword     MaxY_MM   = 0;
dword     MaxX_PX   = 0;
dword     MaxY_PX   = 0;
double  MMPerPX_X   = 0;
double  MMPerPX_Y   = 0;


void          FC   ImageSetUp           (void)
  {
  dword dc = GetDC(0);
  if(dc)
    {
    MaxX_MM   = GetDeviceCaps(dc, HORZSIZE);
    MaxY_MM   = GetDeviceCaps(dc, VERTSIZE);
    MaxX_PX   = GetDeviceCaps(dc, HORZRES);
    MaxY_PX   = GetDeviceCaps(dc, VERTRES);
    MMPerPX_X = (((double)MaxX_MM) * 100.0) / ((double)MaxX_PX);
    MMPerPX_Y = (((double)MaxY_MM) * 100.0) / ((double)MaxY_PX);

    WriteLog("Calculating screen resolution relations.");
    LogDWord("MaxX (0.01 mm)        %s", MaxX_MM);
    LogDWord("MaxY (0.01 mm)        %s", MaxY_MM);
    LogDWord("MaxX (pixels)         %s", MaxX_PX);
    LogDWord("MaxY (pixels)         %s", MaxY_PX);
    LogDWord("0.01 mm per pixel (x) %s", (dword)MMPerPX_X);
    LogDWord("0.01 mm per pixel (y) %s", (dword)MMPerPX_Y);
    ReleaseDC(0, dc);
    }
  else IMAGE_LOG_ONLY("No display device attached or using Windows 95 and earlier.");


  }


c_dword       FC   MM_X                 (c_dword ax)
  {
  return (c_dword)(ceil( ((double)ax) * MMPerPX_X ) );
  }

c_dword       FC   MM_Y                 (c_dword ay)
  {
  return (c_dword)(ceil( ((double)ay) * MMPerPX_Y ) );
  }

c_dword       FC   PX_X                 (c_dword ax)
  {
  return (c_dword)(((double)ax) / MMPerPX_X);
  }


c_dword       FC   PX_Y                 (c_dword ay)
  {
  return (c_dword)(((double)ay) / MMPerPX_Y);
  }

(just in case another poor soul has to wrestle with this).

however, i'll reward you (Dan) for your effords and good ideas with the points. thanks.
0
DanRollinsCommented:
In this and the other thread there is lots of screwy code; i.e, what is a c_dword?  and why clutter your cosde with that?.  Here is some code I used for testing:

RECT     m_Bounds= {0,0,100,100};
char     m_szFile[]= "c:\\temp\\MS.EMF";
HBITMAP  m_hbmpImage= 0;

// Create a 24-bit-per-pixel surface.
HBITMAP Create24BPPDIBSection(HDC hDC, int iWidth, int iHeight)
{
     BITMAPINFO rBMI;
     HBITMAP    hbm;
     void *     pBits;

     ZeroMemory( &rBMI, sizeof(rBMI) );

     rBMI.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
     rBMI.bmiHeader.biWidth = iWidth;
     rBMI.bmiHeader.biHeight = iHeight;
     rBMI.bmiHeader.biPlanes = 1;
     rBMI.bmiHeader.biBitCount = 24;
     rBMI.bmiHeader.biCompression = BI_RGB;

     hbm= CreateDIBSection(hDC, &rBMI, DIB_RGB_COLORS, &pBits, NULL, 0);

     return( hbm );
}


void CD06Dlg::OnButton1()
{
     int nWide= 100;
     int nHigh= 100;

     HDC hdcRef= ::GetDC( m_hWnd );  // compatible with screen
    HDC hdc=    CreateCompatibleDC( hdcRef );
     if ( !hdc) {
          // TBD: handle the error
     }
     ::ReleaseDC(m_hWnd, hdcRef );

     HBITMAP hbmpCanvas= Create24BPPDIBSection( hdc, nWide, nHigh );
     HBITMAP hbmpOld= (HBITMAP)::SelectObject( hdc, hbmpCanvas );

     int nRet= SetMapMode( hdc, MM_TEXT ); // needed?

     RECT rBox= {20,20,80,80};  // test a GDI fn
     ::FillRect( hdc, &rBox, (HBRUSH) (COLOR_WINDOW+1) );

     RECT rBound= {0,0,0,0};
     rBound.right= nWide; rBound.bottom= nHigh;

     // errors reading WMF, gut GetLastError shows 0 !
     HENHMETAFILE hEMF= ::GetEnhMetaFile( m_szFile );
     DWORD nErr= GetLastError();

     ::PlayEnhMetaFile( hdc, hEMF, &rBound );
     
     BOOL fRet= GdiFlush(); // needed?
     fRet=      DeleteEnhMetaFile( hEMF );

     ::SelectObject( hdc, hbmpOld );
     ::DeleteDC(hdc);
     m_hbmpImage= hbmpCanvas; // save result
}

void CD06Dlg::OnButton2()
{
     // display the bitmap
     m_ctlImage.SetBitmap( m_hbmpImage );
}
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.