¿Cómo ocultar icons de escritorio programáticamente?

¿Cómo puedo mostrar u ocultar los icons del escritorio programáticamente, usando C #?

Intento crear un escritorio alternativo, que use widgets, y necesito ocultar los icons antiguos.

Puedes hacer esto usando la API de Windows. Aquí hay un código de muestra en C # que alternará icons de escritorio.

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

Esto envía un mensaje a la ventana secundaria SHELLDLL_DefView de Progman, que le dice que al alternar la visibilidad (agregando o eliminando el estilo WS_VISIBLE) de su único hijo, “FolderView”. “FolderView” es la ventana real que contiene los icons.

Para comprobar si los icons están visibles o no, puede consultar el estilo WS_VISIBLE utilizando la función GetWindowInfo, que se muestra a continuación:

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

Aquí hay una función que llama al código anterior y devuelve verdadero si la ventana está visible, falso si no.

  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; } 

El código API de Windows junto con más información sobre los estilos de ventana se puede encontrar aquí: http://www.pinvoke.net/default.aspx/user32/GetWindowInfo.html

Un enfoque diferente es crear un escritorio separado y mostrarlo en su lugar. No tendrá íconos.

La aplicación se ejecuta en un escritorio separado

Puede crear una aplicación de vista de pantalla completa y convertirla en la ventana superior.

Luego, haga que su aplicación se inicie con Windows.

Puede hacer esto en RegEdit HKEY_CURRENT_USER \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Explorer \ Advanced change HideIcons to 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(); } } 

Use la clase de Registro como se describe aquí.

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

Hay una API oficial para hacer cosas como esa, se llama shell API. Debería ser preferible a la manipulación del registro y el enfoque FindWindow / SendMessage , ambas “soluciones” muy frágiles que tienden a romperse con las versiones futuras de Windows (para este último, esto ya ha sido confirmado por los comentaristas).

Pasos implicados:

  1. Obtenga la interfaz IFolderView2 del escritorio (compatible desde Windows Vista).
  2. Llame a IFolderView2::SetCurrentFolderFlags() con FWF_NOICONS para los parámetros dwMask y dwFlags .

El efecto de la bandera es visible de inmediato. No es necesario reiniciar la computadora ni “explorer.exe”. La bandera también persiste después del cierre de sesión o reinicio.

Lo complicado es el paso 1). Raymond Chen muestra el código de C ++ para eso en su artículo “Manipulando las posiciones de los icons del escritorio” , específicamente en su función FindDesktopFolderView() .

Aquí hay un ejemplo completo de C ++ en forma de una aplicación de consola. Está basado en el código de Raymond Chen. El progtwig alterna la visibilidad de los íconos del escritorio cada vez que se ejecuta.

El código ha sido probado en 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; } 

Estás haciendo esto de la manera incorrecta. Lo que realmente estás tratando de hacer es reemplazar el caparazón. Windows proporciona esto, así que solo debes aprovecharlo. Escribe tu propio caparazón para reemplazar al explorador.