You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Win10桌面小部件开发:如何让C# WinForms窗体置于所有窗口底层?

更简便的Windows 10桌面小部件实现方案

一、替换窗口跟踪逻辑:直接监听"显示桌面"事件

你当前通过跟踪窗口焦点、对比PID判断是否显示桌面的方式可行,但可以简化——直接监听Shell的显示/恢复桌面系统消息,无需复杂的钩子和PID对比操作。

Windows Shell在执行显示桌面/恢复窗口操作时,会广播WM_SYSCOMMAND消息,其中SC_MINIMIZEALL对应显示桌面,SC_RESTOREALL对应恢复窗口。只需给窗体添加消息处理逻辑即可捕获这些事件:

protected override void WndProc(ref Message m)
{
    const int WM_SYSCOMMAND = 0x0112;
    const int SC_MINIMIZEALL = 0xF020;
    const int SC_RESTOREALL = 0xF030;

    if (m.Msg == WM_SYSCOMMAND)
    {
        switch ((int)m.WParam)
        {
            case SC_MINIMIZEALL:
                Show();
                break;
            case SC_RESTOREALL:
                Hide();
                break;
        }
    }
    base.WndProc(ref m);
}

这种方式比SetWinEventHook轻量得多,无需处理钩子生命周期和复杂的窗口信息解析,逻辑更直接。

二、将窗体置于所有窗口底层

要让窗体处于桌面图标与其他窗口之间(即最底层),需要调用WinAPI的SetWindowPos,将窗口Z顺序设为HWND_BOTTOM,同时搭配参数避免激活或移动窗口:

首先添加必要的PInvoke声明:

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

const uint SWP_NOMOVE = 0x0002;
const uint SWP_NOSIZE = 0x0001;
const uint SWP_NOACTIVATE = 0x0010;
static readonly IntPtr HWND_BOTTOM = new IntPtr(1);

然后在窗体初始化或需要调整层级时调用:

SetWindowPos(this.Handle, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);

注意:需确保窗体的TopMost属性设为false,否则会覆盖底层设置。

三、现有代码的其他优化建议

  • 你当前的GetProcessPathByHWND方法未被使用,可直接删除以精简代码。
  • 若保留原钩子逻辑,需妥善管理钩子对象避免内存泄漏:将foregroundHook设为类成员,在窗体关闭时调用UnhookWinEvent释放资源。

完整优化后的示例代码

public partial class Form1 : Form
{
    [DllImport("user32.dll")]
    static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);

    const uint SWP_NOMOVE = 0x0002;
    const uint SWP_NOSIZE = 0x0001;
    const uint SWP_NOACTIVATE = 0x0010;
    static readonly IntPtr HWND_BOTTOM = new IntPtr(1);

    const int WM_SYSCOMMAND = 0x0112;
    const int SC_MINIMIZEALL = 0xF020;
    const int SC_RESTOREALL = 0xF030;

    public Form1()
    {
        InitializeComponent();
        
        // 设置窗口到屏幕右上角
        foreach (var scrn in Screen.AllScreens)
        {
            if (scrn.Bounds.Contains(this.Location))
            {
                this.Location = new Point(scrn.Bounds.Right - this.Width, scrn.Bounds.Top);
                break;
            }
        }
        
        // 将窗体置于底层
        SetWindowPos(this.Handle, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
    }

    protected override void WndProc(ref Message m)
    {
        if (m.Msg == WM_SYSCOMMAND)
        {
            switch ((int)m.WParam)
            {
                case SC_MINIMIZEALL:
                    Show();
                    break;
                case SC_RESTOREALL:
                    Hide();
                    break;
            }
        }
        base.WndProc(ref m);
    }
}

内容的提问来源于stack exchange,提问作者nullrefexc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 01:54:51