当前位置:  开发笔记 > 编程语言 > 正文

窗口"在桌面上"

如何解决《窗口"在桌面上"》经验,为你挑选了4个好方法。

我一直在使用Rainlendar,我注意到它可以选择将窗口"放在桌面上".它就像一个bottomMost窗口(与最顶层相对).

我怎么能在WPF应用程序上这样做?

谢谢



1> Hugh Allen..:

我的答案是Win32 API,不是特定于WPF(可能需要来自C#的P/Invoke):

Rainlendar有两种选择:

"在桌面上",它成为Explorer桌面窗口("程序管理器")的子项.您可以使用SetParent API 实现此目的.

"On Bottom"就是你所描述的 - 它的窗口停留在Z-order的底部,就在桌面前面.将它们放在那里很容易(参见SetWindowPos) - 诀窍是在点击时阻止它们到达前面.我建议处理WM_WINDOWPOSCHANGING消息.



2> Artur Carval..:

这是我使用的,所以窗口总是"在底部":

   using System;
    using System.Runtime.InteropServices;
    using System.Windows;
    using System.Windows.Interop;

...

[DllImport("user32.dll")]
static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X,
   int Y, int cx, int cy, uint uFlags);

const UInt32 SWP_NOSIZE = 0x0001;
const UInt32 SWP_NOMOVE = 0x0002;
const UInt32 SWP_NOACTIVATE = 0x0010;

static readonly IntPtr HWND_BOTTOM = new IntPtr(1);

public static void SetBottom(Window window)
{
    IntPtr hWnd = new WindowInteropHelper(window).Handle;
    SetWindowPos(hWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
}



3> Maurice Flan..:

警告接受的答案表明您调用SetParent来创建桌面的子项.如果你这样做,你会让Win32窗口管理器将桌面的输入队列同步到你的子窗口,这是一件坏事 - 雷蒙德陈解释了原因.基本上,如果您的窗口挂起或阻塞(例如使用MessageBox),您将锁定桌面.


但是,这已在注释中,因此似乎不再适用。`Jordan Russell 2004年2月24日下午6:25``在用于Windows 2000和XP的当前SP中,它们似乎已修复,因此不再可能禁用桌面窗口。(即EnableWindow(GetDesktopWindow(),FALSE)无效)。是的,我是个死灵法师... xD

4> 小智..:

我试图做同样的事情……我使用了很多想法,但是我能够做到这一点并防止闪烁。

我设法覆盖了WndProc,在将setwindowpos放在后台之前使用了一个setwindowpos,并使用了另一个setwindowpos来防止它获得焦点...

    const UInt32 SWP_NOSIZE = 0x0001;
    const UInt32 SWP_NOMOVE = 0x0002;
    const UInt32 SWP_NOACTIVATE = 0x0010;
    const UInt32 SWP_NOZORDER = 0x0004;
    const int WM_ACTIVATEAPP = 0x001C;
    const int WM_ACTIVATE = 0x0006;
    const int WM_SETFOCUS = 0x0007;
    static readonly IntPtr HWND_BOTTOM = new IntPtr(1);
    const int WM_WINDOWPOSCHANGING = 0x0046;

    [DllImport("user32.dll")]
    static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X,
       int Y, int cx, int cy, uint uFlags);
    [DllImport("user32.dll")]
    static extern IntPtr DeferWindowPos(IntPtr hWinPosInfo, IntPtr hWnd,
       IntPtr hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags);
    [DllImport("user32.dll")]
    static extern IntPtr BeginDeferWindowPos(int nNumWindows);
    [DllImport("user32.dll")]
    static extern bool EndDeferWindowPos(IntPtr hWinPosInfo);

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        IntPtr hWnd = new WindowInteropHelper(this).Handle;
        SetWindowPos(hWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);

        IntPtr windowHandle = (new WindowInteropHelper(this)).Handle;
        HwndSource src = HwndSource.FromHwnd(windowHandle);
        src.AddHook(new HwndSourceHook(WndProc));
    }

    private IntPtr WndProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    {
        if (msg == WM_SETFOCUS)
        {
            IntPtr hWnd = new WindowInteropHelper(this).Handle;
            SetWindowPos(hWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
            handled = true;
        }
        return IntPtr.Zero;
    }

    private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
    {
        IntPtr windowHandle = (new WindowInteropHelper(this)).Handle;
        HwndSource src = HwndSource.FromHwnd(windowHandle);
        src.RemoveHook(new HwndSourceHook(this.WndProc));
    }

推荐阅读
kikokikolove
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有