C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 팁&트릭
C++Builder Programming Tip&Tricks
[750] [Dialog] 폴더 선택 다이얼로그 2
장성호 [nasilso] 12224 읽음    2008-03-04 02:43
보통 폴더 선택다이얼로그
아래 팁 처럼
http://cbuilder.borlandforum.com/impboard/impboard.dll?action=read&db=bcb_tip&no=150
shell32.dll의  SHBrowseForFolderA   API를 사용하여 한다.

위방법에는 #include <shlobj.h>  를 해줘야하는데
그러므로 인해 발생하는 컴파일문제를 해결해줘야하는 불편함이 있다.
http://cbuilder.borlandforum.com/impboard/impboard.dll?action=read&db=bcb_tip&no=601

그런데 VCL의 FileCtrl 유닛에 이미 폴더선택 Dialog를 Open하는 함수가 만들어져있다.
SelectDirectory 라는  함수이다.

bool __fastcall SelectDirectory(const AnsiString Caption, const WideString Root, AnsiString &Directory)
bool __fastcall SelectDirectory(AnsiString &Directory, TSelectDirOpts Options, int HelpCtx)

[첫번째함수 사용예]
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    String Dir;
    SelectDirectory("Select a directory", "", Dir);
    ShowMessage(Dir);
}

procedure TForm1.Button5Click(Sender: TObject);
var
  Dir: String;
begin
  SelectDirectory('Select a directory', '', Dir);
  ShowMessage(Dir);
end;


[두번째함수 사용예]
const SELDIRHELP = 1000;
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  AnsiString Dir = "C:\\Program Files\\MyApp";
  if (SelectDirectory(Dir, TSelectDirOpts() << sdAllowCreate << sdPerformCreate << sdPrompt,SELDIRHELP))
    Label1->Caption = Dir;
}

이 함수는 SHBrowseForFolderA  를 호출하는것이 아니라
VCL의 TSelectDirDlg를 Create해서 Show해주방식이다.


근데 이상한것은 첫번째 방법으로 할경우 항상 윈도우가 뜨는 위치가
가운데가 아닌 오른쪽 아랫쪽으로 좀 치우쳐져 있다. (Builder6  ,  Delphi 7  이상함 ,  2007은 정상)

그래서 간단히 PostMessage , MoveWindow로 폴더선택 다이얼로그가 가운데 오도록 해봤다.
//아래 댓글의 김권영 [devilica]님의 의견을 반영하여 약간 수정합니다.
void __fastcall TForm1::SelectDirectyShow(TMessage &Msg)
{
    HWND hwnd= FindWindow(NULL,"폴더 찾아보기");
    TRect rc;
    GetWindowRect(hwnd,&rc);

    // Screen가운데..
    TPoint ptScreen=Point(,(Screen->Width-rc.Width())/2,(Screen->Height-rc.Height())/2);
    MoveWindow(hwnd,ptScreen.x,ptScreen.y,rc.Width(),rc.Height(),true);

   //현재폼 가운데..
    TPoint ptForm=Point(this->Left + (this->Width - rc.Width()) / 2,this->Top + (this->Height - rc.Height()) / 2);
    MoveWindow(hwnd,ptForm.x,ptForm.y,rc.Width(),rc.Height(),true);

}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    String Dir;
    PostMessage(Handle,WM_USER+1,0,0);
    SelectDirectory("Select a directory", "", Dir);
    ShowMessage(Dir);
}
//---------------------------------------------------------------------------

문론  WM_USER+1 메세지를 Mesage Map에 등록해뒀다.

그럼
크레브 [kkol]   2008-03-05 00:28 X
유용한 정보 잘봤습니다. 요즘 연구에 열씸이네요~~ *^^*
DoyongID [doyongid]   2008-03-09 15:47 X
아~ 이런 방법이 있었군요.. 폴더 선택 함수 만드느라 삽질만 했는데...ㅠㅠㅠ
김권영 [devilica]   2009-05-09 21:56 X
윈도우가 영문일 경우엔 FindWindow의 두번째 인자 "폴더 찾아보기"를 Browse for Folder로 바꿔주셔야 하고
듀얼 스크린을 쓰는 경우엔 프로그램이 다른 윈도우에 뜰수 있으므로 MoveWindow의 두번째, 세번째 인자를
this->Left + (this->Width - rc.Width()) / 2,
this->Top + (this->Height - rc.Height()) / 2,
이렇게 수정해 주는것이 좋습니다.
neoshare [neoshare]   2011-03-17 14:48 X
다음의 함수에서는 올바른 위치에서 표시됩니다.
//---------------------------------------------------------------------------  
void __fastcall TForm1::Button1Click(TObject *Sender)  
{  
    String Dir;  
    SelectDirectory(Dir, [sdAllowCreate], 0) ;
    ShowMessage(Dir);  
}  
//--------------------------------------------------------------------------- 

+ -

관련 글 리스트
750 [Dialog] 폴더 선택 다이얼로그 2 장성호 12224 2008/03/04
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.