Windows Vistaから追加されたAPIの1つのSHOpenWithDialogがある。これは「ファイルを開くプログラムの選択」ダイアログを表示するために用意された。ちょっと前まではAPI名が「OpenAsDialog」となっていたが、SHOpenWithDialogに変更されている。
このAPIでは引数にOPENASINFO構造体を利用する。この構造体はメンバ変数としてTCHAR*型が利用されているが...実際にテストしたところUnicodeしか受け付けない。そのため下に用意したテストコードのように(TCHAR*)でキャストする必要がある。
また、実行時には図のようなダイアログが表示される。しかし、プログラムを選択しても指定したファイルは開かない。SHOpenWithDialogの戻り値はS_FALSEが返る(この値は成功を示すので戻り値をSUCCEEDED(hr)のようにしてチェックできないことに注意!)。
ファイルが開かないのは単純にSHOpenWithDialogの使い方を間違えているだけかもしれない。しかし以上のことを考えてみると、Windows VistaのAPI実装にはまだ未完成の部分があるのかもしれない。
#include "shlobj.h" bool Test(void) { HMODULE hModule; HRESULT hr; HRESULT (CALLBACK* pfnSHOpenWithDialog)(HWND hwndParent,POPENASINFO poainfo); hModule = ::LoadLibrary(_T("shell32.dll")); if(hModule == NULL) return false; //MSDNではAPI名が「OpenAsDialog」のことがあるが、VistaではSHOpenWithDialogのみ実装されている (*(FARPROC*)&pfnSHOpenWithDialog) = ::GetProcAddress(hModule,"SHOpenWithDialog"); if(pfnSHOpenWithDialog) { OPENASINFO sInfo; ::ZeroMemory(&sInfo,sizeof(OPENASINFO)); sInfo.pcszFile = (TCHAR*)L"c:\\aa.txt"; //Unicodeで指定 sInfo.pcszClass = NULL; sInfo.oaifInFlags = OAIF_ALLOW_REGISTRATION; //S_FALSEが返ることがある! hr = pfnSHOpenWithDialog(NULL,&sInfo); } else hr = E_FAIL; ::FreeLibrary(hModule); return (hr == S_OK) ? true : false; }