387 lines
No EOL
18 KiB
C++
387 lines
No EOL
18 KiB
C++
#include "stdafx.h"
|
||
#include <windows.h>
|
||
#include <shlobj.h>
|
||
|
||
#include "ExportBrowseFolder.h"
|
||
|
||
|
||
int CALLBACK BrowseCallbackProc(HWND hwnd,UINT uMsg,LPARAM lParam,LPARAM lpData)
|
||
{
|
||
switch (uMsg)
|
||
{
|
||
case BFFM_INITIALIZED:
|
||
SetWindowText(hwnd, _T("폴더 고르기"));
|
||
SetWindowPos(hwnd,NULL,10,10,0,0,SWP_NOSIZE | SWP_NOZORDER);
|
||
break;
|
||
case BFFM_VALIDATEFAILED:
|
||
MessageBox(hwnd,_T("에디트에 입력한 폴더는 존재하지 않습니다. 다시 입력해 주십시요"),
|
||
_T("알림"),MB_OK);
|
||
return 1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
|
||
BOOL ExportBrowseFolder(HWND hWnd, TCHAR *szFolder)
|
||
{
|
||
LPMALLOC pMalloc;
|
||
LPITEMIDLIST pidl;
|
||
BROWSEINFO bi;
|
||
LPITEMIDLIST root;
|
||
|
||
bi.hwndOwner = hWnd;
|
||
|
||
//내 컴퓨터를 루트로 만들기
|
||
SHGetSpecialFolderLocation(hWnd,CSIDL_DRIVES,&root);
|
||
|
||
bi.pidlRoot = root;
|
||
bi.pidlRoot = NULL;
|
||
bi.pszDisplayName = NULL;
|
||
bi.lpszTitle = _T("아래 리스트에서 폴더를 선택하세요.\n선택한폴더+Exports 란 디렉토리에 데이터가 추출됩니다." );
|
||
bi.ulFlags = BIF_EDITBOX | BIF_STATUSTEXT | BIF_VALIDATE;
|
||
bi.lpfn = BrowseCallbackProc;
|
||
bi.lParam = 0;
|
||
|
||
pidl = SHBrowseForFolder(&bi);
|
||
|
||
if (pidl == NULL) {
|
||
return FALSE;
|
||
}
|
||
SHGetPathFromIDList(pidl, szFolder);
|
||
|
||
if (SHGetMalloc(&pMalloc) != NOERROR) {
|
||
return FALSE;
|
||
}
|
||
pMalloc->Free(pidl);
|
||
pMalloc->Release();
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
/*
|
||
DESCRIPTION:
|
||
CFolderDialog - Folder Selection Dialog Class
|
||
Copyright(C) Armen Hakobyan, 2002 - 2005
|
||
http://www.codeproject.com/dialog/cfolderdialog.asp
|
||
|
||
VERSION HISTORY:
|
||
24 Mar 2002 - First release
|
||
30 Mar 2003 - Some minor changes
|
||
- Added missing in old Platform SDK new flag definitions
|
||
- Added support for both MFC 6.0 and 7.0
|
||
- Added OnIUnknown handler for Windows XP folder filtration
|
||
- Added SetExpanded and SetOKText and GetSelectedFolder functions
|
||
24 May 2003 - Added OnSelChanged implementation
|
||
14 Jul 2003 - Added custom filtration for Windows XP, thanks to Arik Poznanski
|
||
29 Nov 2003 - Added SetRootFolder, thanks to Eckhard Schwabe ( and Jose Insa )
|
||
02 Jan 2004 - Added GetRootFolder, uncomment if needed
|
||
15 Feb 2005 - Small bug fix in DoModal, thanks to WindSeven
|
||
*/
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
|
||
#ifndef BFFM_VALIDATEFAILED
|
||
#ifndef UNICODE
|
||
#define BFFM_VALIDATEFAILED 3
|
||
#else
|
||
#define BFFM_VALIDATEFAILED 4
|
||
#endif
|
||
#endif
|
||
|
||
#ifndef BFFM_IUNKNOWN
|
||
#define BFFM_IUNKNOWN 5
|
||
#endif
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// CFolderDialog
|
||
|
||
IMPLEMENT_DYNAMIC( CFolderDialog, CDialog )
|
||
|
||
CFolderDialog::CFolderDialog( IN LPCTSTR pszTitle /*NULL*/,
|
||
IN LPCTSTR pszSelPath /*NULL*/,
|
||
IN CWnd* pWndParent /*NULL*/,
|
||
IN UINT uFlags /*BIF_RETURNONLYFSDIRS*/ )
|
||
: CCommonDialog( pWndParent )
|
||
, m_hWnd( NULL )
|
||
{
|
||
::ZeroMemory( &m_bi, sizeof( BROWSEINFO ) );
|
||
::ZeroMemory( m_szFolPath, MAX_PATH );
|
||
::ZeroMemory( m_szSelPath, MAX_PATH );
|
||
|
||
// Fill data
|
||
|
||
m_bi.hwndOwner = pWndParent->GetSafeHwnd();
|
||
m_bi.pidlRoot = NULL;
|
||
m_bi.lpszTitle = pszTitle;
|
||
m_bi.ulFlags = uFlags;
|
||
m_bi.lpfn = (BFFCALLBACK)&BrowseCallbackProc;
|
||
m_bi.lParam = (LPARAM)this;
|
||
|
||
// The size of this buffer is assumed to be MAX_PATH bytes:
|
||
|
||
m_bi.pszDisplayName = new TCHAR[ MAX_PATH ];
|
||
ASSERT( m_bi.pszDisplayName != NULL );
|
||
|
||
SAFE_ZEROMEMORY(
|
||
m_bi.pszDisplayName, ( MAX_PATH * sizeof( TCHAR ) )
|
||
);
|
||
|
||
if( pszSelPath )
|
||
SetSelectedFolder( pszSelPath );
|
||
}
|
||
|
||
CFolderDialog::~CFolderDialog( VOID )
|
||
{
|
||
SAFE_COTASKMEMFREE( m_bi.pidlRoot );
|
||
SAFE_DELETE2( m_bi.pszDisplayName );
|
||
|
||
::ZeroMemory( &m_bi, sizeof( BROWSEINFO ) );
|
||
}
|
||
|
||
BEGIN_MESSAGE_MAP( CFolderDialog, CCommonDialog )
|
||
END_MESSAGE_MAP()
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// CFolderDialog message handlers
|
||
|
||
// SetRootFolder By Jose Insa
|
||
// Microsoft knowledge Base Article
|
||
// ID Q132750: Convert a File Path to an ITEMIDLIST
|
||
|
||
BOOL CFolderDialog::SetRootFolder( IN LPCTSTR pszPath )
|
||
{
|
||
ASSERT_VALID( this );
|
||
|
||
if( !pszPath )
|
||
{
|
||
SAFE_COTASKMEMFREE( m_bi.pidlRoot );
|
||
return TRUE;
|
||
}
|
||
|
||
ASSERT( AfxIsValidString( pszPath, MAX_PATH ) );
|
||
|
||
HRESULT hResult = S_FALSE;
|
||
IShellFolder* pDeskFolder = NULL;
|
||
|
||
hResult = ::SHGetDesktopFolder( &pDeskFolder );
|
||
if ( hResult == S_OK )
|
||
{
|
||
LPITEMIDLIST pidlRoot = NULL;
|
||
LPTSTR pszRoot = const_cast< LPTSTR >( pszPath );
|
||
|
||
// Convert the path to an ITEMIDLIST:
|
||
|
||
USES_CONVERSION;
|
||
|
||
hResult = pDeskFolder->ParseDisplayName(
|
||
NULL, NULL, T2W( pszRoot ), NULL, &pidlRoot, NULL
|
||
);
|
||
|
||
if( hResult == S_OK )
|
||
{
|
||
SAFE_COTASKMEMFREE( m_bi.pidlRoot );
|
||
m_bi.pidlRoot = pidlRoot;
|
||
}
|
||
|
||
SAFE_RELEASE( pDeskFolder );
|
||
}
|
||
|
||
return ( hResult == S_OK );
|
||
}
|
||
|
||
// NOTE: pszPath buffer must be at least
|
||
// MAX_PATH characters in size:
|
||
|
||
BOOL CFolderDialog::GetRootFolder( IN OUT LPTSTR pszPath )
|
||
{
|
||
ASSERT_VALID( this );
|
||
ASSERT( AfxIsValidString( pszPath, MAX_PATH ) );
|
||
|
||
return ::SHGetPathFromIDList( m_bi.pidlRoot, pszPath );
|
||
}
|
||
|
||
BOOL CFolderDialog::SetSelectedFolder( IN LPCTSTR pszPath )
|
||
{
|
||
ASSERT( AfxIsValidString( pszPath, MAX_PATH ) );
|
||
return (BOOL)::lstrcpy( m_szSelPath, pszPath );
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
|
||
#if ( _MFC_VER >= 0x0700 )
|
||
INT_PTR CFolderDialog::DoModal( VOID )
|
||
#else
|
||
INT CFolderDialog::DoModal( VOID )
|
||
#endif
|
||
{
|
||
ASSERT_VALID( this );
|
||
ASSERT( m_bi.lpfn != NULL );
|
||
|
||
INT_PTR nRet = -1;
|
||
m_bi.hwndOwner = PreModal();
|
||
|
||
LPITEMIDLIST pItemIDList = ::SHBrowseForFolder( &m_bi );
|
||
if( pItemIDList )
|
||
{
|
||
if( ::SHGetPathFromIDList( pItemIDList, m_szFolPath ) )
|
||
nRet = IDOK;
|
||
|
||
SAFE_COTASKMEMFREE( pItemIDList );
|
||
}
|
||
else
|
||
nRet = IDCANCEL;
|
||
|
||
|
||
PostModal();
|
||
return ( nRet );
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// Overridables:
|
||
|
||
VOID CFolderDialog::OnInitialized( VOID )
|
||
{
|
||
if( ::lstrlen( m_szSelPath ) > 0 )
|
||
SetSelection( m_szSelPath );
|
||
}
|
||
|
||
VOID CFolderDialog::OnSelChanged( IN LPITEMIDLIST pItemIDList )
|
||
{
|
||
if( m_bi.ulFlags & BIF_STATUSTEXT )
|
||
{
|
||
TCHAR szSelFol[ MAX_PATH ] = { 0 };
|
||
if( ::SHGetPathFromIDList( pItemIDList, szSelFol ) )
|
||
SetStatusText( szSelFol );
|
||
}
|
||
}
|
||
|
||
INT CFolderDialog::OnValidateFailed( IN LPCTSTR /*pszPath*/ )
|
||
{
|
||
::MessageBeep( MB_ICONHAND );
|
||
return 1; // Return 1 to leave dialog open, 0 - to end one
|
||
}
|
||
|
||
VOID CFolderDialog::OnIUnknown( IN IUnknown* /*pIUnknown*/ )
|
||
{
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// Callback function used with the SHBrowseForFolder function.
|
||
|
||
INT CALLBACK CFolderDialog::BrowseCallbackProc( IN HWND hWnd,
|
||
IN UINT uMsg,
|
||
IN LPARAM lParam,
|
||
IN LPARAM lpData )
|
||
{
|
||
CFolderDialog* pThis = (CFolderDialog*)lpData;
|
||
ASSERT( pThis != NULL );
|
||
|
||
INT nRet = 0;
|
||
pThis->m_hWnd = hWnd;
|
||
|
||
switch( uMsg )
|
||
{
|
||
case BFFM_INITIALIZED:
|
||
pThis->OnInitialized();
|
||
break;
|
||
case BFFM_SELCHANGED:
|
||
pThis->OnSelChanged( (LPITEMIDLIST)lParam );
|
||
break;
|
||
case BFFM_VALIDATEFAILED:
|
||
nRet = pThis->OnValidateFailed( (LPCTSTR)lParam );
|
||
break;
|
||
case BFFM_IUNKNOWN:
|
||
pThis->OnIUnknown( (IUnknown*)lParam );
|
||
break;
|
||
default:
|
||
ASSERT( FALSE );
|
||
break;
|
||
}
|
||
|
||
pThis->m_hWnd = NULL;
|
||
return nRet;
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// Commands, valid to call only from handlers
|
||
|
||
VOID CFolderDialog::SetExpanded( IN LPCTSTR pszPath )
|
||
{
|
||
USES_CONVERSION;
|
||
|
||
ASSERT( m_hWnd != NULL );
|
||
ASSERT( AfxIsValidString( pszPath, MAX_PATH ) );
|
||
|
||
::SendMessage(
|
||
m_hWnd, BFFM_SETEXPANDED,
|
||
(WPARAM)TRUE, (LPARAM)T2CW( pszPath )
|
||
);
|
||
}
|
||
|
||
VOID CFolderDialog::SetOKText( IN LPCTSTR pszText )
|
||
{
|
||
USES_CONVERSION;
|
||
|
||
ASSERT( m_hWnd != NULL );
|
||
|
||
::SendMessage(
|
||
m_hWnd, BFFM_SETOKTEXT,
|
||
(WPARAM)0, (LPARAM)T2CW( pszText )
|
||
);
|
||
}
|
||
|
||
VOID CFolderDialog::EnableOK( IN BOOL bEnable /*TRUE*/ )
|
||
{
|
||
ASSERT( m_hWnd != NULL );
|
||
|
||
::SendMessage(
|
||
m_hWnd, BFFM_ENABLEOK, (WPARAM)bEnable, 0L
|
||
);
|
||
}
|
||
|
||
VOID CFolderDialog::SetSelection( IN LPITEMIDLIST pItemIDList )
|
||
{
|
||
ASSERT( m_hWnd != NULL );
|
||
|
||
::SendMessage(
|
||
m_hWnd, BFFM_SETSELECTION,
|
||
(WPARAM)FALSE, (LPARAM)pItemIDList
|
||
);
|
||
}
|
||
|
||
VOID CFolderDialog::SetSelection( IN LPCTSTR pszPath )
|
||
{
|
||
ASSERT( m_hWnd != NULL );
|
||
ASSERT( AfxIsValidString( pszPath, MAX_PATH ) );
|
||
|
||
::SendMessage(
|
||
m_hWnd, BFFM_SETSELECTION,
|
||
(WPARAM)TRUE, (LPARAM)pszPath
|
||
);
|
||
}
|
||
|
||
VOID CFolderDialog::SetStatusText( IN LPCTSTR pszText )
|
||
{
|
||
ASSERT( m_hWnd != NULL );
|
||
|
||
::SendMessage(
|
||
m_hWnd, BFFM_SETSTATUSTEXT,
|
||
(WPARAM)0, (LPARAM)pszText
|
||
);
|
||
}
|
||
|
||
// Shell version 5.0 or later:
|
||
|
||
VOID CFolderDialog::SetExpanded( IN LPITEMIDLIST pItemIDList )
|
||
{
|
||
ASSERT( m_hWnd != NULL );
|
||
|
||
::SendMessage(
|
||
m_hWnd, BFFM_SETEXPANDED,
|
||
(WPARAM)FALSE, (LPARAM)pItemIDList
|
||
);
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|