?
Solved

PlayEnhMethaFile

Posted on 2003-03-10
24
Medium Priority
?
767 Views
Last Modified: 2013-12-03
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
0
Comment
Question by:drnick
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 18
  • 6
24 Comments
 
LVL 49

Expert Comment

by:DanRollins
ID: 8105515
>>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
 
LVL 5

Author Comment

by:drnick
ID: 8109043
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
 
LVL 5

Author Comment

by:drnick
ID: 8109091
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
Prepare for your VMware VCP6-DCV exam.

Josh Coen and Jason Langer have prepared the latest edition of VCP study guide. Both authors have been working in the IT field for more than a decade, and both hold VMware certifications. This 163-page guide covers all 10 of the exam blueprint sections.

 
LVL 5

Author Comment

by:drnick
ID: 8109098
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
 
LVL 5

Author Comment

by:drnick
ID: 8109108
... 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
 
LVL 5

Author Comment

by:drnick
ID: 8109136
... 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
 
LVL 5

Author Comment

by:drnick
ID: 8109138
sorry for double posting, hit reload by accident
0
 
LVL 5

Author Comment

by:drnick
ID: 8109326
(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
 
LVL 49

Expert Comment

by:DanRollins
ID: 8109425
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
 
LVL 5

Author Comment

by:drnick
ID: 8109483
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
 
LVL 5

Author Comment

by:drnick
ID: 8109486
p.s. awidth and aheight are both 100 in my testing example
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 8109519
Just a guess... Try using
    SetMapMode( hdcDestFroMetafile, MM_TEXT );

before playing the metafile.  Worth a try.

-- Dan
0
 
LVL 5

Author Comment

by:drnick
ID: 8109577
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
 
LVL 5

Author Comment

by:drnick
ID: 8109753
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
 
LVL 5

Author Comment

by:drnick
ID: 8109910
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
 
LVL 49

Expert Comment

by:DanRollins
ID: 8110375
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
 
LVL 5

Author Comment

by:drnick
ID: 8110566
already done: i get the same stuff like in last posting.
strange
0
 
LVL 5

Author Comment

by:drnick
ID: 8111620
any other ideas?
0
 
LVL 5

Author Comment

by:drnick
ID: 8111801
0
 
LVL 5

Author Comment

by:drnick
ID: 8112496
0
 
LVL 49

Accepted Solution

by:
DanRollins earned 300 total points
ID: 8114089
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
 
LVL 5

Author Comment

by:drnick
ID: 8118413
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
 
LVL 5

Author Comment

by:drnick
ID: 8118648
.. 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
 
LVL 49

Expert Comment

by:DanRollins
ID: 8120779
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

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

This tutorial is about how to put some of your C++ program's functionality into a standard DLL, and how to make working with the EXE and the DLL simple and seamless.   We'll be using Microsoft Visual Studio 2008 and we will cut out the noise; that i…
What my article will show is if you ever had to do processing to a listbox without being able to just select all the items in it. My software Visual Studio 2008 crystal report v11 My issue was I wanted to add crystal report to a form and show…
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…
If you’ve ever visited a web page and noticed a cool font that you really liked the look of, but couldn’t figure out which font it was so that you could use it for your own work, then this video is for you! In this Micro Tutorial, you'll learn yo…

801 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