Extending MenuItem

P

Prats

Tried to extend the MenuItem class, following an example in C#. Below is the
code in C++

public ref class ImageMenuItem: MenuItem
{

private: static int ICON_WIDTH= 19;
private: static int ICON_HEIGHT = 19;
private: static int ICON_MARGIN = 4;

private: Color backgroundColor, selectionColor, selectionBorderColor;
//private: Image^ image;
public: property Image^ Image;/*{
System::Drawing::Image^ get(){
return image;
}
void set:):Image^ value) {
image = value;
}
}*/


public:
ImageMenuItem(void)
{
this->OwnerDraw = true;
backgroundColor = SystemColors::ControlLightLight;
selectionColor = Color::FromArgb(50, 0, 0, 150);
selectionBorderColor = SystemColors::Highlight;
}
ImageMenuItem:):Image^ image){
this->OwnerDraw = true;
Image = image;
backgroundColor = SystemColors::ControlLightLight;
selectionColor = Color::FromArgb(50, 0, 0, 150);
selectionBorderColor = SystemColors::Highlight;
}


protected: virtual void OnMeasureItem(MeasureItemEventArgs^ e)override
{
e->ItemWidth = ICON_WIDTH + ICON_MARGIN;
e->ItemHeight = ICON_HEIGHT + 2 * ICON_MARGIN;
}
protected: virtual void
OnDrawItem(System::Windows::Forms::DrawItemEventArgs ^e)override {
Graphics^ g = e->Graphics;
Rectangle bounds = e->Bounds;

DrawBackground(g, bounds, ((e->State &
DrawItemState::Selected)== DrawItemState::Selected ) );
g->DrawImage(Image, bounds.X + ((bounds.Width - ICON_WIDTH) /
2), bounds.Y + ((bounds.Height - ICON_HEIGHT) / 2));
}

protected:
/// <summary>
/// Clean up any resources being used.
/// </summary>
private:
/// <summary>
/// Required designer variable.
/// </summary>



private: void DrawBackground(Graphics^ g, Rectangle rec, bool sel) {
if (sel) {
g->FillRectangle(gcnew SolidBrush(selectionColor),
rec);
g->DrawRectangle(gcnew Pen(selectionBorderColor),
rec.X, rec.Y,
rec.Width - 1, rec.Height - 1);
}
else {
g->FillRectangle(gcnew SolidBrush(backgroundColor),
rec);
}
}

};

The mainForm is like this

private: array<Image ^> ^emoticons;


private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^
e) {
emoticons = gcnew array<Image^>(6);
emoticons[0] = Image::FromFile( "Emoticons\\AngelSmile.png" );
emoticons[1] = Image::FromFile( "Emoticons\\AngrySmile.png" );
emoticons[2] = Image::FromFile( "Emoticons\\Beer.png" );
emoticons[3] = Image::FromFile( "Emoticons\\BrokenHeart.png" );
emoticons[4] = Image::FromFile(
"Emoticons\\ConfusedSmile.png" );
emoticons[5] = Image::FromFile( "Emoticons\\CrySmile.png" );
ImageMenuItem^ mnuItem;
int count = 0;
for each(Image^ emoticon in emoticons) {
mnuItem = gcnew ImageMenuItem(emoticon);
mnuItem->Click += gcnew System::EventHandler(this,
&mainform::cmenu_Emoticons_Click);
if (count % 3 == 0)
mnuItem->BarBreak= true;
contextMenuStrip1->Items->Add(reinterpret_cast<ToolStripItem
^>( mnuItem));
++count;
}

}

private: void cmenu_Emoticons_Click(System::Object^ sender,
System::EventArgs^ e){
ImageMenuItem^ mnuItem = (ImageMenuItem^) sednder;
some more code to display mnuItem->Image
}


This program compiles without any errors, but does not run. When debugging I
get an exception at DrawBackground() stating Parameter is not valid.

what could be causing the error?

On further digging, OnDrawItem() is not called and DrawBackground() is
called, so the Graphics^ g parameter is emty and hence the parameter empty
exception.
How to resolve this?
 
A

Armin Zingler

Prats said:
[...]
This program compiles without any errors, but does not run. When
debugging I get an exception at DrawBackground() stating Parameter is
not valid.

Is the exception inside DrawBackground or when calling DrawBackground?
what could be causing the error?

On further digging, OnDrawItem() is not called and DrawBackground()
is called,

If OnDrawItem is not called, who calls DrawBackground? I only see one call
in your code. What's the callstack when the exception occurs?
so the Graphics^ g parameter is emty and hence the
parameter empty exception.
How to resolve this?

You didn't mention in which line the exception occurs. You also did not
mention the type of Exception. If g was nullptr, you'd get a
NullReferenceException.

BTW, don't forget to dispose the objects you create. In DrawBackground, you
create brushes and pens but don't dispose them.

See also:
http://msdn.microsoft.com/en-us/library/ms177197.aspx
http://msdn.microsoft.com/en-us/library/b1yfkh5e.aspx
http://msdn.microsoft.com/en-us/library/498928w2.aspx
http://msdn.microsoft.com/en-us/library/wxad3cah.aspx


Armin
 

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