Click here to Skip to main content
15,896,557 members
Articles / Desktop Programming / MFC

The Ultimate Toolbox - Updates and User Contributions

Rate me:
Please Sign up or sign in to vote.
4.79/5 (26 votes)
12 Feb 2013CPOL8 min read 256.6K   23.7K   170  
Updates and User Contributions for the Ultimate Toolbox Libraries
// ==========================================================================
// 							Class Implementation : COXDirectoryDialog
// ==========================================================================

// Source file :oxdirdlg.cpp

// Version: 9.3

// This software along with its related components, documentation and files ("The Libraries")
// is � 1994-2007 The Code Project (1612916 Ontario Limited) and use of The Libraries is
// governed by a software license agreement ("Agreement").  Copies of the Agreement are
// available at The Code Project (www.codeproject.com), as part of the package you downloaded
// to obtain this file, or directly from our office.  For a copy of the license governing
// this software, you may contact us at legalaffairs@codeproject.com, or by calling 416-849-8900.                      

// //////////////////////////////////////////////////////////////////////////

#include "stdafx.h"		// standard MFC include
#include <stdlib.h>
#include <dlgs.h>
#include <direct.h>
#include <limits.h>		// For SHRT_MAX
#include "oxdirdlg.h"		// class specification
#include "path.h"		// To get current dir, create a dir, etc.
#include "OXMainRes.h"

// v9.3 - update 03 - 64-bit - added for PtrToUlong
#include "UTB64Bit.h"

#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// Definition of static members


// Data members -------------------------------------------------------------
// protected:
// CString m_sTitle;
// --- The title text of the dialog

// CString m_sFullDir;
// --- The specified directory (may not yet exist);

// CString m_sExistingDir;
// --- That part of the specified directory that does exist

// BOOL m_bNewDirAllowed
// --- Whether the specification of a non-existing directory is allowed

// BOOL m_bAfterInit
// --- Whether the initializations in OnInitDialog executed already or not

// BOOL m_bExplorerOn95
// --- Whether the class is used in a Windows95 environment and with EXPLORER look

// private:

// Member functions ---------------------------------------------------------
// public:

COXDirectoryDialog::COXDirectoryDialog(LPCTSTR pszDefaultDir /* = NULL */,
									   LPCTSTR pszTitle /* = NULL */, BOOL bNewDirAllowed /* = FALSE */,
									   DWORD dwFlags /* = OFN_HIDEREADONLY */, CWnd* pParentWnd /* = NULL */)
									   : 
m_sTitle(pszTitle),
m_sFullDir(pszDefaultDir),
m_sExistingDir(),
m_bNewDirAllowed(bNewDirAllowed),
m_bAfterInit(FALSE),
m_bNewCreated(FALSE),
#ifdef WIN32
m_bExplorerOn95((dwFlags & OFN_EXPLORER) && IsWin95()),
CFileDialog(TRUE, NULL, NULL, ((dwFlags & OFN_EXPLORER) && IsWin95()) ? dwFlags :
			dwFlags | OFN_ENABLETEMPLATE, NULL, pParentWnd)
