Время ожидания истекло до получения соединения из пула, но пул не заполнен

Существует официальный API для подобных действий, он называется API-интерфейсом оболочки. Это должно быть предпочтительнее, чем манипулирование реестром и подход FindWindow / SendMessage, как очень хрупкие «решения», которые имеют тенденцию ломаться с будущими версиями Windows (для последних это уже подтвердили комментаторы).

Шаги:

  1. Получите интерфейс IFolderView2 рабочего стола (поддерживается с Windows Vista).
  2. Вызовите 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;
}

11
задан VMAtm 3 February 2012 в 21:05
поделиться