home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / mfc / src / appcore.cpp < prev    next >
C/C++ Source or Header  |  1998-06-16  |  16KB  |  614 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. #include <malloc.h>
  13.  
  14. #ifdef AFX_CORE1_SEG
  15. #pragma code_seg(AFX_CORE1_SEG)
  16. #endif
  17.  
  18. #ifdef _DEBUG
  19. #undef THIS_FILE
  20. static char THIS_FILE[] = __FILE__;
  21. #endif
  22.  
  23. AFX_STATIC_DATA const TCHAR _afxFileSection[] = _T("Recent File List");
  24. AFX_STATIC_DATA const TCHAR _afxFileEntry[] = _T("File%d");
  25. AFX_STATIC_DATA const TCHAR _afxPreviewSection[] = _T("Settings");
  26. AFX_STATIC_DATA const TCHAR _afxPreviewEntry[] = _T("PreviewPages");
  27.  
  28. /////////////////////////////////////////////////////////////////////////////
  29. // globals (internal library use)
  30.  
  31. // CDocManager statics are in this file for granularity reasons
  32. BOOL CDocManager::bStaticInit = TRUE;
  33. CDocManager* CDocManager::pStaticDocManager = NULL;
  34. CPtrList* CDocManager::pStaticList = NULL;
  35.  
  36. BEGIN_MESSAGE_MAP(CWinApp, CCmdTarget)
  37.     //{{AFX_MSG_MAP(CWinApp)
  38.     // Global File commands
  39.     ON_COMMAND(ID_APP_EXIT, OnAppExit)
  40.     // MRU - most recently used file menu
  41.     ON_UPDATE_COMMAND_UI(ID_FILE_MRU_FILE1, OnUpdateRecentFileMenu)
  42.     ON_COMMAND_EX_RANGE(ID_FILE_MRU_FILE1, ID_FILE_MRU_FILE16, OnOpenRecentFile)
  43.     //}}AFX_MSG_MAP
  44. END_MESSAGE_MAP()
  45.  
  46. /////////////////////////////////////////////////////////////////////////////
  47. // _AFX_WIN_STATE implementation
  48.  
  49. #ifndef _AFX_NO_GRAYDLG_SUPPORT
  50.  
  51. #ifdef AFX_INIT_SEG
  52. #pragma code_seg(AFX_INIT_SEG)
  53. #endif
  54.  
  55. _AFX_WIN_STATE::_AFX_WIN_STATE()
  56. {
  57.     // Note: it is only necessary to intialize non-zero data.
  58. }
  59.  
  60. #ifdef AFX_TERM_SEG
  61. #pragma code_seg(AFX_TERM_SEG)
  62. #endif
  63.  
  64. _AFX_WIN_STATE::~_AFX_WIN_STATE()
  65. {
  66.     AfxDeleteObject((HGDIOBJ*)&m_hDlgBkBrush);
  67. }
  68.  
  69. #endif //!_AFX_NO_GRAYDLG_SUPPORT
  70.  
  71. #ifdef AFX_INIT_SEG
  72. #pragma code_seg(AFX_INIT_SEG)
  73. #endif
  74.  
  75. CWinApp::CWinApp(LPCTSTR lpszAppName)
  76. {
  77.     if (lpszAppName != NULL)
  78.         m_pszAppName = _tcsdup(lpszAppName);
  79.     else
  80.         m_pszAppName = NULL;
  81.  
  82.     // initialize CWinThread state
  83.     AFX_MODULE_STATE* pModuleState = _AFX_CMDTARGET_GETSTATE();
  84.     AFX_MODULE_THREAD_STATE* pThreadState = pModuleState->m_thread;
  85.     ASSERT(AfxGetThread() == NULL);
  86.     pThreadState->m_pCurrentWinThread = this;
  87.     ASSERT(AfxGetThread() == this);
  88.     m_hThread = ::GetCurrentThread();
  89.     m_nThreadID = ::GetCurrentThreadId();
  90.  
  91.     // initialize CWinApp state
  92.     ASSERT(afxCurrentWinApp == NULL); // only one CWinApp object please
  93.     pModuleState->m_pCurrentWinApp = this;
  94.     ASSERT(AfxGetApp() == this);
  95.  
  96.     // in non-running state until WinMain
  97.     m_hInstance = NULL;
  98.     m_pszHelpFilePath = NULL;
  99.     m_pszProfileName = NULL;
  100.     m_pszRegistryKey = NULL;
  101.     m_pszExeName = NULL;
  102.     m_pRecentFileList = NULL;
  103.     m_pDocManager = NULL;
  104.     m_atomApp = m_atomSystemTopic = NULL;
  105.     m_lpCmdLine = NULL;
  106.     m_pCmdInfo = NULL;
  107.  
  108.     // initialize wait cursor state
  109.     m_nWaitCursorCount = 0;
  110.     m_hcurWaitCursorRestore = NULL;
  111.  
  112.     // initialize current printer state
  113.     m_hDevMode = NULL;
  114.     m_hDevNames = NULL;
  115.     m_nNumPreviewPages = 0;     // not specified (defaults to 1)
  116.  
  117.     // initialize DAO state
  118.     m_lpfnDaoTerm = NULL;   // will be set if AfxDaoInit called
  119.  
  120.     // other initialization
  121.     m_bHelpMode = FALSE;
  122.     m_nSafetyPoolSize = 512;        // default size
  123. }
  124.  
  125. BOOL CWinApp::InitApplication()
  126. {
  127.     if (CDocManager::pStaticDocManager != NULL)
  128.     {
  129.         if (m_pDocManager == NULL)
  130.             m_pDocManager = CDocManager::pStaticDocManager;
  131.         CDocManager::pStaticDocManager = NULL;
  132.     }
  133.  
  134.     if (m_pDocManager != NULL)
  135.         m_pDocManager->AddDocTemplate(NULL);
  136.     else
  137.         CDocManager::bStaticInit = FALSE;
  138.  
  139.     return TRUE;
  140. }
  141.  
  142. BOOL CWinApp::InitInstance()
  143. {
  144.     return TRUE;
  145. }
  146.  
  147. void CWinApp::LoadStdProfileSettings(UINT nMaxMRU)
  148. {
  149.     ASSERT_VALID(this);
  150.     ASSERT(m_pRecentFileList == NULL);
  151.  
  152.     if (nMaxMRU != 0)
  153.     {
  154.         // create file MRU since nMaxMRU not zero
  155.         m_pRecentFileList = new CRecentFileList(0, _afxFileSection, _afxFileEntry,
  156.             nMaxMRU);
  157.         m_pRecentFileList->ReadList();
  158.     }
  159.     // 0 by default means not set
  160.     m_nNumPreviewPages = GetProfileInt(_afxPreviewSection, _afxPreviewEntry, 0);
  161. }
  162.  
  163. void CWinApp::ParseCommandLine(CCommandLineInfo& rCmdInfo)
  164. {
  165.     for (int i = 1; i < __argc; i++)
  166.     {
  167.         LPCTSTR pszParam = __targv[i];
  168.         BOOL bFlag = FALSE;
  169.         BOOL bLast = ((i + 1) == __argc);
  170.         if (pszParam[0] == '-' || pszParam[0] == '/')
  171.         {
  172.             // remove flag specifier
  173.             bFlag = TRUE;
  174.             ++pszParam;
  175.         }
  176.         rCmdInfo.ParseParam(pszParam, bFlag, bLast);
  177.     }
  178. }
  179.  
  180. /////////////////////////////////////////////////////////////////////////////
  181. // CCommandLineInfo implementation
  182.  
  183. CCommandLineInfo::CCommandLineInfo()
  184. {
  185.     m_bShowSplash = TRUE;
  186.     m_bRunEmbedded = FALSE;
  187.     m_bRunAutomated = FALSE;
  188.     m_nShellCommand = FileNew;
  189. }
  190.  
  191. CCommandLineInfo::~CCommandLineInfo()
  192. {
  193. }
  194.  
  195. void CCommandLineInfo::ParseParam(const TCHAR* pszParam,BOOL bFlag,BOOL bLast)
  196. {
  197.     if (bFlag)
  198.     {
  199.         USES_CONVERSION;
  200.         ParseParamFlag(T2CA(pszParam));
  201.     }
  202.     else
  203.         ParseParamNotFlag(pszParam);
  204.  
  205.     ParseLast(bLast);
  206. }
  207.  
  208. #ifdef UNICODE
  209. void CCommandLineInfo::ParseParam(const char* pszParam, BOOL bFlag, BOOL bLast)
  210. {
  211.     if (bFlag)
  212.         ParseParamFlag(pszParam);
  213.     else
  214.         ParseParamNotFlag(pszParam);
  215.  
  216.     ParseLast(bLast);
  217. }
  218. #endif // UNICODE
  219.  
  220. void CCommandLineInfo::ParseParamFlag(const char* pszParam)
  221. {
  222.     // OLE command switches are case insensitive, while
  223.     // shell command switches are case sensitive
  224.  
  225.     if (lstrcmpA(pszParam, "pt") == 0)
  226.         m_nShellCommand = FilePrintTo;
  227.     else if (lstrcmpA(pszParam, "p") == 0)
  228.         m_nShellCommand = FilePrint;
  229.     else if (lstrcmpiA(pszParam, "Unregister") == 0 ||
  230.              lstrcmpiA(pszParam, "Unregserver") == 0)
  231.         m_nShellCommand = AppUnregister;
  232.     else if (lstrcmpA(pszParam, "dde") == 0)
  233.     {
  234.         AfxOleSetUserCtrl(FALSE);
  235.         m_nShellCommand = FileDDE;
  236.     }
  237.     else if (lstrcmpiA(pszParam, "Embedding") == 0)
  238.     {
  239.         AfxOleSetUserCtrl(FALSE);
  240.         m_bRunEmbedded = TRUE;
  241.         m_bShowSplash = FALSE;
  242.     }
  243.     else if (lstrcmpiA(pszParam, "Automation") == 0)
  244.     {
  245.         AfxOleSetUserCtrl(FALSE);
  246.         m_bRunAutomated = TRUE;
  247.         m_bShowSplash = FALSE;
  248.     }
  249. }
  250.  
  251. void CCommandLineInfo::ParseParamNotFlag(const TCHAR* pszParam)
  252. {
  253.     if (m_strFileName.IsEmpty())
  254.         m_strFileName = pszParam;
  255.     else if (m_nShellCommand == FilePrintTo && m_strPrinterName.IsEmpty())
  256.         m_strPrinterName = pszParam;
  257.     else if (m_nShellCommand == FilePrintTo && m_strDriverName.IsEmpty())
  258.         m_strDriverName = pszParam;
  259.     else if (m_nShellCommand == FilePrintTo && m_strPortName.IsEmpty())
  260.         m_strPortName = pszParam;
  261. }
  262.  
  263. #ifdef UNICODE
  264. void CCommandLineInfo::ParseParamNotFlag(const char* pszParam)
  265. {
  266.     if (m_strFileName.IsEmpty())
  267.         m_strFileName = pszParam;
  268.     else if (m_nShellCommand == FilePrintTo && m_strPrinterName.IsEmpty())
  269.         m_strPrinterName = pszParam;
  270.     else if (m_nShellCommand == FilePrintTo && m_strDriverName.IsEmpty())
  271.         m_strDriverName = pszParam;
  272.     else if (m_nShellCommand == FilePrintTo && m_strPortName.IsEmpty())
  273.         m_strPortName = pszParam;
  274. }
  275. #endif
  276.  
  277. void CCommandLineInfo::ParseLast(BOOL bLast)
  278. {
  279.     if (bLast)
  280.     {
  281.         if (m_nShellCommand == FileNew && !m_strFileName.IsEmpty())
  282.             m_nShellCommand = FileOpen;
  283.         m_bShowSplash = !m_bRunEmbedded && !m_bRunAutomated;
  284.     }
  285. }
  286.  
  287. /////////////////////////////////////////////////////////////////////////////
  288. // App termination
  289.  
  290. CWinApp::~CWinApp()
  291. {
  292.     // free doc manager
  293.     if (m_pDocManager != NULL)
  294.         delete m_pDocManager;
  295.  
  296.     // free recent file list
  297.     if (m_pRecentFileList != NULL)
  298.         delete m_pRecentFileList;
  299.  
  300.     // free static list of document templates
  301.     if (!afxContextIsDLL)
  302.     {
  303.         if (CDocManager::pStaticList != NULL)
  304.         {
  305.             delete CDocManager::pStaticList;
  306.             CDocManager::pStaticList = NULL;
  307.         }
  308.         if (CDocManager::pStaticDocManager != NULL)
  309.         {
  310.             delete CDocManager::pStaticDocManager;
  311.             CDocManager::pStaticDocManager = NULL;
  312.         }
  313.     }
  314.  
  315.     // free printer info
  316.     if (m_hDevMode != NULL)
  317.         AfxGlobalFree(m_hDevMode);
  318.     if (m_hDevNames != NULL)
  319.         AfxGlobalFree(m_hDevNames);
  320.  
  321.     // free atoms if used
  322.     if (m_atomApp != NULL)
  323.         ::GlobalDeleteAtom(m_atomApp);
  324.     if (m_atomSystemTopic != NULL)
  325.         ::GlobalDeleteAtom(m_atomSystemTopic);
  326.  
  327.     // free cached commandline
  328.     if (m_pCmdInfo != NULL)
  329.         delete m_pCmdInfo;
  330.  
  331.     // cleanup module state
  332.     AFX_MODULE_STATE* pModuleState = _AFX_CMDTARGET_GETSTATE();
  333.     if (pModuleState->m_lpszCurrentAppName == m_pszAppName)
  334.         pModuleState->m_lpszCurrentAppName = NULL;
  335.     if (pModuleState->m_pCurrentWinApp == this)
  336.         pModuleState->m_pCurrentWinApp = NULL;
  337.  
  338.     // free various strings allocated with _tcsdup
  339.     free((void*)m_pszAppName);
  340.     free((void*)m_pszRegistryKey);
  341.     free((void*)m_pszExeName);
  342.     free((void*)m_pszHelpFilePath);
  343.     free((void*)m_pszProfileName);
  344.  
  345.     // avoid calling CloseHandle() on our own thread handle
  346.     // during the CWinThread destructor
  347.     m_hThread = NULL;
  348. }
  349.  
  350. void CWinApp::SaveStdProfileSettings()
  351. {
  352.     ASSERT_VALID(this);
  353.  
  354.     if (m_pRecentFileList != NULL)
  355.         m_pRecentFileList->WriteList();
  356.  
  357.     if (m_nNumPreviewPages != 0)
  358.         WriteProfileInt(_afxPreviewSection, _afxPreviewEntry, m_nNumPreviewPages);
  359. }
  360.  
  361. int CWinApp::ExitInstance()
  362. {
  363.     // if we remember that we're unregistering,
  364.     // don't save our profile settings
  365.  
  366.     if (m_pCmdInfo == NULL ||
  367.         m_pCmdInfo->m_nShellCommand != CCommandLineInfo::AppUnregister)
  368.     {
  369.         if (!afxContextIsDLL)
  370.             SaveStdProfileSettings();
  371.     }
  372.  
  373.     // Cleanup DAO if necessary
  374.     if (m_lpfnDaoTerm != NULL)
  375.     {
  376.         // If a DLL, YOU must call AfxDaoTerm prior to ExitInstance
  377.         ASSERT(!afxContextIsDLL);
  378.         (*m_lpfnDaoTerm)();
  379.     }
  380.  
  381.     return m_msgCur.wParam; // returns the value from PostQuitMessage
  382. }
  383.  
  384. /////////////////////////////////////////////////////////////////////////////
  385.  
  386. #ifdef AFX_CORE1_SEG
  387. #pragma code_seg(AFX_CORE1_SEG)
  388. #endif
  389.  
  390. // Main running routine until application exits
  391. int CWinApp::Run()
  392. {
  393.     if (m_pMainWnd == NULL && AfxOleGetUserCtrl())
  394.     {
  395.         // Not launched /Embedding or /Automation, but has no main window!
  396.         TRACE0("Warning: m_pMainWnd is NULL in CWinApp::Run - quitting application.\n");
  397.         AfxPostQuitMessage(0);
  398.     }
  399.     return CWinThread::Run();
  400. }
  401.  
  402. #ifdef AFX_TERM_SEG
  403. #pragma code_seg(AFX_TERM_SEG)
  404. #endif
  405.  
  406. void AFXAPI AfxPostQuitMessage(int nExitCode)
  407. {
  408.     // cleanup OLE libraries
  409.     CWinThread* pThread = AfxGetThread();
  410.     if (pThread != NULL && pThread->m_lpfnOleTermOrFreeLib != NULL)
  411.         (*pThread->m_lpfnOleTermOrFreeLib)(TRUE, TRUE);
  412.  
  413.     ::PostQuitMessage(nExitCode);
  414. }
  415.  
  416. /////////////////////////////////////////////////////////////////////////////
  417. // WinHelp Helper
  418.  
  419. #ifdef AFX_CORE1_SEG
  420. #pragma code_seg(AFX_CORE1_SEG)
  421. #endif
  422.  
  423. void CWinApp::WinHelp(DWORD dwData, UINT nCmd)
  424. {
  425.     CWnd* pMainWnd = AfxGetMainWnd();
  426.     ASSERT_VALID(pMainWnd);
  427.  
  428.     // return global app help mode state to FALSE (backward compatibility)
  429.     m_bHelpMode = FALSE;
  430.     pMainWnd->PostMessage(WM_KICKIDLE); // trigger idle update
  431.  
  432.     pMainWnd->WinHelp(dwData, nCmd);
  433. }
  434.  
  435. /////////////////////////////////////////////////////////////////////////////
  436. // Special exception handling
  437.  
  438. LRESULT CWinApp::ProcessWndProcException(CException* e, const MSG* pMsg)
  439. {
  440.     // handle certain messages in CWinThread
  441.     switch (pMsg->message)
  442.     {
  443.     case WM_CREATE:
  444.     case WM_PAINT:
  445.         return CWinThread::ProcessWndProcException(e, pMsg);
  446.     }
  447.  
  448.     // handle all the rest
  449.     UINT nIDP = AFX_IDP_INTERNAL_FAILURE;   // generic message string
  450.     LRESULT lResult = 0;        // sensible default
  451.     if (pMsg->message == WM_COMMAND)
  452.     {
  453.         if ((HWND)pMsg->lParam == NULL)
  454.             nIDP = AFX_IDP_COMMAND_FAILURE; // command (not from a control)
  455.         lResult = (LRESULT)TRUE;        // pretend the command was handled
  456.     }
  457.     if (e->IsKindOf(RUNTIME_CLASS(CMemoryException)))
  458.     {
  459.         e->ReportError(MB_ICONEXCLAMATION|MB_SYSTEMMODAL, nIDP);
  460.     }
  461.     else if (!e->IsKindOf(RUNTIME_CLASS(CUserException)))
  462.     {
  463.         // user has not been alerted yet of this catastrophic problem
  464.         e->ReportError(MB_ICONSTOP, nIDP);
  465.     }
  466.     return lResult; // sensible default return from most WndProc functions
  467. }
  468.  
  469. /////////////////////////////////////////////////////////////////////////////
  470. // CWinApp idle processing
  471.  
  472. BOOL CWinApp::OnIdle(LONG lCount)
  473. {
  474.     if (lCount <= 0)
  475.     {
  476.         CWinThread::OnIdle(lCount);
  477.  
  478.         // call doc-template idle hook
  479.         POSITION pos = NULL;
  480.         if (m_pDocManager != NULL)
  481.             pos = m_pDocManager->GetFirstDocTemplatePosition();
  482.  
  483.         while (pos != NULL)
  484.         {
  485.             CDocTemplate* pTemplate = m_pDocManager->GetNextDocTemplate(pos);
  486.             ASSERT_KINDOF(CDocTemplate, pTemplate);
  487.             pTemplate->OnIdle();
  488.         }
  489.     }
  490.     else if (lCount == 1)
  491.     {
  492.         VERIFY(!CWinThread::OnIdle(lCount));
  493.     }
  494.     return lCount < 1;  // more to do if lCount < 1
  495. }
  496.  
  497. /////////////////////////////////////////////////////////////////////////////
  498. // CWinApp idle processing
  499.  
  500. void CWinApp::DevModeChange(LPTSTR lpDeviceName)
  501. {
  502.     if (m_hDevNames == NULL)
  503.         return;
  504.  
  505.     LPDEVNAMES lpDevNames = (LPDEVNAMES)::GlobalLock(m_hDevNames);
  506.     ASSERT(lpDevNames != NULL);
  507.     if (lstrcmp((LPCTSTR)lpDevNames + lpDevNames->wDeviceOffset,
  508.         lpDeviceName) == 0)
  509.     {
  510.         HANDLE hPrinter;
  511.         if (!OpenPrinter(lpDeviceName, &hPrinter, NULL))
  512.             return;
  513.  
  514.         // DEVMODE changed for the current printer
  515.         if (m_hDevMode != NULL)
  516.             AfxGlobalFree(m_hDevMode);
  517.  
  518.         // A zero for last param returns the size of buffer needed.
  519.         int nSize = DocumentProperties(NULL, hPrinter, lpDeviceName,
  520.             NULL, NULL, 0);
  521.         ASSERT(nSize >= 0);
  522.         m_hDevMode = GlobalAlloc(GHND, nSize);
  523.         LPDEVMODE lpDevMode = (LPDEVMODE)GlobalLock(m_hDevMode);
  524.  
  525.         // Fill in the rest of the structure.
  526.         if (DocumentProperties(NULL, hPrinter, lpDeviceName, lpDevMode,
  527.             NULL, DM_OUT_BUFFER) != IDOK)
  528.         {
  529.             AfxGlobalFree(m_hDevMode);
  530.             m_hDevMode = NULL;
  531.         }
  532.         ClosePrinter(hPrinter);
  533.     }
  534. }
  535.  
  536. ///////////////////////////////////////////////////////////////////////////
  537. // CWinApp diagnostics
  538.  
  539. #ifdef _DEBUG
  540. void CWinApp::AssertValid() const
  541. {
  542.     CWinThread::AssertValid();
  543.  
  544.     ASSERT(afxCurrentWinApp == this);
  545.     ASSERT(afxCurrentInstanceHandle == m_hInstance);
  546.  
  547.     if (AfxGetThread() != (CWinThread*)this)
  548.         return;     // only do subset if called from different thread
  549.  
  550.     if (m_pDocManager != NULL)
  551.         ASSERT_VALID(m_pDocManager);
  552. }
  553.  
  554. void CWinApp::Dump(CDumpContext& dc) const
  555. {
  556.     CWinThread::Dump(dc);
  557.  
  558.     dc << "m_hInstance = " << (UINT)m_hInstance;
  559.     dc << "\nm_hPrevInstance = " << (UINT)m_hPrevInstance;
  560.     dc << "\nm_lpCmdLine = " << m_lpCmdLine;
  561.     dc << "\nm_nCmdShow = " << m_nCmdShow;
  562.     dc << "\nm_pszAppName = " << m_pszAppName;
  563.     dc << "\nm_bHelpMode = " << m_bHelpMode;
  564.     dc << "\nm_pszExeName = " << m_pszExeName;
  565.     dc << "\nm_pszHelpFilePath = " << m_pszHelpFilePath;
  566.     dc << "\nm_pszProfileName = " << m_pszProfileName;
  567.     dc << "\nm_hDevMode = " << (UINT)m_hDevMode;
  568.     dc << "\nm_hDevNames = " << (UINT)m_hDevNames;
  569.     dc << "\nm_dwPromptContext = " << m_dwPromptContext;
  570.  
  571.     if (m_pRecentFileList != NULL)
  572.     {
  573.         dc << "\nm_strRecentFiles[] = ";
  574.         int nSize = m_pRecentFileList->GetSize();
  575.         for (int i = 0; i < nSize; i++)
  576.         {
  577.             if ((*m_pRecentFileList)[i].GetLength() != 0)
  578.                 dc << "\n\tFile: " << (*m_pRecentFileList)[i];
  579.         }
  580.     }
  581.  
  582.     if (m_pDocManager != NULL)
  583.         m_pDocManager->Dump(dc);
  584.  
  585.     dc << "\nm_nWaitCursorCount = " << m_nWaitCursorCount;
  586.     dc << "\nm_hcurWaitCursorRestore = " << (UINT)m_hcurWaitCursorRestore;
  587.     dc << "\nm_nNumPreviewPages = " << m_nNumPreviewPages;
  588.  
  589.     dc << "\nm_msgCur = {";
  590.     dc << "\n\thwnd = " << (UINT)m_msgCur.hwnd;
  591.     dc << "\n\tmessage = " << (UINT)m_msgCur.message;
  592.     dc << "\n\twParam = " << (UINT)m_msgCur.wParam;
  593.     dc << "\n\tlParam = " << (void*)m_msgCur.lParam;
  594.     dc << "\n\ttime = " << m_msgCur.time;
  595.     dc << "\n\tpt = " << CPoint(m_msgCur.pt);
  596.     dc << "\n}";
  597.  
  598.     dc << "\n";
  599. }
  600. #endif
  601.  
  602. #ifdef AFX_INIT_SEG
  603. #pragma code_seg(AFX_INIT_SEG)
  604. #endif
  605.  
  606. IMPLEMENT_DYNAMIC(CWinApp, CWinThread)
  607.  
  608. #pragma warning(disable: 4074)
  609. #pragma init_seg(lib)
  610.  
  611. PROCESS_LOCAL(_AFX_WIN_STATE, _afxWinState)
  612.  
  613. /////////////////////////////////////////////////////////////////////////////
  614.