2011-08-03 34 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); 
} 

單擊該圖標顯示在窗口像它應該。但是,只要鼠標被按下,再次點擊就會隱藏它,然後將其重置爲可見。

我的猜測是,鼠標向下的事件從窗口偷取焦點,所以它消失。然後觸發鼠標上移事件,顯示隱藏的窗口。

我的下一個想法是,閱讀在鼠標按下事件的可視窗口,所以我測試了三個事件,並記錄了UNIX時間,因爲他們被稱爲:

notifyIcon.MouseDown 
notifyIcon.MouseUp 
this.LostFocus 

結果是很奇怪的:假設窗口是可見的。當我點擊圖標時會發生這種情況:立即調用焦點丟失。一旦我釋放鼠標,就在鼠標向上事件之前,鼠標向下被稱爲

1312372231 focus lost 
1312372235 mouse down 
1312372235 mouse up 

爲什麼鼠標按下事件被延遲?
如何切換窗口?

回答

2

我認爲這可能適合你。

我發現了一個專家交換帖子,其中包含一個類,它提供了一種方法來檢查光標當前是否在托盤上。

NotifyIcon - Detect MouseOut

使用這個類我修改你的HideOnEvent方法,像這樣:

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

這似乎是你所需要的。

我已經包含下面的類:

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