2010-04-26 12 views
9

Vorrei visualizzare una piccola finestra popup accanto all'area di notifica. È simile a ciò che Outlook/Skype/Live! Messenger/etc fa quando visualizza la notifica relativa a un nuovo messaggio. Nel mio caso avrà alcuni controlli di input (textbox, datetimepicker, bottoni ...) quindi una semplice bolla non lo farà..NET: Come posizionare la mia finestra vicino all'area di notifica (systray)?

Il trucco sta facendo correttamente questo quando l'utente ha più monitor e/o la barra delle applicazioni non si trova nella parte inferiore dello schermo. Non sono riuscito a trovare alcuna funzione che mi permettesse di determinare la posizione e l'orientamento della barra delle applicazioni/dell'area di notifica.

+0

esempio di codice sorgente di qualsiasi all completa? – Kiquenet

+0

@alhambraeidos - Penso che la risposta accettata contenga tutte le informazioni di cui hai bisogno. Non ho il codice sorgente online, ma non è molto difficile fare qualcosa del genere. Hai qualche problema specifico? –

risposta

8

Usa WinAPI chiama a trovare la posizione barra delle applicazioni, e posizionare la finestra in base ad esso

C# Example

class Program 
{ 
    static void Main(string[] args) 
    { 
     Taskbar taskbar = new Taskbar(); 
     Console.WriteLine("Position: {0}, AlwaysOnTop: {1}; AutoHide: {2}; Bounds: {3}", taskbar.Position, taskbar.AlwaysOnTop, taskbar.AutoHide, taskbar.Bounds); 

     Console.ReadLine(); 
    } 
} 

public enum TaskbarPosition 
{ 
    Unknown = -1, 
    Left, 
    Top, 
    Right, 
    Bottom, 
} 

public sealed class Taskbar 
{ 
    private const string ClassName = "Shell_TrayWnd"; 

    public Rectangle Bounds 
    { 
     get; 
     private set; 
    } 
    public TaskbarPosition Position 
    { 
     get; 
     private set; 
    } 
    public Point Location 
    { 
     get 
     { 
      return this.Bounds.Location; 
     } 
    } 
    public Size Size 
    { 
     get 
     { 
      return this.Bounds.Size; 
     } 
    } 
    //Always returns false under Windows 7 
    public bool AlwaysOnTop 
    { 
     get; 
     private set; 
    } 
    public bool AutoHide 
    { 
     get; 
     private set; 
    } 

    public Taskbar() 
    { 
     IntPtr taskbarHandle = User32.FindWindow(Taskbar.ClassName, null); 

     APPBARDATA data = new APPBARDATA(); 
     data.cbSize = (uint) Marshal.SizeOf(typeof(APPBARDATA)); 
     data.hWnd = taskbarHandle; 
     IntPtr result = Shell32.SHAppBarMessage(ABM.GetTaskbarPos, ref data); 
     if (result == IntPtr.Zero) 
      throw new InvalidOperationException(); 

     this.Position = (TaskbarPosition) data.uEdge; 
     this.Bounds = Rectangle.FromLTRB(data.rc.left, data.rc.top, data.rc.right, data.rc.bottom); 

     data.cbSize = (uint) Marshal.SizeOf(typeof(APPBARDATA)); 
     result = Shell32.SHAppBarMessage(ABM.GetState, ref data); 
     int state = result.ToInt32(); 
     this.AlwaysOnTop = (state & ABS.AlwaysOnTop) == ABS.AlwaysOnTop; 
     this.AutoHide = (state & ABS.Autohide) == ABS.Autohide; 
    } 
} 

public enum ABM : uint 
{ 
    New = 0x00000000, 
    Remove = 0x00000001, 
    QueryPos = 0x00000002, 
    SetPos = 0x00000003, 
    GetState = 0x00000004, 
    GetTaskbarPos = 0x00000005, 
    Activate = 0x00000006, 
    GetAutoHideBar = 0x00000007, 
    SetAutoHideBar = 0x00000008, 
    WindowPosChanged = 0x00000009, 
    SetState = 0x0000000A, 
} 

public enum ABE : uint 
{ 
    Left = 0, 
    Top = 1, 
    Right = 2, 
    Bottom = 3 
} 

public static class ABS 
{ 
    public const int Autohide = 0x0000001; 
    public const int AlwaysOnTop = 0x0000002; 
} 

public static class Shell32 
{ 
    [DllImport("shell32.dll", SetLastError = true)] 
    public static extern IntPtr SHAppBarMessage(ABM dwMessage, [In] ref APPBARDATA pData); 
} 

public static class User32 
{ 
    [DllImport("user32.dll", SetLastError = true)] 
    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); 
} 

[StructLayout(LayoutKind.Sequential)] 
public struct APPBARDATA 
{ 
    public uint cbSize; 
    public IntPtr hWnd; 
    public uint uCallbackMessage; 
    public ABE uEdge; 
    public RECT rc; 
    public int lParam; 
} 

[StructLayout(LayoutKind.Sequential)] 
public struct RECT 
{ 
    public int left; 
    public int top; 
    public int right; 
    public int bottom; 
} 
+0

Bello! Grazie! :) –

+0

Esegue un hard-code del nome della classe della barra delle applicazioni, che non è un contratto ma un dettaglio di implementazione. E le persone che usano un'altra shell? – Joey

+0

http://www.codeproject.com/KB/shell/trayposition.aspx Un altro approccio consinder il commento di Johannes Rossel, semplice da porto a C# IMO –