#else
m_bExplorerOn95(FALSE),
CFileDialog(TRUE, NULL, NULL, dwFlags | OFN_ENABLETEMPLATE,	NULL, pParentWnd)
#endif
{
	//{{AFX_DATA_INIT(COXDirectoryDialog)
	//}}AFX_DATA_INIT

#ifdef _DEBUG
	if (!m_bExplorerOn95)
		// ... The new directory dialog resource must be accessable
#ifdef _AFXDLL
		ASSERT(AfxFindResourceHandle(MAKEINTRESOURCE(IDD_OX_FILEOPENDUMMY), RT_DIALOG) != NULL);
#else
		ASSERT(AfxGetResourceHandle() != NULL);
#endif
#endif

	// ... If no directory is specified, use the current default dir
	if (m_sFullDir.IsEmpty())
	{
		COXDirSpec currentDir;
		VERIFY(currentDir.DoGetCurrentDir());
		m_sFullDir = currentDir.GetDirectory();
	}

	// It is possible that some parts of the specified directory do not yet exist
	// (E.g. When specifying C:\ONO\TWO\THREE, it is possible that
	//  C:\ONE\TWO exists, but C:\ONO\TWO\THREE does not)
	// We will now extract the existing part
	COXDirSpec realDir;
	if (!realDir.SetDirectory(m_sFullDir) || realDir.GetDirectory().IsEmpty())
	{
		TRACE(_T("COXDirectoryDialog::COXDirectoryDialog ; Illegal or no directrory (%s) specified, using default dir\n"),
			pszDefaultDir == NULL ? _T("") : pszDefaultDir);
		VERIFY(realDir.DoGetCurrentDir());
		m_sFullDir = m_sExistingDir = realDir.GetDirectory();
	}
	else
	{
		realDir.MakeLargestExisting();
		m_sExistingDir = realDir.GetDirectory();
	}

	m_ofn.lpstrInitialDir = m_sExistingDir;
	m_ofn.lpstrTitle = m_sTitle;

#ifdef WIN32
	if (!m_bExplorerOn95)
	{
		// MFC CFileDialog automatically chooses EXPLORER look when in Win95
		// even when the user did not pass it in the parameter dwFlags
		// so eliminate it again
		m_ofn.Flags &= ~OFN_EXPLORER;
#ifdef _AFXDLL
		m_ofn.hInstance = AfxFindResourceHandle(MAKEINTRESOURCE(IDD_OX_FILEOPENDUMMY), RT_DIALOG);
#else
		m_ofn.hInstance = AfxGetResourceHandle();
#endif // _AFXDLL 
		m_ofn.lpTemplateName = MAKEINTRESOURCE(IDD_OX_FILEOPENDUMMY);
		ASSERT(!(m_ofn.Flags & OFN_EXPLORER));
	}
#else
#ifdef _AFXDLL
	m_ofn.hInstance = AfxFindResourceHandle(MAKEINTRESOURCE(IDD_OX_FILEOPENDUMMY), RT_DIALOG);
#else
	m_ofn.hInstance = AfxGetResourceHandle();
#endif // _AFXDLL 
	m_ofn.lpTemplateName = MAKEINTRESOURCE(IDD_OX_FILEOPENDUMMY);
#endif
}

#ifdef WIN32
BOOL COXDirectoryDialog::IsWin95()
// --- In  : 
// --- Out : 
// --- Returns :
// --- Effect : Determine the environment the app is executing in.
{
	BOOL bWin95 = FALSE;
	OSVERSIONINFO info;

	info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
	GetVersionEx(&info);
	if (info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ||
		(info.dwPlatformId == VER_PLATFORM_WIN32_NT && info.dwMajorVersion >= 4))
		bWin95 = TRUE;

	return bWin95;
}

CString COXDirectoryDialog::GetFolderPath() const
// --- In  : 
// --- Out : 
// --- Returns :
// --- Effect : When in EXPLORER look ask the dialog what is the currently
//				selected directory
{
	ASSERT(::IsWindow(m_hWnd));
	ASSERT(m_bExplorerOn95);

	CString strResult;
	if (GetParent()->SendMessage(CDM_GETFOLDERPATH, (WPARAM)MAX_PATH, (LPARAM)strResult.GetBuffer(MAX_PATH)) < 0)
		strResult.Empty();
	else
		strResult.ReleaseBuffer();

	return strResult;
}
#endif

