是否有任何WinAPI功能来修改桌面图标大小?

Ser*_*ron 0 winapi

也许我没有做好搜索,但找不到任何WinAPI功能来修改桌面图标大小.如果没有,你能建议一种方法来实现吗?

zet*_*t42 5

获取IFolderView2桌面界面并调用其SetViewModeAndIconSize()方法更改图标大小.

困难的是如何获得IFolderView2桌面界面.幸运的是,Raymond Chen来救援.他有一篇关于操纵桌面图标位置的文章,我们只需要其FindDesktopFolderView()功能代码.

我已经修改了他的代码并增加了错误处理.虽然这个问题标记为"C",但我正在使用C++来回答它,因为C++对于COM编程更实用.

首先是必需的包含和一些帮助函数.

#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
{
    HRESULT hr = ::CoInitialize( nullptr );
    CComInit() { ThrowIfFailed( hr, "CoInitialize failed" ); }
    ~CComInit() { ::CoUninitialize(); }
};
Run Code Online (Sandbox Code Playgroud)

现在归结为细节,FindDesktopFolderView():

// 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 );
}
Run Code Online (Sandbox Code Playgroud)

用法示例:

以下示例将桌面图标大小设置为16,甚至小于通过桌面上下文菜单可以实现的大小.

你也可以享受一些乐趣并设置viewMode其他东西,比如说FVM_DETAILS将桌面切换到详细信息视图.通过常规用户界面甚至无法做到这一点.

int main()
{
    try
    {
        CComInit coInit;

        CComPtr<IFolderView2> spView;
        FindDesktopFolderView( IID_PPV_ARGS( &spView ), "IFolderView2" );

        FOLDERVIEWMODE viewMode = FVM_AUTO;
        int iconSize = 0;
        ThrowIfFailed( 
            spView->GetViewModeAndIconSize( &viewMode, &iconSize ),
            "GetViewModeAndIconSize failed" );
        std::cout << "Current view mode: " << viewMode << ", icon size: " << iconSize << '\n';

        ThrowIfFailed( 
            spView->SetViewModeAndIconSize( viewMode, 16 ),
            "SetViewModeAndIconSize failed" );

        return 0;
    }
    catch( std::system_error const& e )
    {
        std::cout << "ERROR: " << e.what() << ", error code: " << e.code() << "\n";
        return 1;
    }
}
Run Code Online (Sandbox Code Playgroud)