Groups | Blog | Home
all groups > dotnet drawing api > october 2006 >

dotnet drawing api : Drawing to a Metafile twice.


mccoyn
10/28/2006 12:06:02 PM
I'm trying to write a program like Paint that draws to a Metafile instead of
a bitmap. I can create the Metafile, but the second time I try to draw to it
I get an OutOfMemoryException.

I've written a simplified program with two buttons. The Click handlers are
below. When I click button1 it works fine, but when I click button2 after
button1 I get an OutOfMemoryException even though I just started the app and
I have plenty of memory left.

Does anyone know what the problem is?


void Form1::button1_Click(Object^ sender, EventArgs^ e)
{
{
Graphics^ graphics = this->CreateGraphics();
IntPtr hdc = graphics->GetHdc();
mMeta = gcnew Metafile(hdc, Rectangle(0, 0, 100, 100));
graphics->ReleaseHdc(hdc);
delete graphics;
}
{
Graphics^ graphics = Graphics::FromImage(mMeta);
graphics->DrawRectangle(gcnew Pen(ForeColor), 10, 10, 20, 20);
delete graphics;
}
}

void Form1::button2_Click(Object^ sender, EventArgs^ e)
{
{
Graphics^ graphics = Graphics::FromImage(mMeta);
graphics->DrawRectangle(gcnew Pen(ForeColor), 30, 10, 20, 20);
delete graphics;
}
mccoyn
11/12/2006 7:26:01 AM
I never got an answer to this. I ended up working around the problem by
creating a new metafile every time I want to edit it and pasting the old one
into the new one. I suspect this leads to slower then needed metafiles that
are recursivly defined.

Below is the code I wrote to do this. I call CreateMetaGraphics() before
drawing to the image, this gives me the graphics object to draw on. When I
am done, I call DisposeMetaGraphics(). I have another function that sets
mCommited to mImage when an action is completed.

I'm still looking for a better solution, but I thought I'd post this since
when I searched the web I found several people with the same question and no
solution.

Graphics^ MetaDraw::CreateMetaGraphics()
{
if (mMetaGraphicsCount <= 0)
{
Drawing::Size size(300, 300);
Graphics^ graphics = this->CreateGraphics();
IntPtr hdc = graphics->GetHdc();
mImage = gcnew Metafile(
hdc,
Rectangle(Point(0,0), size),
MetafileFrameUnit::Millimeter);
graphics->ReleaseHdc(hdc);
delete graphics;

mMetaGraphics = Graphics::FromImage(mImage);

if (mCommited != nullptr)
{
mMetaGraphics->DrawImageUnscaled(mCommited, 0, 0);
}
else
{
SizeF sizeInPixels(
size.Width * mMetaGraphics->DpiX / 25.4f,
size.Height * mMetaGraphics->DpiY / 25.4f);

mMetaGraphics->FillRectangle(
gcnew SolidBrush(ImageBackColor),
0.0, 0.0,
sizeInPixels.Width,
sizeInPixels.Height);
}

mMetaGraphicsCount = 1;
}
else
{
mMetaGraphicsCount++;
}
return mMetaGraphics;
}

void MetaDraw::DisposeMetaGraphics()
{
if (mMetaGraphicsCount == 1)
{
delete mMetaGraphics;
mMetaGraphicsCount = 0;
Invalidate();
}
else
{
mMetaGraphicsCount--;
}
}


[quoted text, click to view]
AddThis Social Bookmark Button