如何在C ++中使用Windows API隐藏桌面图标? [英] How to hide Desktop icons with Windows API in C++?

查看:487
本文介绍了如何在C ++中使用Windows API隐藏桌面图标?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我找到的答案链接到 fHideIcon ,但是我在Microsoft页面上找到这些链接的404错误。



我也尝试过:

  SHELLSTATE ss; 
SecureZeroMemory(& ss,sizeof(ss));
SHGetSetSettings(& ss,SSF_HIDEICONS,TRUE);

但这没有用。

有谁知道该怎么做

解决方案

以下使用官方Shell API的方法有些涉及,但即使在Windows 10下也可以使用。 p>

步骤:


  1. 获取 IFolderView2 界面桌面(自Windows Vista开始受支持)。

  2. 致电 IFolderView2 :: SetCurrentFolderFlags() FWF_NOICONS $ c> dwMask 和 dwFlags 参数等。

该标志的效果立即可见。无需重新启动计算机或 explorer.exe。注销或重新启动后,该标志也会保留。



棘手的是步骤1)。 Raymond Chen在他的文章操纵桌面图标 ,特别是在他的 FindDesktopFolderView()函数中。



下面是一个完整的示例控制台应用程序的形式。它基于Raymond Chen的代码。该程序在每次运行时都会切换桌面图标的可见性。



该代码已在Windows 10版本1803下经过测试。



库代码:

  #include< ShlObj.h> // Shell API 
#include< atlcomcli.h> // CComPtr& Co.
#include< string>
#include< iostream>
#include< system_error>

//如果HRESULT指示失败,则引发std :: system_error。
模板<类型名称T>
void ThrowIfFailed(HRESULT hr,T&& msg)
{
if(FAILED(hr))
throw std :: system_error {hr,std :: system_category() ,std :: forward< T(msg)} ;;
}

// RAII包装器来初始化/取消初始化COM
结构CComInit
{
CComInit(){ThrowIfFailed(:: CoInitialize(nullptr), CoInitialize失败); }
〜CComInit(){:: CoUninitialize(); }
CComInit(CComInit const&)=删除;
CComInit&运算符=(CComInit const&)=删除;
};

//从桌面外壳视图查询接口。
void FindDesktopFolderView(REFIID riid,void ** ppv,std :: string const& interfaceName)
{
CComPtr< IShellWindows> spShellWindows;
ThrowIfFailed(
spShellWindows.CoCreateInstance(CLSID_ShellWindows),
无法创建IShellWindows实例);

CComVariant vtLoc(CSIDL_DESKTOP);
CComVariant vtEmpty;
long lhwnd;
CComPtr< IDispatch> spdisp;
ThrowIfFailed(
spShellWindows-> FindWindowSW(
& vtLoc,& vtEmpty,SWC_DESKTOP,& lhwnd,SWFO_NEEDDISPATCH,& spdisp),
找不到桌面窗口);

CComQIPtr< IServiceProvider> spProv(spdisp);
if(!spProv)
ThrowIfFailed(E_NOINTERFACE,无法获得用于桌面的IServiceProvider接口);

CComPtr< IShellBrowser> spBrowser;
ThrowIfFailed(
spProv-> QueryService(SID_STopLevelBrowser,IID_PPV_ARGS(& spBrowser)),
无法为桌面获取IShellBrowser);

CComPtr< IShellView> spView;
ThrowIfFailed(
spBrowser-> QueryActiveShellView(& spView),
无法为桌面查询IShellView);

ThrowIfFailed(
spView-> QueryInterface(riid,ppv),
无法查询桌面IShellView的接口 + interfaceName);
}

使用上述代码切换桌面图标的示例:

  void ToggleDesktopIcons()
{
CComPtr< IFolderView2> spView;
FindDesktopFolderView(IID_PPV_ARGS(& spView), IFolderView2);

DWORD标志= 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<< 桌面图标已切换。\n;
}
catch(std :: system_error const& e)
{
std :: cout<< 错误:<< e.what()<< ,错误代码:<< e.code()<< \n;
返回1;
}

返回0;
}


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;
SecureZeroMemory(&ss, sizeof(ss));
SHGetSetSettings(&ss, SSF_HIDEICONS, TRUE);

But that didn't work.
Does anyone know how to do this?

解决方案

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

这篇关于如何在C ++中使用Windows API隐藏桌面图标?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