Unhandled exception : The object is currently in use elsewhere while resizing control

S

Sam Barham

I have a ListView control, for which I have overwritten the WndProc
method to gain access to the WM_PAINT message and generate my own
OnPaint and OnPaintBackground messages, in order to colour the columns
of the listview to my liking. When a row of the listview is selected,
some controls are displayed on that row of the listview (so sort of
like a property list thingy). In order to get the controls
(specifically buttons) to display how I wanted them, I have created a
button subclass that also overrides its OnPaint method.

If I resize the listview (by resizing the form it is on), while these
child controls are displayed, I get the following unex error:


An unhandled exception of type 'System.InvalidOperationException'
occurred in system.drawing.dll

Additional information: The object is currently in use elsewhere.


The call stack is:

system.drawing.dll!System.Drawing.Graphics.CheckErrorStatus(int
status = 4) + 0x41 bytes
system.drawing.dll!System.Drawing.Graphics.FillRectangle(System.Drawing.Brush
brush = {Color={RGB=0x0}}, int x = 0, int y = 0, int width = 74, int
height = 159) + 0xc2 bytes
system.drawing.dll!System.Drawing.Graphics.FillRectangle(System.Drawing.Brush
brush = {Color={RGB=0x0}}, System.Drawing.Rectangle rect = {X=0 Y=0
Width=74 Height=159}) + 0x60 bytes
worldeditpanes.dll!WorldEditPanes.AtasPropertyList.OnPaintBackground(System.Windows.Forms.PaintEventArgs
e = 0x0012ba00) Line 353
worldeditpanes.dll!WorldEditPanes.AtasPropertyList.WndProc(System.Windows.Forms.Message
message = 0x0012bb18) Line 554
system.windows.forms.dll!ControlNativeWindow.OnMessage(System.Windows.Forms.Message
m = {System.Windows.Forms.Message}) + 0x13 bytes
system.windows.forms.dll!ControlNativeWindow.WndProc(System.Windows.Forms.Message
m = {System.Windows.Forms.Message}) + 0xda bytes
system.windows.forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(int
hWnd = 133842, int msg = 15, int wparam = 0, int lparam = 0) + 0x3d
bytes

blah, blah, blah...


The relevant code snippets follow. First of all, here is part of my
WndProc method...


//Set up
HWND hwnd = (HWND)message->HWnd.ToInt32();
RECT *updateRect = new RECT();
if(GetUpdateRect(hwnd, updateRect, false) == 0)
break;
System::Drawing::Rectangle managedRect =
Rectangle::FromLTRB(updateRect->left, updateRect->top,
updateRect->right, updateRect->bottom);

PAINTSTRUCT *paintStruct = new PAINTSTRUCT();
IntPtr screenHdc = BeginPaint(hwnd, paintStruct);
Graphics *screenGraphics = Graphics::FromHdc(screenHdc);

//Add the missing OnPaintBackground() call
OnPaintBackground(new PaintEventArgs(mInternalGraphics, managedRect));

//Draw Internal Graphics
IntPtr hdc = mInternalGraphics->GetHdc();
Message printClientMessage = Message::Create(Handle, WM_PRINTCLIENT,
hdc, IntPtr::Zero);
DefWndProc(&printClientMessage);
mInternalGraphics->ReleaseHdc( hdc );

//Add the missing OnPaint() call
OnPaint(new PaintEventArgs(mInternalGraphics, managedRect));

//Draw Screen Graphics
screenGraphics->DrawImage(mInternalBitmap, 0, 0);
screenGraphics->Dispose();

//Tear down
EndPaint(hwnd, paintStruct);
return;


I got that off the web somewhere, and until I added the whole child
control thing it has worked fine.

OnPaintBackground (where the crash happens) looks like:

void AtasPropertyList::OnPaintBackground(PaintEventArgs* e)
{
int width = Columns->Item[0]->Width + Columns->Item[1]->Width;
System::Drawing::Rectangle rcl = System::Drawing::Rectangle(0, 0,
width, Height);
if(!rcl.IsEmpty)
{
SolidBrush *brush = new SolidBrush(Color::LightGray);
e->Graphics->FillRectangle(brush, rcl);
brush->Dispose();
}
rcl = System::Drawing::Rectangle(width, 0, Width - width, Height);
if(!rcl.IsEmpty)
{
SolidBrush *brush = new SolidBrush(Color::White);
e->Graphics->FillRectangle(brush, rcl);
brush->Dispose();
}
}

The idea being that the first two columns are grey and the rest are
white.
Finally, the ownerdrawn button OnPaint code (which I suspect is
contributing to the problem:

void PropertyListButton::OnPaint(PaintEventArgs *e)
{
if (mPushed)
{
if (FlatStyle == System::Windows::Forms::FlatStyle::Flat)
{
e->Graphics->FillRectangle(new SolidBrush(BackColor), 0, 0,
ClientSize.Width, ClientSize.Height);
DrawItem(e->Graphics, 0, 0);
}
else
{
ControlPaint::DrawButton(e->Graphics, 0, 0, Width, Height,
ButtonState::pushed);
DrawItem(e->Graphics, 1, 1);
}
}
else
{
if (FlatStyle == System::Windows::Forms::FlatStyle::Flat)
{
e->Graphics->FillRectangle(new SolidBrush(BackColor), 0, 0,
ClientSize.Width, ClientSize.Height);
DrawItem(e->Graphics, 0, 0);
}
else
{
ControlPaint::DrawButton(e->Graphics, 0, 0, Width, Height,
ButtonState::Normal);
DrawItem(e->Graphics, 0, 0);
}
}
}
void PropertyListButton::DrawItem(Graphics *g, int xOffset, int
yOffset)
{
if (Image == NULL)
{
StringFormat *strf = new StringFormat();
strf->Alignment = StringAlignment::Center;
strf->LineAlignment = StringAlignment::Center;

SizeF szf = g->MeasureString(Text, Font);

int xPos = (ClientSize.Width - (int)Math::Ceiling(szf.Width)) / 2;
int yPos = (ClientSize.Height - (int)Math::Ceiling(szf.Height)) /
2;

RectangleF rf((float)(xPos + xOffset), (float)(yPos + yOffset),
szf.Width, szf.Height);
g->DrawString(Text, Font, new SolidBrush(ForeColor), rf, strf);
}
else
{
int xPos = (ClientSize.Width - Image->Width) / 2;
int yPos = (ClientSize.Height - Image->Height) / 2;

g->DrawImage(Image, xPos + xOffset, yPos + yOffset, Image->Width,
Image->Height);
}
}


I am not running multiple threads (most of the info about this error
seemed to be about multi-threading)

Any ideas?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top