Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Using CFileDialog to select folders

900 views
Skip to first unread message

John Busfield

unread,
Dec 14, 1996, 3:00:00 AM12/14/96
to

How can I use a CFileDialog to select a folder rather than a file. In
other words, when I highlight a folder then hit open I want the folder
name to be returned to me rather than having the next lower level
displayed.
--
John Busfield busf...@ix.netcom.com

Mukesh Bhakta

unread,
Dec 15, 1996, 3:00:00 AM12/15/96
to
I think there is nothing so easy. I think you have to develop one
yourself. I have a code which does what you want, which I am planning to
make a professional release to a client. If you want it we can decide on
a price

Thanks

Mukesh Bhakta

Cecil Galbraith

unread,
Dec 15, 1996, 3:00:00 AM12/15/96
to

John Busfield wrote:
>
> How can I use a CFileDialog to select a folder rather than a file. In
> other words, when I highlight a folder then hit open I want the folder
> name to be returned to me rather than having the next lower level
> displayed.
> --
> John Busfield busf...@ix.netcom.com

There is a directory picker class that I wrote residing on the web page
(address below). It's drop-in and easy to use. You're welcome to it.

--
Cecil Galbraith
CustomSoft mail to cgal...@concentric.net

Free programmer's utilities and MFC tips at
http://www.concentric.net/~cgalbrai

Chris Marriott

unread,
Dec 15, 1996, 3:00:00 AM12/15/96
to

In article <32B34F...@ix.netcom.com>, John Busfield
<busf...@ix.netcom.com> writes

>How can I use a CFileDialog to select a folder rather than a file. In
>other words, when I highlight a folder then hit open I want the folder
>name to be returned to me rather than having the next lower level
>displayed.

Win16: Take a look at the "DIRPKR" sample program.
Win32: Use the "SHBrowseForFolder" API.

Chris

----------------------------------------------------------------
Chris Marriott, SkyMap Software, U.K. e-mail: ch...@skymap.com
Creators of fine astronomy software for Windows.
For full details, visit our web site at http://www.skymap.com


Rail J. Rogut

unread,
Dec 15, 1996, 3:00:00 AM12/15/96
to

Hi Chris,

I tried using SHBrowserForFolder() but it was dinky, so I modified
Directory picker (from the MSDN CD) as follows:

(also allows the user to enter a new directory).

Copy begins:

// ChoosDir.h : header file
//

/////////////////////////////////////////////////////////////////////////////
// CChooseDir dialog

class CChooseDir : public CFileDialog
{
DECLARE_DYNAMIC(CChooseDir)

public:
virtual BOOL OnFileNameOK(void);
CString m_szDirName;
virtual void OnLBSelChangedNotify(UINT nIDBox, UINT iCurSel,
UINT
nCode);
BOOL m_bDlgJustCameUp;
CChooseDir(BOOL bOpenFileDialog, // TRUE for FileOpen, FALSE for
FileSaveAs
LPCTSTR lpszDefExt = NULL,
LPCTSTR lpszFileName = NULL,
DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT |
OFN_ENABLETEMPLATE,
LPCTSTR lpszFilter = NULL,
CWnd* pParentWnd = NULL);

// Dialog Data
//{{AFX_DATA(CChooseDir)
enum { IDD = IDD_FILEOPENORD };
CEdit m_CtrlDirName;
//}}AFX_DATA

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CChooseDir)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV
support
//}}AFX_VIRTUAL

protected:
//{{AFX_MSG(CChooseDir)
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};

*******************************************************************************************


// ChoosDir.cpp : implementation file
//

#include "stdafx.h"
#include <direct.h>
#include <dlgs.h>
#include "ChoosDir.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CChooseRegion

IMPLEMENT_DYNAMIC(CChooseDir, CFileDialog)

CChooseRegion::CChooseDir(BOOL bOpenFileDialog, LPCTSTR lpszDefExt,
LPCTSTR lpszFileName, DWORD dwFlags, LPCTSTR lpszFilter,
CWnd* pParentWnd) :
CFileDialog(bOpenFileDialog, lpszDefExt, lpszFileName,
dwFlags |= OFN_ENABLETEMPLATE, lpszFilter,
pParentWnd)
{
m_ofn.hInstance = AfxGetResourceHandle();
m_ofn.lpTemplateName = MAKEINTRESOURCE(CChooseDir::IDD);

m_ofn.Flags &= ~OFN_EXPLORER; // Lose this for VC
1.52c

//{{AFX_DATA_INIT(CChooseDir)
//}}AFX_DATA_INIT
}

