Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

142 lines
4.1 KiB

  1. ////////////////////////////////////////////////////////////////
  2. // MSDN -- August 2000
  3. // If this code works, it was written by Paul DiLascia.
  4. // If not, I don't know who wrote it.
  5. // Largely based on original implementation by Michael Lemley.
  6. // Compiles with Visual C++ 6.0, runs on Windows 98 and probably NT too.
  7. //
  8. // CFileDialogEx implements a CFileDialog that uses the new Windows
  9. // 2000 style open/save dialog. Use companion class CDocManagerEx in an
  10. // MFC framework app.
  11. //
  12. #include "stdafx.h"
  13. #include <afxpriv.h>
  14. #include "FileDlgEx.h"
  15. IMPLEMENT_DYNAMIC(CFileDialogEx, CFileDialog)
  16. CFileDialogEx::CFileDialogEx(BOOL bOpenFileDialog, LPCTSTR lpszDefExt,
  17. LPCTSTR lpszFileName, DWORD dwFlags, LPCTSTR lpszFilter, CWnd* pParentWnd) :
  18. CFileDialog(bOpenFileDialog, lpszDefExt, lpszFileName,
  19. dwFlags, lpszFilter, pParentWnd)
  20. {
  21. }
  22. BEGIN_MESSAGE_MAP(CFileDialogEx, CFileDialog)
  23. //{{AFX_MSG_MAP(CFileDialogEx)
  24. //}}AFX_MSG_MAP
  25. END_MESSAGE_MAP()
  26. /*+-------------------------------------------------------------------------*
  27. * HasModernFileDialog
  28. *
  29. * Returns true if the system we're running on supports the "modern" file
  30. * open/save dialog (i.e. the one with the places bar). Systems that
  31. * qualify are Win2K and higher, and WinMe and higher.
  32. *--------------------------------------------------------------------------*/
  33. BOOL HasModernFileDialog()
  34. {
  35. OSVERSIONINFO osvi = { sizeof(osvi) };
  36. if (!GetVersionEx (&osvi))
  37. return (false);
  38. switch (osvi.dwPlatformId)
  39. {
  40. // detect Win2K+
  41. case VER_PLATFORM_WIN32_NT:
  42. if (osvi.dwMajorVersion >= 5)
  43. return (true);
  44. break;
  45. // detect WinMe+
  46. case VER_PLATFORM_WIN32_WINDOWS:
  47. if ( (osvi.dwMajorVersion >= 5) ||
  48. ((osvi.dwMajorVersion == 4) && (osvi.dwMinorVersion >= 90)))
  49. return (true);
  50. break;
  51. }
  52. return (false);
  53. }
  54. //////////////////
  55. // DoModal override copied mostly from MFC, with modification to use
  56. // m_ofnEx instead of m_ofn.
  57. //
  58. INT_PTR CFileDialogEx::DoModal()
  59. {
  60. ASSERT_VALID(this);
  61. ASSERT(m_ofn.Flags & OFN_ENABLEHOOK);
  62. ASSERT(m_ofn.lpfnHook != NULL); // can still be a user hook
  63. // zero out the file buffer for consistent parsing later
  64. ASSERT(AfxIsValidAddress(m_ofn.lpstrFile, m_ofn.nMaxFile));
  65. DWORD nOffset = lstrlen(m_ofn.lpstrFile)+1;
  66. ASSERT(nOffset <= m_ofn.nMaxFile);
  67. memset(m_ofn.lpstrFile+nOffset, 0, (m_ofn.nMaxFile-nOffset)*sizeof(TCHAR));
  68. // WINBUG: This is a special case for the file open/save dialog,
  69. // which sometimes pumps while it is coming up but before it has
  70. // disabled the main window.
  71. HWND hWndFocus = ::GetFocus();
  72. BOOL bEnableParent = FALSE;
  73. m_ofn.hwndOwner = PreModal();
  74. AfxUnhookWindowCreate();
  75. if (m_ofn.hwndOwner != NULL && ::IsWindowEnabled(m_ofn.hwndOwner))
  76. {
  77. bEnableParent = TRUE;
  78. ::EnableWindow(m_ofn.hwndOwner, FALSE);
  79. }
  80. _AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
  81. ASSERT(pThreadState->m_pAlternateWndInit == NULL);
  82. if (m_ofn.Flags & OFN_EXPLORER)
  83. pThreadState->m_pAlternateWndInit = this;
  84. else
  85. AfxHookWindowCreate(this);
  86. memset(&m_ofnEx, 0, sizeof(m_ofnEx));
  87. memcpy(&m_ofnEx, &m_ofn, sizeof(m_ofn));
  88. if (HasModernFileDialog())
  89. m_ofnEx.lStructSize = sizeof(m_ofnEx);
  90. int nResult;
  91. if (m_bOpenFileDialog)
  92. nResult = ::GetOpenFileName((OPENFILENAME*)&m_ofnEx);
  93. else
  94. nResult = ::GetSaveFileName((OPENFILENAME*)&m_ofnEx);
  95. memcpy(&m_ofn, &m_ofnEx, sizeof(m_ofn));
  96. m_ofn.lStructSize = sizeof(m_ofn);
  97. if (nResult)
  98. ASSERT(pThreadState->m_pAlternateWndInit == NULL);
  99. pThreadState->m_pAlternateWndInit = NULL;
  100. // WINBUG: Second part of special case for file open/save dialog.
  101. if (bEnableParent)
  102. ::EnableWindow(m_ofnEx.hwndOwner, TRUE);
  103. if (::IsWindow(hWndFocus))
  104. ::SetFocus(hWndFocus);
  105. PostModal();
  106. return nResult ? nResult : IDCANCEL;
  107. }
  108. //////////////////
  109. // When the open dialog sends a notification, copy m_ofnEx to m_ofn in
  110. // case handler function is expecting updated information in the
  111. // OPENFILENAME struct.
  112. //
  113. BOOL CFileDialogEx::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
  114. {
  115. memcpy(&m_ofn, &m_ofnEx, sizeof(m_ofn));
  116. m_ofn.lStructSize = sizeof(m_ofn);
  117. return CFileDialog::OnNotify( wParam, lParam, pResult);
  118. }