[英]How to hide Desktop icons with Windows API in C++?
我找到了指向fHideIcon
链接,但我在 Microsoft 的页面上收到了这些链接的 404 错误。
我也试过:
SHELLSTATE ss;
SecureZeroMemory(&ss, sizeof(ss));
SHGetSetSettings(&ss, SSF_HIDEICONS, TRUE);
但这没有用。
有谁知道如何做到这一点?
以下使用官方 shell API 的方法有点复杂,但即使在 Windows 10 下也能工作。
脚步:
IFolderView2
界面(从 Windows Vista 开始支持)。FWF_NOICONS
为dwMask
和dwFlags
参数调用IFolderView2::SetCurrentFolderFlags()
。旗帜的效果立即可见。 无需重新启动计算机或“explorer.exe”。 该标志在注销或重新启动后仍然存在。
棘手的是步骤 1)。 Raymond Chen 在他的文章“操作桌面图标的位置”中展示了 C++ 代码,特别是在他的FindDesktopFolderView()
函数中。
这是控制台应用程序形式的完整示例。 它基于 Raymond Chen 的代码。 该程序每次运行时都会切换桌面图标的可见性。
代码已在 Windows 10 Version 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;
}
第三个参数不是关于更改设置,而是选择SHGetSetSettings()
行为。
FALSE
将获取当前设置的值并将其存储在ss
, TRUE
将设置的值设置为ss
。
所以基本上你必须做ss.fHideIcons = TRUE
然后调用SHGetSetSettings(&ss, SSF_HIDEICONS, TRUE)
来设置它。
我知道,这很奇怪,但另一方面,它允许您同时更改多个设置,因为SSF_*
是位掩码。
以下似乎有效(改编自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 不支持此方法并禁用在桌面上右键单击。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.