GetModuleFileName を使うと、実行されているプログラムの位置のパスと
プログラムのファイル名(*.exe)が一緒になっている文字列を取得できます。
例を挙げると、\project ディレクトリでsample.exe というプログラムを動かしているのなら
「\\project\\sample.exe」という文字列を取得できるわけですね。
('\'はエスケープ文字なので、'\\'と重ねて文字としての'\'になる)
そして、その文字列から左の「\\project\\」だけを取り出すよう処理すれば
実行ファイルの位置のパスが取得できるというわけです。
では以下に処理の方法を書いていきます。
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; void GetPathName(HWND) ; //グローバル変数なパス WCHAR wcPath[256];
GetPathName() は自作関数で、パスを取得したり操作したりする処理が入っています。
また、wcPath というパスを格納するグローバルを宣言します。
//スタイラスがタップされた case WM_LBUTTONDOWN: GetPathName(hwnd); return 0 ;
スタイラスが画面をタップすると、GetPathName() に行きます。
もっとも、グローバル変数を使うのだから、本来ならWM_CREATEなどで
1度呼べばいいだけなのですが。気分的にここで呼んでいます。
//==================== //実行モジュールのパスを取得 void GetPathName(HWND hwnd) { WCHAR wcStr[256]; int iLength=256; //実行モジュールのフルパスの取得 GetModuleFileName(NULL, wcStr, iLength); //MessageBox(hwnd,wcStr,_T("Path+Filename"),MB_YESNO|MB_ICONQUESTION);
GetPathName() 関数内です。GetModuleFileName は、
第三引数で指定した値の長さ分までで第二引数にパスを格納します。
wcStr にパスが入りました。ここでMessageBoxのコメントアウトを外すと
実行ファイル名入りの文字列を表示できます。
int i = 0; i = wcslen(wcStr); //後ろから一番はじめの\を探す while(i--){ if(wcStr[i] == '\\') break; } //Null文字で'\\'ごとファイル名を消去 wcStr[i] = '\0'; //文字列の最後尾に"\"をつけ足す wcscat(wcStr, _T("\\")); //wcPathを初期化しパスを格納 wcPath[0] = '\0'; wcscat(wcPath, wcStr); MessageBox(hwnd,wcPath,_T("Path name"),MB_YESNO|MB_ICONQUESTION); }
wcslenで文字列wcStr の長さを測り、wcStr の中身を右から左へ検索していっています。
iが0になる(ルートディレクトリ)か、'\'が見つかればループを抜けます。
その最後尾の"\"ごとNull にして"\*.exe" という部分を消去します。
そしてどちらも"\"を最後尾に足して、グローバル変数wcPath を初期化してから
wcscat でパスをwcPath にコピーします。
そしてその値をMessageBox で表示しています。
では以上を踏まえたソースを実行してみましょう。
実行しているプログラムの存在している場所のパスがちゃんと表示されていますね。
このプログラムをいろんなところで実行してみましょう。
日本語のパスが入っていても、正しく表示されるはずです。
これに読みたいファイル名を足せば実行ファイルと同じディレクトリのファイルも読めます。
■DWORD GetModuleFileName (HMODULE hModule, LPTSTR lpFilename, DWORD nSize);
・指定されたモジュールを含む実行ファイルの、フルパス名とファイル名を取得します。
第一引数 hModule には、モジュールのハンドルを指定します
第二引数 lpFilename には、モジュールのパス名とファイル名を受け取るバッファへのポインタを指定します
第三引数 nSize には、バッファのサイズをTCHAR 単位で指定します
戻り値 成功ならTCHAR 単位で文字列の長さが、失敗なら0 が返ります
■ソースの表示■
2005/6/12