環境 VS2005 SDK
現在GetOpenFileName使用後にファイルが開けないという症状に
悩まされています。
具体的にはGetOpenFileNameが成功すると後続でCreateFileが
失敗するという現象です。
ただ後にGetOpenFileNameで開いた場合は成功するようです。
以下に該当部分をあげます。
まず
OPENFILENAME ofn = {0};
static TCHAR strFile[256];
static TCHAR FileTitle[256];
HANDLE hFile;
ofn.lStructSize = sizeof (OPENFILENAME);
ofn.hwndOwner = hwnd;
ofn.lpstrFilter = TEXT(All files (*.*)\0*.*\0\0);
ofn.lpstrFile = strFile;
ofn.lpstrFileTitle = FileTitle;
ofn.nMaxFile = sizeof(strFile);
ofn.nMaxFileTitle = sizeof(FileTitle);
ofn.Flags = OFN_FILEMUSTEXIST|OFN_HIDEREADONLY;
GetOpenFileName(&ofn);
hFile= CreateFile(strFile, GENERIC_READ, FILE_SHARE_READ , NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
if(hFile==INVALID_HANDLE_VALUE){return 1;}
CreateFile(strFile, GENERIC_READ, FILE_SHARE_READ , NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL );
CloseHandle(hFile);
としてファイルを開き閉じます。
その後に
hFile = CreateFile(TEXT(test.txt), GENERIC_READ, FILE_SHARE_READ , NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
if (hFile == INVALID_HANDLE_VALUE){return 1;}
CloseHandle(hFile);
とするとtest.txtのファイルがまったく開けない。
GetOpenFileNameが失敗したらtest.txtが正常に開けるというところから
GetOpenFileNameが関係しているようなのは分かりましたが
原因は分からない状況です。またGetOpenFileNameを再設定し
後続のtest.txtファイルを開いた場合はうまくいきますが、
やはりCreateFile(strFile, ~のstrFile部分をTEXT(test.txt)のように
ファイルへのパスを記述した場合は失敗してしまいます。
あとWindows XP SP2 + Adobe Reader 7でファイルを開くダイアログが
正常に機能しないバグにはすでに遭遇したためAdobe Reader 7は削除してあります。
CreateFileの失敗時にはGetLastErrorで原因が取得可能ですが,どうなっていますか?
DWORD a0;
TCHAR a1[128]={0};
//
//~
hFile = CreateFile(TEXT(test.txt), GENERIC_READ, FILE_SHARE_READ , NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
if (hFile == INVALID_HANDLE_VALUE){
a0=GetLastError();
wsprintf(a1, TEXT(%d) ,a0);
MessageBox(NULL , a1,TEXT(メッセージ) , MB_OK);
return 1;
}
のようにGetLastErrorを使用した所、数字の2が帰ってきました。
Error.hを調べてみたところERROR_FILE_NOT_FOUNDと記述してありました。
>hFile = CreateFile(TEXT(test.txt), GENERIC_READ, FILE_SHARE_READ , NULL,
フルパスで指定してもだめですか?
GetOpenFileName に成功すると、カレントディレクトリが変更されます。
単に、GetOpenFileNameを使ったときにカレントディレクトリが移動してしまうから
今までフルパスして出でなくても動いていたものが動かないようになっただけでしょ
う。
対策としては、
・test.txtフルパス指定に変える
exeから相対的に見えるファイルであれば、GetModuleFileName からパスを作成する。
もしくは、カレントディレクトリをGetOpenFileNameの前に覚えておいて
そこからフルパスを作成する。
それができなければべた書きにする。
(べた書きにもiniファイルやレジストリ等を使っておくとよいかな)
・カレントディレクトリを元に戻す
カレントディレクトリをGetOpenFileNameの前に覚えておいて
SetCurrentDirectoryで元に戻す
・GetOpenFileNameでカレントディレクトリが移動しないようにする
OPENFILENAME構造体のFlagにOFN_NOCHANGEDIRを追加する。
・test.txtをパスが通っているディレクトリに置く(システムフォルダ)
のいずれかになるでしょう。
■isshiさん
情報提供ありがとうございます。
指摘されたようにGetOpenFileNameでカレントディレクトリの
移動が原因だったようです。
■Blueさん
>OPENFILENAME構造体のFlagにOFN_NOCHANGEDIRを追加する。
でうまくいきました。
多数の解決法の情報提供に感謝します。
>GetOpenFileName に成功すると、カレントディレクトリが変更されます。
GetOpenFileNameのカレントディレクトリ変更動作ですが、ダイアログ開いている
最中で既に変更されていたりします。
マルチスレッドのときには注意が必要だったりします。