void CChooseDir::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CChooseDir)
DDX_Control(pDX, IDC_DIRNAME, m_CtrlDirName);
//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CChooseDir, CFileDialog)
//{{AFX_MSG_MAP(CChooseDir)
ON_WM_PAINT()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()


BOOL CChooseDir::OnInitDialog()
{
CString szTemp;

CenterWindow();

GetDlgItem(stc2)->ShowWindow(SW_HIDE);
GetDlgItem(stc3)->ShowWindow(SW_HIDE);
GetDlgItem(edt1)->ShowWindow(SW_HIDE);
GetDlgItem(lst1)->ShowWindow(SW_HIDE);
GetDlgItem(cmb1)->ShowWindow(SW_HIDE);
GetDlgItem(stc1)->ShowWindow(SW_HIDE);
GetDlgItem(chx1)->ShowWindow(SW_HIDE); // Read only... don't
have to
hide this one
// could rely on
OFN_HIDEREADONLY

GetDlgItem(psh15)->EnableWindow(FALSE); // I disable the help
button

SetDlgItemText(edt1, "Junk");

// Need to fill in my edit control (IDC_DIRNAME)

CListBox* pList = (CListBox*)GetDlgItem(lst2);
int iIndex = pList->GetCurSel();

m_szDirName.Empty();

if (iIndex != LB_ERR)
{
pList->GetText(iIndex, szTemp);

for (int i = 0; i <= iIndex; i++)
{
pList->GetText(i, szTemp);

if (i > 1)
{
m_szDirName += "\\";
m_szDirName += szTemp;
}
else
m_szDirName += szTemp;
}

m_szDirName.MakeUpper();


((CEdit*)GetDlgItem(IDC_DIRNAME))->SetWindowText(m_szDirName);

}

GetDlgItem(lst2)->SetFocus();

m_bDlgJustCameUp = TRUE;

CFileDialog::OnInitDialog();

return FALSE; // return TRUE unless you set the focus to a
control
// EXCEPTION: OCX Property Pages should return
FALSE
}

void CChooseDir::OnPaint()
{
CPaintDC dc(this); // device context for painting

if (m_bDlgJustCameUp)
{
m_bDlgJustCameUp = FALSE;
SendDlgItemMessage(lst2, LB_SETCURSEL, 0, 0L);
}

// Do not call CFileDialog::OnPaint() for painting messages
}

void CChooseDir::OnLBSelChangedNotify(UINT nIDBox, UINT iCurSel, UINT
nCode)
{
CString szTemp;
int i;

CListBox* pList = (CListBox*)GetDlgItem(lst2);

int iIndex = pList->GetCurSel();

m_szDirName.Empty();

if (iIndex != LB_ERR)
{
pList->GetText(iIndex, szTemp);

for (i = 0; i <= iIndex; i++)
{
pList->GetText(i, szTemp);

if (i > 1)
{
m_szDirName += "\\";
m_szDirName += szTemp;
}
else
m_szDirName += szTemp;
}


((CEdit*)GetDlgItem(IDC_DIRNAME))->SetWindowText(m_szDirName);

}

}

