[MFC] 디렉토리 선택 가능한 대화상자(SHBrowseForFolder)
디렉토리만 선택해야하는 경우 아래와 같은 박스가 필요함. 아래 코드에서 약간은 수정하여 사용할 수 있습니다.
플래그 설정으로 디렉토리, 파일 선택을 할 수 있습니다. (파일도 가능함)
[Source Code]
:
static int CALLBACK BrowseCallbakProc(HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM pData)
{
switch(uMsg)
{
case BFFM_VALIDATEFAILED:
CString strText;
strText.Format("%s", reinterpret_cast<LPTSTR>(lParam));
AfxMessageBox(strText);
break;
}
return 0;
}
void CNet_ProgDlg::OnButton6() // 여기는 클레스, 함수 이름이 바꾸어야 합니다.
{
// TODO: Add your control notification handler code here
ITEMIDLIST *pildBrowse;
char pszPathname[MAX_PATH];
LPITEMIDLIST pidl = NULL;
BROWSEINFO bInfo;
ZeroMemory( &bInfo, sizeof(BROWSEINFO) );
SHPathToPidl( CSIDL_DESKTOP, &pidl ); // 루트 디렉토리 설정 부분.
bInfo.hwndOwner = GetSafeHwnd();
bInfo.pidlRoot = pidl;
bInfo.pszDisplayName = pszPathname;
bInfo.lpszTitle = "Please Select Directory....";
bInfo.lpfn = BrowseCallbakProc;
// 콜백함수가 필요없다면 NULL이나 지움. 위의 static int 함수 필요 없어짐
bInfo.ulFlags = BIF_RETURNONLYFSDIRS | BIF_EDITBOX | BIF_VALIDATE ;
// 디렉토리만 설정가능하도록 하였습니다... 플래그 설정은 맨 아래 참조하세요, 또는 MSDN
pildBrowse = ::SHBrowseForFolder(&bInfo);
if( pildBrowse != NULL )
{
SHGetPathFromIDList(pildBrowse, pszPathname);
m_strDownFolder = (LPCTSTR)pszPathname; // 선택한 폴더 또는 파일… 이 부분을 목적에 맞게 수정.
UpdateData(FALSE);
}
}
HRESULT CNet_ProgDlg::SHPathToPidl( LPCTSTR szPath, LPITEMIDLIST* ppidl ) // 여기는 클레스 이름 바꾸어야 함.
{
LPSHELLFOLDER pShellFolder = NULL;
OLECHAR wszPath[MAX_PATH] = {0};
ULONG nCharsParsed = 0;
HRESULT hr = SHGetDesktopFolder( &pShellFolder );
if( FAILED(hr) ) return FALSE;
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, szPath, -1, wszPath, MAX_PATH );
hr = pShellFolder->ParseDisplayName( NULL, NULL, wszPath, &nCharsParsed, ppidl, NULL );
pShellFolder->Release();
return hr;
}
:
/*
// Browsing for directory.
#define BIF_RETURNONLYFSDIRS 0x0001 // For finding a folder to start document searching
#define BIF_DONTGOBELOWDOMAIN 0x0002 // For starting the Find Computer
#define BIF_STATUSTEXT 0x0004
#define BIF_RETURNFSANCESTORS 0x0008
#define BIF_EDITBOX 0x0010
#define BIF_VALIDATE 0x0020 // insist on valid result (or CANCEL)
#define BIF_BROWSEFORCOMPUTER 0x1000 // Browsing for Computers.
#define BIF_BROWSEFORPRINTER 0x2000 // Browsing for Printers
#define BIF_BROWSEINCLUDEFILES 0x4000 // Browsing for Everything
*/
-bInfo.ulFlags 플래그
BIF_BROWSEFORCOMPUTER : 네트워크의 컴퓨터만 선택가능
BIF_BROWSEFORPRINTER : 프린터만 선택가능
BIF_BROWSEINCLUDEFILES : 파일도 표시
BIF_DONTGOBELOWDOMAIN : 네트워크의 컴퓨터를 표시하지 않는다
BIF_EDITBOX : 에디트 박스를 표시한다
BIF_RETURNFSANCESTORS : 네트워크의 컴퓨터만 선택가능
BIF_RETURNONLYFSDIRS : 폴더만 선택가능
BIF_STATUSTEXT : 스테이터스 텍스트를 표시한다
BIF_VALIDATE : 부정 입력시에, BFFM_VALIDATEFAILED 이벤트
//Must be static funtion.
static int CALLBACK BrowseForFolder_CallbackProc(HWND m_hWnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
{
if(uMsg == BFFM_INITIALIZED)
SendMessage(m_hWnd, BFFM_SETSELECTION, (WPARAM)TRUE, (LPARAM)lpData);
return 0;
}
위 함수는 꼭 static 함수여야 한다. 그리고 아래에서 함수포인터를 넣어준다.
아래 코드는 폴더 선택 다이얼로그를 띄워야 하는 곳에 넣어주면 되겠지.
BROWSEINFO bi;
ZeroMemory(&bi, sizeof(BROWSEINFO));
bi.hwndOwner = this->GetSafeHwnd();
bi.pidlRoot = NULL;
bi.pszDisplayName = NULL;
bi.lpszTitle = NULL;
bi.ulFlags = BIF_RETURNONLYFSDIRS;
bi.lpfn = BrowseForFolder_CallbackProc;
bi.lParam = (LPARAM)(LPCTSTR)m_strContentsDownloadFolder; //초기값 설정.
LPITEMIDLIST pidl = SHBrowseForFolder(&bi);
TCHAR szPath[MAX_PATH] = {0,};
if( pidl )
{
SHGetPathFromIDList( pidl, szPath );
m_strContentsDownloadFolder = szPath;
GetDlgItem( IDC_DOWNLOAD_ADDRESS )->SetWindowText( m_strContentsDownloadFolder );
}
위와 같이 하면 폴더를 선택할 수 있는 다이얼로그가 뜬다.
보통 많은 프로그램들을 보면 버튼 눌렀을때 폴더 선택할수 있게 다이얼로그를 띄워준다.
이것을 어케 하는지 알아본다.
간단하다.
ITEMIDLIST *pidlBrowse;
char pszPathname[1000];
BROWSEINFO BrInfo;
BrInfo.hwndOwner = GetSafeHwnd();
BrInfo.pidlRoot = NULL;
memset(&BrInfo, 0, sizeof(BrInfo));
BrInfo.pszDisplayName = pszPathname;
BrInfo.lpszTitle = "경로 선택";
BrInfo.ulFlags = BIF_RETURNONLYFSDIRS;
pidlBrowse = ::SHBrowseForFolder(&BrInfo);
if( pidlBrowse != NULL)
{
::SHGetPathFromIDList(pidlBrowse, pszPathname);
m_strFileDownDir = pszPathname; // 폴더 경로
}
반환되는 폴더 경로는 pszPathname 에 저장된다.
'C/C++언어 > 윈도우 MFC' 카테고리의 다른 글
좌표 매핑 관련 함수 (0) | 2008.10.03 |
---|---|
GetWindowRect, GetClientRect, ScreenToClient (0) | 2008.09.26 |
리스트뷰 컨트롤에 관련한 이야기 (0) | 2007.11.15 |
MFC클래스 간의 통신 (포인터 얻기) (0) | 2007.11.11 |
스크롤 범위 세팅 (0) | 2007.11.11 |