BOOL COXDirectoryDialog::OnInitDialog()
{  
	CFileDialog::OnInitDialog();

	CenterWindow();

	if (!m_bExplorerOn95)
	{
		// .... The directory edit control must exist within this dialog
		ASSERT(GetDlgItem(IDC_OX_DIRECTORY) != NULL);

		// ... Use lower case to show a dir
		CString sDirectory(m_sFullDir);
#ifndef OX_FILEMNG_NOCHANGECASE
		sDirectory.MakeLower();
#endif
		GetDlgItem(IDC_OX_DIRECTORY)->SetWindowText(sDirectory);

		// Let's hide these windows so the user cannot tab to them.  Note that in
		// the private template (in cddemo.dlg) the coordinates for these guys are
		// *outside* the coordinates of the dlg window itself.  Without the following
		// ShowWindow()'s you would not see them, but could still tab to them.
		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);

		// We must put something in this field, even though it is hidden.  This is
		// because if this field is empty, or has something like "*.txt" in it,
		// and the user hits OK, the dlg will NOT close.  We'll jam something in
		// there (like "Junk") so when the user hits OK, the dlg terminates.
		// Note that we'll deal with the "Junk" during return processing (see below)
		SetDlgItemText(edt1, _T("Junk"));

		// The directory text shown in the static control above the directory
		// listbox, will always fit.  When the directory text becomes to large
		// full stops are automatically inserted (like "C:\..\DIR1\DIR2")
		// Because we want to use this contents to show in an edit control, 
		// no full stops should be inserted.  
		// This can be done by making the static control large enough 
		// so full stops will never be inserted
		// Because it will always be invisible, this poses no problem

		CWnd* pDirStatic;
		CRect staticRect;
		pDirStatic = GetDlgItem(stc1);
		ASSERT(pDirStatic != NULL);
		// ... Get the present size
		pDirStatic->GetClientRect(staticRect);
		// ... Make as large as possible
		staticRect.left = 0;
		staticRect.right = SHRT_MAX;
		pDirStatic->MoveWindow(staticRect);
		// ... Hide window
		pDirStatic->ShowWindow(SW_HIDE);

		// Now set the focus to the directory edit control and 
		// select that part of the directory that does not yet exist on disk
		GetDlgItem(IDC_OX_DIRECTORY)->SetFocus();
		// Determine the part of the full directory, that is also in the
		// existing directory
		m_sFullDir.MakeLower();
		m_sExistingDir.MakeLower();
		LPCTSTR pszFullDir = m_sFullDir;
		LPCTSTR pszExistingDir = m_sExistingDir;
		// ... While neither has reached the end of the string and both
		//     characters are the same, continue searching
		while ((*pszFullDir == *pszExistingDir) && (*pszFullDir != _T('\0')))
		{
			pszFullDir++;
			pszExistingDir++;
		}
		// ... Select thet apret that does not yet exist on disk
		((CEdit*)GetDlgItem(IDC_OX_DIRECTORY))->SetSel(PtrToLong(pszFullDir - (LPCTSTR)m_sFullDir), 
			INT_MAX);
	}
#ifdef WIN32
	else
	{
		GetParent()->SendMessage(CDM_HIDECONTROL, (WPARAM)stc3, (LPARAM)0);
		GetParent()->SendMessage(CDM_HIDECONTROL, (WPARAM)edt1, (LPARAM)0);
		GetParent()->SendMessage(CDM_HIDECONTROL, (WPARAM)stc2, (LPARAM)0);
		GetParent()->SendMessage(CDM_HIDECONTROL, (WPARAM)cmb1, (LPARAM)0);
	}
#endif

	m_bAfterInit = TRUE;
	// flag that specifies if picked directory was created or already existed
	m_bNewCreated=FALSE;
	// Focus already explicitely set
	return FALSE;
}

CString COXDirectoryDialog::GetDirectory()
{
	return m_sFullDir;
}

// protected:
void COXDirectoryDialog::OnLBSelChangedNotify(UINT nIDBox, UINT iCurSel, UINT nCode)
{
	ASSERT(!m_bExplorerOn95);
	if (m_bExplorerOn95)
		return;

	CFileDialog::OnLBSelChangedNotify(nIDBox, iCurSel, nCode);
	// When the selection in the directory listbox changes,
	// adjust the diretcory in the edit control
	if (m_bAfterInit && ((nIDBox == lst2) && (nCode == CD_LBSELCHANGE) || 
		(nIDBox == cmb2) && (nCode == CD_LBSELCHANGE)))
	{
		// Tranfer the directory spec from the hidden static control
		// to the visible edit control
		CString sDir;

#ifdef OX_FILEMNG_NOCHANGECASE
		int nSel=GetDlgItem(lst2)->SendMessage(LB_GETCURSEL);
		if(nSel!=LB_ERR)
		{
			sDir.Empty();
			CString sPath;
			for(int nIndex=0; nIndex<=nSel; nIndex++)
			{
				if (GetDlgItem(lst2)->SendMessage(LB_GETTEXT,(WPARAM)nIndex, 
					(LPARAM)sPath.GetBuffer(MAX_PATH))==LB_ERR)
				{
					sPath.ReleaseBuffer();
					GetDlgItem(stc1)->GetWindowText(sDir);
					break;
				}
				sPath.ReleaseBuffer();
				sDir+=(nIndex>1 ? _T("\\") : _T(""))+sPath;
			}
		}
#else
		GetDlgItem(stc1)->GetWindowText(sDir);
#endif

		// ... The string should not contain double full stops within the
		//     directory spec (this would mean that the hidden static control
		//     is to small!)
		ASSERT(sDir.Find(_T("..")) == -1);
		GetDlgItem(IDC_OX_DIRECTORY)->SetWindowText(sDir);
	}
}

