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

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

C++&ATLでフォルダのファイル名に使えない文字を取得する

概要

Windows 10でC++&ATLでフォルダのファイル名に使えない文字を取得するには次の手順を踏みます。具体的なサンプルコード等は後に示します。

  1. COMを初期化する。
  2. デスクトップのIShellFolderインターフェイスを取得する。
  3. ファイル名に使えない文字を取得したいフォルダ(目的フォルダ)のLPITEMIDLISTを取得する。
  4. デスクトップのIShellFolderインターフェイスから目的フォルダのIShellFolderインターフェイスを取得する。
  5. 目的フォルダのIShellFolderインターフェイスをIItemNameLimitsインターフェイスに変換する。
  6. IItemNameLimitsインターフェイスのGetValidCharactersメソッドを呼び出す。

サンプルコード

デスクトップのファイル名に使えない文字を取得するサンプルコードです。C++言語で空のWindows デスクトッププロジェクト(またはコンソールプロジェクト)を作成して、適当なcppファイルに以下のコードを記述して実行してください。

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

CComPtr<IItemNameLimits> CreateDesktopItemNameLimits()
{
    CComPtr<IShellFolder> desktop;
    auto hr = SHGetDesktopFolder(&desktop);
    if (FAILED(hr))
        throw new CAtlException(hr);
    return CComQIPtr<IItemNameLimits>(desktop);
}

HRESULT Run()
{
    try
    {
        auto desktopItemNameLimits = CreateDesktopItemNameLimits();
        CComHeapPtr<WCHAR> validChars;
        CComHeapPtr<WCHAR> invalidChars;
        auto hr = desktopItemNameLimits->GetValidCharacters(
            &validChars, &invalidChars);
        if (FAILED(hr))
            return hr;

        // TODO:ここでデスクトップの有効あるいは無効な文字を処理します。
        // validChars:   "\/:*?"<>|"
        // invalidChars: nullptr

        return S_OK;
    }
    catch (CAtlException& ex)
    {
        return ex.m_hr;
    }
}

int WINAPI wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int nCmdShow)
{
    auto hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
    if (SUCCEEDED(hr))
    {
        hr = Run();
        CoUninitialize();
    }
    return hr;
}

補足説明

CoTaskMemFree関数による解放を要求されるメモリのATLにおける管理

CComHeapPtrクラスで扱うことで解放処理をクラスに任せることができます。CComHeapPtrクラスは&演算子オーバーロードしており、関数やメソッドの引数に&<var>を渡すことで内部のポインタのポインタを返すことができます。