Как скрыть значки рабочего стола с Windows API в C ++? - PullRequest
0 голосов
/ 15 ноября 2018

Ответы, которые я нашел, ссылаются на fHideIcon, но я получаю ошибку 404 на странице Microsoft для этих ссылок.

Я также пытался:

SHELLSTATE ss;
SecureZeroMemory(&ss, sizeof(ss));
SHGetSetSettings(&ss, SSF_HIDEICONS, TRUE);

Ноэто не сработало.
Кто-нибудь знает, как это сделать?

Ответы [ 3 ]

0 голосов
/ 15 ноября 2018

Следующее, кажется, работает (адаптировано из https://stackoverflow.com/a/6403014/5743288):

#include <windows.h>

int main ()
{
    HWND hProgman = FindWindowW (L"Progman", L"Program Manager");
    HWND hChild = GetWindow (hProgman, GW_CHILD);
    ShowWindow (hChild, SW_HIDE);
    Sleep (2000);
    ShowWindow (hChild, SW_SHOW);
}

Обратите внимание: этот подход не поддерживается Microsoft и отключает щелчок правой кнопкой мыши на этом рабочем столе.

0 голосов
/ 17 ноября 2018

Следующий подход, использующий официальный API-интерфейс оболочки, немного сложен, но работает даже под Windows 10.

Шаги:

  1. Получить IFolderView2 интерфейс рабочего стола (поддерживается начиная с Windows Vista).
  2. Вызов IFolderView2::SetCurrentFolderFlags() с FWF_NOICONS для dwMask и dwFlagsпараметры.

Эффект флага виден сразу.Нет необходимости ни перезагружать компьютер, ни "explorer.exe".Флаг также сохраняется после выхода из системы или перезагрузки.

Хитрый шаг 1).Раймонд Чен показывает код C ++ для этого в своей статье «Управление позициями значков на рабочем столе» , в частности, в своей функции FindDesktopFolderView().

Вот полный пример в виде консольного приложения,Он основан на коде Рэймонда Чена.Программа переключает видимость значков на рабочем столе при каждом запуске.

Код был протестирован в Windows 10 версии 1803.

Код «библиотеки»:

#include <ShlObj.h>     // Shell API
#include <atlcomcli.h>  // CComPtr & Co.
#include <string> 
#include <iostream> 
#include <system_error>

// 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<T>( msg ) };
}

// RAII wrapper to initialize/uninitialize COM
struct CComInit
{
    CComInit() { ThrowIfFailed( ::CoInitialize( nullptr ), "CoInitialize failed" ); }
    ~CComInit() { ::CoUninitialize(); }
    CComInit( CComInit const& ) = delete;
    CComInit& operator=( CComInit const& ) = delete;
};

// Query an interface from the desktop shell view.
void FindDesktopFolderView( REFIID riid, void **ppv, std::string const& interfaceName )
{
    CComPtr<IShellWindows> spShellWindows;
    ThrowIfFailed( 
        spShellWindows.CoCreateInstance( CLSID_ShellWindows ),
        "Failed to create IShellWindows instance" );

    CComVariant vtLoc( CSIDL_DESKTOP );
    CComVariant vtEmpty;
    long lhwnd;
    CComPtr<IDispatch> spdisp;
    ThrowIfFailed( 
        spShellWindows->FindWindowSW(
            &vtLoc, &vtEmpty, SWC_DESKTOP, &lhwnd, SWFO_NEEDDISPATCH, &spdisp ),
        "Failed to find desktop window" );

    CComQIPtr<IServiceProvider> spProv( spdisp );
    if( ! spProv )
        ThrowIfFailed( E_NOINTERFACE, "Failed to get IServiceProvider interface for desktop" );

    CComPtr<IShellBrowser> spBrowser;
    ThrowIfFailed( 
        spProv->QueryService( SID_STopLevelBrowser, IID_PPV_ARGS( &spBrowser ) ),
        "Failed to get IShellBrowser for desktop" );

    CComPtr<IShellView> 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<IFolderView2> 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;
}
0 голосов
/ 15 ноября 2018

Третий параметр касается не изменения настройки, а выбора поведения SHGetSetSettings().

FALSE получит значение текущей настройки и сохранит ее в ss, TRUE установит значение настройки в значение ss.

Так что в основном вам нужно сделать ss.fHideIcons = TRUE, а затем вызвать SHGetSetSettings(&ss, SSF_HIDEICONS, TRUE), чтобы установить его.

Я знаю, это странно, но, с другой стороны, позволяет одновременно изменять несколько настроек, поскольку SSF_* - это битовая маска.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...