474,060 Members | 1,529 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Using Metafiles

Hi everyone,

I need to draw some rft to the screen. And I found some code out there that
uses a Richedit control and sends it an EM_FORMATRANGE to do exactly that.

Now I need to add scaling to this code. What I'm trying to do is to have
the richedit control draw to a metafile and then I can set the ScaleTrasform
of the Graphics object and draw the metafile.

But everytime I call Metafile.GetHen hmetafile() it throws a "Parameter is
not valid" execption.

I haven't been able to find a solution to this problem anywhere.

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);

//Release the device context handle obtained by a previous call
graphics.Releas eHdc(hdc);

IntPtr hDCEMF = metafile.GetHen hmetafile(); <-------- I can't
get passed this line!

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);

graphics.ScaleT ransform(xFacto r, xFactor);

graphics.DrawIm age(metafile, layoutArea.Loca tion);
}
AliR.
Aug 12 '08 #1
5 6309
On Tue, 12 Aug 2008 08:50:36 -0700, AliR (VC++ MVP) <Al**@online.no spam>
wrote:
Hi everyone,

I need to draw some rft to the screen. And I found some code out there
that
uses a Richedit control and sends it an EM_FORMATRANGE to do exactly
that.

Now I need to add scaling to this code. What I'm trying to do is to have
the richedit control draw to a metafile and then I can set the
ScaleTrasform
of the Graphics object and draw the metafile.

But everytime I call Metafile.GetHen hmetafile() it throws a "Parameter is
not valid" execption.
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.h dc?

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
Aug 12 '08 #2
"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.h dc?

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);
}
Aug 12 '08 #3
"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);
Aug 12 '08 #4
On Tue, 12 Aug 2008 11:27:29 -0700, AliR (VC++ MVP) <Al**@online.no spam>
wrote:
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?
That I know of, no. I was simply commenting on the class
"SafeNativeMeth ods", because that's the exact name used in the .NET
Framework's implementation. Could be that the original source lifted it
from the .NET source code, or just the name.

Personally, it doesn't concern me one way or the other. It's just that
someone using that code should be careful if they are at all concerned
about running afoul of Microsoft's legal department (which, while not as
rabid as those found in other corporations, do still need to justify their
existence).
I don't really see how GraphicFromImag e is going to help.
The Graphics instance you get from that wraps the Metafile itself, so any
DC you get from that Graphics instance is for the Metafile.

In other words, the HDC that you get from the Graphics instance returned
by that method returns exactly the thing you need to assign to the
FORMATRANGE.hdc field.

I don't know why the call to Metafile.GetHen hmetafile() doesn't work,
other than the fact that I personally have had trouble with the .NET
Metafile implementation in the past (in other words, things that you'd
think would work based on how the unmanaged version works, wind up not
working). But I do know that you can get an HDC that draws into the
Metafile by using Graphics.FromIm age() and the Graphics.GetHdc (). I'm
pretty sure I've done that before and had it work (for sure it works with
Bitmaps, and I'm pretty sure I've used it with Metafiles too).
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.
Well, it at least didn't cause an error, right?

I can't say exactly what's wrong with the code you're using. But I
suspect you're closer to a solution now than you were before. :)

You'll probably have to break the problem down into smaller parts and see
what's not working as expected. The code you're using is almost, but not
exactly, like the MSDN code, so one place to start would be to start with
_exactly_ the code in the MSDN sample and see if you can get that to work.

You should also check to see whether you're able to create a Metafile via
more conventional means that does what you want, to double-check that your
Metafile-specific code is valid.

And of course, I hope this is a silly question, but you are in fact
putting that code in a control that inherits RichTextBox, right?

Pete
Aug 12 '08 #5
I think I got it: (thank you Peter for your help)

