如何以编程方式隐藏桌面图标?

如何使用C#以编程方式显示/隐藏桌面图标?

我正在尝试创建一个使用小部件的替代桌面,我需要隐藏旧图标。

您可以使用Windows API执行此操作。 以下是C#中将切换桌面图标的示例代码。

[DllImport("user32.dll", SetLastError = true)] static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll", SetLastError = true)] static extern IntPtr GetWindow(IntPtr hWnd, GetWindow_Cmd uCmd); enum GetWindow_Cmd : uint { GW_HWNDFIRST = 0, GW_HWNDLAST = 1, GW_HWNDNEXT = 2, GW_HWNDPREV = 3, GW_OWNER = 4, GW_CHILD = 5, GW_ENABLEDPOPUP = 6 } [DllImport("user32.dll", CharSet = CharSet.Auto)] static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam); private const int WM_COMMAND = 0x111; static void ToggleDesktopIcons() { var toggleDesktopCommand = new IntPtr(0x7402); IntPtr hWnd = GetWindow(FindWindow("Progman", "Program Manager"), GetWindow_Cmd.GW_CHILD); SendMessage(hWnd, WM_COMMAND, toggleDesktopCommand, IntPtr.Zero); } 

这会向Progman的SHELLDLL_DefView子窗口发送一条消息,该窗口告诉它切换它唯一的子项“FolderView”的可见性(通过添加或删除WS_VISIBLE样式)。 “FolderView”是包含图标的实际窗口。

要测试图标是否可见,可以使用GetWindowInfo函数查询WS_VISIBLE样式,如下所示:

  [return: MarshalAs(UnmanagedType.Bool)] [DllImport("user32.dll", SetLastError = true)] private static extern bool GetWindowInfo(IntPtr hwnd, ref WINDOWINFO pwi); [StructLayout(LayoutKind.Sequential)] public struct RECT { private int _Left; private int _Top; private int _Right; private int _Bottom; } [StructLayout(LayoutKind.Sequential)] struct WINDOWINFO { public uint cbSize; public RECT rcWindow; public RECT rcClient; public uint dwStyle; public uint dwExStyle; public uint dwWindowStatus; public uint cxWindowBorders; public uint cyWindowBorders; public ushort atomWindowType; public ushort wCreatorVersion; public WINDOWINFO(Boolean? filler) : this() // Allows automatic initialization of "cbSize" with "new WINDOWINFO(null/true/false)". { cbSize = (UInt32)(Marshal.SizeOf(typeof(WINDOWINFO))); } } 

这是一个调用上面代码的函数,如果窗口可见则返回true,否则返回false。

  static bool IsVisible() { IntPtr hWnd = GetWindow(GetWindow(FindWindow("Progman", "Program Manager"), GetWindow_Cmd.GW_CHILD), GetWindow_Cmd.GW_CHILD); WINDOWINFO info = new WINDOWINFO(); info.cbSize = (uint)Marshal.SizeOf(info); GetWindowInfo(hWnd, ref info); return (info.dwStyle & 0x10000000) == 0x10000000; } 

可以在此处找到Windows API代码以及有关窗口样式的更多信息: http : //www.pinvoke.net/default.aspx/user32/GetWindowInfo.html

另一种方法是创建一个单独的桌面并显示它。 它没有图标。

应用程序在单独的桌面上运行

您可以创建全屏视图应用程序并使其成为最顶层的窗口。

然后让你的应用程序启动Windows。

您可以在RegEdit中执行此操作HKEY_CURRENT_USER \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Explorer \ Advanced将HideIcons更改为1

  static void HideIcons() { RegistryKey myKey = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced", true); if (myKey != null) { myKey.SetValue("HideIcons", 1); myKey.Close(); } } 

使用此处描述的Registry类。

http://msdn.microsoft.com/en-us/library/microsoft.win32.registry.aspx

有一个官方的API来做这样的事情,它被称为shell API。 它应该优先于操作注册表和FindWindow / SendMessage方法,这两种方法都非常脆弱,这些解决方案往往会破坏未来的Windows版本(对于后者,这已经被评论者证实)。

涉及的步骤:

  1. 获取桌面的IFolderView2界面(自Windows Vista以来支持)。
  2. 对于dwMaskdwFlags参数,使用FWF_NOICONS调用IFolderView2::SetCurrentFolderFlags()

标志的效果立即可见。 无需重新启动计算机,也无需“explorer.exe”。 注销或重新启动后,该标志也会保留。

棘手的是步骤1)。 Raymond Chen在他的文章“操纵桌面图标的位置”中展示了C ++代码,特别是在他的FindDesktopFolderView()函数中。

以下是控制台应用程序forms的完整C ++示例 。 它基于Raymond Chen的代码。 该程序每次运行时都会切换桌面图标的可见性。

该代码已在Windows 10 Build 17134下测试过。

 #include  // Shell API #include  // CComPtr & Co. #include  #include  #include  // Throw a std::system_error if the HRESULT indicates failure. template< typename T > void ThrowIfFailed( HRESULT hr, T&& msg ) { if( FAILED( hr ) ) throw std::system_error{ hr, std::system_category(), std::forward( msg ) }; } // RAII wrapper to initialize/uninitialize COM struct CComInit { CComInit() { ThrowIfFailed( ::CoInitialize( nullptr ), "CoInitialize failed" ); } ~CComInit() { ::CoUninitialize(); } }; // Query an interface from the desktop shell view. void FindDesktopFolderView( REFIID riid, void **ppv, std::string const& interfaceName ) { CComPtr spShellWindows; ThrowIfFailed( spShellWindows.CoCreateInstance( CLSID_ShellWindows ), "Failed to create IShellWindows instance" ); CComVariant vtLoc( CSIDL_DESKTOP ); CComVariant vtEmpty; long lhwnd; CComPtr spdisp; ThrowIfFailed( spShellWindows->FindWindowSW( &vtLoc, &vtEmpty, SWC_DESKTOP, &lhwnd, SWFO_NEEDDISPATCH, &spdisp ), "Failed to find desktop window" ); CComQIPtr spProv( spdisp ); if( ! spProv ) ThrowIfFailed( E_NOINTERFACE, "Failed to get IServiceProvider interface for desktop" ); CComPtr spBrowser; ThrowIfFailed( spProv->QueryService( SID_STopLevelBrowser, IID_PPV_ARGS( &spBrowser ) ), "Failed to get IShellBrowser for desktop" ); CComPtr spView; ThrowIfFailed( spBrowser->QueryActiveShellView( &spView ), "Failed to query IShellView for desktop" ); ThrowIfFailed( spView->QueryInterface( riid, ppv ), "Could not query desktop IShellView for interface " + interfaceName ); } void ToggleDesktopIcons() { CComPtr spView; FindDesktopFolderView( IID_PPV_ARGS(&spView), "IFolderView2" ); DWORD flags = 0; ThrowIfFailed( spView->GetCurrentFolderFlags( &flags ), "GetCurrentFolderFlags failed" ); ThrowIfFailed( spView->SetCurrentFolderFlags( FWF_NOICONS, flags ^ FWF_NOICONS ), "SetCurrentFolderFlags failed" ); } int wmain(int argc, wchar_t **argv) { try { CComInit init; ToggleDesktopIcons(); std::cout << "Desktop icons have been toggled.\n"; } catch( std::system_error const& e ) { std::cout << "ERROR: " << e.what() << ", error code: " << e.code() << "\n"; return 1; } return 0; } 

你这是错误的方式。 你真正想要做的是更换shell。 Windows提供了这个,所以你应该利用它。 编写自己的shell来替换资源管理器。