山本ワールド
Windowsプログラミング
アルゴリズム Vitual C++ 2008/2013によるWin32/Win64 APIレベルのプログラム 基礎 Vitual C++ 2008/2013によるAPIレベルのプログラム(32/64bit) Wix3でインストーラーを作る Visual C++ 2008 Standard Editonによるフォームアプリケーションのプログラム(32/64bit) Vitual C++ 2008 Standard EditonによるAPIレベルのプログラム(32/64bit) Windows 7対応 Visual C++ 2008 ExpressによるAPIレベルのプログラム Visual C++ 2005 ExpressによるAPIレベルのプログラム Visual C++ Versiosn 5 BORLAND C++ Windowsプログラム全般 Excel VBA その他エラーコードを日本語文章で表示する(FormatMessage)
概要
APIで発生したエラーの種類はGetLastError APIの戻り値で確認できますが、これはエラーコードなので、エラー原因を調べたり、文字列化するのが面倒です。
APIの中に、エラーコードに対するメッセージを取得できる便利なFormatMessageがあります。
エラーコードを引数で指定してFormatMessage APIを呼び出すと、エラーの内容を示す日本語の文章が取得できます。
FormatMessage APIは、printf関数の様に書式化文字の指定によりDWORD型を10進文字列に変換して表示することも可能です。
ただし、エラーコードを日本語文章に変換することと書式化文字列の指定は同時に指定することはできません。
本プログラムは、動作確認のため存在しないファイルを開こうとするときに発生するエラーコードを、GetLastError APIの戻り値により取得しFormatMessage APIにより日本語の文章を取得し表示するプログラムです。
以下に動作例を示します。
APIの中に、エラーコードに対するメッセージを取得できる便利なFormatMessageがあります。
エラーコードを引数で指定してFormatMessage APIを呼び出すと、エラーの内容を示す日本語の文章が取得できます。
FormatMessage APIは、printf関数の様に書式化文字の指定によりDWORD型を10進文字列に変換して表示することも可能です。
ただし、エラーコードを日本語文章に変換することと書式化文字列の指定は同時に指定することはできません。
本プログラムは、動作確認のため存在しないファイルを開こうとするときに発生するエラーコードを、GetLastError APIの戻り値により取得しFormatMessage APIにより日本語の文章を取得し表示するプログラムです。
以下に動作例を示します。
テスト環境
コンパイラ
Visual C++ 2008 Standard 32/64bitVisual C++ 2013 Express 32/64bit
プロジェクトの作成
Win32プロジェクト Windowsアプリケーション実行環境
Windows 8.1 Enterprise 64bitWindows 7 EnterPrise Service Pack 1 64bit
Windows Vista Ultimate Service Pack 2 32bit
Windows XP Professional Service Pack 3 32bit
プログラムソースの概要
_tWinMain関数
_tfopen_s関数によって、存在しないファイルを読み取り属性で開こうとします。_tfopen_s関数がエラーを返すので、error_dialog関数を呼び出しエラー原因を表示します。
error_dialog関数
GetLastError APIを呼び出し最後に発生したエラーコードを取得し、FormatMessage APIにより日本語文字列を取得後、MessageBox APIで表します。メッセージボックスが閉じられたら、FormatMessage APIにより動的に確保された文字列をLocalFree APIにより解放します。
FormatMessage
概要で触れたとおり、エラーコードの日本語文字列取得と、書式文字列による文字列の作成ができます。ここでは、第1引数でエラーコードの文字列取得(FORMAT_MESSAGE_IGNORE_INSERTSフラグ)、 文字列に必要なメモリはFormatMessage APIにより確保する(FORMAT_MESSAGE_ALLOCATE_BUFFERフラグ)ように指定して呼び出します。
このAPIの引数は以下の通りです。
DWORD FormatMessage(
DWORD dwFlags, // 入力元と処理方法のオプション
LPCVOID lpSource, // メッセージの入力元
DWORD dwMessageId, // メッセージ識別子
DWORD dwLanguageId, // 言語識別子
LPTSTR lpBuffer, // メッセージバッファ
DWORD nSize, // メッセージバッファの最大サイズ
va_list *Arguments // 複数のメッセージ挿入シーケンスからなる配列
);
プログラムソース
// エラーコードに対するエラーメッセージを取得する
// Visual C++ 2008/2013 Express
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
// APIのエラーコードからエラーメッセージを作成しダイアログボックスに表示
void error_dialog(HWND hWnd);
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPreInst, TCHAR* lpszCmdLine, int nCmdShow){
FILE* fp; // 存在しないファイルを開こうとしてエラーを発生させる。
if (_tfopen_s(&fp, _TEXT("この世に存在しない幽霊ファイル"), _TEXT("r"))){
error_dialog(0);
}
return 0;
}
// エラーコードに対するメッセージを表示
void error_dialog(HWND hWnd){
DWORD errorcode = GetLastError();
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER // テキストのメモリ割り当てを要求する
| FORMAT_MESSAGE_FROM_SYSTEM // エラーメッセージはWindowsが用意しているものを使用
| FORMAT_MESSAGE_IGNORE_INSERTS,// 次の引数を無視してエラーコードに対するエラーメッセージを作成する
NULL, errorcode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),// 言語を指定
(LPTSTR)&lpMsgBuf, // メッセージテキストが保存されるバッファへのポインタ
0,
NULL);
MessageBox(hWnd, (LPCTSTR)lpMsgBuf, _TEXT("エラー"), MB_OK | MB_ICONINFORMATION);
LocalFree(lpMsgBuf);
}
ソースファイルと実行ファイルのダウンロード
Copyright (C) 2012 山本ワールド All Rights Reserved.