home *** CD-ROM | disk | FTP | other *** search
/ Supercompiler 1997 / SUPERCOMPILER97.iso / MS_VC.50 / VC / MFC / SRC / DLGFILE.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1996-10-30  |  12.7 KB  |  524 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1997 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11. #include "stdafx.h"
  12. #include <dlgs.h>       // for standard control IDs for commdlg
  13.  
  14. #ifdef AFX_AUX_SEG
  15. #pragma code_seg(AFX_AUX_SEG)
  16. #endif
  17.  
  18. #ifdef _DEBUG
  19. #undef THIS_FILE
  20. static char THIS_FILE[] = __FILE__;
  21. #endif
  22.  
  23. #define new DEBUG_NEW
  24.  
  25. ////////////////////////////////////////////////////////////////////////////
  26. // FileOpen/FileSaveAs common dialog helper
  27.  
  28. CFileDialog::CFileDialog(BOOL bOpenFileDialog,
  29.     LPCTSTR lpszDefExt, LPCTSTR lpszFileName, DWORD dwFlags,
  30.     LPCTSTR lpszFilter, CWnd* pParentWnd) : CCommonDialog(pParentWnd)
  31. {
  32.     memset(&m_ofn, 0, sizeof(m_ofn)); // initialize structure to 0/NULL
  33.     m_szFileName[0] = '\0';
  34.     m_szFileTitle[0] = '\0';
  35.     m_pofnTemp = NULL;
  36.  
  37.     m_bOpenFileDialog = bOpenFileDialog;
  38.     m_nIDHelp = bOpenFileDialog ? AFX_IDD_FILEOPEN : AFX_IDD_FILESAVE;
  39.  
  40.     m_ofn.lStructSize = sizeof(m_ofn);
  41.     m_ofn.lpstrFile = m_szFileName;
  42.     m_ofn.nMaxFile = _countof(m_szFileName);
  43.     m_ofn.lpstrDefExt = lpszDefExt;
  44.     m_ofn.lpstrFileTitle = (LPTSTR)m_szFileTitle;
  45.     m_ofn.nMaxFileTitle = _countof(m_szFileTitle);
  46.     m_ofn.Flags |= dwFlags | OFN_ENABLEHOOK;
  47.     if (!afxData.bWin4 && AfxHelpEnabled())
  48.         m_ofn.Flags |= OFN_SHOWHELP;
  49.     if (afxData.bWin4)
  50.     {
  51.         m_ofn.Flags |= OFN_EXPLORER;
  52.         m_ofn.hInstance = AfxGetResourceHandle();
  53.     }
  54.     m_ofn.lpfnHook = (COMMDLGPROC)_AfxCommDlgProc;
  55.  
  56.     // setup initial file name
  57.     if (lpszFileName != NULL)
  58.         lstrcpyn(m_szFileName, lpszFileName, _countof(m_szFileName));
  59.  
  60.     // Translate filter into commdlg format (lots of \0)
  61.     if (lpszFilter != NULL)
  62.     {
  63.         m_strFilter = lpszFilter;
  64.         LPTSTR pch = m_strFilter.GetBuffer(0); // modify the buffer in place
  65.         // MFC delimits with '|' not '\0'
  66.         while ((pch = _tcschr(pch, '|')) != NULL)
  67.             *pch++ = '\0';
  68.         m_ofn.lpstrFilter = m_strFilter;
  69.         // do not call ReleaseBuffer() since the string contains '\0' characters
  70.     }
  71. }
  72.  
  73. int CFileDialog::DoModal()
  74. {
  75.     ASSERT_VALID(this);
  76.     ASSERT(m_ofn.Flags & OFN_ENABLEHOOK);
  77.     ASSERT(m_ofn.lpfnHook != NULL); // can still be a user hook
  78. #ifdef _MAC
  79.     ASSERT((m_ofn.Flags & OFN_ALLOWMULTISELECT) == 0);
  80. #endif
  81.  
  82.     // WINBUG: This is a special case for the file open/save dialog,
  83.     //  which sometimes pumps while it is coming up but before it has
  84.     //  disabled the main window.
  85.     HWND hWndFocus = ::GetFocus();
  86.     BOOL bEnableParent = FALSE;
  87.     m_ofn.hwndOwner = PreModal();
  88.     AfxUnhookWindowCreate();
  89.     if (m_ofn.hwndOwner != NULL && ::IsWindowEnabled(m_ofn.hwndOwner))
  90.     {
  91.         bEnableParent = TRUE;
  92.         ::EnableWindow(m_ofn.hwndOwner, FALSE);
  93.     }
  94.  
  95.     _AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
  96.     ASSERT(pThreadState->m_pAlternateWndInit == NULL);
  97.  
  98.     if (m_ofn.Flags & OFN_EXPLORER)
  99.         pThreadState->m_pAlternateWndInit = this;
  100.     else
  101.         AfxHookWindowCreate(this);
  102.  
  103.     int nResult;
  104.     if (m_bOpenFileDialog)
  105.         nResult = ::GetOpenFileName(&m_ofn);
  106.     else
  107.         nResult = ::GetSaveFileName(&m_ofn);
  108.  
  109.     if (nResult)
  110.         ASSERT(pThreadState->m_pAlternateWndInit == NULL);
  111.     pThreadState->m_pAlternateWndInit = NULL;
  112.  
  113.     // WINBUG: Second part of special case for file open/save dialog.
  114.     if (bEnableParent)
  115.         ::EnableWindow(m_ofn.hwndOwner, TRUE);
  116.     if (::IsWindow(hWndFocus))
  117.         ::SetFocus(hWndFocus);
  118.  
  119.     PostModal();
  120.     return nResult ? nResult : IDCANCEL;
  121. }
  122.  
  123. CString CFileDialog::GetPathName() const
  124. {
  125. #ifndef _MAC
  126.     if ((m_ofn.Flags & OFN_EXPLORER) && m_hWnd != NULL)
  127.     {
  128.         ASSERT(::IsWindow(m_hWnd));
  129.         CString strResult;
  130.         if (GetParent()->SendMessage(CDM_GETSPEC, (WPARAM)MAX_PATH,
  131.             (LPARAM)strResult.GetBuffer(MAX_PATH)) < 0)
  132.         {
  133.             strResult.Empty();
  134.         }
  135.         else
  136.         {
  137.             strResult.ReleaseBuffer();
  138.         }
  139.  
  140.         if (!strResult.IsEmpty())
  141.         {
  142.             if (GetParent()->SendMessage(CDM_GETFILEPATH, (WPARAM)MAX_PATH,
  143.                 (LPARAM)strResult.GetBuffer(MAX_PATH)) < 0)
  144.                 strResult.Empty();
  145.             else
  146.             {
  147.                 strResult.ReleaseBuffer();
  148.                 return strResult;
  149.             }
  150.         }
  151.     }
  152.     return m_ofn.lpstrFile;
  153. #else
  154.     CString strResult;
  155.     LPSTR pstr;
  156.     ::GetFullPathName(m_ofn.lpstrFile, MAX_PATH, strResult.GetBuffer(MAX_PATH), &pstr);
  157.     strResult.ReleaseBuffer();
  158.     return strResult;
  159. #endif
  160. }
  161.  
  162. CString CFileDialog::GetFileName() const
  163. {
  164. #ifndef _MAC
  165.     if ((m_ofn.Flags & OFN_EXPLORER) && m_hWnd != NULL)
  166.     {
  167.         ASSERT(::IsWindow(m_hWnd));
  168.         CString strResult;
  169.         if (GetParent()->SendMessage(CDM_GETSPEC, (WPARAM)MAX_PATH,
  170.             (LPARAM)strResult.GetBuffer(MAX_PATH)) < 0)
  171.         {
  172.             strResult.Empty();
  173.         }
  174.         else
  175.         {
  176.             strResult.ReleaseBuffer();
  177.             return strResult;
  178.         }
  179.     }
  180. #endif
  181.     return m_ofn.lpstrFileTitle;
  182. }
  183.  
  184. CString CFileDialog::GetFileExt() const
  185. {
  186. #ifndef _MAC
  187.     if ((m_ofn.Flags & OFN_EXPLORER) && m_hWnd != NULL)
  188.     {
  189.         ASSERT(::IsWindow(m_hWnd));
  190.         CString strResult;
  191.         if (GetParent()->SendMessage(CDM_GETSPEC, (WPARAM)MAX_PATH,
  192.             (LPARAM)strResult.GetBuffer(MAX_PATH)) < 0)
  193.             strResult.Empty();
  194.         else
  195.         {
  196.             strResult.ReleaseBuffer();
  197.             int pos = strResult.ReverseFind('.');
  198.             if (pos >= 0)
  199.                 return strResult.Right(strResult.GetLength() - pos - 1);
  200.             strResult.Empty();
  201.         }
  202.         return strResult;
  203.     }
  204. #endif
  205.  
  206.     if (m_pofnTemp != NULL)
  207.         if (m_pofnTemp->nFileExtension == 0)
  208.             return &afxChNil;
  209.         else
  210.             return m_pofnTemp->lpstrFile + m_pofnTemp->nFileExtension;
  211.  
  212.     if (m_ofn.nFileExtension == 0)
  213.         return &afxChNil;
  214.     else
  215.         return m_ofn.lpstrFile + m_ofn.nFileExtension;
  216. }
  217.  
  218. CString CFileDialog::GetFileTitle() const
  219. {
  220. #ifndef _MAC
  221.     CString strResult = GetFileName();
  222.     int pos = strResult.ReverseFind('.');
  223.     if (pos >= 0)
  224.         return strResult.Left(pos);
  225.     return strResult;
  226. #else
  227.     return GetFileName();
  228. #endif
  229. }
  230.  
  231. CString CFileDialog::GetNextPathName(POSITION& pos) const
  232. {
  233. #ifndef _MAC
  234.     BOOL bExplorer = m_ofn.Flags & OFN_EXPLORER;
  235.     TCHAR chDelimiter;
  236.     if (bExplorer)
  237.         chDelimiter = '\0';
  238.     else
  239.         chDelimiter = ' ';
  240.  
  241.     LPTSTR lpsz = (LPTSTR)pos;
  242.     if (lpsz == m_ofn.lpstrFile) // first time
  243.     {
  244.         if ((m_ofn.Flags & OFN_ALLOWMULTISELECT) == 0)
  245.         {
  246.             pos = NULL;
  247.             return m_ofn.lpstrFile;
  248.         }
  249.  
  250.         // find char pos after first Delimiter
  251.         while(*lpsz != chDelimiter && *lpsz != '\0')
  252.             lpsz = _tcsinc(lpsz);
  253.         lpsz = _tcsinc(lpsz);
  254.  
  255.         // if single selection then return only selection
  256.         if ((lpsz - m_ofn.lpstrFile) > m_ofn.nFileOffset)
  257.         {
  258.             pos = NULL;
  259.             return m_ofn.lpstrFile;
  260.         }
  261.     }
  262.  
  263.     CString strPath = m_ofn.lpstrFile;
  264.     if (!bExplorer)
  265.     {
  266.         LPTSTR lpszPath = m_ofn.lpstrFile;
  267.         while(*lpszPath != chDelimiter)
  268.             lpszPath = _tcsinc(lpszPath);
  269.         strPath = strPath.Left(lpszPath - m_ofn.lpstrFile);
  270.     }
  271.  
  272.     LPTSTR lpszFileName = lpsz;
  273.     CString strFileName = lpsz;
  274.  
  275.     // find char pos at next Delimiter
  276.     while(*lpsz != chDelimiter && *lpsz != '\0')
  277.         lpsz = _tcsinc(lpsz);
  278.  
  279.     if (!bExplorer && *lpsz == '\0')
  280.         pos = NULL;
  281.     else
  282.     {
  283.         if (!bExplorer)
  284.             strFileName = strFileName.Left(lpsz - lpszFileName);
  285.  
  286.         lpsz = _tcsinc(lpsz);
  287.         if (*lpsz == '\0') // if double terminated then done
  288.             pos = NULL;
  289.         else
  290.             pos = (POSITION)lpsz;
  291.     }
  292.  
  293.     // only add '\\' if it is needed
  294.     if (!strPath.IsEmpty())
  295.     {
  296.         // check for last back-slash or forward slash (handles DBCS)
  297.         LPCTSTR lpsz = _tcsrchr(strPath, '\\');
  298.         if (lpsz == NULL)
  299.             lpsz = _tcsrchr(strPath, '/');
  300.         // if it is also the last character, then we don't need an extra
  301.         if (lpsz != NULL &&
  302.             (lpsz - (LPCTSTR)strPath) == strPath.GetLength()-1)
  303.         {
  304.             ASSERT(*lpsz == '\\' || *lpsz == '/');
  305.             return strPath + strFileName;
  306.         }
  307.     }
  308.     return strPath + '\\' + strFileName;
  309. #else
  310.     pos = NULL;
  311.     return m_ofn.lpstrFile;
  312. #endif
  313. }
  314.  
  315. void CFileDialog::SetTemplate(LPCTSTR lpWin3ID, LPCTSTR lpWin4ID)
  316. {
  317. #ifndef _MAC
  318.     if (m_ofn.Flags & OFN_EXPLORER)
  319.         m_ofn.lpTemplateName = lpWin4ID;
  320.     else
  321.         m_ofn.lpTemplateName = lpWin3ID;
  322.     m_ofn.Flags |= OFN_ENABLETEMPLATE;
  323. #else
  324.     UNUSED_ALWAYS(lpWin3ID);
  325.     UNUSED_ALWAYS(lpWin4ID);
  326. #endif
  327. }
  328.  
  329. #ifndef _MAC
  330. CString CFileDialog::GetFolderPath() const
  331. {
  332.     ASSERT(::IsWindow(m_hWnd));
  333.     ASSERT(m_ofn.Flags & OFN_EXPLORER);
  334.  
  335.     CString strResult;
  336.     if (GetParent()->SendMessage(CDM_GETFOLDERPATH, (WPARAM)MAX_PATH, (LPARAM)strResult.GetBuffer(MAX_PATH)) < 0)
  337.         strResult.Empty();
  338.     else
  339.         strResult.ReleaseBuffer();
  340.     return strResult;
  341. }
  342.  
  343. void CFileDialog::SetControlText(int nID, LPCSTR lpsz)
  344. {
  345.     ASSERT(::IsWindow(m_hWnd));
  346.     ASSERT(m_ofn.Flags & OFN_EXPLORER);
  347.     GetParent()->SendMessage(CDM_SETCONTROLTEXT, (WPARAM)nID, (LPARAM)lpsz);
  348. }
  349.  
  350. void CFileDialog::HideControl(int nID)
  351. {
  352.     ASSERT(::IsWindow(m_hWnd));
  353.     ASSERT(m_ofn.Flags & OFN_EXPLORER);
  354.     GetParent()->SendMessage(CDM_HIDECONTROL, (WPARAM)nID, 0);
  355. }
  356.  
  357. void CFileDialog::SetDefExt(LPCSTR lpsz)
  358. {
  359.     ASSERT(::IsWindow(m_hWnd));
  360.     ASSERT(m_ofn.Flags & OFN_EXPLORER);
  361.     GetParent()->SendMessage(CDM_SETDEFEXT, 0, (LPARAM)lpsz);
  362. }
  363. #endif //!_MAC
  364.  
  365. UINT CFileDialog::OnShareViolation(LPCTSTR)
  366. {
  367.     ASSERT_VALID(this);
  368.  
  369.     // Do not call Default() if you override
  370.     return OFN_SHAREWARN; // default
  371. }
  372.  
  373. BOOL CFileDialog::OnFileNameOK()
  374. {
  375.     ASSERT_VALID(this);
  376.  
  377.     // Do not call Default() if you override
  378.     return FALSE;
  379. }
  380.  
  381. void CFileDialog::OnLBSelChangedNotify(UINT, UINT, UINT)
  382. {
  383.     ASSERT_VALID(this);
  384.  
  385.     // Do not call Default() if you override
  386.     // no default processing needed
  387. }
  388.  
  389. void CFileDialog::OnInitDone()
  390. {
  391.     ASSERT_VALID(this);
  392.     GetParent()->CenterWindow();
  393.  
  394.     // Do not call Default() if you override
  395.     // no default processing needed
  396. }
  397.  
  398. void CFileDialog::OnFileNameChange()
  399. {
  400.     ASSERT_VALID(this);
  401.  
  402.     // Do not call Default() if you override
  403.     // no default processing needed
  404. }
  405.  
  406. void CFileDialog::OnFolderChange()
  407. {
  408.     ASSERT_VALID(this);
  409.  
  410.     // Do not call Default() if you override
  411.     // no default processing needed
  412. }
  413.  
  414. void CFileDialog::OnTypeChange()
  415. {
  416.     ASSERT_VALID(this);
  417.  
  418.     // Do not call Default() if you override
  419.     // no default processing needed
  420. }
  421.  
  422. BOOL CFileDialog::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
  423. {
  424.     ASSERT(pResult != NULL);
  425.  
  426.     // allow message map to override
  427.     if (CCommonDialog::OnNotify(wParam, lParam, pResult))
  428.         return TRUE;
  429.  
  430. #ifndef _MAC
  431.     OFNOTIFY* pNotify = (OFNOTIFY*)lParam;
  432.     switch(pNotify->hdr.code)
  433.     {
  434.     case CDN_INITDONE:
  435.         OnInitDone();
  436.         return TRUE;
  437.     case CDN_SELCHANGE:
  438.         OnFileNameChange();
  439.         return TRUE;
  440.     case CDN_FOLDERCHANGE:
  441.         OnFolderChange();
  442.         return TRUE;
  443.     case CDN_SHAREVIOLATION:
  444.         *pResult = OnShareViolation(pNotify->pszFile);
  445.         return TRUE;
  446.     case CDN_HELP:
  447.         if (!SendMessage(WM_COMMAND, ID_HELP))
  448.             SendMessage(WM_COMMANDHELP, 0, 0);
  449.         return TRUE;
  450.     case CDN_FILEOK:
  451.         *pResult = OnFileNameOK();
  452.         return TRUE;
  453.     case CDN_TYPECHANGE:
  454.         OnTypeChange();
  455.         return TRUE;
  456.     }
  457. #endif
  458.  
  459.     return FALSE;   // not handled
  460. }
  461.  
  462. ////////////////////////////////////////////////////////////////////////////
  463. // CFileDialog diagnostics
  464.  
  465. #ifdef _DEBUG
  466. void CFileDialog::Dump(CDumpContext& dc) const
  467. {
  468.     CDialog::Dump(dc);
  469.  
  470.     if (m_bOpenFileDialog)
  471.         dc << "File open dialog";
  472.     else
  473.         dc << "File save dialog";
  474.     dc << "\nm_ofn.hwndOwner = " << (UINT)m_ofn.hwndOwner;
  475.     dc << "\nm_ofn.nFilterIndex = " << m_ofn.nFilterIndex;
  476.     dc << "\nm_ofn.lpstrFile = " << m_ofn.lpstrFile;
  477.     dc << "\nm_ofn.nMaxFile = " << m_ofn.nMaxFile;
  478.     dc << "\nm_ofn.lpstrFileTitle = " << m_ofn.lpstrFileTitle;
  479.     dc << "\nm_ofn.nMaxFileTitle = " << m_ofn.nMaxFileTitle;
  480.     dc << "\nm_ofn.lpstrTitle = " << m_ofn.lpstrTitle;
  481.     dc << "\nm_ofn.Flags = " << (LPVOID)m_ofn.Flags;
  482.     dc << "\nm_ofn.lpstrDefExt = " << m_ofn.lpstrDefExt;
  483.     dc << "\nm_ofn.nFileOffset = " << m_ofn.nFileOffset;
  484.     dc << "\nm_ofn.nFileExtension = " << m_ofn.nFileExtension;
  485.  
  486.     dc << "\nm_ofn.lpstrFilter = ";
  487.     LPCTSTR lpstrItem = m_ofn.lpstrFilter;
  488.     LPTSTR lpszBreak = _T("|");
  489.  
  490.     while (lpstrItem != NULL && *lpstrItem != '\0')
  491.     {
  492.         dc << lpstrItem << lpszBreak;
  493.         lpstrItem += lstrlen(lpstrItem) + 1;
  494.     }
  495.     if (lpstrItem != NULL)
  496.         dc << lpszBreak;
  497.  
  498.     dc << "\nm_ofn.lpstrCustomFilter = ";
  499.     lpstrItem = m_ofn.lpstrCustomFilter;
  500.     while (lpstrItem != NULL && *lpstrItem != '\0')
  501.     {
  502.         dc << lpstrItem << lpszBreak;
  503.         lpstrItem += lstrlen(lpstrItem) + 1;
  504.     }
  505.     if (lpstrItem != NULL)
  506.         dc << lpszBreak;
  507.  
  508.     if (m_ofn.lpfnHook == (COMMDLGPROC)_AfxCommDlgProc)
  509.         dc << "\nhook function set to standard MFC hook function";
  510.     else
  511.         dc << "\nhook function set to non-standard hook function";
  512.  
  513.     dc << "\n";
  514. }
  515. #endif //_DEBUG
  516.  
  517. #ifdef AFX_INIT_SEG
  518. #pragma code_seg(AFX_INIT_SEG)
  519. #endif
  520.  
  521. IMPLEMENT_DYNAMIC(CFileDialog, CDialog)
  522.  
  523. ////////////////////////////////////////////////////////////////////////////
  524.