VS.NET 2003
I have a OwnerDrawFixed ComboBox. Sometimes, only sometimes but too frequently, when I click or is scrolling through the list (5 items) I get an Out of Memory exception in the DrawItem event handler at the point where I was drawing a dashed line (my drop down list is a list of dash styles). The exact error is "'System.OutOfMemoryException' occurred in system.drawing.dll"
I have plenty of memory. A cursory check with Task Manager shows that it is using only low tens of MB. I put a Debug.WriteLine statement in the event handler, and the handler is called only a few times before it crashes. What information can I output in the Debug statement to try and trace the source of the error
What does Out of Memory really mean when there is plenty of memory Are there any caveats to watch out when doing DrawItem I searched and found only one unanswered question at here: http://www.codeproject.com/vb/net/VbNetOwnerDrawMenu.asp msg=869630#xxxx.
Thanks for any help.

What is "Out of Memory" when I have lots?
Dave Wesst
Developers - Dany Acosta
public class ValueHelper
{
private string _text;
private DashStyle _value;
public string Text
{
get
{
return _text;
}
set
{
_text = value;
}
}
public DashStyle Value
{
get
{
return value;
}
set
{
_value = value;
}
}
public ValueHelper()
{
// Nothing todo.
}
public ValueHelper( string text, DashStyle value )
{
_text = text;
_value = value;
}
public override string ToString()
{
if( Text != null )
{
return Text;
}
else
{
return string.Empty;
}
}
}
Create the needed instances and add them to the combobox. If you need the selected value, just cast the SelectedItem property of the combobox to an ValueHelper object and read the value.
shahrul
I don't see any strange thing, only you don't dispose you pen. But that shouldn't be the bottleneck, but you can give it a try:
private void TodayStyle_DrawItem(object sender, DrawItemEventArgs e)
{
if( e.Index < 0 || e.Index > 4 )
{
return;
}
e.DrawBackground();
Rectangle r = e.Bounds;
using(Pen pen = new Pen( TodayColor.BackColor,TodayThickness.SelectedIndex + 1 ) )
{
pen.DashStyle=(DashStyle)e.Index+1; //going for enum values of 1-5
Point beginPoint = new Point( 0, r.Top + r.Height / 2 );
Point endPoint = new Point( r.Right, r.Top + r.Height / 2 );
e.Graphics.DrawLine( pen, beginPoint, endPoint );
}
if ( (e.State & DrawItemState.Focus) != 0 )
{
e.DrawFocusRectangle();
}
}
Stephen Lawson
Thanks for the fast response.
My Code:
private void TodayStyle_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)
{
Debug.WriteLine("DrawItem "+e.Index+" state: "+e.State.ToString()+" Color: "+e.BackColor.Name+" "+e.Bounds.ToString());
if (e.Index<0 || e.Index>4) return;
e.DrawBackground();
Rectangle r = e.Bounds;
Pen pen = new Pen(TodayColor.BackColor,TodayThickness.SelectedIndex+1);
pen.DashStyle=(DashStyle)e.Index+1; //going for enum values of 1-5
e.Graphics.DrawLine(pen,0,r.Top+r.Height/2,r.Right,r.Top+r.Height/2); if ((e.State & DrawItemState.Focus)!=0) e.DrawFocusRectangle();
}
---Output when I just clicked the combo once and the drop down list opens (third item was selected at start). Doesn't look like an endless loop situation:
DrawItem 2 state: ComboBoxEdit Color: Window {X=3,Y=3,Width=94,Height=15}
DrawItem 2 state: Selected, Focus, ComboBoxEdit Color: Highlight {X=3,Y=3,Width=94,Height=15}
DrawItem 2 state: ComboBoxEdit Color: Window {X=3,Y=3,Width=94,Height=15}
DrawItem 2 state: ComboBoxEdit Color: Window {X=3,Y=3,Width=94,Height=15}
DrawItem 2 state: Selected Color: Highlight {X=0,Y=30,Width=114,Height=15}
DrawItem 0 state: None Color: Window {X=0,Y=0,Width=114,Height=15}
DrawItem 1 state: None Color: Window {X=0,Y=15,Width=114,Height=15}
DrawItem 2 state: Selected Color: Highlight {X=0,Y=30,Width=114,Height=15}
DrawItem 3 state: None Color: Window {X=0,Y=45,Width=114,Height=15}
DrawItem 4 state: None Color: Window {X=0,Y=60,Width=114,Height=15}
An unhandled exception of type 'System.OutOfMemoryException' occurred in system.drawing.dll
Additional information: Out of memory.
------Stack trace:
I have global replaced system.windows.forms to S.W.F for brevity.
system.drawing.dll!System.Drawing.Graphics.CheckErrorStatus(int status = 3) + 0x41 bytes
system.drawing.dll!System.Drawing.Graphics.DrawLine(System.Drawing.Pen pen = {Color={RGB=0xff004040}}, int x1 = 0, int y1 = 67, int x2 = 114, int y2 = 67) + 0xc2 bytes
>My Prog.exe!MyProg.TodayMarker.TodayStyle_DrawItem(System.Object sender = {S.W.F.ComboBox}, S.W.F.DrawItemEventArgs e = {S.W.F.DrawItemEventArgs}) + 0x312 bytesC#
S.W.F.dll!S.W.F.ComboBox.OnDrawItem(S.W.F.DrawItemEventArgs e = {S.W.F.DrawItemEventArgs}) + 0x4c bytes
S.W.F.dll!S.W.F.ComboBox.WmReflectDrawItem(S.W.F.Message m = {S.W.F.Message}) + 0x165 bytes
S.W.F.dll!S.W.F.ComboBox.WndProc(S.W.F.Message m = {S.W.F.Message}) + 0x28b bytes
S.W.F.dll!ControlNativeWindow.OnMessage(S.W.F.Message m = {S.W.F.Message}) + 0x13 bytes
S.W.F.dll!ControlNativeWindow.WndProc(S.W.F.Message m = {S.W.F.Message}) + 0xda bytes
S.W.F.dll!S.W.F.NativeWindow.DebuggableCallback(int hWnd = 14486086, int msg = 8235, int wparam = 14486086, int lparam = 1239140) + 0x3d bytes
S.W.F.dll!S.W.F.Control.SendMessage(int msg = 8235, int wparam = 14486086, int lparam = 1239140) + 0x48 bytes
.... stuff deleted on Mar 31 after problem was solved
dwComponentID = 172, int reason = -1, int pvLoopData = 0) + 0x349 bytes
S.W.F.dll!ThreadContext.RunMessageLoopInner(int reason = -1, S.W.F.ApplicationContext context = {S.W.F.ApplicationContext}) + 0x1f5 bytes
S.W.F.dll!ThreadContext.RunMessageLoop(int reason = -1, S.W.F.ApplicationContext context = {S.W.F.ApplicationContext}) + 0x50 bytes
S.W.F.dll!S.W.F.Application.Run(S.W.F.Form mainForm = {MyProg.Form1}) + 0x34 bytes
My Prog.exe!MyProg.Form1.Main() + 0x20 bytesC#
--
I am developing on a Windows Server 2003 PC. Error occurs both in IDE and standalone exe. When I run the exe on an XP machine, I have not managed to generate the error.
Thanks for your help
ChrisMM.
Add names value
String[] names = Enum.GetNames( typeof(DashStyle) );
comboBox.Items.AddRange( names );
Get selected style
String name = (String)comboBox.SelectedItem;
DashStyle style = (DashStyle)Enum.Parse( typeof(DashStyle), name, true );
TimirP
PJ, thanks for all your help. I think (I hope) I have found the problem.
The DashStyle Eumeration members are Custom, Dash, DashDot, DashDotDot, Dot and Solid. I mistook them to be 0 to 5 in that order. But that was in alphabetical order.
0 to 5 are actually Solid, Dash, Dot, DashDot, DashDotDot and Custom.
I wanted to avoid Custom. The problem occurs only during when the ComboBox SelectedIndex of 4 (meaning 5), Custom, is painted. And I didn't define what Custom is.
Thanks.
PS: A separate question would be how to use enumerated values and be future proof
fred369
This can also be the stack that can be full very quickly when a get property that refers to itself or a endless loop that builds a buffer and more then thousand other scenarios.
Can you post relevant code Does it allways happen on the same statement Can you post the stack-trace