How to hide Desktop icons with Windows API in C++?

前端 未结 3 1434
走了就别回头了
走了就别回头了 2020-12-22 10:29

The answers I\'ve found link to fHideIcon, but I get a 404 error on Microsoft\'s page for those links.

I\'ve also tried:

SHELLSTATE ss;         


        
相关标签:
3条回答
  • 2020-12-22 11:09

    The third parameter isn't about changing the setting, it's to select the SHGetSetSettings() behavior.

    FALSE will get the value of the current setting and store it in ss, TRUE will set the value of the setting to what is in ss.

    So basically you have to do ss.fHideIcons = TRUE and then call SHGetSetSettings(&ss, SSF_HIDEICONS, TRUE) to set it.

    I know, it's weird, but on the other hand it allows you to change multiple settings simultaneously because SSF_* is a bitmask.

    0 讨论(0)
  • 2020-12-22 11:09

    The following seems to work (adapted from 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);
    }
    

    Please note: this approach is not supported by Microsoft and disables right-clicking on ths desktop.

    0 讨论(0)
  • 2020-12-22 11:17

    The following approach which uses the official shell API is a little bit involved, but works even under Windows 10.

    Steps:

    1. Get the IFolderView2 interface of the desktop (supported since Windows Vista).
    2. Call IFolderView2::SetCurrentFolderFlags() with FWF_NOICONS for both the dwMask and dwFlags parameters.

    The effect of the flag is visible immediately. There is no need to restart the computer nor "explorer.exe". The flag also persists after logoff or reboot.

    The tricky thing is step 1). Raymond Chen shows C++ code for that in his article "Manipulating the positions of desktop icons", specifically in his FindDesktopFolderView() function.

    Here is a full example in form of a console application. It is based on Raymond Chen's code. The program toggles the visibility of the desktop icons each time it is run.

    The code has been tested under Windows 10 Version 1803.

    "Library" code:

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

    Example to toggle desktop icons using the above code:

    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 讨论(0)
提交回复
热议问题