也许我没有做好搜索,但找不到任何WinAPI功能来修改桌面图标大小。如果没有,你能建议一种方法来实现吗?
答案 0 :(得分:5)
获取桌面的IFolderView2
界面并调用其SetViewModeAndIconSize()
方法更改图标大小。
困难的是如何获取桌面的IFolderView2
界面。幸运的是,Raymond Chen来救援。他有一篇关于manipulating the positions of desktop icons的文章,我们只需要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(); }
};
现在归结为细节, 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 );
}
用法示例:
以下示例将桌面图标大小设置为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;
}
}