Существует официальный API для подобных действий, он называется API-интерфейсом оболочки. Это должно быть предпочтительнее, чем манипулирование реестром и подход FindWindow
/ SendMessage
, как очень хрупкие «решения», которые имеют тенденцию ломаться с будущими версиями Windows (для последних это уже подтвердили комментаторы).
Шаги:
IFolderView2
рабочего стола (поддерживается с Windows Vista). IFolderView2::SetCurrentFolderFlags()
с помощью FWF_NOICONS
для параметров dwMask
и dwFlags
. Эффект флага видно сразу. Нет необходимости перезагружать компьютер или «explorer.exe». Флаг также сохраняется после выхода из системы или перезагрузки.
Сложная вещь - шаг 1). Raymond Chen показывает код C ++ для этой статьи в статье «Манипулирование положениями значков рабочего стола» , особенно в его функции FindDesktopFolderView()
.
Вот полный пример 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;
}