.NETプログラミング研究 第6号

.NET Tips

メニューにアイコンを表示する3 完結編

またまた前回の続きです。今回でようやく本当に完結します。

さて、残る問題は

2.チェックが付いているとき(CheckedがTrueのとき)の処理

だけとなっていました。早速解決法を考えてみましょう。

メニューのチェックマークを描画するには通常APIのDrawFrameControl関数を使用します。以下にその例を示します。ちなみに「排他的チェックマーク」というのは「オプションボタン」(丸いチェックマーク)のことです。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
'API宣言部分
Private Declare Function DrawFrameControl Lib "user32" _
    Alias "DrawFrameControl" (ByVal hDC As IntPtr, _
        <MarshalAs(UnmanagedType.Struct)> ByRef lpRect As RECT, _
        ByVal un1 As Integer, _
        ByVal un2 As Integer) As Integer
 
<StructLayout(LayoutKind.Sequential)> _
Private Structure RECT
    Public Left As Integer
    Public Top As Integer
    Public Right As Integer
    Public Bottom As Integer
End Structure
 
Private Const DFC_MENU = 2
Private Const DFCS_MENUBULLET = &H2
Private Const DFCS_MENUCHECK = &H1
 
'----------
 
'以下、描画のためのコード
'表示位置
Dim r1 As RECT
r1.Left = 0
r1.Right = 16
r1.Top = 0
r1.Bottom = 16
 
Dim r2 As RECT
r2.Left = 0
r2.Right = 16
r2.Top = 50
r2.Bottom = 66
 
Dim hdc As IntPtr = e.Graphics.GetHdc()
'メニューのチェックマークの描画
DrawFrameControl(hdc, r1, DFC_MENU, DFCS_MENUCHECK)
'メニューの排他的チェックマークの描画
DrawFrameControl(hdc, r2, DFC_MENU, DFCS_MENUBULLET)
e.Graphics.ReleaseHdc(hdc)

ところが全く同じことが.NET FrameworkのControlPaint.DrawMenuGlyphメソッドでできるのです。わざわざAPIを使う必要はありませんでした(じゃあ書くなって話ですが...)。

  1
  2
  3
  4
'メニューのチェックマークの描画
ControlPaint.DrawMenuGlyph(g, 0, 0, 16, 16, MenuGlyph.Checkmark)
'メニューの排他的チェックマークの描画
ControlPaint.DrawMenuGlyph(g, 0, 50, 16, 16, MenuGlyph.Bullet)

しかしこの方法で描画されたマークは必ず白黒になるようで、マークは黒く、背景色は白くなります。よって適当な色のマークを適当な背景色で描画するには、色を変換して描画する必要があります。これはImageAttributes.SetRemapTableメソッドを使用すればできます。

次の例では新しく作成した16x16のBitmapオブジェクトにチェックマークを描画し、そのBitmapを黒がSystemColors.MenuTextに白がColor.TransparentになるようにしてGraphicsオブジェクトgに描画しています。ちょっと面倒ですが、この方法を使えば任意の色と背景色でチェックマークを描画することができます。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
'新しいBitmapオブジェクトの作成
Dim bmp As New Bitmap(16, 16)
'作成したBitmapオブジェクトにチェックマークを描画
ControlPaint.DrawMenuGlyph(Graphics.FromImage(bmp), _
    0, 0, 16, 16, MenuGlyph.Checkmark)
'色を入れ替えるための準備
Dim cms() As ColorMap = _
    New ColorMap() {New ColorMap(), New ColorMap()}
'入れ替える色を指定する
cms(0).OldColor = Color.Black
cms(0).NewColor = SystemColors.MenuText
cms(1).OldColor = Color.White
cms(1).NewColor = Color.Transparent
'ImageAttributesオブジェクトの作成
Dim imageAttr As New ImageAttributes()
imageAttr.SetRemapTable(cms)
'ImageAttributesを指定して描画
g.DrawImage(bmp, New Rectangle(0, 0, bmp.Width, bmp.Height), _
    0, 0, bmp.Width, bmp.Height, GraphicsUnit.Pixel, _
    imageAttr)

さて、これでようやく必要な技術がそろいました。今まで紹介したテクニックを使って前のImageMenuItemクラスを書き換えましょう。ここでそのコードを紹介したいところですが、あまりに長くなってしまうため、下記URLで紹介させていただきますので、こちらをご覧ください。

苦労の末、せっかく出来上がったImageMenuItemクラスですが、よくみるアイコンメニューとはかなり違います。一般的なアイコンメニューはOffice97タイプのもので、メニュー項目が選択されるとアイコンが出っ張ったようになり、チェックが付くと引っ込んだようになります。今後ImageMenuItemクラスもそうできるようにする予定ですが、そろそろ飽きてきたので、今回で一応完結とされていただきます。

コメント



ページ情報
  • カテゴリ : .NET
  • 作成日 : 2003-05-01 (木) 06:00:00
  • 作成者 : DOBON!
  • 最終編集日 : 2010-03-20 (土) 02:26:43
  • 最終編集者 : DOBON!
[ トップ ]   [ 編集 | 凍結 | 差分 | バックアップ | 添付 | 複製 | 名前変更 | リロード ]   [ 新規 | 子ページ作成 | 一覧 | 単語検索 | 最終更新 | ヘルプ ]