#ifdef WIN32
void COXDirectoryDialog::OnFolderChange()
// Notification for Windows 95 and Windows NT 4.0
{
	ASSERT(m_bExplorerOn95);
	if (!m_bExplorerOn95)
		return;

	COXPathSpec sPath;
	m_sFullDir = GetFolderPath();
	sPath.SetDirectory(m_sFullDir);
	sPath.SetFileName(_T("junk.xxx"));
	GetParent()->SendMessage(CDM_SETCONTROLTEXT, (WPARAM)edt1, (LPARAM)(LPCTSTR)sPath.GetPath());
}
#endif

void COXDirectoryDialog::OnOK()
// --- In  : 
// --- Out : 
// --- Returns :
// --- Effect : Called when the user clicks the OK button 
//				(the button with an ID of IDOK).
{
	// .... The directory edit control must exist within this dialog
	ASSERT(GetDlgItem(IDC_OX_DIRECTORY) != NULL);
	GetDlgItem(IDC_OX_DIRECTORY)->GetWindowText(m_sFullDir);

	BOOL bOK = TRUE;

	COXDirSpec fullDir;
	if (!fullDir.SetDirectory(m_sFullDir))
	{
		TRACE(_T("COXDirectoryDialog::OnOK : Invalid dir : %s\n"), (LPCTSTR)m_sFullDir);
		CString sPrompt;
		AfxFormatString1(sPrompt, IDS_OX_INVALID_DIR, (LPCTSTR)m_sFullDir);
		AfxMessageBox(sPrompt, MB_ICONEXCLAMATION, IDS_OX_INVALID_DIR);
		// ... Invalid dir specified
		bOK = FALSE;
	}
	else
	{
		if (!fullDir.Exists() && m_bNewDirAllowed)
		{
			CString sPrompt;
			AfxFormatString1(sPrompt, IDS_OX_CREATE_NEW_DIR, (LPCTSTR)m_sFullDir);
			if (AfxMessageBox(sPrompt, MB_ICONINFORMATION | MB_YESNO, IDS_OX_CREATE_NEW_DIR) == IDYES)
			{
				if (fullDir.DoMakeNew())
				{
					m_sExistingDir = fullDir.GetDirectory();
					//#ifndef OX_FILEMNG_NOCHANGECASE
					m_sFullDir = m_sExistingDir;
					//#endif
					m_bNewCreated=TRUE;
				}
				else
				{
					AfxMessageBox(IDS_OX_FAILED_CREATE_DIR, MB_ICONEXCLAMATION, IDS_OX_FAILED_CREATE_DIR);
					// .... Failed to create dir
					bOK = FALSE;
				}
			}
			else
			{
				// ... User did not allow to create a new directory
				bOK = FALSE;
			}
		}
		else
		{
			if (!fullDir.Exists() && !m_bNewDirAllowed)
			{
				AfxMessageBox(IDS_OX_NON_EXISTING_DIR, MB_ICONEXCLAMATION, IDS_OX_NON_EXISTING_DIR);
				// .... Directory does not exist and not allowed to create
				bOK = FALSE;
			}
		}
	}

	// ... If everything went OK, call base class implementation
	if (bOK)
		CFileDialog::OnOK();
	else
		// ... Set focus on invalid entry
		GetDlgItem(IDC_OX_DIRECTORY)->SetFocus();
}

void COXDirectoryDialog::OnCancel()
// --- In  : 
// --- Out : 
// --- Returns :
// --- Effect : Called when the user clicks the CANCEL button 
//				(the button with an ID of IDCANCEL).
{
	// ... Clear the result dir
	m_sFullDir.Empty();
	// ... Call base class implementation
	CFileDialog::OnCancel();
}

// private:

// Message handlers ---------------------------------------------------------

BEGIN_MESSAGE_MAP(COXDirectoryDialog, CFileDialog)
	//{{AFX_MSG_MAP(COXDirectoryDialog)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

// ==========================================================================

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
Canada Canada
In January 2005, David Cunningham and Chris Maunder created TheUltimateToolbox.com, a new group dedicated to the continued development, support and growth of Dundas Software’s award winning line of MFC, C++ and ActiveX control products.

Ultimate Grid for MFC, Ultimate Toolbox for MFC, and Ultimate TCP/IP have been stalwarts of C++/MFC development for a decade. Thousands of developers have used these products to speed their time to market, improve the quality of their finished products, and enhance the reliability and flexibility of their software.
This is a Organisation

476 members

Comments and Discussions