// COptionTree
//
// License
// -------
// This code is provided "as is" with no expressed or implied warranty.
//
// You may use this code in a commercial product with or without acknowledgement.
// However you may not sell this code or any modification of this code.
//
// I would appreciate a notification of any bugs to help the control grow.
//
// History:
// --------
// See License.txt for full history information.
//
//
// Copyright (c) 1999-2002
// ComputerSmarts.net
// mattrmiller@computersmarts.net
#include "stdafx.h"
#include "COptionTreeDemo.h"
#include "OptionTreeFileDlg.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
COptionTreeFileDlg::COptionTreeFileDlg()
{
// Initialize variables
m_strFilter = _T("");
::ZeroMemory(&m_ofn, sizeof(m_ofn));
::ZeroMemory(&m_szFile, sizeof(m_szFile));
::ZeroMemory(&m_szFileTitle, sizeof(m_szFileTitle));
::ZeroMemory(&m_szSelectedFolder, sizeof(m_szSelectedFolder));
}
COptionTreeFileDlg::COptionTreeFileDlg(BOOL bOpenFileDialog, LPCTSTR lpszDefExt, LPCTSTR lpszFileName, DWORD dwFlags, LPCTSTR lpszFilter, CWnd* pParentWnd)
{
// Set dialog
SetDialog(bOpenFileDialog, lpszDefExt, lpszFileName, dwFlags, lpszFilter, pParentWnd);
}
COptionTreeFileDlg::~COptionTreeFileDlg()
{
}
void COptionTreeFileDlg::SetDialog(BOOL bOpenFileDialog, LPCTSTR lpszDefExt, LPCTSTR lpszFileName, DWORD dwFlags, LPCTSTR lpszFilter, CWnd* pParentWnd)
{
// Declare variables
CString strFilter;
int nIndex = 0;
// Store parameters into structure
m_bOpenFileDialog = bOpenFileDialog;
m_ofn.lpstrDefExt = lpszDefExt;
if (lpszFileName != NULL)
{
_tcscpy(m_szFile, lpszFileName);
m_ofn.lpstrFile = m_szFile;
m_ofn.nMaxFile = MAX_PATH;
}
else
{
m_ofn.lpstrFile = m_szFile;
m_ofn.nMaxFile = MAX_PATH;
}
m_ofn.lpstrFileTitle = m_szFileTitle;
m_ofn.nMaxFileTitle = MAX_PATH;
m_ofn.Flags = dwFlags | OFN_EXPLORER;
if (lpszFilter != NULL)
{
m_strFilter = lpszFilter;
LPTSTR pch = m_strFilter.GetBuffer(0);
while ((pch = _tcschr(pch, '|')) != NULL)
{
*pch++ = '\0';
}
m_ofn.lpstrFilter = m_strFilter;
}
if (pParentWnd != NULL)
{
m_ofn.hwndOwner = pParentWnd->GetSafeHwnd();
}
}
int COptionTreeFileDlg::DoModal()
{
// Declare variables
BOOL bRetValue;
DWORD dwWinMajor;
// Get OS version
dwWinMajor = (DWORD)(LOBYTE(LOWORD(::GetVersion())));
if (dwWinMajor >= 5)
{
m_ofn.lStructSize = sizeof(m_ofn);
}
else
{
m_ofn.lStructSize = sizeof(OPENFILENAME);
}
// Execute dialog
if (m_bOpenFileDialog)
{
bRetValue = ::GetOpenFileName(&m_ofn);
}
else
{
bRetValue = ::GetSaveFileName(&m_ofn);
}
return (bRetValue ? IDOK : IDCANCEL);
}
CString COptionTreeFileDlg::GetPathName() const
{
return m_ofn.lpstrFile;
}
CString COptionTreeFileDlg::GetFileName() const
{
return m_ofn.lpstrFileTitle;
}
CString COptionTreeFileDlg::GetFileTitle() const
{
TCHAR szTitle[MAX_PATH];
// Validate
if (m_ofn.lpstrFile == NULL)
{
return _T("");
}
// Split path into components
_tsplitpath(m_ofn.lpstrFile, NULL, NULL, szTitle, NULL);
return szTitle;
}
CString COptionTreeFileDlg::GetFileExt() const
{
// Declare variables
TCHAR szExt[MAX_PATH];
// Validate
if (m_ofn.lpstrFile == NULL)
{
return _T("");
}
// Split path into components
_tsplitpath(m_ofn.lpstrFile, NULL, NULL, NULL, szExt);
memmove(szExt, szExt + 1,strlen(szExt) -1);
szExt[strlen(szExt) -1] = '\0';
return szExt;
}
CString COptionTreeFileDlg::GetFileDir() const
{
// Declare variables
TCHAR szDrive[MAX_PATH];
TCHAR szDir[MAX_PATH];
// Validate
if (m_ofn.lpstrFile == NULL)
{
return _T("");
}
// Split path into components
_tsplitpath(m_ofn.lpstrFile, szDrive, szDir, NULL, NULL);
::lstrcat(szDrive, szDir);
return szDrive;
}
CString COptionTreeFileDlg::GetFileDrive() const
{
// Declare variables
TCHAR szDrive[MAX_PATH];
// Validate
if (m_ofn.lpstrFile == NULL)
{
return _T("");
}
// Split path into components
_tsplitpath(m_ofn.lpstrFile, szDrive, NULL, NULL, NULL);
return szDrive;
}
POSITION COptionTreeFileDlg::GetStartPosition() const
{
return (POSITION)m_ofn.lpstrFile;
}
CString COptionTreeFileDlg::GetNextPathName(POSITION& pos) const
{
// Declare variables
BOOL bExplorer = m_ofn.Flags & OFN_EXPLORER;
TCHAR chDelimiter;
LPTSTR lpsz;
CString strPath;
LPTSTR lpszPath;
LPTSTR lpszFileName;
CString strFileName;
// Explorer?
if (bExplorer)
{
chDelimiter = _T('\0');
}
else
{
chDelimiter = _T(' ');
}
// Get it
lpsz = (LPTSTR)pos;
if (lpsz == m_ofn.lpstrFile)
{
if ((m_ofn.Flags & OFN_ALLOWMULTISELECT) == FALSE)
{
pos = NULL;
return m_ofn.lpstrFile;
}
// -- find char pos after first Delimiter
while(*lpsz != chDelimiter && *lpsz != '\0')
lpsz = _tcsinc(lpsz);
lpsz = _tcsinc(lpsz);
// -- If single selection then return only selection
if (*lpsz == 0)
{
pos = NULL;
return m_ofn.lpstrFile;
}
}
strPath = m_ofn.lpstrFile;
if (!bExplorer)
{
lpszPath = m_ofn.lpstrFile;
while(*lpszPath != chDelimiter)
{
lpszPath = _tcsinc(lpszPath);
}
strPath = strPath.Left(lpszPath - m_ofn.lpstrFile);
}
lpszFileName = lpsz;
strFileName = lpsz;
// Find char pos at next Delimiter
while(*lpsz != chDelimiter && *lpsz != '\0')
{
lpsz = _tcsinc(lpsz);
}
if (!bExplorer && *lpsz == '\0')
{
pos = NULL;
}
else
{
if (!bExplorer)
{
strFileName = strFileName.Left(lpsz - lpszFileName);
}
// -- If double terminated then done
lpsz = _tcsinc(lpsz);
if (*lpsz == '\0')
{
pos = NULL;
}
else
{
pos = (POSITION)lpsz;
}
}
// -- Only add '\\' if it is needed
if (!strPath.IsEmpty())
{
// -- check for last back-slash or forward slash (handles DBCS)
LPCTSTR lpsz = _tcsrchr(strPath, '\\');
if (lpsz == NULL)
{
lpsz = _tcsrchr(strPath, '/');
}
// -- if it is also the last character, then we don't need an extra
if (lpsz != NULL && (lpsz - (LPCTSTR)strPath) == strPath.GetLength()-1)
{
ASSERT(*lpsz == '\\' || *lpsz == '/');
return strPath + strFileName;
}
}
return strPath + '\\' + strFileName;
}
int COptionTreeFileDlg::SelectFolder(LPCTSTR lpszTitle, LPCTSTR lpszStartPath, UINT ulFlags, CWnd* pParentWnd)
{
// Declare variables
LPMALLOC pMalloc;
BROWSEINFO bi;
LPITEMIDLIST pidl;
int nRetValue = IDCANCEL;
::ZeroMemory(&bi, sizeof(bi));
// Gets the Shell's default allocator
if (::SHGetMalloc(&pMalloc) == NOERROR)
{
// -- Get help on BROWSEINFO struct - it's got all the bit settings.
if (pParentWnd != NULL)
{
bi.hwndOwner = pParentWnd->GetSafeHwnd();
}
bi.pidlRoot = NULL;
bi.pszDisplayName = m_szSelectedFolder;
bi.lpszTitle = lpszTitle;
bi.ulFlags = ulFlags;
bi.lpfn = BrowseCtrlCallback;
bi.lParam = (LPARAM)lpszStartPath;
// -- This next call issues the dialog box.
if ((pidl = ::SHBrowseForFolder(&bi)) != NULL)
{
if (::SHGetPathFromIDList(pidl, m_szSelectedFolder))
{
// -- -- At this point pszBuffer contains the selected path
nRetValue = IDOK;
}
// -- -- Free the PIDL allocated by SHBrowseForFolder.
pMalloc->Free(pidl);
}
// -- Release the shell's allocator.
pMalloc->Release();
}
return nRetValue;
}
int __stdcall COptionTreeFileDlg::BrowseCtrlCallback(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
{
if (uMsg == BFFM_INITIALIZED && lpData != NULL)
{
::SendMessage(hwnd, BFFM_SETSELECTION, TRUE, lpData);
}
return 0;
}
CString COptionTreeFileDlg::GetSelectedFolder() const
{
return m_szSelectedFolder;
}