home *** CD-ROM | disk | FTP | other *** search
/ Team Palmtops 7 / Palmtops_numero07.iso / WinCE / SDKWindowsCE / HandHeldPCPro30 / sdk.exe / Jupiter SDK / data1.cab / MFC / src / dlgfile.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-02-19  |  13.4 KB  |  524 lines

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