代码之家  ›  专栏  ›  技术社区  ›  Roger Far

C将表单固定到deskop

  •  2
  • Roger Far  · 技术社区  · 16 年前

    我正在尝试将表单固定到桌面,例如小工具侧边栏。

    它不应该受到win+d和显示桌面按钮的影响。

    哪种方法是最好的?

    我可以找到程序并将窗体的父级设置为这个,但我阅读它不是最好的方法。

    6 回复  |  直到 12 年前
        1
  •  5
  •   BillW    16 年前

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

    请注意,通过“干扰”Windows-D组合键的设计行为和任务栏中的“显示桌面”图标,您正在进行用户机器的非标准配置:常见的“智慧”表示这样做不是一个好主意!

    “伪侧边栏”可以在Vista中的C Winforms中模拟…不受Windows-D隐藏或使用系统托盘中的“显示桌面”图标的影响…没有API调用或“钩住”:但是 抓住 :窗体/窗口将显示在桌面上的项目(文件夹、文件)的顶部,并且由于它是不可移动的,因此您将无法访问“其下”的项目。如果您愿意“忍受”该限制:请阅读:)另一个“较小的怪异”在结尾处注明。

    例子:

    1. 在Visual Studio中创建新的表单解决方案:

      A.设置窗体的大小、背景色等以适应口味

      b.添加控件或用户控件。

      c.如果您希望始终显示在其他应用程序的窗口前面,请将窗体的“最顶层”属性设置为“真”;如果您希望其他应用程序的窗口能够显示在其前面,请设置为“假”。

    2. 将窗体的“controlBox”、“minimizeBox”和“maximizeBox”属性设置为“false”。

    3. 将“FormBorderStyle”设置为“属性资源管理器”下拉列表中显示的固定样式之一。正如您可能知道的那样,将FormBorderStyle=FixedToolWindow与表单的文本属性一起使用“空字符串”:您将拥有一个没有标题栏和标题的窗口。讨论:是的,如果愿意,您可以允许调整大小:只需在sizeChanged处理程序中编写一些代码,并保持表单未锁定。

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

    ……草图代码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");
    }
    

    “Click Event Handler for”按钮1在那里做什么?只是为了在测试中验证表单是否可用。

    正是在上面的“停用事件处理程序”中重新激活窗体,使窗体不受Windows-D和“显示桌面”的影响:但在Vista中也有一个奇怪的副作用:当您将焦点从窗体窗口切换开时(例如,通过单击桌面上的文件夹):任务栏将弹起,保持向上(如果它是隐藏的),一个D眨眨眨眼:我想向你展示一下它渴望活跃起来。

    忍受一个卡住的打开的任务栏可能是使用这个“Ersatz侧边栏”而不是使用API的另一个代价。

    注意:不要忘记:你想要“不透明度:你得到了”不透明度:)

    [1]注意:您想给用户一种隐藏或关闭表单的方法吗?[ / 1 ]

        2
  •  2
  •   P Daddy    16 年前

    听起来你想要的是 Application Desktop Toolbar .

        3
  •  1
  •   Vivek Bernard    16 年前

    我可能是错的,但是,可能是win+d可能会向所有打开的窗口发送一个全局最小化消息。

    所以试着让你的表单免疫窗口最小化消息。 使用钩子

    这是一篇相关的文章。

    Hooking

        4
  •  0
  •   Roger Far    16 年前

    感谢大家的回答,

    起初我有这种方法:

        [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);
    

    但马乔尔的问题是,子窗口也是Deskop的父窗口,您不能使用任何形式的不透明或透明。

        5
  •  0
  •   Suriyan Suresh    16 年前

    使用以下代码并在窗体加载时将窗口句柄传递给函数,希望这样可以完全解决您的问题。

    public void SetFormOnDesktop(IntPtr hwnd) {      
    IntPtr hwndf = hwnd;
    IntPtr hwndParent = FindWindow("ProgMan", null);
    SetParent(hwndf, hwndParent);
    }
    
        6
  •  0
  •   Chris Wiede    12 年前

    一个简单的解决方法可能是只使用win+m,而不听取停用事件。这将消除激活/停用闪烁。