DOBON.NET DOBON.NETプログラミング掲示板過去ログ

メニューへツールチップを表示する。

分類:[.NET]

初めて投稿させて頂きます。「だぁ」と申します。

先日からメニューへツールチップを表示する方法を探しているのですが全くわかりません。
目的は、例えば、「ファイル→保存」メニューへマウスを持ってきた時に横にツールチップを表示したいのです。


今まで次の2点について試行してみましたが、うまくいきませんでした。

1.
"System.Windows.Forms.ToolTip"タイプの"SetToolTip"メソッドを使用するには"System.Windows.Forms.Control"タイプが必要なようでした。
しかし、"System.Windows.Forms.MainMenu"タイプは"System.Windows.Forms.Control"タイプへはキャストできません。
"System.Windows.Forms.MainMenu"タイプの"Handle"プロパティを使用するのかとも考えましたが、うまくいきませんでした。

2.
強引な方法として新規にウィンドウを作成し適当なタイミングで”ツールチップらしく”表示させようとも考えましたが
やはり、"System.Windows.Forms.MainMenu"タイプの"Handle"プロパティが絡んでくるようで、うまくいきませんでした。


現在の開発環境は
C# .NET Compiler version 7.00.9466
.NET Framework version 1.0.3705
Windows XP Professional 5.1.2600 Service Pack 1 ビルド 2600
以上です。



うまい解決方法をご存知の方がいらっしゃいましたら
ご教授頂ければ大変助かります。

拙い質問の投稿で申し訳ありませんが、識者の皆様どうぞよろしくお願いいたします。
だぁ と申します。自己レスです。

根本的な解決には至りませんでしたが、一応
目的とする仕様は満たしましたのでご報告いたします。


> 先日からメニューへツールチップを表示する方法を探しているのですが全くわかりません。
> 目的は、例えば、「ファイル→保存」メニューへマウスを持ってきた時に横にツールチップを表示したいのです。
目的/仕様は変更なしです。

> 1.
> "System.Windows.Forms.ToolTip"タイプの"SetToolTip"メソッドを使用するには"System.Windows.Forms.Control"タイプが必要なようでした。
> しかし、"System.Windows.Forms.MainMenu"タイプは"System.Windows.Forms.Control"タイプへはキャストできません。
> "System.Windows.Forms.MainMenu"タイプの"Handle"プロパティを使用するのかとも考えましたが、うまくいきませんでした。
この"ToolTip"タイプはどうやら、コントロールに対してツールチップを表示することが目的のタイプのようです。
私的には「なぜ、MainMenuタイプはコントロールじゃないの?」と言いたいですが・・。


> 2.
> 強引な方法として新規にウィンドウを作成し適当なタイミングで”ツールチップらしく”表示させようとも考えましたが
> やはり、"System.Windows.Forms.MainMenu"タイプの"Handle"プロパティが絡んでくるようで、うまくいきませんでした。
今回は次の2つの方法を試行して2番目の方法を採用いたしました。

1.
Win32 APIのCreateWindowEx関数を使用してウィンドウを自作しました。
======== Code Start ========
//ツールチップウィンドウを表示
//
hWnd = CreateWindowEx( API.WS_EX_TOPMOST,
"STATIC",
"",
API.WS_POPUP,
0,
0,
100,
100,
this.Handle,
IntPtr.Zero,
this.Handle,
IntPtr.Zero );

ShowWindow(hWnd, API.SW_HIDE);

※APIタイプでは、対応する値を宣言済み。(WinUser.hから引用)
======== Code End ========

そして、MainMenuタイプのMenuItemsのSelectイベントを補足して
その中で、

======== Code Start ========
SetWindowPos(hWnd, API.HWND_TOPMOST, Cursor.Position.X, Cursor.Position.Y, 200, 200, API.SWP_NOACTIVATE);
ShowWindow(hWnd, API.SW_SHOWNA);

Graphics g = Graphics.FromHwnd(hWnd);
g.DrawRectangle(new Pen(Color.Red), 50,20,50, 20);
g.DrawString("Hello World!", this.Font, new SolidBrush(Color.Purple), 50, 20);

※APIタイプでは、対応する値を宣言済み。(WinUser.hから引用)
======== Code End ========
としました。しかし、”一番初めにウィンドウを表示する時に絵も文字も表示されない”という
現象を解決できずこの手法を諦めました。



2.
新しく、Formタイプの継承オブジェクトを作成します。
MainMenuタイプのMenuItemsのSelectイベントを補足して、表示します。

======== Code Start ========
IntPtr hWnd = MenuTip.Handle;
SetWindowPos(hWnd, API.HWND_TOPMOST, Cursor.Position.X, Cursor.Position.Y, 100, 100, API.SWP_NOACTIVATE);
ShowWindow(hWnd, API.SW_SHOWNA);

※APIタイプでは、対応する値を宣言済み。(WinUser.hから引用)
======== Code End ========
わざわざWin32APIを使用したのは、FormオブジェクトのShow()メソッドではSetWindowPosやShowWindow関数などのような
細かい、ウィンドウ制御が出来ないからです。

しかし、最初に表示する前に
ShowWindow(hWnd, SW_HIDE);
をしないとなぜかウィンドウがアクティブになってしまいます。
(私は、コンストラクタでインスタンス生成時に行いました。)


以上です。

もっとスマートな方法があるのではないかとは思いますが、わかりませんでした。
もっとうまい解決方法をご存知の方がいらっしゃいましたら
ご教授頂ければ大変助かります。

拙い投稿で失礼いたしました。
解決済み!
> 目的/仕様は変更なしです。

(^^;;;
Selectで、ステータスバーあたりにでも出すのが妥協点かなぁと
思ってましたが、ついにCreateWindowまで持ち出しましたか。。。

"STATIC"でやっておられますが、ClassNameには TOOLTIPS_CLASS
というツールチップ用のClassがあります。

<from MSDN VS6 (C++コード)>
    InitCommonControls(); 
    g_hwndTT = CreateWindowEx(0, TOOLTIPS_CLASS, (LPSTR) NULL, 
        TTS_ALWAYSTIP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 
        CW_USEDEFAULT, g_hwndDlg, (HMENU) NULL, g_hinst, NULL); 

こちらなら、"一番初め"の現象も回避できるかも。(私は全然試してません)

DOBON.NET | プログラミング道 | プログラミング掲示板