c#将表单固定到桌面上

时间:2010-01-17 12:39:04

标签: c# forms desktop pinning

我正在尝试将表单固定到桌面上,就像小工具侧边栏一样。

它不应受Win + D和显示桌面按钮的影响。

这是最好的方法吗?

我可以找到Progman并将我的表格的父级设置为此,但我读到它并不是最好的方法。

6 个答案:

答案 0 :(得分:5)

免责声明:仅仅因为可以在没有API调用或“挂钩”的WinForms中以某种方式执行某些操作,并不意味着您使用该技术。 API要求使窗体/窗口不可移动,最顶层等非常简单。请注意,通常的API“简单技术”将出现与下面演示的技术相同的问题,该技术出现在桌面上的文件和文件夹图标上。

请注意,通过“干扰”Windows-D组合键的设计行为和TaskBar中的“Show Desktop”图标 - hickey,您将参与用户计算机的非标准配置:常见的“智慧”表明这样做不是一个好主意!

可以在Vista中使用C#WinForms模拟“伪边栏”...不受Windows-D隐藏或使用系统托盘中的“显示桌面”图标 - 没有API调用或“挂钩”:但是有一个 catch :表单/窗口将出现在桌面上的项目(文件夹,文件)之上,并且由于它不可移动,你不会能够访问“在它下面”的项目。如果你愿意“忍受”这个限制:请继续阅读:)在此结尾处注意到另一个“较小的怪异”。

示例:

  1. 在Visual Studio中创建一个新的Form解决方案:

    一个。将表格的大小,背景颜色等设置为品味

    湾添加您的控件或用户控件。

    ℃。如果你想要总是出现在其他应用程序的窗口前面,将Form的'TopMost属性设置为'true',如果你希望其他应用程序的窗口能够出现在它前面,则为false。

  2. 将“ControlBox”,“MinimizeBox”和“Formize的MaximizeBox属性”设置为“false”。

  3. 将“FormBorderStyle”设置为“属性浏览器”下拉列表中显示的“固定样式”之一。您可能知道使用FormBorderStyle = FixedToolWindow,Form的Text属性为“空字符串”:您将拥有一个没有TitleBar和Caption的窗口。讨论:是的,如果您愿意,可以允许调整大小:只需在SizeChanged处理程序中编写一些代码,然后保持表单解锁。

  4. 这些事件处理程序应该让您了解使表单不可关闭,不可移动,不可最小化等所需的内容。

  5. .........粗略草图代码p.o.c.如下:显然你可以重构,改进......

    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        e.Cancel = true;
    }
    
    // set your Form's 'Top here ...
    private void Form1_LocationChanged(object sender, EventArgs e)
    {
        this.Top = 100;
        this.Left = Screen.PrimaryScreen.Bounds.Width - this.Width;
    }
    
    private void Form1_VisibleChanged(object sender, EventArgs e)
    {
        if (this.WindowState == FormWindowState.Minimized) this.WindowState = FormWindowState.Normal;
    }
    
    private void Form1_Deactivate(object sender, EventArgs e)
    {
        this.Activate();
    }
    
    private void Form1_SizeChanged(object sender, EventArgs e)
    {
        if (this.WindowState == FormWindowState.Minimized) this.WindowState = FormWindowState.Normal;
    }
    
    private void button1_Click(object sender, EventArgs e)
    {
        MessageBox.Show("button1 is alive");
    }
    

    那个'button1在那里做点击事件处理程序是什么?只是在我的测试中验证表格是否可用。

    这是在上面的'Deactivate Event处理程序中重新激活Form,使Form免受Windows-D和“Show Desktop”的影响:但是在Vista中也有一个奇怪的副作用:当你切换焦点时从窗体的窗口(例如,通过点击桌面上的文件夹):任务栏将弹起,保持,(如果它被隐藏)并闪烁一段时间:我想向你展示它的向往活跃。

    使用这个“ersatz侧边栏”,而不是使用API​​,可能是另一个使用固定开启的TaskBar的价格。

    注意:不要忘记:你想要'不透明度:你得到'不透明度:)。

    [1]注意:您确实想考虑为用户提供隐藏表单或关闭表单的方法吗? [/ 1]

答案 1 :(得分:2)

听起来你所追求的是Application Desktop Toolbar

答案 2 :(得分:1)

我可能错了,但可能是Win + D可能会向所有打开的窗口发送全局最小化消息

因此,请尝试使您的表单免受窗口最小化消息的影响。 使用钩子

这是一篇相关的文章。

Hooking

答案 3 :(得分:0)

谢谢大家的回答,

我最初有这个方法:

    [DllImport("User32.dll")]
    static extern IntPtr FindWindow(String lpClassName, String lpWindowName);
    [DllImport("user32.dll", SetLastError = true)]
    static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
    [DllImport("user32.dll")]
    static extern int SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

        IntPtr pWnd = FindWindow("Progman", null);
        pWnd = FindWindowEx(pWnd, IntPtr.Zero, "SHELLDLL_DefVIew", null);
        pWnd = FindWindowEx(pWnd, IntPtr.Zero, "SysListView32", null);
        IntPtr tWnd = this.Handle;
        SetParent(tWnd, pWnd);

但是,主要的问题是儿童窗户也是桌面电脑的父母,你不能使用任何形式的不透明或透明度。

答案 4 :(得分:0)

使用以下代码并将窗口句柄传递给函数,而表单加载希望完全解决您的问题

public void SetFormOnDesktop(IntPtr hwnd) {      
IntPtr hwndf = hwnd;
IntPtr hwndParent = FindWindow("ProgMan", null);
SetParent(hwndf, hwndParent);
}

答案 5 :(得分:0)

一个简单的解决方法可能是使用Win + M并且不要听取停用事件。这将消除激活/停用闪烁。