如何制作'永远在底'窗口

时间:2009-02-09 12:29:44

标签: c# delphi

有人知道如何制作一个“永远在底”的窗户或固定在桌面上的窗户吗?它应该接收焦点和鼠标点击,但应该保持在Z顺序的底部。即使用户最小化全部或显示桌面操作,它也可以保留在桌面上。

delphi和c#解决方案(或部分解决方案/提示)都很棒。

3 个答案:

答案 0 :(得分:12)

警告有人建议您可以通过调用SetParent并将窗口设置为桌面的子项来完成此操作。如果你这样做,你会导致Win32窗口管理器将桌面的输入队列组合到你的子窗口,这是坏事 - Raymond Chen explains why.

另外,请记住,使用HWND_BOTTOM调用SetWindowPos是不完整的。每当窗口改变zorder时,您都需要这样做。处理WM_WINDOWPOSCHANGING事件,请查看SWP_NOZORDER以获取更多信息。

答案 1 :(得分:8)

SetWindowPos可以使Windows AlwaysOnTop。很可能它会产生相反的结果。尝试以下几点:

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


 public const uint SWP_NOSIZE          = 0x0001;
 public const uint SWP_NOMOVE          = 0x0002;
 public const uint SWP_NOACTIVATE      = 0x0010;
 public const int HWND_BOTTOM = 1;


SetWindowPos(hWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);

注意:

  • 尚未测试此方法(使窗口始终位于底部)
  • 如果它恰好工作,那么很可能show桌面操作将隐藏窗口。所以也许你应该更深入地研究这个'漂亮'的API。

编辑:完成了一些搜索,以确认它是否会发挥作用并找到一些有趣的东西 - a duplicate

答案 2 :(得分:1)

这是ATL窗口的解决方案。 如果您可以申请c#,它会对您有所帮助。


BEGIN_MSG_MAP(...)
   ...
   MESSAGE_HANDLER(WM_WINDOWPOSCHANGING, OnWindowPosChanging)
   ...
END_MSG_MAP()

LRESULT OnWindowPosChanging(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)

{

    if (_bStayOnBottom)
    {
        auto pwpos = (WINDOWPOS*)lParam;

        pwpos->hwndInsertAfter = HWND_BOTTOM;

        pwpos->flags &= (~SWP_NOZORDER);

    }
    return 0;
}