NotifyIconを左クリックすると、コンテキストメニュー(ContextMenuStripプロパティで設定)も開くようにしたいのですが。どうすればこれを達成できますか? Clickを処理して自分で位置を把握する必要がありますか?
編集:trayIcon.ContextMenuStrip.Show()の結果でメニューを表示すると、いくつかの望ましくない動作が発生します。
NotifyIconを右クリックした場合と同じ場所にメニューが表示されません(少なくとも、実行しているWindows 7では、タスクバーの場所にx座標とy座標を設定できないようです)。タスクバーの上に表示されます(それほど大きな問題ではありませんが、一貫性はいいでしょう)。
メニューが表示されている間、タスクバーに追加のアイコンが追加されています。
メニュー以外の場所をクリックしても、メニューは閉じません(右クリックしてコンテキストメニューを表示した場合、他の場所をクリックすると、自動的にコンテキストメニューが閉じます)。
組み込みの右クリックハンドラーがメニューを呼び出すだけでまったく可能ですか?
通常、MouseClickイベントを処理してクリックを検出し、ContextMenuStrip.Show()メソッドを呼び出します。
private void notifyIcon1_MouseClick(object sender, MouseEventArgs e) {
contextMenuStrip1.Show(Control.MousePosition);
}
しかし、それは実際には正しく機能しません。CMSの外側をクリックしても、CMSは閉じません。根本的な問題は このKB記事 で説明されているWindowsの癖(別名「バグ」)です。
独自のコードでこの回避策を呼び出すのはかなり面倒です。ピンボークは不愉快です。 NotifyIconクラスの ShowContextMenu()メソッド にこの回避策があります。プライベートメソッドであるため、アクセスが困難になっています。リフレクションはその制限を回避できます。私は5年前にこのハッキングを発見しましたが、まだ誰も問題を報告していません。 NFIのContextMenuStripプロパティを設定し、次のようにMouseUpイベントを実装します。
using System.Reflection;
...
private void notifyIcon1_MouseUp(object sender, MouseEventArgs e) {
if (e.Button == MouseButtons.Left) {
MethodInfo mi = typeof(NotifyIcon).GetMethod("ShowContextMenu", BindingFlags.Instance | BindingFlags.NonPublic);
mi.Invoke(notifyIcon1, null);
}
}
次のコードを使用して、notifyiconの右クリックと左クリックの両方でコンテキストメニューを表示します。問題が見つかった場合は、arshad_mcs786 @ hotmail.com(Islamabdからのarshad)にテキストメッセージを送信してください。
// System.Runtime.InteropServicesはこれを参照として使用します
[DllImport("User32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
public static extern bool SetForegroundWindow(HandleRef hWnd);
private void notifyIcon1_Click(object sender, EventArgs e)
{
SetForegroundWindow(new HandleRef(this, this.Handle));
int x = Control.MousePosition.X;
int y = Control.MousePosition.Y;
x = x - 10;
y = y - 40;
this.contextMenuStrip1.Show(x,y );
//this.PointToClient(Cursor.Position)
}
通知アイコンのonClickイベントに配線してから、クリック時にshowを呼び出すことができます
private void wire()
{
notifyIcon1.Click += new EventHandler(notifyIcon1_Click);
}
void notifyIcon1_Click(object sender, EventArgs e)
{
contextMenuStrip1.Show(Cursor.Position);
}
ClickではなくMouseUpを処理する場合は、クリックされたボタンと、クリックの location を確認できます。この場所をContextMenuを表示する場所として使用できます
notifyIcon.MouseUp += new MouseEventHandler(delegate(object sender, MouseEventArgs e) { contextMenu.Show(e.Location); });