public void Draw(Graphics graphics, RectangleF layoutArea, float
xFactor)
{
//Calculate the area to render.
SafeNativeMetho ds.RECT rectLayoutArea;
rectLayoutArea. Top = (int)(0 * anInch);
rectLayoutArea. Bottom = (int)(layoutAre a.Bottom * anInch);
rectLayoutArea. Left = (int)(0 * anInch);
rectLayoutArea. Right = (int)(layoutAre a.Right * anInch);
Bitmap Bmp = new Bitmap((int)lay outArea.Width,
(int)layoutArea .Height, PixelFormat.For mat32bppArgb);
Graphics g = Graphics.FromIm age(Bmp);
IntPtr hdc = g.GetHdc();

//create a metafile, convert the size to himetrics
Metafile metafile = new Metafile(hdc, new
RectangleF(0,0, layoutArea.Widt h*26,layoutArea .Height*26));

g.ReleaseHdc(hd c);
g.Dispose();

g = Graphics.FromIm age(metafile);
IntPtr hDCEMF = g.GetHdc();

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);

//Release the device context handle obtained by a previous call
g.ReleaseHdc(hD CEMF);
g.Dispose();

graphics.ScaleT ransform(xFacto r, xFactor);
graphics.DrawIm age(metafile, layoutArea.Loca tion);
}

AliR.

Aug 12 '08 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
1512
by: Barry | last post by:
Thanks for any help provided. How can I access enhancedmetafile format images in the Windows clipboard? The images appear when you use the clipbook viewer in the "Clipboard" not the "Local Clipboard". I can paste these images into the MS Paint Application with no problem. The application producing the images will only create an EMF (it is the AutoDesk MapGuide activex control version 6.3). It appears as if there is a known problem with...
2
5982
by: rawCoder | last post by:
Hi All, I have a *.cer file, a public key of some one and I want to encrypt some thing using this public key. Can someone point me to a sample code for Encrypting some file using X509Certificate ( *.cer file ) so that it can be used to email as attachment. The real part is Encrypting using X509Certificate and CryptoServiceProvider.
1
567
by: Mike | last post by:
When trying to compile (using Visual Web Developer 2005 Express Beta; frameworkv2.0.50215 ) the source code below I get errors (listed below due to the use of ICallBackEventHandler. Ultimately I want to use a callback from the client side to update webcontrols based on user input without using postback. I am seeking a way to stop the compile errors. using System; using System.Data;
10
2684
by: Christopher Benson-Manica | last post by:
Why can't I use a class destructor in a using declaration: using MyClass::~MyClass; ? -- Christopher Benson-Manica | I *should* know what I'm talking about - if I ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
17
3546
by: beliavsky | last post by:
Many of my C++ programs have the line using namespace std; but the "Accelerated C++" book of Koenig and Moo has many examples where the library names are included one at a time, for example using std::cin; using std::cout;
15
12346
by: Peter Duniho | last post by:
I'm trying to use .NET and C# to draw a metafile copied to the clipboard by another application (Word 2003 in this case, but it shouldn't matter). I naively thought that I'd be able to use the Clipboard class to get an EnhancedMetafile or MetafilePict object from the Clipboard, use that to create a new Metafile object, and then draw that Metafile object using Graphics.DrawImage. It doesn't seem to be that simple.
2
12806
by: rejidasan | last post by:
Hello All, I have a MFC Dialog based application. I am not using GDI or GDI+ libraries. I need to load PNG and JPEG images in this Dialog Based application. Can you suggest me how to to do without using GDI\GDI+? Thanks in advance, Reji
3
8338
by: JDeats | last post by:
I have some .NET 1.1 code that utilizes this technique for encrypting and decrypting a file. http://support.microsoft.com/kb/307010 In .NET 2.0 this approach is not fully supported (a .NET 2.0 build with these methods, will appear to encrypt and decrypt, but the resulting decrypted file will be corrupted. I tried encrypting a .bmp file and then decrypting, the resulting decrypted file under .NET 2.0 is garbage, the .NET 1.1 build works...
0
1154
by: Christian Nein | last post by:
Hi, does anybody know a component or library that deals with metafiles? In particular I am searching for a way to build 1 Metafile from many metafiles by assembling them together. With bitmaps this is quite an easy task but with the vector-based metafile format i still don't k now how to do this. Thanx in advance for any help & best regards Christian
0
10592
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10398
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
1
12123
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
11181
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
8761
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
7917
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
6706
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
5469
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
4974
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.