ツールチップにイメージを表示する その2

ツールチップにイメージを表示する その1」に続き、実際に作ってみたのがこのサンプル。
マウスカーソルをラベルへ持っていくと、下図のようなかんじで、通常のテキストに加えてイメージ付きのツールチップを表示します。
ツールチップに表示されるイメージは、予めリソースに追加したものを表示しています。また、対象になるコントロールごとにイメージを特定するためにTagプロパティの値を利用しています。
この例だとLabelコントロールのTagプロパティが使われます。(下図、”dancer”がイメージの名前)

基本的にMicrosoft社のサンプルを参考にしていますが、そのままだとVSの環境で扱いにくいので普通にプロジェクトを作成する手順で作っていきます。

それから、これは試しに書いているコードなので、参考にされる場合は自己責任でお願いします。かなりエラー判定が緩いですし、正直なところ、はじめてのオーナードローなので初歩的な事を見落としている可能性があります。
1. プロジェクトの準備
新規にWindowsフォームのプロジェクトを用意して、フォームの上に最低限必要な下記のコントロールを配置します。
  • Labelコントロール
  • ToolTipコントロール
コントロールの名前はひとまずデフォルトのままでOKです。
2. ToolTipコントロールの初期化
フォームのコンストラクタでToolTipコントロール(toolTip1)のOwnerDrawプロパティとイベントハンドラを設定します。
public Form1()

{     InitializeComponent();       // Make the OwnerDraw enabled     this.toolTip1.OwnerDraw = true;     this.toolTip1.Draw += new DrawToolTipEventHandler(this.toolTip1_Draw);     this.toolTip1.Popup += new PopupEventHandler(this.toolTip1_Popup);   }

これでtoolTip1のDraw,Popupイベントハンドラを作成する準備はOKです。
3. Popupメソッドの実装
ここでツールチップの大きさを設定します。
デフォルトではテキストの大きさになっているので、一緒に表示するイメージが収まるように大きさを再設定します。
リソースに含まれているイメージをリソースマネージャから取得し、大きさを調べてツールチップの大きさを再設定しています。
// Determines the correct size for the ToolTip. private const int PADDING = 20; private Size size; private void toolTip1_Popup(object sender, PopupEventArgs e) {     if (e.AssociatedControl.Tag != null)     {         this.size = e.ToolTipSize;         this.size.Width += PADDING;           // Create assembly         System.Reflection.Assembly assembly;         assembly = System.Reflection.Assembly.GetExecutingAssembly();           // Get image from the resources;         System.Resources.ResourceManager rm = new System.Resources.ResourceManager(“ToolTipOwnerDraw.Properties.Resources”, assembly);         Image image = (Image)rm.GetObject(e.AssociatedControl.Tag.ToString());           int height = e.ToolTipSize.Height + image.Size.Height;         int width = e.ToolTipSize.Width + PADDING;         if (width < image.Size.Width) width = image.Size.Width;         e.ToolTipSize = new Size(width, height);     } }

4. Drawメソッドの実装
ツールチップの描画処理を実装します。
ここでイメージの描画処理とテキストの描画処理を行います。
イメージはともかくとして、テキストはデフォルトでも大丈夫なんじゃないかと思ってたんですが、Popupメソッドでツールチップの大きさを再設定しているため、表示位置がずれます。
ツールチップの中央にテキストが描かれてしまうため、その部分も自前でツールチップ上部に描く処理を実装します。

// Handles drawing the ToolTip. private void toolTip1_Draw(System.Object sender,     System.Windows.Forms.DrawToolTipEventArgs e) {     if (e.AssociatedControl.Tag != null)     {         e.DrawBackground();           // Create assembly         System.Reflection.Assembly assembly;         assembly = System.Reflection.Assembly.GetExecutingAssembly();           // Create ResourceManager         System.Resources.ResourceManager rm = new System.Resources.ResourceManager(“ToolTipOwnerDraw.Properties.Resources”, assembly);                 // Get the image from the resources         Image image = (Image)rm.GetObject(e.AssociatedControl.Tag.ToString());             // Create point for upper-left corner of image.         float posX = 0;         if (this.size.Width > image.Width) posX = (this.size.Width – image.Width) / 2;         PointF upperLeft = new PointF(posX, this.size.Height-10);           // Draw image to screen.         e.Graphics.DrawImage(image, upperLeft);           // Draw the standard border.         e.DrawBorder();                   // Draw the custom text.         // The using block will dispose the StringFormat automatically.         using (StringFormat sf = new StringFormat())         {             sf.Alignment = StringAlignment.Near;             sf.LineAlignment = StringAlignment.Center;             sf.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.None;             sf.FormatFlags = StringFormatFlags.NoWrap;               Rectangle rect = new Rectangle(new Point(PADDING/2, 0), this.size);             e.Graphics.DrawString(e.ToolTipText, e.Font, SystemBrushes.ActiveCaptionText, rect, sf);         }     }     else     {         // Draw the ToolTip using default values         e.DrawBackground();         e.DrawBorder();         e.DrawText();     } }