【发布时间】:2012-04-28 06:04:58
【问题描述】:
在我的 vb.net windows 窗体应用程序中,我想制作一个按钮,当用户单击该按钮时,应显示桌面,(显示桌面按钮)。
考虑一个表单名称为form1,它有一个类似“显示桌面”的按钮,当用户点击时,所有的应用程序都应该被最小化并且应该显示桌面,有没有VB.NET Windows Form应用程序的代码。
【问题讨论】:
在我的 vb.net windows 窗体应用程序中,我想制作一个按钮,当用户单击该按钮时,应显示桌面,(显示桌面按钮)。
考虑一个表单名称为form1,它有一个类似“显示桌面”的按钮,当用户点击时,所有的应用程序都应该被最小化并且应该显示桌面,有没有VB.NET Windows Form应用程序的代码。
【问题讨论】:
编辑
虽然我提出的解决方案有效,但我建议使用下面的 Code Gray 的 answer,因为这是正确的方法。
在 C# 中是这样的:
using System;
using System.Runtime.InteropServices;
namespace ConsoleApplication1 {
class Program {
[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", EntryPoint = "SendMessage", SetLastError = true)]
static extern IntPtr SendMessage(IntPtr hWnd, Int32 Msg, IntPtr wParam, IntPtr lParam);
const int WM_COMMAND = 0x111;
const int MIN_ALL = 419;
const int MIN_ALL_UNDO = 416;
static void Main(string[] args) {
IntPtr lHwnd = FindWindow("Shell_TrayWnd", null);
SendMessage(lHwnd, WM_COMMAND, (IntPtr)MIN_ALL, IntPtr.Zero);
System.Threading.Thread.Sleep(2000);
SendMessage(lHwnd, WM_COMMAND, (IntPtr)MIN_ALL_UNDO, IntPtr.Zero);
}
}
}
我使用online converter tool转换上述代码,请验证是否有效
Imports System
Imports System.Runtime.InteropServices
Namespace ConsoleApplication1
Class Program
<DllImport("user32.dll", EntryPoint := "FindWindow", SetLastError := True)> _
Private Shared Function FindWindow(lpClassName As String, lpWindowName As String) As IntPtr
End Function
<DllImport("user32.dll", EntryPoint := "SendMessage", SetLastError := True)> _
Private Shared Function SendMessage(hWnd As IntPtr, Msg As Int32, wParam As IntPtr, lParam As IntPtr) As IntPtr
End Function
Const WM_COMMAND As Integer = &H111
Const MIN_ALL As Integer = 419
Const MIN_ALL_UNDO As Integer = 416
Private Shared Sub Main(args As String())
Dim lHwnd As IntPtr = FindWindow("Shell_TrayWnd", Nothing)
SendMessage(lHwnd, WM_COMMAND, DirectCast(MIN_ALL, IntPtr), IntPtr.Zero)
System.Threading.Thread.Sleep(2000)
SendMessage(lHwnd, WM_COMMAND, DirectCast(MIN_ALL_UNDO, IntPtr), IntPtr.Zero)
End Sub
End Class
End Namespace
【讨论】:
现有答案中提出的解决方案是依赖于 Windows 未记录方面的黑客攻击。它们现在可以工作,但它们随时可能因 Windows 更新而停止工作。
Marshal's solution 尝试在任务栏中找到实际的“显示桌面”按钮。一个明显的问题是窗口的名称和 ID 是硬编码的,这意味着如果操作系统本身发生更改,代码就会中断。这些操作系统内部没有记录,不打算由应用程序进行编程操作,并且随时可能更改。我也不知道如果用户修改他们的操作系统设置以不在任务栏中显示此按钮会发生什么。代码是否继续有效?这些消息是否仍受支持?我不知道。你呢?
Harsh's solution 依赖于合成按下 Win+D 组合键,这是显示桌面的键盘快捷键。这具有合成键盘输入的所有标准问题,另外一个缺点是它使用了旧的、已弃用的keybd_event 函数(SendInput 是它的替代品,它解决了keybd_input 的一些问题,即没有处理错误的方法,但不能解决合成键盘事件的更大问题。)此解决方案不太可能因 Windows 更新而中断,因为此键盘快捷键已记录在案,但可能具有不良副作用和与其他交互的细微问题系统功能和/或应用程序。
更好的解决方案是委托给 COM 组件 Shell32.dll,调用其记录在案的 ToggleDesktop method,这正是您想要做的。来自 MSDN 文档:
此方法与任务栏上的显示桌面按钮效果相同。它要么隐藏所有打开的窗口以显示桌面,要么通过显示所有打开的窗口来隐藏桌面。
ToggleDesktop方法不显示用户界面,它只是调用切换操作。
由于这已记录在案,因此随着 Windows 的更新,它更有可能继续工作。由于它不依赖黑客或综合事件,因此不太可能导致细微的不兼容。它也很简单更容易使用。
C# 和 VB.NET 都可以轻松访问 COM 库。在 C# 中,调用函数很简单:
Shell32.Shell shell = new Shell32.Shell();
shell.ToggleDesktop();
在 VB.NET 中,这变成了(看 ma,没有分号):
Dim shell As Shell32.Shell = New Shell32.Shell()
shell.ToggleDesktop()
如果您的项目中尚不存在“Microsoft Shell 控件和自动化”(Shell32.dll 库)的引用,您可能需要添加该引用。这是一个系统 DLL,因此它存在于所有系统上。
唯一的要求是您从使用单线程单元 (STA) 模型的线程调用此函数。换句话说,它不是线程安全的,也不处理自己的同步。然而,这并不是一个明显的缺点,因为所有 Windows 窗体应用程序都使用 STA 线程:它是主线程,即处理 UI 和泵送消息的线程。 UI 线程几乎总是 STA,并且保证在 WinForms 中也是如此。只是不要尝试从后台/工作线程调用它。并非如此,因为您应该只尝试显示桌面以响应直接的用户交互,这无论如何都会在 UI 线程上处理。
【讨论】:
检查此链接。这包含最小化所有显示桌面的窗口的代码。 http://www.dreamincode.net/code/snippet2109.htm
Public Sub ShowDesktop()
keybd_event(VK_LWIN, 0, 0, 0)
keybd_event(77, 0, 0, 0)
keybd_event(VK_LWIN, 0, KEYEVENTF_KEYUP, 0)
End Sub
Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, _
ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
Private Const KEYEVENTF_KEYUP = &H2
Private Const VK_LWIN = &H5B
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Call ShowDesktop()
End Sub
【讨论】:
shell:::{3080F90D-D7AD-11D9-BD98-0000947B0257} 确实是最好的解决方案,因为它是 MSDN 中已知的文档化 CLSID
【讨论】:
Shell("cmd.exe /c %windir%\explorer.exe shell:::{3080F90D-D7AD-11D9-BD98-0000947B0257}", AppWinStyle.MinimizedNoFocus)
最佳解决方案
【讨论】: