DoboWiki
Top
> .NETプログラミング研究/4 をテンプレートにして作成
.NETプログラミング研究/4 をテンプレートにして作成
開始行:
#title(.NETプログラミング研究 第4号)
#navi(.NETプログラミング研究)
#contents
*.NETプログラミング研究 第4号 [#teb83ffc]
**注意事項 [#s6067321]
今回はコードが長いため、VB.NETのコードのみを紹介します。...
**ピンポイントリンク [#o34c4c3d]
***メニューにアイコンを表示する [#led4fdb1]
#column(注意){{
「[[メニューにアイコンを表示する>https://dobon.net/vb/dot...
}}
メニュー項目の右側にアイコンが表示されているようなアプリ...
メニューにアイコンを表示するためには「オーナードロー(オ...
早速ですが、オーナードローでメニューを表示させてみましょ...
Form1というフォームに、MainMenu1というMainMenuオブジェク...
ここではMenuItem2にオーナードローにより画像を表示してみる...
以下の例ではMenuItem2にアイコン"open.ico"を表示させていま...
#code(vbnet){{
'メニュー項目に表示させるアイコン
Private _icon As New Icon("open.ico")
'メニュー項目の大きさを計算する
Private Sub MenuItem2_MeasureItem(ByVal sender As Object, _
ByVal e As System.Windows.Forms.MeasureItemEventA...
Handles MenuItem2.MeasureItem
'高さを"e.ItemHeight"に幅を"e.ItemWidth"に入れる
'メニュー項目の高さを設定する
e.ItemHeight = _icon.Height
'メニュー項目の幅を設定する
e.ItemWidth = _icon.Width
End Sub
'メニュー項目の描画
Private Sub MenuItem2_DrawItem(ByVal sender As Object, _
ByVal e As System.Windows.Forms.DrawItemEventArgs...
Handles MenuItem2.DrawItem
'e.Graphicsに描画する
'メニュー項目の境界はe.Boundsから取得できる
e.Graphics.DrawIcon(_icon, e.Bounds.X, e.Bounds.Y)
End Sub
}}
うまくメニューに画像が表示できたことと思います。メニュー...
この調子だと目的を達成するのも簡単そうに思えるでしょう。...
#code(vbnet){{
'メニュー項目に表示させるアイコン
Private _icon As New Icon("open.ico")
'メニュー項目の大きさを計算する
Private Sub MenuItem2_MeasureItem(ByVal sender As System....
ByVal e As System.Windows.Forms.MeasureItemEventA...
Handles MenuItem2.MeasureItem
'幅を決定する
'文字列の幅を計算する
'メニューで使うフォントは
'SystemInformation.MenuFontプロパティで取得できる
Dim textWidth As Integer = CInt( _
e.Graphics.MeasureString(sender.Text, _
SystemInformation.MenuFont).Width)
e.ItemWidth = textWidth + 46
'高さを決定する
e.ItemHeight = _
Math.Max(SystemInformation.MenuFont.Height, _icon...
+ 2
End Sub
'メニュー項目の描画
Private Sub MenuItem2_DrawItem(ByVal sender As System.Obj...
ByVal e As System.Windows.Forms.DrawItemEventArgs...
Handles MenuItem2.DrawItem
'背景の塗りつぶし
'DrawItemEventArgs.DrawBackgroundメソッドを使ってみる
e.DrawBackground()
'アイコンの描画
If Not (_icon Is Nothing) Then
e.Graphics.DrawIcon(_icon, _
e.Bounds.Left + 2, _
e.Bounds.Top + (e.Bounds.Height - _icon.Heigh...
End If
'文字の描画
Dim textBrush As Brush
'DrawItemEventArgs.ForeColorプロパティを使ってみる
textBrush = New SolidBrush(e.ForeColor)
e.Graphics.DrawString(sender.Text, _
SystemInformation.MenuFont, _
textBrush, _
e.Bounds.Left + 22, _
e.Bounds.Top + _
(e.Bounds.Height - _
SystemInformation.MenuFont.Height) \ 2)
'リソースを開放
textBrush.Dispose()
End Sub
}}
ところがこのサンプルには多くの問題があります。なんといっ...
さらに、このようなコードを直接一つ一つのMenuItemオブジェ...
何を隠そう、これらの問題をクリアしたサンプルがMicrosoftの...
#code(vbnet){{
Imports System
Imports System.ComponentModel
Imports System.Drawing
Imports System.Drawing.Text
Imports System.Windows.Forms
Public Class ImageMenuItem : Inherits MenuItem
'定数-----------------------------------------
'表示する画像のサイズ
Private Const imageHeight As Integer = 16
Private Const imageWidth As Integer = 16
'上の余白(下の余白も同じになる)
Private Const topMargin As Integer = 1
'左側の余白
Private Const leftMargin As Integer = 2
'画像とテキストの間隔
Private Const intervalImageAndText As Integer = 4
'右側の余白
Private Const rightMargin As Integer = 20
'メニューのテキストの表示位置
Private Const textLeft As Integer = _
leftMargin + imageWidth + intervalImageAndText
'テキスト以外の部分の幅
Private Const widthExceptText As Integer = _
imageWidth + leftMargin + intervalImageAndText + ...
'プロパティ-----------------------------------
'表示する画像
Private _image As Image
Public Property Image() As Image
Get
Return _image
End Get
Set(ByVal Value As Image)
_image = Value
End Set
End Property
'コンストラクタ-------------------------------
Public Sub New(ByVal text As String)
MyBase.New(text)
Me.OwnerDraw = True
End Sub
'メソッド-------------------------------------
'OnMeasureItemのオーバーライド
'メニューアイテムの大きさを計算する
'高さを"e.ItemHeight"に幅を"e.ItemWidth"に入れる
Protected Overrides Sub OnMeasureItem( _
ByVal e As MeasureItemEventArgs)
'基本クラスのOnMeasureItemを処理する
MyBase.OnMeasureItem(e)
'メニューに表示する文字列を取得
Dim menuText As String
menuText = Text
'シュートカットを表示するときは、その文字列を追加...
If ShowShortcut = True And _
Shortcut <> Shortcut.None Then
menuText += _
TypeDescriptor.GetConverter(GetType(Keys)...
ConvertToString(CType(Shortcut, Keys))
End If
Dim sf As New StringFormat()
'ホットキープリフィックスの表示(&を_にする)
sf.HotkeyPrefix = HotkeyPrefix.Show
'幅を決定する
e.ItemWidth = CInt( _
e.Graphics.MeasureString(menuText, _
SystemInformation.MenuFont, _
Integer.MaxValue, _
sf).Width) + widthExceptText
'リソースを開放
sf.Dispose()
'高さを決定する
e.ItemHeight = _
Math.Max(SystemInformation.MenuFont.Height, t...
+ topMargin * 2
End Sub
'OnDrawItemのオーバーライド
'メニュー項目を描画する
Protected Overrides Sub OnDrawItem(ByVal e As DrawIte...
Dim textBrush As Brush
'基本クラスのOnDrawItemを処理する
MyBase.OnDrawItem(e)
If CBool(e.State And DrawItemState.Selected) Then
'選択されている時
'背景を塗りつぶす
e.Graphics.FillRectangle(SystemBrushes.Highli...
e.Bounds)
'文字列の描画に使用するブラシの作成
textBrush = New SolidBrush(SystemColors.Highl...
Else
'選択されていない時
'背景を塗りつぶす
e.Graphics.FillRectangle(SystemBrushes.Menu, ...
'文字列の描画に使用するブラシの作成
textBrush = New SolidBrush(SystemColors.MenuT...
End If
'画像の描画
If Not (_image Is Nothing) Then
e.Graphics.DrawImage(_image, _
e.Bounds.Left + leftMargin, _
e.Bounds.Top + (e.Bounds.Height - imageHe...
imageWidth, _
imageHeight)
End If
'文字列の描画の準備
Dim sf As New StringFormat()
'ホットキープリフィックスの表示(&をアンダーライン...
sf.HotkeyPrefix = HotkeyPrefix.Show
'Text部分の表示位置を決定する
Dim textPosition As New PointF()
textPosition.X = e.Bounds.Left + textLeft
textPosition.Y = e.Bounds.Top + _
(e.Bounds.Height - SystemInformation.MenuFont...
'Text部分の文字列を描画
e.Graphics.DrawString(Text, _
SystemInformation.MenuFont, _
textBrush, _
textPosition, _
sf)
'Shortcut部分を描画
If ShowShortcut = True And _
Shortcut <> Shortcut.None Then
'Shortcut部分の文字列を取得
Dim shortcutText As String = _
TypeDescriptor.GetConverter(GetType(Keys)...
ConvertToString(CType(Shortcut, Keys))
'Shortcut部分の幅を取得
Dim shortcutWidth As Integer = _
CInt( _
e.Graphics.MeasureString(shortcutText, _
SystemInformation.MenuFont, _
Integer.MaxValue, _
sf).Width _
)
'Shortcut部分の表示位置を決定する
Dim shortcutPosition As New PointF()
shortcutPosition.X = _
e.Bounds.Right - shortcutWidth - rightMar...
shortcutPosition.Y = textPosition.Y
'Shortcut部分の文字列を描画
e.Graphics.DrawString(shortcutText, _
SystemInformation.MenuFont, _
textBrush, _
shortcutPosition, _
sf)
End If
'リソースを開放
textBrush.Dispose()
sf.Dispose()
End Sub
End Class
}}
次にこのImageMenuItemクラスの使い方を説明します。ImageMen...
具体例を以下に示します。Form1にImageList1があり、画像が2...
#code(vbnet){{
Friend mainMenu1 As MainMenu
'トップレベルメニュー項目はMenuItemクラスを使用する
Friend WithEvents menuFile As MenuItem
'画像つきメニュー項目
Friend WithEvents menuNew As ImageMenuItem
Friend WithEvents menuOpen As ImageMenuItem
Friend WithEvents menuExit As ImageMenuItem
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles MyBase.Load
'メインメニューの作成
mainMenu1 = New MainMenu()
'トップレベルメニュー項目の作成
menuFile = New MenuItem("ファイル(&F)")
'画像つきメニュー項目の作成
menuNew = New ImageMenuItem("新規作成(&N)")
menuNew.Shortcut = Shortcut.CtrlN
'画像を指定する
'ImageList1に画像が登録されているものとする
menuNew.Image = ImageList1.Images(0)
menuOpen = New ImageMenuItem("開く(&O)")
menuOpen.Shortcut = Shortcut.CtrlO
menuOpen.Image = ImageList1.Images(1)
menuExit = New ImageMenuItem("終了(&X)")
'menuFileのサブメニューにする
menuFile.MenuItems.Add(menuNew)
menuFile.MenuItems.Add(menuOpen)
'セパレータの追加
menuFile.MenuItems.Add(New MenuItem("-"))
menuFile.MenuItems.Add(menuExit)
'MainMenuに追加する
mainMenu1.MenuItems.Add(menuFile)
'Form1のメインメニューとする
Me.Menu = mainMenu1
End Sub
Private Sub menuNew_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles menuNew.Click
MessageBox.Show("「新規作成」がクリックされました。")
End Sub
Private Sub menuOpen_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles menuOpen.Click
MessageBox.Show("「開く」がクリックされました。")
End Sub
Private Sub menuExit_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles menuExit.Click
Me.Close()
End Sub
}}
だいぶよくなったように見えますが、これだけやっても実用に...
このメニューのオーナードローを使えば、Visual Studio .NET...
-[[The Code Project: Visual Studio .NET Menu Style: By Ca...
-[[C# Help: .NET Menu Style Revisited: By Francesco Natal...
-[[Planet Source Code: Create a Menu like as VS.NET Menu:...
-[[Planet Source Code: Another XPStyle menu: By Mick Dohe...
最後に補足ですが、現在NotifyIconコントロールのContextMenu...
**コメント [#u9e51f28]
#comment
//これより下は編集しないでください
#pageinfo([[:Category/.NET]],2003-04-03 (木) 06:00:00,DOB...
終了行:
#title(.NETプログラミング研究 第4号)
#navi(.NETプログラミング研究)
#contents
*.NETプログラミング研究 第4号 [#teb83ffc]
**注意事項 [#s6067321]
今回はコードが長いため、VB.NETのコードのみを紹介します。...
**ピンポイントリンク [#o34c4c3d]
***メニューにアイコンを表示する [#led4fdb1]
#column(注意){{
「[[メニューにアイコンを表示する>https://dobon.net/vb/dot...
}}
メニュー項目の右側にアイコンが表示されているようなアプリ...
メニューにアイコンを表示するためには「オーナードロー(オ...
早速ですが、オーナードローでメニューを表示させてみましょ...
Form1というフォームに、MainMenu1というMainMenuオブジェク...
ここではMenuItem2にオーナードローにより画像を表示してみる...
以下の例ではMenuItem2にアイコン"open.ico"を表示させていま...
#code(vbnet){{
'メニュー項目に表示させるアイコン
Private _icon As New Icon("open.ico")
'メニュー項目の大きさを計算する
Private Sub MenuItem2_MeasureItem(ByVal sender As Object, _
ByVal e As System.Windows.Forms.MeasureItemEventA...
Handles MenuItem2.MeasureItem
'高さを"e.ItemHeight"に幅を"e.ItemWidth"に入れる
'メニュー項目の高さを設定する
e.ItemHeight = _icon.Height
'メニュー項目の幅を設定する
e.ItemWidth = _icon.Width
End Sub
'メニュー項目の描画
Private Sub MenuItem2_DrawItem(ByVal sender As Object, _
ByVal e As System.Windows.Forms.DrawItemEventArgs...
Handles MenuItem2.DrawItem
'e.Graphicsに描画する
'メニュー項目の境界はe.Boundsから取得できる
e.Graphics.DrawIcon(_icon, e.Bounds.X, e.Bounds.Y)
End Sub
}}
うまくメニューに画像が表示できたことと思います。メニュー...
この調子だと目的を達成するのも簡単そうに思えるでしょう。...
#code(vbnet){{
'メニュー項目に表示させるアイコン
Private _icon As New Icon("open.ico")
'メニュー項目の大きさを計算する
Private Sub MenuItem2_MeasureItem(ByVal sender As System....
ByVal e As System.Windows.Forms.MeasureItemEventA...
Handles MenuItem2.MeasureItem
'幅を決定する
'文字列の幅を計算する
'メニューで使うフォントは
'SystemInformation.MenuFontプロパティで取得できる
Dim textWidth As Integer = CInt( _
e.Graphics.MeasureString(sender.Text, _
SystemInformation.MenuFont).Width)
e.ItemWidth = textWidth + 46
'高さを決定する
e.ItemHeight = _
Math.Max(SystemInformation.MenuFont.Height, _icon...
+ 2
End Sub
'メニュー項目の描画
Private Sub MenuItem2_DrawItem(ByVal sender As System.Obj...
ByVal e As System.Windows.Forms.DrawItemEventArgs...
Handles MenuItem2.DrawItem
'背景の塗りつぶし
'DrawItemEventArgs.DrawBackgroundメソッドを使ってみる
e.DrawBackground()
'アイコンの描画
If Not (_icon Is Nothing) Then
e.Graphics.DrawIcon(_icon, _
e.Bounds.Left + 2, _
e.Bounds.Top + (e.Bounds.Height - _icon.Heigh...
End If
'文字の描画
Dim textBrush As Brush
'DrawItemEventArgs.ForeColorプロパティを使ってみる
textBrush = New SolidBrush(e.ForeColor)
e.Graphics.DrawString(sender.Text, _
SystemInformation.MenuFont, _
textBrush, _
e.Bounds.Left + 22, _
e.Bounds.Top + _
(e.Bounds.Height - _
SystemInformation.MenuFont.Height) \ 2)
'リソースを開放
textBrush.Dispose()
End Sub
}}
ところがこのサンプルには多くの問題があります。なんといっ...
さらに、このようなコードを直接一つ一つのMenuItemオブジェ...
何を隠そう、これらの問題をクリアしたサンプルがMicrosoftの...
#code(vbnet){{
Imports System
Imports System.ComponentModel
Imports System.Drawing
Imports System.Drawing.Text
Imports System.Windows.Forms
Public Class ImageMenuItem : Inherits MenuItem
'定数-----------------------------------------
'表示する画像のサイズ
Private Const imageHeight As Integer = 16
Private Const imageWidth As Integer = 16
'上の余白(下の余白も同じになる)
Private Const topMargin As Integer = 1
'左側の余白
Private Const leftMargin As Integer = 2
'画像とテキストの間隔
Private Const intervalImageAndText As Integer = 4
'右側の余白
Private Const rightMargin As Integer = 20
'メニューのテキストの表示位置
Private Const textLeft As Integer = _
leftMargin + imageWidth + intervalImageAndText
'テキスト以外の部分の幅
Private Const widthExceptText As Integer = _
imageWidth + leftMargin + intervalImageAndText + ...
'プロパティ-----------------------------------
'表示する画像
Private _image As Image
Public Property Image() As Image
Get
Return _image
End Get
Set(ByVal Value As Image)
_image = Value
End Set
End Property
'コンストラクタ-------------------------------
Public Sub New(ByVal text As String)
MyBase.New(text)
Me.OwnerDraw = True
End Sub
'メソッド-------------------------------------
'OnMeasureItemのオーバーライド
'メニューアイテムの大きさを計算する
'高さを"e.ItemHeight"に幅を"e.ItemWidth"に入れる
Protected Overrides Sub OnMeasureItem( _
ByVal e As MeasureItemEventArgs)
'基本クラスのOnMeasureItemを処理する
MyBase.OnMeasureItem(e)
'メニューに表示する文字列を取得
Dim menuText As String
menuText = Text
'シュートカットを表示するときは、その文字列を追加...
If ShowShortcut = True And _
Shortcut <> Shortcut.None Then
menuText += _
TypeDescriptor.GetConverter(GetType(Keys)...
ConvertToString(CType(Shortcut, Keys))
End If
Dim sf As New StringFormat()
'ホットキープリフィックスの表示(&を_にする)
sf.HotkeyPrefix = HotkeyPrefix.Show
'幅を決定する
e.ItemWidth = CInt( _
e.Graphics.MeasureString(menuText, _
SystemInformation.MenuFont, _
Integer.MaxValue, _
sf).Width) + widthExceptText
'リソースを開放
sf.Dispose()
'高さを決定する
e.ItemHeight = _
Math.Max(SystemInformation.MenuFont.Height, t...
+ topMargin * 2
End Sub
'OnDrawItemのオーバーライド
'メニュー項目を描画する
Protected Overrides Sub OnDrawItem(ByVal e As DrawIte...
Dim textBrush As Brush
'基本クラスのOnDrawItemを処理する
MyBase.OnDrawItem(e)
If CBool(e.State And DrawItemState.Selected) Then
'選択されている時
'背景を塗りつぶす
e.Graphics.FillRectangle(SystemBrushes.Highli...
e.Bounds)
'文字列の描画に使用するブラシの作成
textBrush = New SolidBrush(SystemColors.Highl...
Else
'選択されていない時
'背景を塗りつぶす
e.Graphics.FillRectangle(SystemBrushes.Menu, ...
'文字列の描画に使用するブラシの作成
textBrush = New SolidBrush(SystemColors.MenuT...
End If
'画像の描画
If Not (_image Is Nothing) Then
e.Graphics.DrawImage(_image, _
e.Bounds.Left + leftMargin, _
e.Bounds.Top + (e.Bounds.Height - imageHe...
imageWidth, _
imageHeight)
End If
'文字列の描画の準備
Dim sf As New StringFormat()
'ホットキープリフィックスの表示(&をアンダーライン...
sf.HotkeyPrefix = HotkeyPrefix.Show
'Text部分の表示位置を決定する
Dim textPosition As New PointF()
textPosition.X = e.Bounds.Left + textLeft
textPosition.Y = e.Bounds.Top + _
(e.Bounds.Height - SystemInformation.MenuFont...
'Text部分の文字列を描画
e.Graphics.DrawString(Text, _
SystemInformation.MenuFont, _
textBrush, _
textPosition, _
sf)
'Shortcut部分を描画
If ShowShortcut = True And _
Shortcut <> Shortcut.None Then
'Shortcut部分の文字列を取得
Dim shortcutText As String = _
TypeDescriptor.GetConverter(GetType(Keys)...
ConvertToString(CType(Shortcut, Keys))
'Shortcut部分の幅を取得
Dim shortcutWidth As Integer = _
CInt( _
e.Graphics.MeasureString(shortcutText, _
SystemInformation.MenuFont, _
Integer.MaxValue, _
sf).Width _
)
'Shortcut部分の表示位置を決定する
Dim shortcutPosition As New PointF()
shortcutPosition.X = _
e.Bounds.Right - shortcutWidth - rightMar...
shortcutPosition.Y = textPosition.Y
'Shortcut部分の文字列を描画
e.Graphics.DrawString(shortcutText, _
SystemInformation.MenuFont, _
textBrush, _
shortcutPosition, _
sf)
End If
'リソースを開放
textBrush.Dispose()
sf.Dispose()
End Sub
End Class
}}
次にこのImageMenuItemクラスの使い方を説明します。ImageMen...
具体例を以下に示します。Form1にImageList1があり、画像が2...
#code(vbnet){{
Friend mainMenu1 As MainMenu
'トップレベルメニュー項目はMenuItemクラスを使用する
Friend WithEvents menuFile As MenuItem
'画像つきメニュー項目
Friend WithEvents menuNew As ImageMenuItem
Friend WithEvents menuOpen As ImageMenuItem
Friend WithEvents menuExit As ImageMenuItem
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles MyBase.Load
'メインメニューの作成
mainMenu1 = New MainMenu()
'トップレベルメニュー項目の作成
menuFile = New MenuItem("ファイル(&F)")
'画像つきメニュー項目の作成
menuNew = New ImageMenuItem("新規作成(&N)")
menuNew.Shortcut = Shortcut.CtrlN
'画像を指定する
'ImageList1に画像が登録されているものとする
menuNew.Image = ImageList1.Images(0)
menuOpen = New ImageMenuItem("開く(&O)")
menuOpen.Shortcut = Shortcut.CtrlO
menuOpen.Image = ImageList1.Images(1)
menuExit = New ImageMenuItem("終了(&X)")
'menuFileのサブメニューにする
menuFile.MenuItems.Add(menuNew)
menuFile.MenuItems.Add(menuOpen)
'セパレータの追加
menuFile.MenuItems.Add(New MenuItem("-"))
menuFile.MenuItems.Add(menuExit)
'MainMenuに追加する
mainMenu1.MenuItems.Add(menuFile)
'Form1のメインメニューとする
Me.Menu = mainMenu1
End Sub
Private Sub menuNew_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles menuNew.Click
MessageBox.Show("「新規作成」がクリックされました。")
End Sub
Private Sub menuOpen_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles menuOpen.Click
MessageBox.Show("「開く」がクリックされました。")
End Sub
Private Sub menuExit_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles menuExit.Click
Me.Close()
End Sub
}}
だいぶよくなったように見えますが、これだけやっても実用に...
このメニューのオーナードローを使えば、Visual Studio .NET...
-[[The Code Project: Visual Studio .NET Menu Style: By Ca...
-[[C# Help: .NET Menu Style Revisited: By Francesco Natal...
-[[Planet Source Code: Create a Menu like as VS.NET Menu:...
-[[Planet Source Code: Another XPStyle menu: By Mick Dohe...
最後に補足ですが、現在NotifyIconコントロールのContextMenu...
**コメント [#u9e51f28]
#comment
//これより下は編集しないでください
#pageinfo([[:Category/.NET]],2003-04-03 (木) 06:00:00,DOB...
ページ名:
▲
▼
[
トップ
] [
新規
|
子ページ作成
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]