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:
rawing::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:
rawItemEventArgs ^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?
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:
![Big Grin :D :D](/styles/default/custom/smilies/grin.gif)
return image;
}
void set
![Smile (: (:](/styles/default/custom/smilies/smile.gif)
image = value;
}
}*/
public:
ImageMenuItem(void)
{
this->OwnerDraw = true;
backgroundColor = SystemColors::ControlLightLight;
selectionColor = Color::FromArgb(50, 0, 0, 150);
selectionBorderColor = SystemColors::Highlight;
}
ImageMenuItem
![Smile (: (:](/styles/default/custom/smilies/smile.gif)
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:
![Big Grin :D :D](/styles/default/custom/smilies/grin.gif)
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?