home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / C++-7 / DISK10 / MFC / SRC / WINDLGS.CP$ / windlgs
Encoding:
Text File  |  1992-03-18  |  20.2 KB  |  780 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library. 
  2. // Copyright (C) 1992 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 Microsoft 
  7. // QuickHelp documentation provided with the library. 
  8. // See these sources for detailed information regarding the 
  9. // Microsoft Foundation Classes product. 
  10.  
  11.  
  12. #include "afxwin.h"
  13. #pragma hdrstop
  14.  
  15. #include "afxdlgs.h"    // standard AFX dialogs
  16.  
  17. #include "stddef.h"     // for offsetof macro
  18. #include "window_.h"    // for hooks and other internals 
  19. #include "dlgs.h"       // for standard control IDs for commdlg
  20.  
  21. #ifdef AFX_CORE_SEG
  22. #pragma code_seg(AFX_AUX_SEG)
  23. #endif
  24.  
  25. #ifdef _DEBUG
  26. #undef THIS_FILE
  27. static char BASED_CODE THIS_FILE[] = __FILE__;
  28. #define new DEBUG_NEW
  29. #endif
  30.  
  31. static char BASED_CODE szLBSELCH[] = LBSELCHSTRING;
  32. static char BASED_CODE szSHAREVI[] = SHAREVISTRING;
  33. static char BASED_CODE szFILEOK[] = FILEOKSTRING;
  34. static char BASED_CODE szCOLOROK[] = COLOROKSTRING;
  35. static char BASED_CODE szSETRGB[] = SETRGBSTRING;
  36.  
  37. static UINT nMsgLBSELCHANGE = ::RegisterWindowMessage(szLBSELCH);
  38. static UINT nMsgSHAREVI = ::RegisterWindowMessage(szSHAREVI);
  39. static UINT nMsgFILEOK = ::RegisterWindowMessage(szFILEOK);
  40. static UINT nMsgCOLOROK = ::RegisterWindowMessage(szCOLOROK);
  41. static UINT nMsgSETRGB = ::RegisterWindowMessage(szSETRGB);
  42.  
  43. typedef UINT (FAR PASCAL* COMMDLGPROC)(HWND, UINT, UINT, LONG);
  44.  
  45. UINT FAR PASCAL AFX_EXPORT
  46. _AfxCommDlgProc(HWND hWnd, register UINT message, UINT wParam, LONG lParam)
  47. {
  48.     if (message == WM_SETFONT || message == WM_INITDIALOG)
  49.         return (UINT)_AfxDlgProc(hWnd, message, wParam, lParam);
  50.  
  51.     if (message < 0xC000)
  52.         // not a ::RegisterWindowMessage message
  53.         return 0;
  54.  
  55.     // RegisterWindowMessage - does not copy to lastState buffer, so
  56.     // CWnd::GetCurrentMessage and CWnd::Default will NOT work
  57.     // while in these handlers
  58.  
  59.     // Get our Window
  60.     // assume it is already wired up to a permanent one
  61.     CDialog* pDlg = (CDialog*) CWnd::FromHandlePermanent(hWnd);
  62.     ASSERT(pDlg != NULL);
  63.     ASSERT(pDlg->m_hWnd == hWnd);
  64.     ASSERT(pDlg->IsKindOf(RUNTIME_CLASS(CDialog)));
  65.  
  66.     // Dispatch special commdlg messages through our virtual callbacks
  67.     if (message == nMsgSHAREVI)
  68.     {
  69.         ASSERT(pDlg->IsKindOf(RUNTIME_CLASS(CFileDialog)));
  70.         return ((CFileDialog*)pDlg)->OnShareViolation((LPCSTR)lParam);
  71.     }
  72.     else if (message == nMsgFILEOK)
  73.     {
  74.         ASSERT(pDlg->IsKindOf(RUNTIME_CLASS(CFileDialog)));
  75.         return ((CFileDialog*)pDlg)->OnFileNameOK();
  76.     }
  77.     else if (message == nMsgLBSELCHANGE)
  78.     {
  79.         ASSERT(pDlg->IsKindOf(RUNTIME_CLASS(CFileDialog)));
  80.         ((CFileDialog*)pDlg)->OnLBSelChangedNotify(wParam, LOWORD(lParam), 
  81.                 HIWORD(lParam));
  82.         return 0;
  83.     }
  84.     else if (message == nMsgCOLOROK)
  85.     {
  86.         ASSERT(pDlg->IsKindOf(RUNTIME_CLASS(CColorDialog)));
  87.         return ((CColorDialog*)pDlg)->OnColorOK();
  88.     }
  89.     else if (message == nMsgSETRGB)
  90.     {
  91.         // nothing to do here, since this is a SendMessage
  92.         return 0;
  93.     }
  94.  
  95.     TRACE("_AfxCommDlgProc: received unknown user message, returning 0\n");
  96.     return 0;
  97. }
  98.  
  99. ////////////////////////////////////////////////////////////////////////////
  100. // FileOpen/FileSaveAs common dialog helper
  101.  
  102. IMPLEMENT_DYNAMIC(CFileDialog, CModalDialog)
  103.  
  104. CFileDialog::CFileDialog(BOOL bOpenFileDialog,
  105.         LPCSTR lpszDefExt /* = NULL */,
  106.         LPCSTR lpszFileName /* = NULL */,
  107.         DWORD dwFlags /* = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT */,
  108.         LPCSTR lpszFilter /* = NULL */, 
  109.         CWnd* pParentWnd /* = NULL */) : CModalDialog((UINT)0, pParentWnd)
  110. {
  111.     memset(&m_ofn, 0, sizeof(m_ofn)); // initialize structure to 0/NULL
  112.     m_szFileName[0] = '\0';
  113.     m_szFileTitle[0] = '\0';
  114.  
  115.     m_bOpenFileDialog = bOpenFileDialog;
  116.     
  117.     m_ofn.lStructSize = sizeof(m_ofn);
  118.  
  119.     if (m_pParentWnd != NULL)
  120.         m_ofn.hwndOwner = m_pParentWnd->m_hWnd;
  121.     else
  122.         m_ofn.hwndOwner = AfxGetApp()->m_pMainWnd->GetSafeHwnd();
  123.     m_ofn.lpstrFile = (LPSTR)&m_szFileName;
  124.     m_ofn.nMaxFile = sizeof(m_szFileName);
  125.     m_ofn.lpstrDefExt = lpszDefExt;
  126.     m_ofn.lpstrFileTitle = (LPSTR)m_szFileTitle;
  127.     m_ofn.nMaxFileTitle = sizeof(m_szFileTitle);
  128.  
  129.     m_ofn.Flags |= dwFlags | OFN_ENABLEHOOK;
  130.     m_ofn.lpfnHook = (COMMDLGPROC)_AfxCommDlgProc;
  131.  
  132.     // setup initial file name
  133.     if (lpszFileName)
  134.     {
  135.         _fstrncpy(m_szFileName, lpszFileName, sizeof(m_szFileName));
  136.         m_szFileName[sizeof(m_szFileName)-1] = '\0';
  137.     }
  138.  
  139.     // Translate filter into commdlg format (lots of \0)
  140.     if (lpszFilter)
  141.     {
  142.         int nLen = _fstrlen(lpszFilter);
  143.  
  144.         m_strFilter.GetBuffer(_fstrlen(lpszFilter)); // required because of '\0'
  145.         while (*lpszFilter)
  146.         {
  147.             if (*lpszFilter == '|') // MFC delimits with ':' not '\0'
  148.                 m_strFilter += (char)'\0';
  149.             else
  150.                 m_strFilter += *lpszFilter;
  151.             lpszFilter++;
  152.         }
  153.         m_ofn.lpstrFilter = m_strFilter;
  154.         m_strFilter.ReleaseBuffer(nLen);
  155.     }
  156. }
  157.  
  158. int
  159. CFileDialog::DoModal()
  160. {
  161.     ASSERT_VALID(this);
  162.     ASSERT(m_ofn.Flags & OFN_ENABLEHOOK);
  163.     ASSERT(m_ofn.lpfnHook != NULL); // can still be a user hook
  164.  
  165.     BOOL bResult;
  166.  
  167.     _AfxHookWindowCreate(this);
  168.  
  169.     if (m_bOpenFileDialog)
  170.         bResult = ::GetOpenFileName(&m_ofn);
  171.     else
  172.         bResult = ::GetSaveFileName(&m_ofn);
  173.  
  174.     _AfxUnhookWindowCreate();   // just in case
  175.     Detach();                   // just in case
  176.  
  177.     return bResult ? IDOK : IDCANCEL;
  178. }
  179.  
  180. CString CFileDialog::GetFileName() const
  181.     ASSERT_VALID(this);
  182.     char szFile[32];
  183.  
  184.     if (m_ofn.nFileExtension == 0 || 
  185.             m_ofn.lpstrFile[m_ofn.nFileExtension] == '\0')
  186.         return m_ofn.lpstrFile + m_ofn.nFileOffset;
  187.     else
  188.     {
  189.         int nFileLen = m_ofn.nFileExtension - m_ofn.nFileOffset - 1;
  190.         _fstrncpy(szFile, m_ofn.lpstrFile + m_ofn.nFileOffset, nFileLen);
  191.         szFile[nFileLen] = '\0';
  192.         return szFile;
  193.     }
  194. }
  195.  
  196. UINT 
  197. CFileDialog::OnShareViolation(LPCSTR)
  198. {
  199.     ASSERT_VALID(this);
  200.  
  201.     // Do not call Default() if you override
  202.     return OFN_SHAREWARN; // default
  203. }
  204.  
  205. BOOL 
  206. CFileDialog::OnFileNameOK()
  207. {
  208.     ASSERT_VALID(this);
  209.  
  210.     // Do not call Default() if you override
  211.     return FALSE;
  212. }
  213.  
  214. void 
  215. CFileDialog::OnLBSelChangedNotify(UINT, UINT, UINT)
  216. {
  217.     ASSERT_VALID(this);
  218.  
  219.     // Do not call Default() if you override
  220.     // no default processing needed
  221. }
  222.  
  223. void
  224. CFileDialog::OnOK()
  225. {
  226.     // Common dialogs do not require ::EndDialog
  227.     ASSERT_VALID(this);
  228.     Default();
  229. }
  230.  
  231. void
  232. CFileDialog::OnCancel()
  233. {
  234.     // Common dialogs do not require ::EndDialog
  235.     ASSERT_VALID(this);
  236.     Default();
  237. }
  238.  
  239. #ifdef _DEBUG
  240. void 
  241. CFileDialog::Dump(CDumpContext& dc) const
  242. {
  243.     ASSERT_VALID(this);
  244.  
  245.     CModalDialog::Dump(dc);
  246.  
  247.     if (m_bOpenFileDialog)
  248.         dc << "\nFile open dialog";
  249.     else
  250.         dc << "\nFile save dialog";
  251.     dc << "\nm_ofn.hwndOwner = " << (void NEAR*)m_ofn.hwndOwner;
  252.     dc << "\nm_ofn.nFilterIndex = " << m_ofn.nFilterIndex;
  253.     dc << "\nm_ofn.lpstrFile = " << m_ofn.lpstrFile;
  254.     dc << "\nm_ofn.nMaxFile = " << m_ofn.nMaxFile;
  255.     dc << "\nm_ofn.lpstrFileTitle = " << m_ofn.lpstrFileTitle;
  256.     dc << "\nm_ofn.nMaxFileTitle = " << m_ofn.nMaxFileTitle;
  257.     dc << "\nm_ofn.lpstrTitle = " << m_ofn.lpstrTitle;
  258.     dc << "\nm_ofn.Flags = " << (LPVOID)m_ofn.Flags;
  259.     dc << "\nm_ofn.lpstrDefExt = " << m_ofn.lpstrDefExt;
  260.     dc << "\nm_ofn.nFileOffset = " << m_ofn.nFileOffset;
  261.     dc << "\nm_ofn.nFileExtension = " << m_ofn.nFileExtension;
  262.  
  263.     dc << "\nm_ofn.lpstrFilter = ";
  264.     LPCSTR lpstrItem = m_ofn.lpstrFilter;
  265.     char* szBreak = "|";
  266.  
  267.     while (lpstrItem != NULL && *lpstrItem != '\0')
  268.     {
  269.         dc << lpstrItem << szBreak;
  270.         lpstrItem += _fstrlen(lpstrItem) + 1;
  271.     }
  272.     if (lpstrItem != NULL)
  273.         dc << szBreak;
  274.  
  275.     dc << "\nm_ofn.lpstrCustomFilter = ";
  276.     lpstrItem = m_ofn.lpstrCustomFilter;
  277.     while (lpstrItem != NULL && *lpstrItem != '\0')
  278.     {
  279.         dc << lpstrItem << szBreak;
  280.         lpstrItem += _fstrlen(lpstrItem) + 1;
  281.     }
  282.     if (lpstrItem != NULL)
  283.         dc << szBreak;
  284.     
  285.     if (m_ofn.lpfnHook == (COMMDLGPROC)_AfxCommDlgProc)
  286.         dc << "\nhook function set to standard MFC hook function";
  287.     else
  288.         dc << "\nhook function set to non-standard hook function";
  289. }
  290. #endif
  291.  
  292.  
  293. /////////////////////////////////////////////////////////////////////////////
  294. // Choose Color dialog
  295.  
  296. IMPLEMENT_DYNAMIC(CColorDialog, CModalDialog)
  297.  
  298. COLORREF CColorDialog::clrSavedCustom[16] = { RGB(255, 255, 255), 
  299.     RGB(255, 255, 255), RGB(255, 255, 255), RGB(255, 255, 255),
  300.     RGB(255, 255, 255), RGB(255, 255, 255), RGB(255, 255, 255),
  301.     RGB(255, 255, 255), RGB(255, 255, 255), RGB(255, 255, 255),
  302.     RGB(255, 255, 255), RGB(255, 255, 255), RGB(255, 255, 255),
  303.     RGB(255, 255, 255), RGB(255, 255, 255), RGB(255, 255, 255) };
  304.  
  305. CColorDialog::CColorDialog(COLORREF clrInit /* = 0 */,
  306.         DWORD dwFlags /* = 0 */, 
  307.         CWnd* pParentWnd /* = NULL */) : CModalDialog((UINT)0, pParentWnd)
  308. {
  309.     memset(&m_cc, 0, sizeof(m_cc));
  310.  
  311.     m_cc.lStructSize = sizeof(m_cc);
  312.     if (m_pParentWnd != NULL)
  313.         m_cc.hwndOwner = m_pParentWnd->m_hWnd;
  314.     else
  315.         m_cc.hwndOwner = AfxGetApp()->m_pMainWnd->GetSafeHwnd();
  316.     m_cc.lpCustColors = (COLORREF FAR*)&clrSavedCustom;
  317.     m_cc.Flags = dwFlags | CC_ENABLEHOOK;
  318.     m_cc.lpfnHook = (COMMDLGPROC)_AfxCommDlgProc;
  319.  
  320.     if ((m_cc.rgbResult = clrInit) != 0)
  321.         m_cc.Flags |= CC_RGBINIT;
  322.  
  323.     // There is a "bug" in the Windows 3.1 COMMDLG implementation
  324.     // of ::ChooseColor that prevents the "new AFX look" from
  325.     // functioning correctly.  If you wish to disable the default
  326.     // AFX look, then ::DeleteObject(m_hBrushCtlBk) and set it
  327.     // to NULL at this point.
  328. }
  329.  
  330. int
  331. CColorDialog::DoModal()
  332. {
  333.     ASSERT_VALID(this);
  334.     ASSERT(m_cc.Flags & CC_ENABLEHOOK);
  335.     ASSERT(m_cc.lpfnHook != NULL); // can still be a user hook
  336.  
  337.     BOOL bResult;
  338.  
  339.     _AfxHookWindowCreate(this);
  340.  
  341.     bResult = ::ChooseColor(&m_cc);
  342.  
  343.     _AfxUnhookWindowCreate();   // just in case
  344.     Detach();                   // just in case
  345.  
  346.     return bResult ? IDOK : IDCANCEL;
  347. }
  348.  
  349. BOOL 
  350. CColorDialog::OnColorOK()
  351. {
  352.     ASSERT_VALID(this);
  353.     // Do not call Default() if you override
  354.     return FALSE;
  355. }
  356.  
  357. void 
  358. CColorDialog::SetCurrentColor(COLORREF clr)
  359. {
  360.     ASSERT_VALID(this);
  361.     ASSERT(m_hWnd != NULL);
  362.  
  363.     SendMessage(nMsgSETRGB, 0, (DWORD)clr);
  364. }
  365.  
  366. void
  367. CColorDialog::OnOK()
  368. {
  369.     // Common dialogs do not require ::EndDialog
  370.     ASSERT_VALID(this);
  371.  
  372.     Default();
  373. }
  374.  
  375. void
  376. CColorDialog::OnCancel()
  377. {
  378.     // Common dialogs do not require ::EndDialog
  379.     ASSERT_VALID(this);
  380.     Default();
  381. }
  382.  
  383. #ifdef _DEBUG
  384. void 
  385. CColorDialog::Dump(CDumpContext& dc) const
  386. {
  387.     ASSERT_VALID(this);
  388.     CModalDialog::Dump(dc);
  389.     
  390.     dc << "\nm_cc.hwndOwner = " << (void NEAR*)m_cc.hwndOwner;
  391.     dc << "\nm_cc.rgbResult = " << (LPVOID)m_cc.rgbResult;
  392.     dc << "\nm_cc.Flags = " << (LPVOID)m_cc.Flags;
  393.     dc << "\nm_cc.lpCustColors ";
  394.     for (int iClr = 0; iClr < 16; iClr++)
  395.         dc << "\n\t" << (LPVOID)m_cc.lpCustColors[iClr];
  396.     if (m_cc.lpfnHook == (COMMDLGPROC)_AfxCommDlgProc)
  397.         dc << "\nhook function set to standard MFC hook function";
  398.     else
  399.         dc << "\nhook function set to non-standard hook function";
  400. }
  401. #endif
  402.  
  403. /////////////////////////////////////////////////////////////////////////////
  404. // Choose Font dialog
  405.  
  406. IMPLEMENT_DYNAMIC(CFontDialog, CModalDialog)
  407.  
  408. CFontDialog::CFontDialog(LPLOGFONT lplfInitial  /* = NULL */,
  409.         DWORD dwFlags /* = CF_EFFECTS | CF_SCREENFONTS */, 
  410.         CDC* pdcPrinter /* = NULL */,
  411.         CWnd* pParentWnd /* = NULL */) : CModalDialog((UINT)0, pParentWnd)
  412. {
  413.     memset(&m_cf, 0, sizeof(m_cf));
  414.     memset(&m_lf, 0, sizeof(m_lf));
  415.     memset(&m_szStyleName, 0, sizeof(m_szStyleName));
  416.  
  417.     m_cf.lStructSize = sizeof(m_cf);
  418.     if (m_pParentWnd != NULL)
  419.         m_cf.hwndOwner = m_pParentWnd->m_hWnd;
  420.     else
  421.         m_cf.hwndOwner = AfxGetApp()->m_pMainWnd->GetSafeHwnd();
  422.     m_cf.lpszStyle = (LPSTR)&m_szStyleName;
  423.     m_cf.Flags = dwFlags | CF_USESTYLE | CF_ENABLEHOOK;
  424.     m_cf.lpfnHook = (COMMDLGPROC)_AfxCommDlgProc;
  425.  
  426.     if (lplfInitial)
  427.     {
  428.         m_cf.lpLogFont = lplfInitial;
  429.         m_cf.Flags |= CF_INITTOLOGFONTSTRUCT;
  430.         _fmemcpy(&m_lf, m_cf.lpLogFont, sizeof(m_lf));
  431.     }
  432.     else
  433.     {
  434.         m_cf.lpLogFont = &m_lf;
  435.     }
  436.  
  437.     if (pdcPrinter)
  438.     {
  439.         ASSERT(pdcPrinter->m_hDC != NULL);
  440.         m_cf.hDC = pdcPrinter->m_hDC;
  441.         m_cf.Flags |= CF_PRINTERFONTS;
  442.     }
  443. }
  444.  
  445. BOOL 
  446. CFontDialog::DoModal()
  447. {
  448.     ASSERT_VALID(this);
  449.     ASSERT(m_cf.Flags & CF_ENABLEHOOK);
  450.     ASSERT(m_cf.lpfnHook != NULL); // can still be a user hook
  451.  
  452.     BOOL bResult;
  453.  
  454.     _AfxHookWindowCreate(this);
  455.  
  456.     bResult = ::ChooseFont(&m_cf);
  457.  
  458.     _AfxUnhookWindowCreate();   // just in case
  459.     Detach();                   // just in case
  460.  
  461.     if (bResult)
  462.         // copy logical font from user's initialization buffer (if needed)
  463.         _fmemcpy(&m_lf, m_cf.lpLogFont, sizeof(m_lf));
  464.         
  465.     return bResult ? IDOK : IDCANCEL;
  466. }
  467.  
  468.  
  469. void
  470. CFontDialog::OnOK()
  471. {
  472.     // Common dialogs do not require ::EndDialog
  473.     ASSERT_VALID(this);
  474.     Default();
  475. }
  476.  
  477. void
  478. CFontDialog::OnCancel()
  479. {
  480.     // Common dialogs do not require ::EndDialog
  481.     ASSERT_VALID(this);
  482.     Default();
  483. }
  484.  
  485. #ifdef _DEBUG
  486. void 
  487. CFontDialog::Dump(CDumpContext& dc) const
  488. {
  489.     ASSERT_VALID(this);
  490.  
  491.     CModalDialog::Dump(dc);
  492.     dc << "\nm_cf.hwndOwner = " << (void NEAR*)m_cf.hwndOwner;
  493.     if (m_cf.hDC != NULL)
  494.         dc << "\nm_cf.hDC = " << CDC::FromHandle(m_cf.hDC);
  495.     dc << "\nm_cf.iPointSize = " << m_cf.iPointSize;
  496.     dc << "\nm_cf.Flags = " << (LPVOID)m_cf.Flags;
  497.     dc << "\nm_cf.lpszStyle = " << m_cf.lpszStyle;
  498.     dc << "\nm_cf.nSizeMin = " << m_cf.nSizeMin;
  499.     dc << "\nm_cf.nSizeMax = " << m_cf.nSizeMax;
  500.     dc << "\nm_cf.nFontType = " << (void NEAR*)m_cf.nFontType;
  501.     dc << "\nm_cf.rgbColors = " << (LPVOID)m_cf.rgbColors;
  502.     if (m_cf.lpfnHook == (COMMDLGPROC)_AfxCommDlgProc)
  503.         dc << "\nhook function set to standard MFC hook function";
  504.     else
  505.         dc << "\nhook function set to non-standard hook function";
  506. }
  507.  
  508. #endif
  509.  
  510. /////////////////////////////////////////////////////////////////////////////
  511. // Print/Print Setup dialog
  512.  
  513. IMPLEMENT_DYNAMIC(CPrintDialog, CModalDialog)
  514.  
  515. BEGIN_MESSAGE_MAP(CPrintDialog, CModalDialog)
  516.     // Handle the print setup button when print is displayed
  517.     ON_COMMAND(psh1, OnPrintSetup)
  518. END_MESSAGE_MAP()
  519.  
  520. CPrintDialog::CPrintDialog(BOOL bPrintSetupOnly,
  521.     DWORD dwFlags /* = PD_ALLPAGES | PD_USEDEVMODECOPIES | PD_NOPAGENUMS
  522.         | PD_HIDEPRINTTOFILE | PD_NOSELECTION */,
  523.     CWnd* pParentWnd /* = NULL */) 
  524.         : m_pd(m_pdActual), CModalDialog((UINT)0, pParentWnd)
  525. {
  526.     memset(&m_pdActual, 0, sizeof(m_pdActual));
  527.  
  528.     m_pd.lStructSize = sizeof(m_pdActual);
  529.     if (m_pParentWnd != NULL)
  530.         m_pd.hwndOwner = m_pParentWnd->m_hWnd;
  531.     else
  532.         m_pd.hwndOwner = AfxGetApp()->m_pMainWnd->GetSafeHwnd();
  533.     m_pd.Flags = (dwFlags | PD_ENABLEPRINTHOOK | PD_ENABLESETUPHOOK);
  534.     m_pd.lpfnPrintHook = (COMMDLGPROC)_AfxCommDlgProc;
  535.     m_pd.lpfnSetupHook = (COMMDLGPROC)_AfxCommDlgProc;
  536.         
  537.  
  538.     if (bPrintSetupOnly)
  539.         m_pd.Flags |= PD_PRINTSETUP;
  540.     else
  541.         m_pd.Flags |= PD_RETURNDC;
  542.  
  543.     m_pd.Flags &= ~PD_RETURNIC; // do not support information context
  544. }
  545.  
  546. // Helper ctor for AttachOnSetup
  547. CPrintDialog::CPrintDialog(PRINTDLG FAR& pdInit)
  548.         : m_pd(pdInit), CModalDialog((UINT)0, NULL)
  549. {   
  550. }
  551.  
  552. // Function to keep m_pd in sync after user invokes Setup from
  553. // the print dialog (via the Setup button)
  554. // If you decide to handle any messages/notifications and wish to
  555. // handle them differently between Print/PrintSetup then override
  556. // this function and create an object of a derived class
  557. CPrintDialog* 
  558. CPrintDialog::AttachOnSetup()
  559. {
  560.     ASSERT_VALID(this);
  561.  
  562.     CPrintDialog* pDlgSetup;
  563.  
  564.     pDlgSetup = new CPrintDialog(m_pd);
  565.     pDlgSetup->m_hWnd = NULL;
  566.     pDlgSetup->m_pParentWnd = m_pParentWnd;
  567.     return pDlgSetup;
  568. }
  569.  
  570. void
  571. CPrintDialog::OnPrintSetup()
  572. {
  573.     ASSERT_VALID(this);
  574.  
  575.     CPrintDialog* pDlgSetup;
  576.  
  577.     VERIFY((pDlgSetup = this->AttachOnSetup()) != NULL);
  578.  
  579.     _AfxHookWindowCreate(pDlgSetup);
  580.     Default();
  581.     _AfxUnhookWindowCreate();
  582.  
  583.     delete pDlgSetup;
  584. }
  585.  
  586. int
  587. CPrintDialog::DoModal()
  588. {
  589.     ASSERT_VALID(this);
  590.     ASSERT(m_pd.Flags & PD_ENABLEPRINTHOOK);
  591.     ASSERT(m_pd.Flags & PD_ENABLESETUPHOOK);
  592.     ASSERT(m_pd.lpfnPrintHook != NULL); // can still be a user hook
  593.     ASSERT(m_pd.lpfnSetupHook != NULL); // can still be a user hook
  594.  
  595.     BOOL bResult;
  596.  
  597.     _AfxHookWindowCreate(this);
  598.  
  599.     bResult = ::PrintDlg(&m_pd);
  600.  
  601.     _AfxUnhookWindowCreate();   // just in case
  602.     Detach();                   // just in case
  603.  
  604.     return bResult ? IDOK : IDCANCEL;
  605. }
  606.  
  607. // Return an HDC.  We don't return a CDC* so the user can decide
  608. // where to attach this HDC: either to a newly allocated object
  609. // (use operator delete to clean up) or to an embedded/frame
  610. // object (destructor will clean up when leaving scope)
  611. HDC
  612. CPrintDialog::GetPrinterDC() const
  613. {
  614.     ASSERT_VALID(this);
  615.     ASSERT(m_pd.Flags & PD_RETURNDC);
  616.     
  617.     return m_pd.hDC;
  618. }
  619.  
  620. int 
  621. CPrintDialog::GetCopies() const
  622. {   
  623.     ASSERT_VALID(this);
  624.     if (m_pd.Flags & PD_USEDEVMODECOPIES)
  625.         return GetDevMode()->dmCopies;
  626.     else
  627.         return m_pd.nCopies; 
  628. }
  629.  
  630. void
  631. CPrintDialog::OnOK()
  632. {
  633.     // Common dialogs do not require ::EndDialog
  634.     ASSERT_VALID(this);
  635.     Default();
  636. }
  637.  
  638. void
  639. CPrintDialog::OnCancel()
  640. {
  641.     // Common dialogs do not require ::EndDialog
  642.     ASSERT_VALID(this);
  643.     Default();
  644. }
  645.  
  646. #ifdef _DEBUG
  647. void 
  648. CPrintDialog::Dump(CDumpContext& dc) const
  649. {
  650.     ASSERT_VALID(this);
  651.     CModalDialog::Dump(dc);
  652.  
  653.     dc << "\nm_pd.hwndOwner = " << (void NEAR*)m_pd.hwndOwner;
  654.     if (m_pd.hDC != NULL)
  655.         dc << "\nm_pd.hDC = " << CDC::FromHandle(m_pd.hDC);
  656.     dc << "\nm_pd.Flags = " << (LPVOID)m_pd.Flags;
  657.     dc << "\nm_pd.nFromPage = " << m_pd.nFromPage;
  658.     dc << "\nm_pd.nToPage = " << m_pd.nToPage;
  659.     dc << "\nm_pd.nMinPage = " << m_pd.nMinPage;
  660.     dc << "\nm_pd.nMaxPage = " << m_pd.nMaxPage;
  661.     dc << "\nm_pd.nCopies = " << m_pd.nCopies;
  662.     if (m_pd.lpfnSetupHook == (COMMDLGPROC)_AfxCommDlgProc)
  663.         dc << "\nsetup hook function set to standard MFC hook function";
  664.     else
  665.         dc << "\nsetup hook function set to non-standard hook function";
  666.     if (m_pd.lpfnPrintHook == (COMMDLGPROC)_AfxCommDlgProc)
  667.         dc << "\nprint hook function set to standard MFC hook function";
  668.     else
  669.         dc << "\nprint hook function set to non-standard hook function";
  670.  
  671. }
  672. #endif
  673.  
  674. /////////////////////////////////////////////////////////////////////////////
  675. // Find/FindReplace dialogs
  676.  
  677. IMPLEMENT_DYNAMIC(CFindReplaceDialog, CDialog)
  678.  
  679. CFindReplaceDialog::CFindReplaceDialog()
  680. {
  681.     memset(&m_fr, 0, sizeof(m_fr));
  682.     m_szFindWhat[0] = '\0';
  683.     m_szReplaceWith[0] = '\0';
  684.  
  685.     m_fr.Flags = FR_ENABLEHOOK;
  686.     m_fr.lpfnHook = (COMMDLGPROC)_AfxCommDlgProc;
  687.     m_fr.lStructSize = sizeof(m_fr);
  688.     m_fr.lpstrFindWhat = (LPSTR)m_szFindWhat;
  689. }
  690.  
  691. void
  692. CFindReplaceDialog::PostNcDestroy()
  693. {
  694.     ASSERT(m_hWnd == NULL);
  695.     delete this;
  696. }
  697.  
  698.  
  699. BOOL
  700. CFindReplaceDialog::Create(BOOL bFindDialogOnly,
  701.         LPCSTR lpszFindWhat,
  702.         LPCSTR lpszReplaceWith /* = NULL */,
  703.         DWORD dwFlags /* = FR_DOWN */,
  704.         CWnd* pParentWnd /* = NULL */) : CDialog((UINT)0, pParentWnd)
  705. {
  706.     ASSERT_VALID(this);
  707.     ASSERT(m_fr.Flags & FR_ENABLEHOOK);
  708.     ASSERT(m_fr.lpfnHook != NULL);
  709.  
  710.     HWND hwndResult;
  711.  
  712.     m_fr.wFindWhatLen = sizeof(m_szFindWhat);
  713.     m_fr.lpstrReplaceWith = (LPSTR)m_szReplaceWith;
  714.     m_fr.wReplaceWithLen = sizeof(m_szReplaceWith);
  715.     m_fr.Flags |= dwFlags;
  716.  
  717.     if (pParentWnd == NULL)
  718.         m_fr.hwndOwner = AfxGetApp()->m_pMainWnd->GetSafeHwnd();
  719.     else
  720.     {
  721.         ASSERT_VALID(pParentWnd);
  722.         m_fr.hwndOwner = pParentWnd->m_hWnd;
  723.     }
  724.     ASSERT(m_fr.hwndOwner != NULL); // must have a parent for modeless dialog
  725.     
  726.  
  727.     if (lpszFindWhat)
  728.         _fstrncpy(m_szFindWhat, lpszFindWhat, sizeof(m_szFindWhat));
  729.  
  730.     if (lpszReplaceWith)
  731.         _fstrncpy(m_szReplaceWith, lpszReplaceWith, sizeof(m_szReplaceWith));
  732.  
  733.  
  734.     _AfxHookWindowCreate(this);
  735.     if (bFindDialogOnly)
  736.         hwndResult = ::FindText(&m_fr);
  737.     else
  738.         hwndResult = ::ReplaceText(&m_fr);
  739.     _AfxUnhookWindowCreate();   // just in case
  740.  
  741.     ASSERT(hwndResult == NULL || m_hWnd != NULL);
  742.  
  743.     return hwndResult == NULL ? FALSE : TRUE;
  744. }
  745.  
  746. /* static */ CFindReplaceDialog* 
  747. CFindReplaceDialog::GetNotifier(LONG lParam)
  748. {
  749.     ASSERT(lParam != NULL);
  750.     CFindReplaceDialog* pDlg;
  751.  
  752.     pDlg = (CFindReplaceDialog*)(lParam - offsetof(CFindReplaceDialog, m_fr));
  753.     ASSERT_VALID(pDlg);
  754.     ASSERT(pDlg->IsKindOf(RUNTIME_CLASS(CFindReplaceDialog)));
  755.     
  756.     return pDlg;
  757. }
  758.  
  759. #ifdef _DEBUG
  760. void 
  761. CFindReplaceDialog::Dump(CDumpContext& dc) const
  762. {
  763.     ASSERT_VALID(this);
  764.  
  765.     CDialog::Dump(dc);
  766.  
  767.     dc << "\nm_fr.hwndOwner = " << (void NEAR*)m_fr.hwndOwner;
  768.     dc << "\nm_fr.Flags = " << (LPVOID)m_fr.Flags;
  769.     dc << "\nm_fr.lpstrFindWhat = " << m_fr.lpstrFindWhat;
  770.     dc << "\nm_fr.lpstrReplaceWith = " << m_fr.lpstrReplaceWith;
  771.     if (m_fr.lpfnHook == (COMMDLGPROC)_AfxCommDlgProc)
  772.         dc << "\nhook function set to standard MFC hook function";
  773.     else
  774.         dc << "\nhook function set to non-standard hook function";
  775. }
  776. #endif
  777.  
  778. /////////////////////////////////////////////////////////////////////////////
  779.