2

その少し奇妙です。さて、私はいくつかのファイルストリームをバックグラウンドで開いたままにする「SceneManager」クラスを持つOGREゲームエンジンを使用しています。GetOpenFileName()を使用する直前にこれらのストリームを使用すると、これらのストリームは正常に機能しますが、GetOpenFileName()の後でこれらのストリームを使用しようとすると、これらのストリームが閉じていることがわかります。GetOpenFileName()が私のバックグラウンドストリームを強制終了する理由を誰かが明らかにすることはできますか?

String Submerge::showFileDialog(char* filters, bool savedialog, char* title)
// need to tweak flags for open/save
{
OPENFILENAME ofn ;
char szFile[255] ;
HWND hwnd = NULL;
//getOgre()->getAutoCreatedWindow()->getCustomAttribute("WINDOW", &hwnd);

ZeroMemory( &ofn , sizeof(ofn) );
ofn.hwndOwner = hwnd;
ofn.lStructSize = sizeof ( ofn );
ofn.lpstrFile = szFile;
ofn.lpstrFile[0] = '\0';
ofn.nMaxFile = sizeof( szFile );
ofn.lpstrFilter = filters ? filters : "All files\0*.*\0";
ofn.nFilterIndex =1;
ofn.lpstrFileTitle = NULL ;
ofn.nMaxFileTitle = 0 ;
ofn.lpstrInitialDir=NULL ;
if(title!=NULL)
    ofn.lpstrTitle=title;
//ofn.Flags = OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST ;

MeshLoadTest(); // this is where i use background file streams
bool success = false;
if(savedialog)
    success = GetSaveFileName( &ofn );
else
    success = GetOpenFileName( &ofn );
MeshLoadTest(); // this is where i use background file streams

if(!success)
    return "";
String str;
str.append(ofn.lpstrFile);
return str;
return "";
}
4

3 に答える 3

3

GetOpenFileName()プロセス全体の現在のディレクトリを変更できること、および変更することに注意してください。これは、他に何が起こっているかを妨げている可能性があります。

と呼ばれるオプションがありますが、ドキュメントOFN_NOCHANGEDIRによると、それは効果がありません:

ユーザーがファイルの検索中にディレクトリを変更した場合、現在のディレクトリを元の値に復元します。 Windows NT 4.0 / 2000 / XP:このフラグはGetOpenFileNameには無効です。

この呼び出しを行う前後に、現在のディレクトリを確認する必要があります。それが変わる場合、これはあなたの問題かもしれません。その場合は、への呼び出しの周りに現在のディレクトリを保存および復元するコードを追加しますGetOpenFileName()

于 2009-12-22T10:52:23.160 に答える
1

みんなありがとう、そして私は別の発見をしました、私はOFN_NOCHANGEDIRを使用しました、そして問題は実際に解決されました(WinXP SP3)、多分彼らは時々MSDNドキュメントを更新する必要があります:P

于 2009-12-22T11:39:25.860 に答える
0

(これは実際には、現在のディレクトリの変更で問題の原因が特定された他の回答に対する回答です)

現在のディレクトリを保存するには:

#define ARRSIZE(arr) (sizeof(arr)/sizeof(*(arr)))

//...

TCHAR curDir[MAX_PATH];
DWORD ret;
ret=GetCurrentDirectory(ARRSIZE(curDir),curDir);
if(ret==0)
{
    // The function falied for some reason (see GetLastError), handle the error
}
else if(ret>ARRSIZE(curDir))
{
    // The function failed because the buffer is too small, implementation of a function that uses dynamic allocation left to the reader
}
else
{
    // Now the current path is in curDir
}

パスを復元するには、次の手順を実行します。

if(!SetCurrentDirectory(curDir))
{
    // The function failed, handle the error
}

ヒント:アプリケーションの最初から文字の代わりにTCHARSと汎用テキストマッピング関数を使用してください。これにより、アプリケーションがUnicodeパスと互換性を持つ必要がある場合に、将来多くの問題を回避できます。

于 2009-12-22T11:22:45.723 に答える