ここでは、メニュー項目にアイコン(画像)を表示する方法を紹介します。MenuStripコントロールの場合と、MainMenuコントロールの場合に分けて説明します。
.NET Framework 2.0以降で、メニューにMenuStripコントロールやContextMenuStripコントロールを使用している場合はとても簡単です。メニュー項目のToolStripMenuItem.Imageプロパティに画像を設定して、ToolStripMenuItem.DisplayStyleプロパティを「ImageAndText」(または、「Image」)にするだけです。(DisplayStyleプロパティはデフォルトで「ImageAndText」です。)
フォームデザイナのプロパティウィンドウを使用してImageプロパティを設定しようとすると、「リソースの選択」ダイアログが表示されます。Imageプロパティに画像ファイルを設定する場合は、ここで「ローカルリソース」を選択してから「インポート」ボタンをクリックし、画像ファイルを選択してください。
補足:このようにしてインポートした画像は、フォームのリソース(resxファイル)に埋め込まれます。よって、インポート元の画像ファイルを編集したり、削除したりしても、メニューの画像は変わりません。画像を変えるには、もう一度画像ファイルをインポートします。なお「プロジェクトリソースファイル」を選択して画像ファイルをインポートした場合は、コンボボックスに表示されているresxファイル(デフォルトでは、C#では「Properties\Resources.resx」、VB.NETでは「My Project\Resources.resx」)に埋め込まれます。
透明色を指定する場合は、ToolStripItem.ImageTransparentColorプロパティを使います。
デフォルト(ToolStripItem.ImageScalingプロパティがSizeToFitの時)では、基の画像の大きさにかかわらず、適当な大きさ(ToolStrip.ImageScalingSizeプロパティで指定された大きさ)に拡大、縮小されて表示されます。ImageScalingプロパティをNoneにすると、画像は拡大、縮小されなくなります。
補足:ここで紹介した方法以外に、ImageListコンポーネントとToolStrip.ImageListプロパティ、そしてToolStripItem.ImageIndexプロパティかToolStripItem.ImageKeyプロパティを使用して、アイコンを表示することもできます。ただしこの方法はフォームデザイナでは行うことができませんので、ToolStrip.ImageListプロパティとToolStripItem.ImageIndexプロパティ(またはImageKeyプロパティ)の設定は自分でコードを書いて行う必要があります。
.NET Framework 1.1以前ではMainMenuコントロール(または、ContextMenuコントロール)を使うしかありませんが、簡単にアイコンを表示する方法は用意されていません。そこでここでは、オーナードローによりMainMenuにアイコンを表示する方法を紹介します。
メニューにアイコンを表示するにはオーナードローを行います。オーナードローとは、コントロールの描画をOS等に任せるのではなく、自分でコードを書いて行うということです。
ここでは、メニューにアイコンを表示するためにはどのようなことを行えばいいのかというごく簡単な例のみを示します。この例はメニューアイテムが無効になっているときや、チェックが付いているとき、セパレータのときなどを全く考慮してないため実用には程遠いですが、参考にはなると思います。なお実際にはMenuItemクラスから派生させた新しいクラスを作成し、使用するとよいでしょう(そのようなクラスをこちらで紹介しています)。
以下にその手順を示します。
1.フォーム(Form1)にMainMenuコントロール(MainMenu1)を貼り付ける。
2.MainMenu1にMenuItemを一つ追加し(MenuItem1)、Textを「ファイル(&F)」とする。
3.MenuItem1の下に新しいMenuItemを追加し(MenuItem2)、Textを「新規作成(&N)」、Shuortcutを「CtrlN」とする。この左側にアイコンを表示するようにする。
4.MenuItem2のOwnerDrawプロパティをTrueにする。
5.MenuItem2のMeasureItemイベントハンドラ(MenuItem2_MeasureItem)と、DrawItemイベントハンドラ(MenuItem2_DrawItem)を作成し、次のようなコードを書く。
'メニューに表示するアイコンをあらかじめ読み込んでおく Private newIcon As New Icon("new.ico") Private Sub MenuItem2_MeasureItem(ByVal sender As Object, _ ByVal e As System.Windows.Forms.MeasureItemEventArgs) _ Handles MenuItem2.MeasureItem 'メニューアイテムの大きさを計算する '高さを"e.ItemHeight"に幅を"e.ItemWidth"に入れる Dim mi As MenuItem = CType(sender, MenuItem) 'メニューに表示する文字列を取得 Dim menuText As String menuText = mi.Text If mi.ShowShortcut AndAlso mi.Shortcut <> Shortcut.None Then 'ショートカットを表示するときは、その文字列を追加する menuText += " " + _ System.ComponentModel.TypeDescriptor.GetConverter( _ GetType(Keys)).ConvertToString(CType(mi.Shortcut, Keys)) End If Dim sf As New StringFormat() 'ホットキープリフィックスの表示(&を_にする) sf.HotkeyPrefix = Drawing.Text.HotkeyPrefix.Show '幅を決定する '文字列の幅にアイコンの幅16と余白30を足す e.ItemWidth = CInt(e.Graphics.MeasureString(menuText, _ SystemInformation.MenuFont, Integer.MaxValue, sf).Width + 46) 'リソースを解放 sf.Dispose() '高さを決定する(19bitに固定する) e.ItemHeight = 19 End Sub Private Sub MenuItem2_DrawItem(ByVal sender As Object, _ ByVal e As System.Windows.Forms.DrawItemEventArgs) _ Handles MenuItem2.DrawItem 'メニューアイテムを描く Dim mi As MenuItem = CType(sender, MenuItem) Dim b As Brush If (e.State And DrawItemState.Selected) = DrawItemState.Selected Then '選択されている時 '背景を塗りつぶす e.Graphics.FillRectangle(SystemBrushes.Highlight, e.Bounds) '文字列の描画に使用するブラシの作成 b = New SolidBrush(SystemColors.HighlightText) Else '選択されていない時 '背景を塗りつぶす e.Graphics.FillRectangle(SystemBrushes.Menu, e.Bounds) '文字列の描画に使用するブラシの作成 b = New SolidBrush(SystemColors.MenuText) End If 'アイコンを描く e.Graphics.DrawIcon(newIcon, e.Bounds.Left + 2, _ e.Bounds.Top + (e.Bounds.Height - newIcon.Height) \ 2) '文字を描画 Dim sf As New StringFormat() 'ホットキープリフィックスの表示(&を_にする) sf.HotkeyPrefix = Drawing.Text.HotkeyPrefix.Show 'Text部分を描画 Dim top As Integer = _ (e.Bounds.Height - SystemInformation.MenuFont.Height) \ 2 e.Graphics.DrawString(mi.Text, SystemInformation.MenuFont, _ b, e.Bounds.Left + 22, e.Bounds.Top + top, sf) If mi.ShowShortcut AndAlso mi.Shortcut <> Shortcut.None Then 'Shortcut部分を描画 'Shortcut部分の文字列を取得 Dim shortcutText As String = _ System.ComponentModel.TypeDescriptor.GetConverter( _ GetType(Keys)).ConvertToString(CType(mi.Shortcut, Keys)) 'Shortcut部分の幅を取得 Dim shortcutWidth As Integer = _ CInt(e.Graphics.MeasureString(shortcutText, _ SystemInformation.MenuFont, Integer.MaxValue, sf).Width) 'Shortcut部分の文字列を描画 e.Graphics.DrawString(shortcutText, SystemInformation.MenuFont, _ b, e.Bounds.Right - shortcutWidth - 24, _ e.Bounds.Top + top, sf) End If 'リソースを解放 b.Dispose() sf.Dispose() End Sub
//メニューに表示するアイコンをあらかじめ読み込んでおく private Icon newIcon = new Icon("new.ico"); private void MenuItem2_MeasureItem(object sender, System.Windows.Forms.MeasureItemEventArgs e) { //メニューアイテムの大きさを計算する //高さを"e.ItemHeight"に幅を"e.ItemWidth"に入れる MenuItem mi = (MenuItem) sender; //メニューに表示する文字列を取得 string menuText; menuText = mi.Text; if (mi.ShowShortcut && mi.Shortcut != Shortcut.None) { //ショートカットを表示するときは、その文字列を追加する menuText += " " + System.ComponentModel.TypeDescriptor.GetConverter( typeof(Keys)).ConvertToString((Keys) mi.Shortcut); } StringFormat sf = new StringFormat(); //ホットキープリフィックスの表示(&を_にする) sf.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.Show; //幅を決定する //文字列の幅にアイコンの幅16と余白30を足す e.ItemWidth = (int) e.Graphics.MeasureString(menuText, SystemInformation.MenuFont, int.MaxValue, sf).Width + 46; //リソースを解放 sf.Dispose(); //高さを決定する(19bitに固定する) e.ItemHeight = 19; } private void MenuItem2_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e) { //メニューアイテムを描く MenuItem mi= (MenuItem) sender; Brush b; if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) { //選択されている時 //背景を塗りつぶす e.Graphics.FillRectangle(SystemBrushes.Highlight, e.Bounds); //文字列の描画に使用するブラシの作成 b = new SolidBrush(SystemColors.HighlightText); } else { //選択されていない時 //背景を塗りつぶす e.Graphics.FillRectangle(SystemBrushes.Menu, e.Bounds); //文字列の描画に使用するブラシの作成 b = new SolidBrush(SystemColors.MenuText); } //アイコンを描く e.Graphics.DrawIcon(newIcon, e.Bounds.Left + 2, e.Bounds.Top + (e.Bounds.Height - newIcon.Height) / 2); //文字を描画 StringFormat sf = new StringFormat(); //ホットキープリフィックスの表示(&を_にする) sf.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.Show; //Text部分を描画 int top= (e.Bounds.Height - SystemInformation.MenuFont.Height) / 2; e.Graphics.DrawString(mi.Text, SystemInformation.MenuFont, b, e.Bounds.Left + 22, e.Bounds.Top + top, sf); if (mi.ShowShortcut && mi.Shortcut != Shortcut.None) { //Shortcut部分を描画 //Shortcut部分の文字列を取得 string shortcutText= System.ComponentModel.TypeDescriptor.GetConverter( typeof(Keys)).ConvertToString((Keys) mi.Shortcut); //Shortcut部分の幅を取得 int shortcutWidth= (int) e.Graphics.MeasureString(shortcutText, SystemInformation.MenuFont, int.MaxValue, sf).Width; //Shortcut部分の文字列を描画 e.Graphics.DrawString(shortcutText, SystemInformation.MenuFont, b, e.Bounds.Right - shortcutWidth - 24, e.Bounds.Top + top, sf); } //リソースを解放 b.Dispose(); sf.Dispose(); }