カタバミさんのプログラミングノート

日曜プログラマーがプログラミング関係のメモを記録するブログです。

C++でATLを使用してデスクトップの最初のオブジェクトの表示名を取得する

ATLを使用してデスクトップの最初のオブジェクトの表示名を取得するサンプルコードです。 開発環境:Windows 10、Microsoft Visual Studio 2019、C++17

#define STRICT
#include <Windows.h>
#include <ShlObj.h>

#include <atlbase.h>
#include <atlcom.h>

HRESULT CreateFirstObjectItemFromShellFolder(IShellFolder* pFolder, SHCONTF flags, IShellItem** ppItem);

int main()
{
    auto hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
    if (FAILED(hr))
    {
        return hr;
    }

    ATL::CComPtr<IShellFolder> pDesktop;
    hr = SHGetDesktopFolder(&pDesktop);
    if (FAILED(hr))
    {
        return hr;
    }

    ATL::CComPtr<IShellItem> pItem;
    hr = CreateFirstObjectItemFromShellFolder(pDesktop,
        SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDESUPERHIDDEN,
        &pItem);
    CComHeapPtr<WCHAR> pszName;
    hr = pItem->GetDisplayName(SIGDN::SIGDN_NORMALDISPLAY, &pszName);
    if (FAILED(hr))
    {
        return hr;
    }

    CoUninitialize();

    return hr;
}

// フォルダの最初のオブジェクトのIShellItemを返します。
HRESULT CreateFirstObjectItemFromShellFolder(
    IShellFolder* pFolder,
    SHCONTF flags,
    IShellItem** ppItem)
{
    *ppItem = nullptr;

    ATL::CComPtr<IEnumIDList> pEnumIDList;
    auto hr = pFolder->EnumObjects(
        nullptr,
        flags,
        &pEnumIDList);
    ATL::CComHeapPtr<ITEMIDLIST> pidl;
    if (FAILED(hr) || FAILED(hr = pEnumIDList->Next(1, &pidl, nullptr)))
    {
        return hr;
    }

    ATL::CComPtr<IShellItem> pItem;
    hr = SHCreateItemFromIDList(pidl, IID_PPV_ARGS(&pItem));
    if (SUCCEEDED(hr))
    {
        *ppItem = pItem.Detach();
    }

    return hr;
}