WIC一覧の取得
上記の方法で、いろいろなファイルが読み込めることがわかったが、一方で、WIC経由で開くことのできる(はずの)ファイル形式の一覧がほしいことがある。端的に言えば、「ファイルを開く」ダイアログのフィルターを作ったりするときに、*.*では格好悪すぎる。
下記のコードは、レジストリの情報を読み込んで、WIC対応のファイル拡張子一覧を取得する。
#include <windows.h> #include <shlwapi.h> #include <shlguid.h> #include <tchar.h> #include <clocale> #include "atlbase.h" #include "atlstr.h" static CString RegGetString(HKEY hKey, LPCTSTR path, LPCTSTR name) { CRegKey regKey; if(regKey.Open(hKey, path, KEY_READ) != ERROR_SUCCESS) return _T(""); ULONG sz = 0; if(regKey.QueryStringValue(name, NULL, &sz) != ERROR_SUCCESS) return _T(""); CString s; regKey.QueryStringValue(name, s.GetBufferSetLength(sz), &sz); s.ReleaseBuffer(); return s; } int main() { std::setlocale(LC_ALL, ""); CString keyPath = _T("CLSID\\{7ED96837-96F0-4812-B211-F13C24117ED3}\\Instance"); CRegKey regKey; if(regKey.Open(HKEY_CLASSES_ROOT, keyPath, KEY_READ) == 0) { for(DWORD i = 0;; i++) { CString name; LPTSTR pName = name.GetBufferSetLength(MAX_PATH); ULONG sz = name.GetLength(); if(regKey.EnumKey(i, pName, &sz, NULL) != 0) break; name.ReleaseBuffer(); CString clsid = RegGetString(regKey, name, _T("CLSID")); if(clsid.GetLength() == 0) continue; keyPath.Format(_T("CLSID\\%s"), clsid); CString exts = RegGetString(HKEY_CLASSES_ROOT, keyPath, _T("FileExtensions")); if(exts.GetLength() == 0) continue; CString filters, prevTypeName; for(int p = 0; p >= 0;) { int np = exts.Find(_T(","), p); CString ext; if(np >= p) { ext = exts.Mid(p, np - p); p = np + 1; } else { ext = exts.Mid(p); p = -1; } CComPtr<IQueryAssociations> qa; AssocCreate( CLSID_QueryAssociations, __uuidof(IQueryAssociations), (void**)&qa); qa->Init(ASSOCF_INIT_DEFAULTTOSTAR, CT2W(ext), NULL, NULL); DWORD dwSize = 0; qa->GetString(ASSOCF_NOTRUNCATE, ASSOCSTR_FRIENDLYDOCNAME, NULL, NULL, &dwSize); CStringW typeNameW; qa->GetString(ASSOCF_NOTRUNCATE, ASSOCSTR_FRIENDLYDOCNAME, NULL, typeNameW.GetBufferSetLength(dwSize), &dwSize); typeNameW.ReleaseBuffer(); if(typeNameW.GetLength() == 0) continue; CString typeName = CW2T(typeNameW); if(prevTypeName == typeName) { filters += _T(";*") + ext; } else { if(prevTypeName.GetLength()) _tprintf(_T("%s (%s)\n"), prevTypeName, filters); prevTypeName = typeName; filters = _T("*") + ext; } } if(prevTypeName.GetLength()) _tprintf(_T("%s (%s)\n"), prevTypeName, filters); } regKey.Close(); } return 0; }
これで表示される拡張子一覧の例:
GIF イメージ (*.gif) PNG イメージ (*.png) LizardTech DjVu File (*.djvu;*.djv;*.sdjvu;*.sdjv) ビットマップ イメージ (*.bmp;*.dib) ペイントブラシの絵 (*.rle) JPEG イメージ (*.jpeg;*.jpe;*.jpg;*.jfif) EXIF ファイル (*.exif) 高画質の写真 (*.wdp) TIFF イメージ (*.tiff;*.tif) アイコン (*.ico) ICON ファイル (*.icon)