해답이 아닌 답변입니다.
TOpenDialog를 보면 최종적으로 comdlg32.dll에 있는 함수를 호출합니다.
FontDialog 및 ColorDialog 모두 마찬가지죠
결론적으로 comdlg32.dll 에 있는 API를 직접 사용하여
DLL안에서 OpenDialog를 Execute할때 껌뻑거리는 문제는 해결할수 있습니다.
TOpenDialog 에서 사용하는 comdlg32.dll에 있는 API는 GetOpenFileNameA 입니다.
아래 간단한 사용예가 있습니다.
1. LoadLibrary로 comdlg32.dll를 Load한다.
2. GetProcAddress로 comdlg32.dll 에서 GetOpenFileNameA 함수를 찾는다.
3. OPENFILENAME 구조체에 적절한 data를 설정한다.
4. 앞에 찾은 GetOpenFileNameA 함수를 호출한다. 호출하면서 OPENFILENAME 구조체를 넘겨준다.
5. FreeLibrary로 comdlg32.dll를 Free한다.
void __fastcall TForm1::Button1Click(TObject *Sender)
{
OPENFILENAME OFN;
TDialogFunc GetOpenFileNameAFunc;
HINSTANCE hInstcomdlg32;
typedef BOOL __stdcall ( *TDialogFunc)( OPENFILENAME *FN);
if(hInstcomdlg32==NULL)hInstcomdlg32=LoadLibrary("comdlg32.dll");
if(hInstcomdlg32==NULL)return;
memset(&OFN, 0, sizeof(OPENFILENAME));
OFN.lStructSize = sizeof(OPENFILENAME); // openfilename 구조체의 크기 지정
OFN.hwndOwner=Handle; //대화상자의 소유자. 소유자 윈도우가 없을경우 null
OFN.nFilterIndex=1; //파일 콤보 박스에서 사용할 필터의 인덱스. 1이면 lpstrfilter의 첫번재 필터.
OFN.lpstrFilter="텍스트 파일\0*.txt\0모든 파일(*.*)\0*.*\0"; //파일 형식 콤보 박스에 나타낼 필터
OFN.lpstrFile="C:\\Zzang\\Test.txt"; //파일 이름 에디트에 처음 나타낼 파일명
OFN.nMaxFile=MAX_PATH; //lpstrfile 멤버의 길이.
OFN.lpstrDefExt="txt"; //사용자가 확장자를 입력하지 않았을 경우 디폴트 확장자 지정
if(GetOpenFileNameAFunc==NULL)
GetOpenFileNameAFunc=(TDialogFunc)GetProcAddress(hInstcomdlg32,"GetOpenFileNameA");
if( GetOpenFileNameAFunc!=NULL)
{
if(GetOpenFileNameAFunc(&OFN))
{
ShowMessage(OFN.lpstrFile);
}
else
{
ShowMessage("실패");
}
}
FreeLibrary(hInstcomdlg32);
hInstcomdlg32=NULL;
GetOpenFileNameAFunc=NULL;
}
//---------------------------------------------------------------------------
그런데 위 방법에는 몇가지 심각한 문제가 있습니다.
저도 처음써보는 API이기 때문에 잘모릅니다.
문제점들
1. Open할때 Folder를 변경하면 다음 호출때 Default Folder설정이 제대로 안먹혀 OpenDialog가 뜨지 않는 문제
==> 아마 설정에 무슨 문제가 있는것같습니다. 빠뜨렸거나..
2. Dialog화면이 Screen한가운데 오지 않는 문제 등등...
==> CallBack함수를 걸어서 넘오는 HWND를 가지고 윈도우를 screen한가운데(또는 원하는 위치에) 배치시켜야 합니다.
그럼....
시몬 님이 쓰신 글 :
: 폼을 포함한 DLL을 만들었습니다.
: DLL에 있는 폼에서는 TOpenDialog를 사용한 파일열기 기능이 있구요.
:
: 이 DLL을 로드하여 폼을 띄워서 사용하는데 잘 동작합니다.
: 그런데 딱 하나 TOpenDialog를 Execute()해서 다이얼로그가 띄웠다가 닫으면 갑자기
: DLL을 로드해서 띄운 폼이 없어져 버립니다.
: 그냥 없어지는게 아니라 그 자리에는 복원(repaint)이 안됩니다. - 스샷 첨부파일을 올렸습니다
:
: 이런 현상이 왜 일어날까요???
: 그런데 더 이상한건 사라져 버린 윈도우에 메세지도 잘 도착하고 그 폼에 public으로 선언된 함수도
: 잘 동작합니다.
: 현재 위치하고 사이즈도 확인을 했구요..
:
: 제발 고수님들 조그만 조언이라도 부탁드립니다.
|