summaryrefslogtreecommitdiffstats
path: root/Source/MFCDialog
diff options
context:
space:
mode:
authorBill Hoffman <bill.hoffman@kitware.com>2001-06-05 21:26:48 (GMT)
committerBill Hoffman <bill.hoffman@kitware.com>2001-06-05 21:26:48 (GMT)
commit9c149dda8124ed87ebcf381abf8723128bc5cfc8 (patch)
tree45eeeeefa5f6158f41c736bead519a6fe7f1e20b /Source/MFCDialog
parent8e281e5d5f1d59fc404f2cd694d4e871c001e3a1 (diff)
downloadCMake-9c149dda8124ed87ebcf381abf8723128bc5cfc8.zip
CMake-9c149dda8124ed87ebcf381abf8723128bc5cfc8.tar.gz
CMake-9c149dda8124ed87ebcf381abf8723128bc5cfc8.tar.bz2
ENH: add better path chooser dialog
Diffstat (limited to 'Source/MFCDialog')
-rw-r--r--Source/MFCDialog/CMakeSetupDialog.cpp55
-rw-r--r--Source/MFCDialog/PathDialog.cpp380
-rw-r--r--Source/MFCDialog/PathDialog.h74
-rw-r--r--Source/MFCDialog/PropertyList.cpp37
4 files changed, 469 insertions, 77 deletions
diff --git a/Source/MFCDialog/CMakeSetupDialog.cpp b/Source/MFCDialog/CMakeSetupDialog.cpp
index d6819eb..0c558dc 100644
--- a/Source/MFCDialog/CMakeSetupDialog.cpp
+++ b/Source/MFCDialog/CMakeSetupDialog.cpp
@@ -3,6 +3,7 @@
#include "stdafx.h"
#include "CMakeSetup.h"
+#include "PathDialog.h"
#include "CMakeSetupDialog.h"
#include "../cmCacheManager.h"
#include "../cmake.h"
@@ -205,57 +206,19 @@ HCURSOR CMakeSetupDialog::OnQueryDragIcon()
-// Insane Microsoft way of setting the initial directory
-// for the Shbrowseforfolder function...
-// SetSelProc
-// Callback procedure to set the initial selection of the browser.
-int CALLBACK CMakeSetupDialog_SetSelProc( HWND hWnd, UINT uMsg,
- LPARAM lParam, LPARAM lpData )
-{
- if (uMsg==BFFM_INITIALIZED)
- {
- ::SendMessage(hWnd, BFFM_SETSELECTION, TRUE, lpData );
- }
- return 0;
-}
-
-inline void ILFree(LPITEMIDLIST pidl)
-{
- LPMALLOC pMalloc;
- if (pidl)
- {
- SHGetMalloc(&pMalloc);
- pMalloc->Free( pidl);
- pMalloc->Release();
- }
-}
-
-
// Browse button
bool CMakeSetupDialog::Browse(CString &result, const char *title)
{
-// don't know what to do with initial right now...
- char szPathName[4096];
- BROWSEINFO bi;
-
- bi.hwndOwner = m_hWnd;
- bi.pidlRoot = NULL;
- bi.pszDisplayName = (LPTSTR)szPathName;
- bi.lpszTitle = title;
- bi.ulFlags = BIF_BROWSEINCLUDEFILES;
- // set up initial directory code
- bi.lpfn = CMakeSetupDialog_SetSelProc;
- bi.lParam = (LPARAM)(LPCSTR) result;
- // open the directory chooser
- LPITEMIDLIST pidl = SHBrowseForFolder(&bi);
- // get the result
- bool bSuccess = (SHGetPathFromIDList(pidl, szPathName) ? true : false);
- if(bSuccess)
+ CPathDialog dlg("Select Path", title, result);
+ if(dlg.DoModal()==IDOK)
+ {
+ result = dlg.GetPathName();
+ return true;
+ }
+ else
{
- result = szPathName;
+ return false;
}
- ILFree(pidl);
- return bSuccess;
}
diff --git a/Source/MFCDialog/PathDialog.cpp b/Source/MFCDialog/PathDialog.cpp
new file mode 100644
index 0000000..58337f9
--- /dev/null
+++ b/Source/MFCDialog/PathDialog.cpp
@@ -0,0 +1,380 @@
+//////////////////////////////////////////////////////////////////////////
+//PathDialog.h file
+//
+//Written by Nguyen Tan Hung <tanhung@yahoo.com>
+//////////////////////////////////////////////////////////////////////////
+
+#include "stdafx.h"
+#include "PathDialog.h"
+#include <io.h>
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+#define IDC_FOLDERTREE 0x3741
+#define IDC_TITLE 0x3742
+#define IDC_STATUSTEXT 0x3743
+
+#define IDC_NEW_EDIT_PATH 0x3744
+
+// Class CDlgWnd
+BEGIN_MESSAGE_MAP(CPathDialogSub, CWnd)
+ ON_BN_CLICKED(IDOK, OnOK)
+ ON_EN_CHANGE(IDC_NEW_EDIT_PATH, OnChangeEditPath)
+ END_MESSAGE_MAP()
+
+ void CPathDialogSub::OnOK()
+{
+ ::GetWindowText(::GetDlgItem(m_hWnd, IDC_NEW_EDIT_PATH),
+ m_pPathDialog->m_szPathName, MAX_PATH);
+
+ if(CPathDialog::MakeSurePathExists(m_pPathDialog->m_szPathName)==0)
+ {
+ m_pPathDialog->m_bGetSuccess=TRUE;
+ ::EndDialog(m_pPathDialog->m_hWnd, IDOK);
+ }
+ else
+ {
+ ::SetFocus(::GetDlgItem(m_hWnd, IDC_NEW_EDIT_PATH));
+ }
+}
+
+void CPathDialogSub::OnChangeEditPath()
+{
+ ::GetWindowText(::GetDlgItem(m_hWnd, IDC_NEW_EDIT_PATH),
+ m_pPathDialog->m_szPathName, MAX_PATH);
+ BOOL bEnableOKButton = (_tcslen(m_pPathDialog->m_szPathName)>0);
+ SendMessage(BFFM_ENABLEOK, 0, bEnableOKButton);
+}
+/////////////////////////////////////////////////////////////////////////////
+// CPathDialog dialog
+
+
+CPathDialog::CPathDialog(LPCTSTR lpszCaption,
+ LPCTSTR lpszTitle,
+ LPCTSTR lpszInitialPath,
+ CWnd* pParent)
+{
+ m_hWnd=NULL;
+ m_PathDialogSub.m_pPathDialog= this;
+ m_bParentDisabled = FALSE;
+
+ // Get the true parent of the dialog
+ m_pParentWnd = CWnd::GetSafeOwner(pParent);
+
+ m_lpszCaption = lpszCaption;
+ m_lpszInitialPath = lpszInitialPath;
+
+ memset(&m_bi, 0, sizeof(BROWSEINFO) );
+ m_bi.hwndOwner = (m_pParentWnd==NULL)?NULL:m_pParentWnd->GetSafeHwnd();
+ m_bi.pszDisplayName = 0;
+ m_bi.pidlRoot = 0;
+ m_bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT;
+ m_bi.lpfn = BrowseCallbackProc;
+ m_bi.lpszTitle = lpszTitle;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// CPathDialog message handlers
+
+CString CPathDialog::GetPathName()
+{
+ return CString(m_szPathName);
+}
+
+int CALLBACK CPathDialog::BrowseCallbackProc(HWND hwnd,UINT uMsg,LPARAM lParam, LPARAM pData)
+{
+ CPathDialog* pDlg = (CPathDialog*)pData;
+
+ switch(uMsg)
+ {
+ case BFFM_INITIALIZED:
+ {
+ RECT rc;
+ HWND hEdit;
+ HFONT hFont;
+
+ pDlg->m_hWnd = hwnd;
+
+ if(pDlg->m_lpszCaption!=NULL)
+ {
+ ::SetWindowText(hwnd, pDlg->m_lpszCaption);
+ }
+
+ VERIFY(pDlg->m_PathDialogSub.SubclassWindow(hwnd));
+ ::ShowWindow(::GetDlgItem(hwnd, IDC_STATUSTEXT), SW_HIDE);
+ ::GetWindowRect(::GetDlgItem(hwnd, IDC_FOLDERTREE), &rc);
+ rc.bottom = rc.top - 4;
+ rc.top = rc.bottom - 23;
+ ::ScreenToClient(hwnd, (LPPOINT)&rc);
+ ::ScreenToClient(hwnd, ((LPPOINT)&rc)+1);
+ hEdit = ::CreateWindowEx(WS_EX_CLIENTEDGE, _T("EDIT"), _T(""),
+ WS_CHILD|WS_TABSTOP|WS_VISIBLE|ES_AUTOHSCROLL,
+ rc.left, rc.top,
+ rc.right-rc.left, rc.bottom-rc.top,
+ hwnd, NULL, NULL, NULL);
+ ::SetWindowLong(hEdit, GWL_ID, IDC_NEW_EDIT_PATH);
+ ::ShowWindow(hEdit, SW_SHOW);
+
+ hFont = (HFONT)::SendMessage(hwnd, WM_GETFONT, 0, 0);
+ ::SendMessage(hEdit, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(TRUE, 0));
+
+ LPCTSTR lpszPath = pDlg->m_lpszInitialPath;
+ TCHAR szTemp[MAX_PATH];
+ if(lpszPath==NULL)
+ {
+ ::GetCurrentDirectory(MAX_PATH, szTemp );
+ lpszPath = szTemp;
+ }
+ // WParam is TRUE since you are passing a path.
+ // It would be FALSE if you were passing a pidl.
+ ::SendMessage(hwnd,BFFM_SETSELECTION,TRUE,
+ (LPARAM)lpszPath);
+ break;
+ }
+ case BFFM_SELCHANGED:
+ {
+ char szSelection[MAX_PATH];
+ if(!::SHGetPathFromIDList((LPITEMIDLIST)lParam, szSelection) ||
+ (szSelection[1] !=':' && szSelection[1] != '\\'))
+ {
+ szSelection[0] = '\0';
+ ::SendMessage(hwnd, BFFM_ENABLEOK, 0, FALSE);
+ }
+ else
+ {
+ ::SendMessage(hwnd, BFFM_ENABLEOK, 0, TRUE);
+ }
+ ::SendMessage(hwnd,BFFM_SETSTATUSTEXT,0,(LPARAM)szSelection);
+ ::SetWindowText(::GetDlgItem(hwnd, IDC_NEW_EDIT_PATH), szSelection);
+ break;
+ }
+ default:
+ break;
+ }
+ return 0;
+}
+
+
+
+int CPathDialog::DoModal()
+{
+
+ /////////////////////////////////////////////////////////
+ TCHAR szPathTemp[MAX_PATH];
+ m_bi.lpfn = BrowseCallbackProc; // address of callback function
+ m_bi.lParam = (LPARAM)this; // pass address of object to callback function
+ m_bi.pszDisplayName = szPathTemp;
+
+ LPITEMIDLIST pidl;
+ LPMALLOC pMalloc;
+
+ int iResult=-1;
+ if(SUCCEEDED(SHGetMalloc(&pMalloc)))
+ {
+ m_bGetSuccess = FALSE;
+ pidl = SHBrowseForFolder(&m_bi);
+ if (pidl!=NULL)
+ {
+ //not need do this because OnOK function did
+ //bSucceeded = SHGetPathFromIDList(pidl, m_szPathName);
+ // In C++:
+ pMalloc->Free(pidl);
+ //In C:
+ //pMalloc->lpVtbl->Free(pMalloc,pidl);
+ //pMalloc->lpVtbl->Release(pMalloc);
+ }
+ if(m_bGetSuccess)
+ {
+ iResult = IDOK;
+ }
+ pMalloc->Release();
+ }
+
+ if(m_bParentDisabled && (m_pParentWnd!=NULL))
+ {
+ m_pParentWnd->EnableWindow(TRUE);
+ }
+ m_bParentDisabled=FALSE;
+
+ return iResult;
+}
+
+BOOL CPathDialog::IsFileNameValid(LPCTSTR lpFileName)
+{
+ return TRUE;
+}
+
+const TCHAR c_FolderDoesNotExist[] = _T(
+ "The folder:\n\n"
+ "%s\n\n"
+ "does not exist. Do you want the folder to be created?");
+const TCHAR c_szErrInvalidPath[] = _T(
+ "The folder:"
+ "\n\n"
+ "%s\n\n"
+ "is invalid. Please reenter.");
+const TCHAR c_szErrCreatePath[] = _T(
+ "The folder:"
+ "\n\n"
+ "%s"
+ "\n\ncan not be created. Please double check.");
+
+//return -1: user break;
+//return 0: no error
+//return 1: lpPath is invalid
+//return 2: can not create lpPath
+int CPathDialog::MakeSurePathExists(LPCTSTR lpPath)
+{
+ CString strMsg;
+ int iRet;
+ try
+ {
+ //validate path
+ iRet=Touch(lpPath, TRUE);
+ if(iRet!=0)
+ {
+ throw iRet;
+ }
+
+ if(_taccess(lpPath, 0)==0)
+ {
+ return (int)0;
+ }
+
+ strMsg.Format(c_FolderDoesNotExist, lpPath);
+ if(AfxMessageBox(strMsg, MB_YESNO|MB_ICONQUESTION) != IDYES)
+ {
+ return (int)-1;
+ }
+
+ //create path
+ iRet=Touch(lpPath, FALSE);
+ if(iRet!=0)
+ {
+ throw iRet;
+ }
+
+ return 0;
+ }
+ catch(int nErrCode)
+ {
+ switch(nErrCode)
+ {
+ case 1:
+ strMsg.Format(c_szErrInvalidPath, lpPath);
+ break;
+ case 2:
+ default:
+ strMsg.Format(c_szErrCreatePath, lpPath);
+ break;
+ }
+
+ AfxMessageBox(strMsg, MB_OK|MB_ICONEXCLAMATION);
+
+ }
+
+ return iRet;
+}
+
+//return 0: no error
+//return 1: lpPath is invalid
+//return 2: lpPath can not be created(bValidate==FALSE)
+int CPathDialog::Touch(LPCTSTR lpPath, BOOL bValidate)
+{
+ if(lpPath==NULL)
+ {
+ return 1;
+ }
+
+ TCHAR szPath[MAX_PATH];
+ _tcscpy(szPath, lpPath);
+ int nLen = _tcslen(szPath);
+
+ int i;
+ if(nLen==3)
+ {
+ if(!bValidate)
+ {
+ if(_access(szPath, 0)!=0)
+ {
+ return 2;
+ }
+ }
+ return 0;
+ }
+
+ i = 3;
+ BOOL bLastOne=TRUE;
+ LPTSTR lpCurrentName;
+ while(szPath[i]!=0)
+ {
+ lpCurrentName = &szPath[i];
+ while( (szPath[i]!=0) && (szPath[i]!=_T('\\')) )
+ {
+ i++;
+ }
+
+ bLastOne =(szPath[i]==0);
+ szPath[i] = 0;
+
+ if(!bValidate)
+ {
+ CreateDirectory(szPath, NULL);
+ if(_taccess(szPath, 0)!=0)
+ {
+ return 2;
+ }
+ }
+
+ if(bLastOne)
+ {
+ break; //it's done
+ }
+ else
+ {
+ szPath[i] = _T('\\');
+ }
+
+ i++;
+ }
+
+ return (bLastOne?0:1);
+}
+
+//return 0: ok
+//return 1: error
+int CPathDialog::ConcatPath(LPTSTR lpRoot, LPCTSTR lpMorePath)
+{
+ if(lpRoot==NULL)
+ {
+ return 1;
+ }
+
+ int nLen = _tcslen(lpRoot);
+
+ if(nLen<3)
+ {
+ return 1;
+ }
+
+ if(lpMorePath==NULL)
+ {
+ return 0;
+ }
+
+ if(nLen==3)
+ {
+ _tcscat(lpRoot, lpMorePath);
+ return 0;
+ }
+
+ _tcscat(lpRoot, _T("\\"));
+ _tcscat(lpRoot, lpMorePath);
+
+ return 0;
+}
diff --git a/Source/MFCDialog/PathDialog.h b/Source/MFCDialog/PathDialog.h
new file mode 100644
index 0000000..6a18429
--- /dev/null
+++ b/Source/MFCDialog/PathDialog.h
@@ -0,0 +1,74 @@
+//////////////////////////////////////////////////////////////////////////
+//PathDialog.h file
+//
+//Written by Nguyen Tan Hung <tanhung@yahoo.com>
+//////////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_PATHDIALOG_H__0F70BC86_11DB_11D4_B012_0000E8DD8DAA__INCLUDED_)
+#define AFX_PATHDIALOG_H__0F70BC86_11DB_11D4_B012_0000E8DD8DAA__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+// PathDialog.h : header file
+//
+#include "shlobj.h"
+
+class CPathDialog;
+
+// CPathDialogSub - intercepts messages from child controls
+class CPathDialogSub : public CWnd
+{
+ friend CPathDialog;
+public:
+ CPathDialog* m_pPathDialog;
+protected:
+ afx_msg void OnOK(); // OK button clicked
+ afx_msg void OnChangeEditPath();
+ DECLARE_MESSAGE_MAP()
+private:
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// CPathDialog dialog
+
+class CPathDialog
+{
+ friend CPathDialogSub;
+// Construction
+public:
+ CPathDialog(LPCTSTR lpszCaption=NULL,
+ LPCTSTR lpszTitle=NULL,
+ LPCTSTR lpszInitialPath=NULL,
+ CWnd* pParent = NULL);
+
+ CString GetPathName();
+ virtual int DoModal();
+
+ static Touch(LPCTSTR lpPath, BOOL bValidate=TRUE);
+ static int MakeSurePathExists(LPCTSTR lpPath);
+ static BOOL IsFileNameValid(LPCTSTR lpFileName);
+ static int ConcatPath(LPTSTR lpRoot, LPCTSTR lpMorePath);
+
+private:
+ static int CALLBACK BrowseCallbackProc(HWND hwnd,UINT uMsg,LPARAM lParam, LPARAM pData);
+
+ LPCTSTR m_lpszCaption;
+ LPCTSTR m_lpszInitialPath;
+
+ TCHAR m_szPathName[MAX_PATH];
+
+ BROWSEINFO m_bi;
+ HWND m_hWnd;
+ CWnd* m_pParentWnd;
+ BOOL m_bParentDisabled;
+ BOOL m_bGetSuccess;
+
+ CPathDialogSub m_PathDialogSub;
+
+};
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_PATHDIALOG_H__0F70BC86_11DB_11D4_B012_0000E8DD8DAA__INCLUDED_)
diff --git a/Source/MFCDialog/PropertyList.cpp b/Source/MFCDialog/PropertyList.cpp
index 407278e..903ca45 100644
--- a/Source/MFCDialog/PropertyList.cpp
+++ b/Source/MFCDialog/PropertyList.cpp
@@ -3,6 +3,7 @@
#include "stdafx.h"
#include "PropertyList.h"
+#include "PathDialog.h"
#include "../cmCacheManager.h"
#define IDC_PROPCMBBOX 712
@@ -366,20 +367,6 @@ void CPropertyList::OnCheckBox()
m_Dirty = true;
}
-// Insane Microsoft way of setting the initial directory
-// for the Shbrowseforfolder function...
-// SetSelProc
-// Callback procedure to set the initial selection of the browser.
-
-int CALLBACK SetSelProc( HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM
- lpData )
-{
- if (uMsg==BFFM_INITIALIZED)
- {
- ::SendMessage(hWnd, BFFM_SETSELECTION, TRUE, lpData );
- }
- return 0;
-}
void CPropertyList::OnButton()
{
@@ -471,24 +458,12 @@ void CPropertyList::OnButton()
initialDir = currPath.Left(endSlash);
}
initialDir.Replace("/", "\\");
- char szPathName[4096];
- BROWSEINFO bi;
- bi.lpfn = SetSelProc;
- bi.lParam = (LPARAM)(LPCSTR) initialDir;
-
- bi.hwndOwner = m_hWnd;
- bi.pidlRoot = NULL;
- bi.pszDisplayName = (LPTSTR)szPathName;
- bi.lpszTitle = "Select Directory";
- bi.ulFlags = BIF_EDITBOX | BIF_RETURNONLYFSDIRS;
-
- LPITEMIDLIST pidl = SHBrowseForFolder(&bi);
-
- BOOL bSuccess = SHGetPathFromIDList(pidl, szPathName);
- CString SelectedFile;
- if(bSuccess)
+ CString title = "Setting Cache Value: ";
+ title += pItem->m_propName;
+ CPathDialog dlg("Select Path", title, initialDir);
+ if(dlg.DoModal()==IDOK)
{
- SelectedFile = szPathName;
+ CString SelectedFile = dlg.GetPathName();
m_btnCtrl.ShowWindow(SW_HIDE);
pItem->m_curValue = SelectedFile;
m_Dirty = true;