home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tricks of the Windows Gam…ming Gurus (2nd Edition)
/
Disc2.iso
/
vc98
/
mfc
/
src
/
dlgfile.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1998-06-16
|
13KB
|
497 lines
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992-1998 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.
#include "stdafx.h"
#include <dlgs.h> // for standard control IDs for commdlg
#ifdef AFX_AUX_SEG
#pragma code_seg(AFX_AUX_SEG)
#endif
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define new DEBUG_NEW
////////////////////////////////////////////////////////////////////////////
// FileOpen/FileSaveAs common dialog helper
CFileDialog::CFileDialog(BOOL bOpenFileDialog,
LPCTSTR lpszDefExt, LPCTSTR lpszFileName, DWORD dwFlags,
LPCTSTR lpszFilter, CWnd* pParentWnd) : CCommonDialog(pParentWnd)
{
memset(&m_ofn, 0, sizeof(m_ofn)); // initialize structure to 0/NULL
m_szFileName[0] = '\0';
m_szFileTitle[0] = '\0';
m_pofnTemp = NULL;
m_bOpenFileDialog = bOpenFileDialog;
m_nIDHelp = bOpenFileDialog ? AFX_IDD_FILEOPEN : AFX_IDD_FILESAVE;
m_ofn.lStructSize = sizeof(m_ofn);
m_ofn.lpstrFile = m_szFileName;
m_ofn.nMaxFile = _countof(m_szFileName);
m_ofn.lpstrDefExt = lpszDefExt;
m_ofn.lpstrFileTitle = (LPTSTR)m_szFileTitle;
m_ofn.nMaxFileTitle = _countof(m_szFileTitle);
m_ofn.Flags |= dwFlags | OFN_ENABLEHOOK | OFN_ENABLESIZING;
if (!afxData.bWin4 && AfxHelpEnabled())
m_ofn.Flags |= OFN_SHOWHELP;
if (afxData.bWin4)
{
m_ofn.Flags |= OFN_EXPLORER;
m_ofn.hInstance = AfxGetResourceHandle();
}
m_ofn.lpfnHook = (COMMDLGPROC)_AfxCommDlgProc;
// setup initial file name
if (lpszFileName != NULL)
lstrcpyn(m_szFileName, lpszFileName, _countof(m_szFileName));
// Translate filter into commdlg format (lots of \0)
if (lpszFilter != NULL)
{
m_strFilter = lpszFilter;
LPTSTR pch = m_strFilter.GetBuffer(0); // modify the buffer in place
// MFC delimits with '|' not '\0'
while ((pch = _tcschr(pch, '|')) != NULL)
*pch++ = '\0';
m_ofn.lpstrFilter = m_strFilter;
// do not call ReleaseBuffer() since the string contains '\0' characters
}
}
int CFileDialog::DoModal()
{
ASSERT_VALID(this);
ASSERT(m_ofn.Flags & OFN_ENABLEHOOK);
ASSERT(m_ofn.lpfnHook != NULL); // can still be a user hook
// zero out the file buffer for consistent parsing later
ASSERT(AfxIsValidAddress(m_ofn.lpstrFile, m_ofn.nMaxFile));
DWORD nOffset = lstrlen(m_ofn.lpstrFile)+1;
ASSERT(nOffset <= m_ofn.nMaxFile);
memset(m_ofn.lpstrFile+nOffset, 0, (m_ofn.nMaxFile-nOffset)*sizeof(TCHAR));
// WINBUG: This is a special case for the file open/save dialog,
// which sometimes pumps while it is coming up but before it has
// disabled the main window.
HWND hWndFocus = ::GetFocus();
BOOL bEnableParent = FALSE;
m_ofn.hwndOwner = PreModal();
AfxUnhookWindowCreate();
if (m_ofn.hwndOwner != NULL && ::IsWindowEnabled(m_ofn.hwndOwner))
{
bEnableParent = TRUE;
::EnableWindow(m_ofn.hwndOwner, FALSE);
}
_AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
ASSERT(pThreadState->m_pAlternateWndInit == NULL);
if (m_ofn.Flags & OFN_EXPLORER)
pThreadState->m_pAlternateWndInit = this;
else
AfxHookWindowCreate(this);
int nResult;
if (m_bOpenFileDialog)
nResult = ::GetOpenFileName(&m_ofn);
else
nResult = ::GetSaveFileName(&m_ofn);
if (nResult)
ASSERT(pThreadState->m_pAlternateWndInit == NULL);
pThreadState->m_pAlternateWndInit = NULL;
// WINBUG: Second part of special case for file open/save dialog.
if (bEnableParent)
::EnableWindow(m_ofn.hwndOwner, TRUE);
if (::IsWindow(hWndFocus))
::SetFocus(hWndFocus);
PostModal();
return nResult ? nResult : IDCANCEL;
}
CString CFileDialog::GetPathName() const
{
if ((m_ofn.Flags & OFN_EXPLORER) && m_hWnd != NULL)
{
ASSERT(::IsWindow(m_hWnd));
CString strResult;
if (GetParent()->SendMessage(CDM_GETSPEC, (WPARAM)MAX_PATH,
(LPARAM)strResult.GetBuffer(MAX_PATH)) < 0)
{
strResult.Empty();
}
else
{
strResult.ReleaseBuffer();
}
if (!strResult.IsEmpty())
{
if (GetParent()->SendMessage(CDM_GETFILEPATH, (WPARAM)MAX_PATH,
(LPARAM)strResult.GetBuffer(MAX_PATH)) < 0)
strResult.Empty();
else
{
strResult.ReleaseBuffer();
return strResult;
}
}
}
return m_ofn.lpstrFile;
}
CString CFileDialog::GetFileName() const
{
if ((m_ofn.Flags & OFN_EXPLORER) && m_hWnd != NULL)
{
ASSERT(::IsWindow(m_hWnd));
CString strResult;
if (GetParent()->SendMessage(CDM_GETSPEC, (WPARAM)MAX_PATH,
(LPARAM)strResult.GetBuffer(MAX_PATH)) < 0)
{
strResult.Empty();
}
else
{
strResult.ReleaseBuffer();
return strResult;
}
}
return m_ofn.lpstrFileTitle;
}
CString CFileDialog::GetFileExt() const
{
if ((m_ofn.Flags & OFN_EXPLORER) && m_hWnd != NULL)
{
ASSERT(::IsWindow(m_hWnd));
CString strResult;
if (GetParent()->SendMessage(CDM_GETSPEC, (WPARAM)MAX_PATH,
(LPARAM)strResult.GetBuffer(MAX_PATH)) < 0)
strResult.Empty();
else
{
strResult.ReleaseBuffer();
int pos = strResult.ReverseFind('.');
if (pos >= 0)
return strResult.Right(strResult.GetLength() - pos - 1);
strResult.Empty();
}
return strResult;
}
if (m_pofnTemp != NULL)
if (m_pofnTemp->nFileExtension == 0)
return &afxChNil;
else
return m_pofnTemp->lpstrFile + m_pofnTemp->nFileExtension;
if (m_ofn.nFileExtension == 0)
return &afxChNil;
else
return m_ofn.lpstrFile + m_ofn.nFileExtension;
}
CString CFileDialog::GetFileTitle() const
{
CString strResult = GetFileName();
int pos = strResult.ReverseFind('.');
if (pos >= 0)
return strResult.Left(pos);
return strResult;
}
CString CFileDialog::GetNextPathName(POSITION& pos) const
{
BOOL bExplorer = m_ofn.Flags & OFN_EXPLORER;
TCHAR chDelimiter;
if (bExplorer)
chDelimiter = '\0';
else
chDelimiter = ' ';
LPTSTR lpsz = (LPTSTR)pos;
if (lpsz == m_ofn.lpstrFile) // first time
{
if ((m_ofn.Flags & OFN_ALLOWMULTISELECT) == 0)
{
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;
}
}
CString strPath = m_ofn.lpstrFile;
if (!bExplorer)
{
LPTSTR lpszPath = m_ofn.lpstrFile;
while(*lpszPath != chDelimiter)
lpszPath = _tcsinc(lpszPath);
strPath = strPath.Left(lpszPath - m_ofn.lpstrFile);
}
LPTSTR lpszFileName = lpsz;
CString 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);
lpsz = _tcsinc(lpsz);
if (*lpsz == '\0') // if double terminated then done
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;
}
void CFileDialog::SetTemplate(LPCTSTR lpWin3ID, LPCTSTR lpWin4ID)
{
if (m_ofn.Flags & OFN_EXPLORER)
m_ofn.lpTemplateName = lpWin4ID;
else
m_ofn.lpTemplateName = lpWin3ID;
m_ofn.Flags |= OFN_ENABLETEMPLATE;
}
CString CFileDialog::GetFolderPath() const
{
ASSERT(::IsWindow(m_hWnd));
ASSERT(m_ofn.Flags & OFN_EXPLORER);
CString strResult;
if (GetParent()->SendMessage(CDM_GETFOLDERPATH, (WPARAM)MAX_PATH, (LPARAM)strResult.GetBuffer(MAX_PATH)) < 0)
strResult.Empty();
else
strResult.ReleaseBuffer();
return strResult;
}
void CFileDialog::SetControlText(int nID, LPCSTR lpsz)
{
ASSERT(::IsWindow(m_hWnd));
ASSERT(m_ofn.Flags & OFN_EXPLORER);
GetParent()->SendMessage(CDM_SETCONTROLTEXT, (WPARAM)nID, (LPARAM)lpsz);
}
void CFileDialog::HideControl(int nID)
{
ASSERT(::IsWindow(m_hWnd));
ASSERT(m_ofn.Flags & OFN_EXPLORER);
GetParent()->SendMessage(CDM_HIDECONTROL, (WPARAM)nID, 0);
}
void CFileDialog::SetDefExt(LPCSTR lpsz)
{
ASSERT(::IsWindow(m_hWnd));
ASSERT(m_ofn.Flags & OFN_EXPLORER);
GetParent()->SendMessage(CDM_SETDEFEXT, 0, (LPARAM)lpsz);
}
UINT CFileDialog::OnShareViolation(LPCTSTR)
{
ASSERT_VALID(this);
// Do not call Default() if you override
return OFN_SHAREWARN; // default
}
BOOL CFileDialog::OnFileNameOK()
{
ASSERT_VALID(this);
// Do not call Default() if you override
return FALSE;
}
void CFileDialog::OnLBSelChangedNotify(UINT, UINT, UINT)
{
ASSERT_VALID(this);
// Do not call Default() if you override
// no default processing needed
}
void CFileDialog::OnInitDone()
{
ASSERT_VALID(this);
GetParent()->CenterWindow();
// Do not call Default() if you override
// no default processing needed
}
void CFileDialog::OnFileNameChange()
{
ASSERT_VALID(this);
// Do not call Default() if you override
// no default processing needed
}
void CFileDialog::OnFolderChange()
{
ASSERT_VALID(this);
// Do not call Default() if you override
// no default processing needed
}
void CFileDialog::OnTypeChange()
{
ASSERT_VALID(this);
// Do not call Default() if you override
// no default processing needed
}
BOOL CFileDialog::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
ASSERT(pResult != NULL);
// allow message map to override
if (CCommonDialog::OnNotify(wParam, lParam, pResult))
return TRUE;
OFNOTIFY* pNotify = (OFNOTIFY*)lParam;
switch(pNotify->hdr.code)
{
case CDN_INITDONE:
OnInitDone();
return TRUE;
case CDN_SELCHANGE:
OnFileNameChange();
return TRUE;
case CDN_FOLDERCHANGE:
OnFolderChange();
return TRUE;
case CDN_SHAREVIOLATION:
*pResult = OnShareViolation(pNotify->pszFile);
return TRUE;
case CDN_HELP:
if (!SendMessage(WM_COMMAND, ID_HELP))
SendMessage(WM_COMMANDHELP, 0, 0);
return TRUE;
case CDN_FILEOK:
*pResult = OnFileNameOK();
return TRUE;
case CDN_TYPECHANGE:
OnTypeChange();
return TRUE;
}
return FALSE; // not handled
}
////////////////////////////////////////////////////////////////////////////
// CFileDialog diagnostics
#ifdef _DEBUG
void CFileDialog::Dump(CDumpContext& dc) const
{
CDialog::Dump(dc);
if (m_bOpenFileDialog)
dc << "File open dialog";
else
dc << "File save dialog";
dc << "\nm_ofn.hwndOwner = " << (UINT)m_ofn.hwndOwner;
dc << "\nm_ofn.nFilterIndex = " << m_ofn.nFilterIndex;
dc << "\nm_ofn.lpstrFile = " << m_ofn.lpstrFile;
dc << "\nm_ofn.nMaxFile = " << m_ofn.nMaxFile;
dc << "\nm_ofn.lpstrFileTitle = " << m_ofn.lpstrFileTitle;
dc << "\nm_ofn.nMaxFileTitle = " << m_ofn.nMaxFileTitle;
dc << "\nm_ofn.lpstrTitle = " << m_ofn.lpstrTitle;
dc << "\nm_ofn.Flags = " << (LPVOID)m_ofn.Flags;
dc << "\nm_ofn.lpstrDefExt = " << m_ofn.lpstrDefExt;
dc << "\nm_ofn.nFileOffset = " << m_ofn.nFileOffset;
dc << "\nm_ofn.nFileExtension = " << m_ofn.nFileExtension;
dc << "\nm_ofn.lpstrFilter = ";
LPCTSTR lpstrItem = m_ofn.lpstrFilter;
LPTSTR lpszBreak = _T("|");
while (lpstrItem != NULL && *lpstrItem != '\0')
{
dc << lpstrItem << lpszBreak;
lpstrItem += lstrlen(lpstrItem) + 1;
}
if (lpstrItem != NULL)
dc << lpszBreak;
dc << "\nm_ofn.lpstrCustomFilter = ";
lpstrItem = m_ofn.lpstrCustomFilter;
while (lpstrItem != NULL && *lpstrItem != '\0')
{
dc << lpstrItem << lpszBreak;
lpstrItem += lstrlen(lpstrItem) + 1;
}
if (lpstrItem != NULL)
dc << lpszBreak;
if (m_ofn.lpfnHook == (COMMDLGPROC)_AfxCommDlgProc)
dc << "\nhook function set to standard MFC hook function";
else
dc << "\nhook function set to non-standard hook function";
dc << "\n";
}
#endif //_DEBUG
#ifdef AFX_INIT_SEG
#pragma code_seg(AFX_INIT_SEG)
#endif
IMPLEMENT_DYNAMIC(CFileDialog, CDialog)
////////////////////////////////////////////////////////////////////////////