Windows のデスクトップアプリ開発において,OS の「インデックスのオプション」設定画面をプログラム内部から直接呼び出したいケースがあります.
純粋な C++(Win32 API / MFC)環境からこれを実現する場合,::ShellExecute をどのように構成すれば良いか,また呼び出し失敗時にシステムのエラーメッセージを正しく取得してハンドリングするための実装ノウハウについての備忘録です.
1. ::ShellExecute によるコントロールパネル項目の起動方法
Windows のコントロールパネルに属する特定の機能やダイアログ(正規名を持つアイテム)は,コマンドプロンプト等で control.exe /name に続けてオブジェクト名を指定することで直接起動できます.
「インデックスのオプション」を開く場合,内部的には以下のパラメータ構成でプロセスを立ち上げることで実現可能です.
■ 起動用パラメータの構成
- 実行ファイル名(File):
control.exe - 引数(Parameters):
/name Microsoft.IndexingOptions - 操作(Operation):
open(またはNULL)
これを ::ShellExecute に渡すことで,.NET等に依存せず,純粋なネイティブ C++ コードから OS のインデックス設定画面を直接呼び出すことが可能になります.
2. 実行成否の判定と ::FormatMessage によるエラー処理の自動化
::ShellExecute は,呼び出しに失敗した場合の戻り値(HINSTANCE)の扱いが特殊であり,正しいエラー処理の実装にはコツが必要です.
■ 戻り値による成否判定
-
::ShellExecuteの戻り値は,呼び出し成功時は 32 より大きい値が返されます. - 32 以下の値が返された場合は何らかの理由で起動に失敗しているため,即座に
::GetLastError()を呼び出してシステムのエラーコードを取得する必要があります.
■ システムエラーメッセージの動的取得
- 取得したエラーコード(DWORD)をそのまま数値としてダイアログ表示しても原因の特定が困難です.
- Win32 API の
::FormatMessageを利用し,FORMAT_MESSAGE_FROM_SYSTEMフラグを適切に指定することで,OS が保持している「ファイルが見つかりません」といった人間が読める正確なエラーメッセージ文字列に動的に変換し,安全にバッファを解放してハンドリングする機構を構築しておくとデバッグが非常に容易になります.
ソースコードの全容とサンプルプロジェクトの配布先
::ShellExecute を呼び出すための具体的な引数設定コード(CShellEDlg::OnExecute)や,::FormatMessage で取得したエラーメッセージを安全にハンドリング・解放する CString 汎用ラッパー関数の実装全文,実際の動作確認用ダイアログ(ShellE.exe)のスクリーンショット,およびそのままビルドして実験できるプロジェクト一式(ShellE.zip)は,私のブログにて詳細な公式ドキュメント(Canonical Names)の解説とともに公開しています.
実際のソースコードや検証用のプロジェクトファイルが必要な方は,ぜひ以下のリンク先をご参照ください.