BOOL CChooseDir::OnFileNameOK(void)
{
CString szDrive;
CString szMessage;
int iResult;

m_CtrlDirName.GetWindowText(m_szDirName);

szDrive = m_szDirName.Left(3);

// I do a basic check for Win3.11 DOS file name compatibility

// This is set up for Win.311 to set it for Win95 change it to:

// iResult = m_szDirName.FindOneOf("*?|/<>\""); // Win95

iResult = m_szDirName.FindOneOf("*?|/<> .[]^+\""); // Win 3.11

if (iResult >= 0)
{
szMessage.Format("%s is not a valid pathname.",
m_szDirName);
AfxMessageBox(szMessage, MB_OK);
return TRUE;
}

if (_chdir(m_szDirName))
{
szMessage.Format("Directory %s does not exist.\nCreate
this
directory?", m_szDirName);
iResult = AfxMessageBox(szMessage, MB_YESNO);

if (iResult == IDYES)
{
// Create the new directory:

iResult = _mkdir(m_szDirName);

if (iResult)
{
szMessage.Format("There was a problem
creating %s.\nThe new
directory was not created.", m_szDirName);
AfxMessageBox(szMessage, MB_OK);
return TRUE;
}
}
else
return TRUE;

char szBuffer[MAX_PATH];

szMessage = m_szDirName + "\\" + m_ofn.lpstrFileTitle;

strcpy (szBuffer, szMessage);

strcpy(m_ofn.lpstrFile, szBuffer);

m_pofnTemp->nFileOffset = m_szDirName.GetLength() + 1;
// For 32bit
m_pofnTemp->nFileExtension = szMessage.GetLength(); //
For 32bit

// For VC 1.52c change m_pofnTemp-> to m_ofn. in the
above 2 lines:

// m_ofn.nFileOffset = m_szDirName.GetLength() + 1; // For 16bit
// m_ofn.nFileExtension = szMessage.GetLength(); // For
16bit

}

return FALSE;
}


*******************************************************************************

Add to your RC file:
********************

IDD_FILEOPENORD DIALOG DISCARDABLE 109, 35, 165, 134
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Choose Directory"
FONT 8, "Helv"
BEGIN
LTEXT "File &Name:",stc3,168,0,76,10
EDITTEXT edt1,166,10,90,12,ES_AUTOHSCROLL | ES_OEMCONVERT
LISTBOX lst1,166,26,90,68,LBS_SORT | LBS_OWNERDRAWFIXED |
LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL |
WS_TABSTOP
LTEXT "&Directories:",IDC_STATIC,63,156,92,9
LTEXT "Directory &name:",IDC_STATIC,7,4,92,9
EDITTEXT IDC_DIRNAME,7,16,92,12,ES_AUTOHSCROLL
LTEXT "",stc1,164,156,92,9,SS_NOPREFIX
LISTBOX lst2,7,32,92,67,LBS_SORT | LBS_OWNERDRAWFIXED |
LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL |
WS_TABSTOP
LTEXT "List Files of &Type:",stc2,166,98,90,9
COMBOBOX cmb1,166,108,90,36,CBS_DROPDOWNLIST |
CBS_AUTOHSCROLL |
WS_BORDER | WS_VSCROLL | WS_TABSTOP
LTEXT "Dri&ves:",stc4,7,103,92,9
COMBOBOX cmb2,7,113,92,68,CBS_DROPDOWNLIST |
CBS_OWNERDRAWFIXED |
CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS |
WS_BORDER |
WS_VSCROLL | WS_TABSTOP
DEFPUSHBUTTON "OK",IDOK,105,6,50,14,WS_GROUP
PUSHBUTTON "Cancel",IDCANCEL,105,24,50,14,WS_GROUP
PUSHBUTTON "&Help",psh15,105,46,50,14,WS_GROUP
CONTROL "&Read Only",chx1,"Button",BS_AUTOCHECKBOX |
WS_GROUP |
WS_TABSTOP,105,68,50,12
END


************************************************

In the Developer Studio under View -> Resource Includes...

In the read only symbol directives add:

#include "dlgs.h"

Also go to the menu: View -> Resource Symbols

Click on New & type in IDC_DIRNAME.

***********************************************

To call it do something like:

void CMyDlg::OnDirectory()
{
CChooseDir dlg(FALSE, NULL, NULL, OFN_SHOWHELP |
OFN_HIDEREADONLY |
OFN_OVERWRITEPROMPT | OFN_ENABLETEMPLATE,
NULL);

CWinApp* pApp;

pApp = AfxGetApp();

CString szDrive = pApp->GetProfileString("Region Filer",
"DefaultDir","");
CString szDirectory = pApp->GetProfileString("Region Filer",
"TargetDir", szDrive);

if (szDrive != szDirectory.Left(3))
szDirectory = szDrive;

dlg.m_ofn.lpstrInitialDir = szDirectory;

if (IDOK == dlg.DoModal())
{
WORD wFileOffset;
// char szBuffer[128];

wFileOffset = dlg.m_ofn.nFileOffset;

dlg.m_ofn.lpstrFile[wFileOffset-1] = 0;

szDirectory = dlg.m_ofn.lpstrFile;
szDirectory.MakeUpper();
szDrive = szDirectory.Left(3);

// wsprintf(szBuffer, "Selected directory is %s",
(LPSTR)dlg.m_ofn.lpstrFile);

pApp->WriteProfileString("Region Filer", "TargetDir",
szDirectory);
pApp->WriteProfileString("Region Filer", "DefaultDir",
szDrive);

CString szTemp;

szTemp.Format("Region Filer - [%s\\*]", szDirectory);

SetWindowText(szTemp); // Place szTemp in Title bar
}
}

That should do it.

Hope this helps.

Rail
Ocean Way Recording

Rail J. Rogut

unread,
Dec 15, 1996, 3:00:00 AM12/15/96
to

Rail J. Rogut wrote:

> // ChoosDir.cpp : implementation file
> //
>
> #include "stdafx.h"
> #include <direct.h>
> #include <dlgs.h>
> #include "ChoosDir.h"
>
> #ifdef _DEBUG
> #define new DEBUG_NEW
> #undef THIS_FILE
> static char THIS_FILE[] = __FILE__;
> #endif
>
> /////////////////////////////////////////////////////////////////////////////
> // CChooseRegion
>
> IMPLEMENT_DYNAMIC(CChooseDir, CFileDialog)
>
> CChooseRegion::CChooseDir(BOOL bOpenFileDialog, LPCTSTR lpszDefExt,
> LPCTSTR lpszFileName, DWORD dwFlags, LPCTSTR lpszFilter,
> CWnd* pParentWnd) :
> CFileDialog(bOpenFileDialog, lpszDefExt, lpszFileName,
> dwFlags |= OFN_ENABLETEMPLATE, lpszFilter,
> pParentWnd)
> {
> m_ofn.hInstance = AfxGetResourceHandle();
> m_ofn.lpTemplateName = MAKEINTRESOURCE(CChooseDir::IDD);
>

************************************************************************************


Sorry - for this posting I changed the class name from CChooseRegion to
CChooseDir ....but missed one:


/////////////////////////////////////////////////////////////////////////////
// CChooseRegion

IMPLEMENT_DYNAMIC(CChooseDir, CFileDialog)

CChooseRegion::CChooseDir(BOOL bOpenFileDialog, LPCTSTR lpszDefExt,
LPCTSTR lpszFileName, DWORD dwFlags, LPCTSTR
lpszFilter,
CWnd* pParentWnd) :
CFileDialog(bOpenFileDialog, lpszDefExt,
lpszFileName,
dwFlags |= OFN_ENABLETEMPLATE, lpszFilter,
pParentWnd)

should be:

/////////////////////////////////////////////////////////////////////////////
// CChooseDir

IMPLEMENT_DYNAMIC(CChooseDir, CFileDialog)

CChooseDir::CChooseDir(BOOL bOpenFileDialog, LPCTSTR lpszDefExt,


LPCTSTR lpszFileName, DWORD dwFlags, LPCTSTR
lpszFilter,
CWnd* pParentWnd) :
CFileDialog(bOpenFileDialog, lpszDefExt,
lpszFileName,
dwFlags |= OFN_ENABLETEMPLATE, lpszFilter,
pParentWnd)


Apologies again.

Rail

Ocean Way Recording
rai...@earthlink.net

David Loendorf

unread,
Dec 17, 1996, 3:00:00 AM12/17/96
to

> >How can I use a CFileDialog to select a folder rather than a file.
> Win32: Use the "SHBrowseForFolder" API.
>
> Chris
>

SHBrowseForFolder does not seem to work on NT 3.51 so you better
look elsewhere.

David

Chris Marriott

unread,
Dec 18, 1996, 3:00:00 AM12/18/96
to

In article <32B6D5...@lanl.gov>, David Loendorf <dloe...@lanl.gov>
writes

>SHBrowseForFolder does not seem to work on NT 3.51 so you better
>look elsewhere.

I really didn't think it necessary to point out the blindingly obvious
fact that a "shell" function - one starting with "SH", would only work
on a machine running the Windows 95 shell - Win95 and NT 4.

On NT 3.51 you can of course use the method illustrated by the "DIRPKR"
sample program.

0 new messages