MENU > HOME VB.NET VB6 VBA ソフトウェア リンク サイト情報
VB.NET> VB.NET 突撃レポート > 1  2  3  4  5  6  7  8  9  10  11  12 
PART12: (続)オーナードロー/コンボボックス(2002年11月6日)

年年末近くなってくると、もぉ〜忙しい。てな感じでまたまた更新頻度が減っております。
前回はコンボボックスのオーナードローを使用し、フォント一覧を作成してみました。

で、前回の結末なんですが、そう!ショボかったんです、出来上がりが。
そこで何気にOfficeツールバーのフォントコンボを見てみると、実はテキストフォントよりもリストのフォントサイズが大きいんですね。

じゃあってことで、前回のコードのDrawItemイベントでフォントサイズを9にしているところを12に変更して実行したところ...

のように見るも無残な姿になってしまいました。(^^;

見てのとおり、ほも?違った、ほぼ文字全体が表示できているものや、半分くらい文字が消えてしまっているものがあります。
フォント毎に高さが違うのだから、事前にフォントサイズを調べてリスト毎に高さを変えることができたら幸せになれそうです。

こんな時に使用するのが、MeasureItemイベントです。
Measure(=寸法を測る)つまり、アイテムの寸法を取得してみたり設定してみたりすることができるイベントで、DrawItemイベントの直前に発生します。
(実はこれ、オーナードローではお決まりのイベントなんです)
このイベントを有効にするためには、DrawModeプロパティの値をOwnerDrawVariableに設定する必要があります。

では手順です。

1.MeasureItemイベントでDrawItemイベントと同様のフォントを作成して、そのFontオブジェクトのHeightプロパティを取得!
2.取得した値(高さ)をMeasureItemイベントの引数、MeasureItemEventArgs型の変数eのItemHeightプロパティにセット!!

と、たったこれだけです。

以下、MeasureItemイベントのコードです。
Private Sub ComboBox1_MeasureItem( _
                  ByVal sender As Object, _
                  ByVal e As System.Windows.Forms.MeasureItemEventArgs _
                  ) Handles ComboBox1.MeasureItem

    Dim ff As FontFamily
    Dim f As Font
    Dim fs As FontStyle

    ff = New FontFamily(ComboBox1.Items.Item(e.Index).ToString)

    If ff.IsStyleAvailable(FontStyle.Regular) Then
        fs = FontStyle.Regular
    Else
        fs = FontStyle.Italic
    End If

    f = New Font(ff, 12, fs)

    e.ItemHeight = f.Height + 2

    f.Dispose()
    ff.Dispose()

End Sub
前回のDrawItemイベント内でFontを作成したコードとフォントサイズが違うこと意外は全く同じです。
最後に e.ItemHeight = f.Height + 2 とアイテムの高さをセットしています。
求めた高さに対し、+2しているのは、求めた高さそのままだとムチムチに文字列が描画され、窮屈そうに見えるのを防ぐためにアソビを持たせるといった意味合いです。

高さをセットするところでフォントサイズを12にしたので、当然描画するイベントでもフォントサイズを12で描画するように修正するのをお忘れなく。
そうそう、高さにアソビを持たせた分、描画の際にもアソビを持たせて

     e.Graphics.DrawString(ComboBox1.Items.Item(e.Index).ToString, f, b, e.Bounds.X, e.Bounds.Y + 1)

のように描画ポイントのY座標に1加えておきましょう。

さて、実行してみます。


「すばらしい!!」

細かく気になる点はまだまだあるのですが、サンプルということでコンボボックスのオーナードローはこんなところにします。

さて次回は「(続続)オーナードロー:アイコンメニュー」です。
VB6でこれを実現するにはサブクラス化とWin32APIを使用した大量のコードが必要だった、

なメニューがわずか数行のコードで本当にデキちゃうんです。うれしいです。すばらしいです。

それでは、お楽しみに!!


Copyright©Sugi. All rights reserved.