2011-08-03 15 views
0

C#アプリケーションは、タスクバーアイコン(NotifyIcon)と最初は非表示のオーバーヘッドウィンドウで構成されています。 NotifyIcon(左クリック、一回クリック)をクリックすると、ウィンドウの表示を切り替えることができます。また、フォーカスを失うとウィンドウが非表示になります。NotifyIcon(タスクバーアイコン)をクリックするとC#トグルウィンドウが表示されます

これは、私がこれまで持っているものサブクラス化System.Windows.Forms.Formです:

初期化:

this.ControlBox = false; 
this.ShowIcon = false; 
this.ShowInTaskbar = false; 

// Instance variables: bool allowVisible; 
//      System.Windows.Forms.NotifyIcon notifyIcon; 

this.allowVisible = false; 
this.notifyIcon = new NotifyIcon(); 
this.notifyIcon.MouseUp += new MouseEventHandler(NotifyIconClicked); 
this.Deactivate += new EventHandler(HideOnEvent); 

インスタンスメソッド:それが必要のようなアイコンをクリックする

private void NotifyIconClicked(object sender, MouseEventArgs e) 
{ 
    if (e.Button == System.Windows.Forms.MouseButtons.Left) 
    { 
     if (this.Visible) 
      this.Hide(); 
     else 
      this.Show(); 
    } 
} 

new public void Show() 
{ 
    this.allowVisible = true; 
    this.Visible = true; 
    this.Activate(); 
} 

new public void Hide() 
{ 
    this.allowVisible = false; 
    this.Visible = false; 
} 

private void HideOnEvent(object sender, EventArgs e) 
{ 
    this.Hide(); 
} 

protected override void SetVisibleCore(bool visible) 
{ 
    base.SetVisibleCore(this.allowVisible ? visible : this.allowVisible); 
} 

は窓を明らかに。マウスを押している間はもう一度クリックすると表示が隠され、表示されます。

私の推測では、マウスのダウンイベントがウィンドウからフォーカスを奪って消えるためです。次に、マウスアップイベントがトリガされ、ウィンドウが非表示になっていることが表示されます。

私の次のアイデアは、マウスダウンイベントで、ウィンドウの可視性を読み取ることだったので、私は彼らが呼び出されるよう3つのイベントをテストし、UNIX時間をログに記録:

notifyIcon.MouseDown 
notifyIcon.MouseUp 
this.LostFocus 

結果はかなり奇妙です:のウィンドウをしましょう表示されます。これは、アイコンをクリックすると発生します。フォーカスが失われたときはすぐに呼び出されます。マウスを上げるイベントの直前にマウスを放すとすぐに、マウスダウンはとなります。

1312372231 focus lost 
1312372235 mouse down 
1312372235 mouse up 

なぜマウスダウンイベントが遅れているのですか?
どのようにしてウィンドウを切り替えることができますか?

答えて

2

これはあなたのために働くかもしれないと思います。

カーソルが現在トレイ上にあるかどうかをチェックする方法を提供するクラスを含むエキスパートエクスチェンジポストが見つかりました。

private void HideOnEvent(object sender, EventArgs e) 
    { 
     if (!WinAPI.GetTrayRectangle().Contains(Cursor.Position)) 
     { 
      this.Hide(); 
     } 
    } 

あなたが必要なものをやっているようだ。私はそうのようなあなたのHideOnEvent方法を変更し、このクラスを使用して

NotifyIcon - Detect MouseOut

私は以下のクラスが含まれている:

using System.Runtime.InteropServices; 
using System.Drawing; 

public class WinAPI 
{ 
    public struct RECT 
    { 
     public int left; 
     public int top; 
     public int right; 
     public int bottom; 

     public override string ToString() 
     { 
      return "(" + left + ", " + top + ") --> (" + right + ", " + bottom + ")"; 
     } 
    } 

    [DllImport("user32.dll", CharSet = CharSet.Auto)] 
    public static extern IntPtr FindWindow(string strClassName, string strWindowName); 

    [DllImport("user32.dll", SetLastError = true)] 
    public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, IntPtr windowTitle); 

    [DllImport("user32.dll")] 
    [return: MarshalAs(UnmanagedType.Bool)] 
    static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect); 


    public static IntPtr GetTrayHandle() 
    { 
     IntPtr taskBarHandle = WinAPI.FindWindow("Shell_TrayWnd", null); 
     if (!taskBarHandle.Equals(IntPtr.Zero)) 
     { 
      return WinAPI.FindWindowEx(taskBarHandle, IntPtr.Zero, "TrayNotifyWnd", IntPtr.Zero); 
     } 
     return IntPtr.Zero; 
    } 

    public static Rectangle GetTrayRectangle() 
    { 
     WinAPI.RECT rect; 
     WinAPI.GetWindowRect(WinAPI.GetTrayHandle(), out rect); 
     return new Rectangle(new Point(rect.left, rect.top), new Size((rect.right - rect.left) + 1, (rect.bottom - rect.top) + 1)); 
    } 
} 

これは完璧なソリューションではありませんが、私はこのことができます願っています。

+0

ありがとうございます! – David

関連する問題