"AliR (VC++ MVP)" <Al**@online.no spamwrote in message
news:iC******** **********@nlpi 067.nbdc.sbc.co m...
"Peter Duniho" <Np*********@nn owslpianmk.comw rote in message
news:op******** *******@petes-computer.local. ..
>Why not use Graphics.FromIm age() to get a Graphics instance from the
Metafile, and then Graphics.GetHdc () to get the HDC to assign to
fmtRange.chrg. hdc?
By the way, the class "SafeNativeMeth ods" looks very much like code from
the .NET Framework itself. I don't know where you got that, but you may
want to be very careful to not be using code copied from .NET.
Microsoft's published the code, but I'm pretty sure the license is for
debugging purposes only, not for reuse within your own code.
Pete
I got the code from here http://www.andrewvos.com/?p=392
which is pretty much the same code as
http://support.microsoft.com/kb/812425/en-us
Which .Net code are you refering to? Am I reinventing the wheele? Is
there built-in code that does this already?
I don't really see how GraphicFromImag e is going to help. Under native
c++ code, I have to draw to a meta file and then I can use world
transformations to scale the text in a way that would not case detering
and things like that.
I tried your suggestion but it didn't draw anything.
public void Draw(Graphics graphics, RectangleF layoutArea, float
xFactor)
{
//Calculate the area to render.
SafeNativeMetho ds.RECT rectLayoutArea;
rectLayoutArea. Top = (int)(layoutAre a.Top * anInch);
rectLayoutArea. Bottom = (int)(layoutAre a.Bottom * anInch);
rectLayoutArea. Left = (int)(layoutAre a.Left * anInch);
rectLayoutArea. Right = (int)(layoutAre a.Right * anInch);
IntPtr hdc = graphics.GetHdc ();
Metafile metafile = new Metafile(hdc, layoutArea);
Graphics metagraphic = Graphics.FromIm age(metafile);
IntPtr hDCEMF = metagraphic.Get Hdc();
SafeNativeMetho ds.FORMATRANGE fmtRange;
fmtRange.chrg.c pMax = -1; //Indicate character from
to character to
fmtRange.chrg.c pMin = 0;
fmtRange.hdc = hDCEMF; //Use the same DC for
measuring and rendering
fmtRange.hdcTar get = hDCEMF; //Point at printer hDC
fmtRange.rc = rectLayoutArea; //Indicate the area on
page to print
fmtRange.rcPage = rectLayoutArea; //Indicate size of page
IntPtr wParam = IntPtr.Zero;
wParam = new IntPtr(1);
//Get the pointer to the FORMATRANGE structure in memory
IntPtr lParam = IntPtr.Zero;
lParam = Marshal.AllocCo TaskMem(Marshal .SizeOf(fmtRang e));
Marshal.Structu reToPtr(fmtRang e, lParam, false);
SafeNativeMetho ds.SendMessage( this.Handle,
SafeNativeMetho ds.EM_FORMATRAN GE, wParam, lParam);
//Free the block of memory allocated
Marshal.FreeCoT askMem(lParam);
metagraphic.Rel easeHdc(hDCEMF) ;
//Release the device context handle obtained by a previous call
graphics.Releas eHdc(hdc);
graphics.ScaleT ransform(xFacto r, xFactor);
graphics.DrawIm age(metafile, layoutArea.Loca tion);
}
Here is the MFC version of this:
// setup rectangles for metafile fiddling
DC->DPtoHIMETRIC(& cTargetSize); // from MM_Text to MM_HIMETRIC
CRect cHiMetricRect(0 ,0,cTargetSize. cx,cTargetSize. cy);
CRect cTwipsRect(0,0, (TWIPS_INCH * cTargetSize.cx + HIMETRIC_INCH / 2) /
HIMETRIC_INCH,
(TWIPS_INCH * cTargetSize.cy + HIMETRIC_INCH / 2) / HIMETRIC_INCH);
// create the enhanced metafile
HDC hDCEMF = CreateEnhMetaFi le(DC->m_hDC,NULL,cHi MetricRect,NULL );
// setup the format struct and do the RTF range formatting call
FORMATRANGE stFR;
stFR.hdcTarget = stFR.hdc = hDCEMF; // render to the memory helper EMF
stFR.rcPage = stFR.rc = cTwipsRect; // using this rectangle (in twips)
stFR.chrg.cpMin = 0; // and render all of the text
stFR.chrg.cpMax = -1;
pCtrl->SendMessage(EM _FORMATRANGE,TR UE,(LPARAM) &stFR);
pCtrl->SendMessage(EM _FORMATRANGE,TR UE,NULL); // this call clears the cache
// drawing into the metafile is done, get ourselves an handle to it (used
for the replay)
HENHMETAFILE hEMF = CloseEnhMetaFil e(hDCEMF);
// calculate the automagic fudge factors by getting the device metrics
int nHorzSize = DC->GetDeviceCaps( HORZSIZE ); // width in millimeters
int nVertSize = DC->GetDeviceCaps( VERTSIZE ); // height in millimeters
int nHorzRes = DC->GetDeviceCaps( HORZRES ); // width in pixels
int nVertRes = DC->GetDeviceCaps( VERTRES ); // height in pixels
int nLogPixelsX = DC->GetDeviceCaps( LOGPIXELSX); // # of pixels per inch
horizontally
int nLogPixelsY = DC->GetDeviceCaps( LOGPIXELSY); // # of pixels per inch
vertically
float fHorzSizeInches = nHorzSize / 25.4f;
float fVertSizeInches = nVertSize / 25.4f;
float fHorzFudgeFacto r = (nHorzRes / fHorzSizeInches ) / nLogPixelsX; //
divide expected DPI with actual DPI
float fVertFudgeFacto r = (nVertRes / fVertSizeInches ) / nLogPixelsY; //
// do the world transforms, first apply the scale and fudge factors
XFORM stX;
ZeroMemory(&stX ,sizeof(stX));
stX.eM11 = fHorzFudgeFacto r * (m_XFactor);
stX.eM22 = fVertFudgeFacto r * (m_XFactor);
SetWorldTransfo rm(DC->m_hDC,&stX);
long Top = WinRect.top;
long Left = WinRect.left;
WinRect.OffsetR ect(-Left,-Top);
WinRect.OffsetR ect((int)(Left/fHorzFudgeFacto r),int(Top/fVertFudgeFacto r));
DC->PlayMetaFile(h EMF,&WinRect);
// that's it, kiss the metafile goodbye
DeleteEnhMetaFi le(hEMF);