windows-nt/Source/XPSP1/NT/admin/activec/conui/filedlgex.cpp

143 lines
4.1 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
////////////////////////////////////////////////////////////////
// MSDN -- August 2000
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// Largely based on original implementation by Michael Lemley.
// Compiles with Visual C++ 6.0, runs on Windows 98 and probably NT too.
//
// CFileDialogEx implements a CFileDialog that uses the new Windows
// 2000 style open/save dialog. Use companion class CDocManagerEx in an
// MFC framework app.
//
#include "stdafx.h"
#include <afxpriv.h>
#include "FileDlgEx.h"
IMPLEMENT_DYNAMIC(CFileDialogEx, CFileDialog)
CFileDialogEx::CFileDialogEx(BOOL bOpenFileDialog, LPCTSTR lpszDefExt,
LPCTSTR lpszFileName, DWORD dwFlags, LPCTSTR lpszFilter, CWnd* pParentWnd) :
CFileDialog(bOpenFileDialog, lpszDefExt, lpszFileName,
dwFlags, lpszFilter, pParentWnd)
{
}
BEGIN_MESSAGE_MAP(CFileDialogEx, CFileDialog)
//{{AFX_MSG_MAP(CFileDialogEx)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/*+-------------------------------------------------------------------------*
* HasModernFileDialog
*
* Returns true if the system we're running on supports the "modern" file
* open/save dialog (i.e. the one with the places bar). Systems that
* qualify are Win2K and higher, and WinMe and higher.
*--------------------------------------------------------------------------*/
BOOL HasModernFileDialog()
{
OSVERSIONINFO osvi = { sizeof(osvi) };
if (!GetVersionEx (&osvi))
return (false);
switch (osvi.dwPlatformId)
{
// detect Win2K+
case VER_PLATFORM_WIN32_NT:
if (osvi.dwMajorVersion >= 5)
return (true);
break;
// detect WinMe+
case VER_PLATFORM_WIN32_WINDOWS:
if ( (osvi.dwMajorVersion >= 5) ||
((osvi.dwMajorVersion == 4) && (osvi.dwMinorVersion >= 90)))
return (true);
break;
}
return (false);
}
//////////////////
// DoModal override copied mostly from MFC, with modification to use
// m_ofnEx instead of m_ofn.
//
INT_PTR CFileDialogEx::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);
memset(&m_ofnEx, 0, sizeof(m_ofnEx));
memcpy(&m_ofnEx, &m_ofn, sizeof(m_ofn));
if (HasModernFileDialog())
m_ofnEx.lStructSize = sizeof(m_ofnEx);
int nResult;
if (m_bOpenFileDialog)
nResult = ::GetOpenFileName((OPENFILENAME*)&m_ofnEx);
else
nResult = ::GetSaveFileName((OPENFILENAME*)&m_ofnEx);
memcpy(&m_ofn, &m_ofnEx, sizeof(m_ofn));
m_ofn.lStructSize = sizeof(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_ofnEx.hwndOwner, TRUE);
if (::IsWindow(hWndFocus))
::SetFocus(hWndFocus);
PostModal();
return nResult ? nResult : IDCANCEL;
}
//////////////////
// When the open dialog sends a notification, copy m_ofnEx to m_ofn in
// case handler function is expecting updated information in the
// OPENFILENAME struct.
//
BOOL CFileDialogEx::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
memcpy(&m_ofn, &m_ofnEx, sizeof(m_ofn));
m_ofn.lStructSize = sizeof(m_ofn);
return CFileDialog::OnNotify( wParam, lParam, pResult);
}