Feedback

TopMost bei anderen Fenster setzen

Sprache: C#

Durch eine Frage im MSDN Forum (siehe Links) kam ich darauf zu versuchen ein fremdes Fenster in den TopMost-Zustand zu versetzen. Dadurch sollte gewährleistet werden, das kein anderes Fenster vüberlappend dargestellt wird, wärend ein Screenshot erstellt wird. Dieses Snippet zeigt eine Möglichkeit über die WinAPI. [b]Getestete Programme[/b] notepad.exe, winver.exe Zu beachten ist, dass einige Programme – wie der Taskmanager, kein MainWindowHandle (von der Process-Klasse) angeben. Somit muss man auf anderem Wege an das Handle gelangen [b]Benötigte Namespaces[/b] System System.Runtime.InteropServices [b]Links[/b] Frage im MSDN-Forum: http://social.msdn.microsoft.com/Forums/de-DE/91a34879-6120-4d7c-9aa2-7188d03ead57/ MSDN Artikel zu… SetWindowPos: http://msdn.microsoft.com/de-de/library/windows/desktop/ms633545.aspx GetWindowRect: http://msdn.microsoft.com/de-de/library/windows/desktop/ms633519.aspx
/// <summary>
/// Bestimmt ob ein Fenster mit dem TopMost Attribut versehen werden soll oder nicht.
/// </summary>
/// <param name="wndHandle">Das Handle des Fensters</param>
/// <param name="topMost"><c>true</c> wenn das Fenster TopMost sein soll; andernfalls <c>false</c>.</param>
public static void SetTopMost(IntPtr wndHandle, bool topMost)
{
    RECT rect;
    GetWindowRect(wndHandle, out rect);
    SetWindowPos(wndHandle, topMost ? HWND_TOPMOST : HWND_NOTOPMOST, rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top, 0);
}

//Nachfolgend: Der benötigte Code für InterOp
internal const int HWND_TOPMOST = -1;
internal const int HWND_NOTOPMOST = -2;

[DllImport("user32.dll", SetLastError = true)]
internal static extern bool SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int X, int Y, int W, int H, uint uFlags);
[DllImport("user32.dll", SetLastError = true)]
internal static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);

internal struct RECT
{
    //Die Reihenfolge unbedingt so lassen, in die automatisch generierten Felder trägt Windows die Werte in der Reihenfolge ein. 
    public int Left { get; set; }
    public int Top { get; set; }
    public int Right { get; set; }
    public int Bottom { get; set; }
}
/// <summary>
/// Bestimmt ob ein Fenster mit dem TopMost Attribut versehen werden soll oder nicht.
/// </summary>
/// <param name="wndHandle">Das Handle des Fensters</param>
/// <param name="topMost"><c>true</c> wenn das Fenster TopMost sein soll; andernfalls <c>false</c>.</param>
public static void SetTopMost(IntPtr wndHandle, bool topMost)
{
    RECT rect;
    GetWindowRect(wndHandle, out rect);
    SetWindowPos(wndHandle, topMost ? HWND_TOPMOST : HWND_NOTOPMOST, rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top, 0);
}

//Nachfolgend: Der benötigte Code für InterOp
internal const int HWND_TOPMOST = -1;
internal const int HWND_NOTOPMOST = -2;

[DllImport("user32.dll", SetLastError = true)]
internal static extern bool SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int X, int Y, int W, int H, uint uFlags);
[DllImport("user32.dll", SetLastError = true)]
internal static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);

internal struct RECT
{
    //Die Reihenfolge unbedingt so lassen, in die automatisch generierten Felder trägt Windows die Werte in der Reihenfolge ein. 
    public int Left { get; set; }
    public int Top { get; set; }
    public int Right { get; set; }
    public int Bottom { get; set; }
}