P
Peter Duniho
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.
When I try to get the EnhancedMetafile object from the Clipboard, .NET
crashes. When I have the debugger running, the MDA tells me I've got a
FatalExecutionEngineError and that it's due either to improper use of unsafe
code or a bug in .NET. Since I'm not using any unsafe code, that leaves a
bug in .NET.
??? How could something this simple crash .NET?
Anyway, so I tried using the MetafilePict format instead. This doesn't
crash .NET, but the object that's returned is a MemoryStream. In and of
itself, that seems reasonable. You can construct a new Metafile object
using a MemoryStream. However, the MemoryStream returned is only 16 bytes
long, much too short to be the metafile I'm trying to get. Of course, I get
a whole new exception trying to use this MemoryStream object to construct a
Metafile, but even if I didn't, I'm sure it wouldn't be the data I want.
The code I'm trying to use is pretty straightforward:
mfstream = (Stream)Clipboard.GetData(DataFormats.MetafilePict);
metafile = new Metafile(mfstream);
(or DataForms.EnhancedMetafile for the case that just crashes within the
..NET code)
I mean, I've written other code to do things like check the clipboard
formats and whatnot, but the problematic code boils down to those two lines.
(And yes, when I check the formats in the clipboard, both "Enhanced
Metafile" and "MetaFile Pict" are in there).
I Googled the issue a bit, and found two categories of messages: people who
also can't figure out how to do this, and suggestions to use inter-op. I
actually was able to inter-op to sort of accomplish it, but I wound up
having to basically use *no* .NET stuff...I just p/invoked the basic
clipboard and metafile functions required to draw a metafile to a DC,
passing the DC provided by the e.Graphics object for the OnPaint handler
(which is where, for the moment, I'm trying to get this to work...though
once I can draw the metafile succesfully on the screen, I have other plans
for it ).
If I wanted to do it that way, I'd just write a native Win32 program. I
suppose I may wind up doing that after all, but I was hoping to do this in
..NET. I've gotten spoiled not having to do any real work to build a UI.
Using inter-op in the way the online messages suggested did not work. In
particular, they recommend using the regular Win32 clipboard functions to
get the handle to the metafile, and then construct a new Metafile object
using that handle. When I try that, I get the same general "GDI+ error"
exception that I get just using .NET stuff (though perhaps for different
reasons...the exception is too generic to know for sure).
Given the degree of interest that there appears in doing this, and the lack
of useful information about *how* to do it, I'm not hopeful. But I figure I
gotta try...
Anyone reading this ever successfully use .NET to get a metafile (enhanced
or otherwise) from the clipboard and draw it to your form (or do anything
else with it)? If so, how do you do it? What am I doing wrong?
Thanks!
Pete
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.
When I try to get the EnhancedMetafile object from the Clipboard, .NET
crashes. When I have the debugger running, the MDA tells me I've got a
FatalExecutionEngineError and that it's due either to improper use of unsafe
code or a bug in .NET. Since I'm not using any unsafe code, that leaves a
bug in .NET.
??? How could something this simple crash .NET?
Anyway, so I tried using the MetafilePict format instead. This doesn't
crash .NET, but the object that's returned is a MemoryStream. In and of
itself, that seems reasonable. You can construct a new Metafile object
using a MemoryStream. However, the MemoryStream returned is only 16 bytes
long, much too short to be the metafile I'm trying to get. Of course, I get
a whole new exception trying to use this MemoryStream object to construct a
Metafile, but even if I didn't, I'm sure it wouldn't be the data I want.
The code I'm trying to use is pretty straightforward:
mfstream = (Stream)Clipboard.GetData(DataFormats.MetafilePict);
metafile = new Metafile(mfstream);
(or DataForms.EnhancedMetafile for the case that just crashes within the
..NET code)
I mean, I've written other code to do things like check the clipboard
formats and whatnot, but the problematic code boils down to those two lines.
(And yes, when I check the formats in the clipboard, both "Enhanced
Metafile" and "MetaFile Pict" are in there).
I Googled the issue a bit, and found two categories of messages: people who
also can't figure out how to do this, and suggestions to use inter-op. I
actually was able to inter-op to sort of accomplish it, but I wound up
having to basically use *no* .NET stuff...I just p/invoked the basic
clipboard and metafile functions required to draw a metafile to a DC,
passing the DC provided by the e.Graphics object for the OnPaint handler
(which is where, for the moment, I'm trying to get this to work...though
once I can draw the metafile succesfully on the screen, I have other plans
for it ).
If I wanted to do it that way, I'd just write a native Win32 program. I
suppose I may wind up doing that after all, but I was hoping to do this in
..NET. I've gotten spoiled not having to do any real work to build a UI.
Using inter-op in the way the online messages suggested did not work. In
particular, they recommend using the regular Win32 clipboard functions to
get the handle to the metafile, and then construct a new Metafile object
using that handle. When I try that, I get the same general "GDI+ error"
exception that I get just using .NET stuff (though perhaps for different
reasons...the exception is too generic to know for sure).
Given the degree of interest that there appears in doing this, and the lack
of useful information about *how* to do it, I'm not hopeful. But I figure I
gotta try...
Anyone reading this ever successfully use .NET to get a metafile (enhanced
or otherwise) from the clipboard and draw it to your form (or do anything
else with it)? If so, how do you do it? What am I doing wrong?
Thanks!
Pete