mirror of https://github.com/lianthony/NT4.0
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.
881 lines
20 KiB
881 lines
20 KiB
// This is a part of the Microsoft Foundation Classes C++ library.
|
|
// Copyright (C) 1992-1995 Microsoft Corporation
|
|
// All rights reserved.
|
|
//
|
|
// This source code is only intended as a supplement to the
|
|
// Microsoft Foundation Classes Reference and related
|
|
// electronic documentation provided with the library.
|
|
// See these sources for detailed information regarding the
|
|
// Microsoft Foundation Classes product.
|
|
|
|
#include "stdafx.h"
|
|
#include <malloc.h>
|
|
#ifdef _MAC
|
|
#include <macname1.h>
|
|
#include <Types.h>
|
|
#include <GestaltEqu.h>
|
|
#include <AERegistry.h>
|
|
#include <Errors.h>
|
|
#include <macname2.h>
|
|
#endif
|
|
|
|
#ifdef AFX_CORE1_SEG
|
|
#pragma code_seg(AFX_CORE1_SEG)
|
|
#endif
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
static const TCHAR szFileSection[] = _T("Recent File List");
|
|
static const TCHAR szFileEntry[] = _T("File%d");
|
|
static const TCHAR szPreviewSection[] = _T("Settings");
|
|
static const TCHAR szPreviewEntry[] = _T("PreviewPages");
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// globals (internal library use)
|
|
|
|
// CDocManager statics are in this file for granularity reasons
|
|
BOOL CDocManager::bStaticInit = TRUE;
|
|
CDocManager* CDocManager::pStaticDocManager = NULL;
|
|
CPtrList* CDocManager::pStaticList = NULL;
|
|
|
|
BEGIN_MESSAGE_MAP(CWinApp, CCmdTarget)
|
|
//{{AFX_MSG_MAP(CWinApp)
|
|
// Global File commands
|
|
ON_COMMAND(ID_APP_EXIT, OnAppExit)
|
|
// MRU - most recently used file menu
|
|
ON_UPDATE_COMMAND_UI(ID_FILE_MRU_FILE1, OnUpdateRecentFileMenu)
|
|
ON_COMMAND_EX_RANGE(ID_FILE_MRU_FILE1, ID_FILE_MRU_FILE16, OnOpenRecentFile)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// _AFX_WIN_STATE implementation
|
|
|
|
#ifdef AFX_INIT_SEG
|
|
#pragma code_seg(AFX_INIT_SEG)
|
|
#endif
|
|
|
|
_AFX_WIN_STATE::_AFX_WIN_STATE()
|
|
{
|
|
// Note: it is only necessary to intialize non-zero data.
|
|
|
|
#ifdef _MAC
|
|
// by default, don't override DefWindowProc's coloring
|
|
m_crDlgTextClr = (COLORREF)-1;
|
|
#endif
|
|
}
|
|
|
|
#ifdef AFX_TERM_SEG
|
|
#pragma code_seg(AFX_TERM_SEG)
|
|
#endif
|
|
|
|
_AFX_WIN_STATE::~_AFX_WIN_STATE()
|
|
{
|
|
AfxDeleteObject((HGDIOBJ*)&m_hDlgBkBrush);
|
|
}
|
|
|
|
#ifdef AFX_INIT_SEG
|
|
#pragma code_seg(AFX_INIT_SEG)
|
|
#endif
|
|
|
|
CWinApp::CWinApp(LPCTSTR lpszAppName)
|
|
{
|
|
if (lpszAppName != NULL)
|
|
m_pszAppName = _tcsdup(lpszAppName);
|
|
else
|
|
m_pszAppName = NULL;
|
|
|
|
// initialize CWinThread state
|
|
AFX_MODULE_STATE* pModuleState = _AFX_CMDTARGET_GETSTATE();
|
|
AFX_MODULE_THREAD_STATE* pThreadState = pModuleState->m_thread;
|
|
ASSERT(AfxGetThread() == NULL);
|
|
pThreadState->m_pCurrentWinThread = this;
|
|
ASSERT(AfxGetThread() == this);
|
|
m_hThread = ::GetCurrentThread();
|
|
m_nThreadID = ::GetCurrentThreadId();
|
|
|
|
// initialize CWinApp state
|
|
ASSERT(afxCurrentWinApp == NULL); // only one CWinApp object please
|
|
pModuleState->m_pCurrentWinApp = this;
|
|
ASSERT(AfxGetApp() == this);
|
|
|
|
// in non-running state until WinMain
|
|
m_hInstance = NULL;
|
|
m_pszHelpFilePath = NULL;
|
|
m_pszProfileName = NULL;
|
|
m_pszRegistryKey = NULL;
|
|
m_pszExeName = NULL;
|
|
m_pRecentFileList = NULL;
|
|
m_pDocManager = NULL;
|
|
m_atomApp = m_atomSystemTopic = NULL;
|
|
m_lpCmdLine = NULL;
|
|
m_pCmdInfo = NULL;
|
|
|
|
// initialize wait cursor state
|
|
m_nWaitCursorCount = 0;
|
|
m_hcurWaitCursorRestore = NULL;
|
|
|
|
// initialize current printer state
|
|
m_hDevMode = NULL;
|
|
m_hDevNames = NULL;
|
|
m_nNumPreviewPages = 0; // not specified (defaults to 1)
|
|
|
|
// initialize DAO state
|
|
m_lpfnDaoTerm = NULL; // will be set if AfxDaoInit called
|
|
|
|
// other initialization
|
|
m_bHelpMode = FALSE;
|
|
m_nSafetyPoolSize = 512; // default size
|
|
|
|
#ifdef _MAC
|
|
m_nSaveOption = saveAsk;
|
|
#endif
|
|
}
|
|
|
|
BOOL CWinApp::InitApplication()
|
|
{
|
|
if (CDocManager::pStaticDocManager != NULL)
|
|
{
|
|
if (m_pDocManager == NULL)
|
|
m_pDocManager = CDocManager::pStaticDocManager;
|
|
CDocManager::pStaticDocManager = NULL;
|
|
}
|
|
|
|
if (m_pDocManager != NULL)
|
|
m_pDocManager->AddDocTemplate(NULL);
|
|
else
|
|
CDocManager::bStaticInit = FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CWinApp::InitInstance()
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
void CWinApp::LoadStdProfileSettings(UINT nMaxMRU)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(m_pRecentFileList == NULL);
|
|
|
|
if (nMaxMRU != 0)
|
|
{
|
|
// create file MRU since nMaxMRU not zero
|
|
m_pRecentFileList = new CRecentFileList(0, szFileSection, szFileEntry,
|
|
nMaxMRU);
|
|
m_pRecentFileList->ReadList();
|
|
}
|
|
// 0 by default means not set
|
|
m_nNumPreviewPages = GetProfileInt(szPreviewSection, szPreviewEntry, 0);
|
|
}
|
|
|
|
void CWinApp::ParseCommandLine(CCommandLineInfo& rCmdInfo)
|
|
{
|
|
#ifndef _MAC
|
|
for (int i = 1; i < __argc; i++)
|
|
{
|
|
LPCTSTR pszParam = __targv[i];
|
|
BOOL bFlag = FALSE;
|
|
BOOL bLast = ((i + 1) == __argc);
|
|
if (pszParam[0] == '-' || pszParam[0] == '/')
|
|
{
|
|
// remove flag specifier
|
|
bFlag = TRUE;
|
|
++pszParam;
|
|
}
|
|
rCmdInfo.ParseParam(pszParam, bFlag, bLast);
|
|
}
|
|
#else
|
|
// WLM command line can contain only one parameter,
|
|
// /Embedding
|
|
|
|
if (m_lpCmdLine[0] == '-' || m_lpCmdLine[0] == '/')
|
|
{
|
|
rCmdInfo.ParseParam(m_lpCmdLine+1, TRUE, TRUE);
|
|
}
|
|
|
|
#endif // _MAC
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CCommandLineInfo implementation
|
|
|
|
CCommandLineInfo::CCommandLineInfo()
|
|
{
|
|
m_bShowSplash = TRUE;
|
|
m_bRunEmbedded = FALSE;
|
|
m_bRunAutomated = FALSE;
|
|
m_nShellCommand = FileNew;
|
|
}
|
|
|
|
CCommandLineInfo::~CCommandLineInfo()
|
|
{
|
|
}
|
|
|
|
void CCommandLineInfo::ParseParam(const TCHAR* pszParam,BOOL bFlag,BOOL bLast)
|
|
{
|
|
if (bFlag)
|
|
{
|
|
USES_CONVERSION;
|
|
ParseParamFlag(T2CA(pszParam));
|
|
}
|
|
else
|
|
ParseParamNotFlag(pszParam);
|
|
|
|
ParseLast(bLast);
|
|
}
|
|
|
|
#ifdef UNICODE
|
|
void CCommandLineInfo::ParseParam(const char* pszParam, BOOL bFlag, BOOL bLast)
|
|
{
|
|
if (bFlag)
|
|
ParseParamFlag(pszParam);
|
|
else
|
|
ParseParamNotFlag(pszParam);
|
|
|
|
ParseLast(bLast);
|
|
}
|
|
#endif // UNICODE
|
|
|
|
void CCommandLineInfo::ParseParamFlag(const char* pszParam)
|
|
{
|
|
if (lstrcmpA(pszParam, "pt") == 0)
|
|
m_nShellCommand = FilePrintTo;
|
|
else if (lstrcmpA(pszParam, "p") == 0)
|
|
m_nShellCommand = FilePrint;
|
|
else if (lstrcmpA(pszParam, "Unregister") == 0)
|
|
m_nShellCommand = AppUnregister;
|
|
else if (lstrcmpA(pszParam, "dde") == 0)
|
|
{
|
|
AfxOleSetUserCtrl(FALSE);
|
|
m_nShellCommand = FileDDE;
|
|
}
|
|
else if (lstrcmpA(pszParam, "Embedding") == 0)
|
|
{
|
|
AfxOleSetUserCtrl(FALSE);
|
|
m_bRunEmbedded = TRUE;
|
|
m_bShowSplash = FALSE;
|
|
}
|
|
else if (lstrcmpA(pszParam, "Automation") == 0)
|
|
{
|
|
AfxOleSetUserCtrl(FALSE);
|
|
m_bRunAutomated = TRUE;
|
|
m_bShowSplash = FALSE;
|
|
}
|
|
}
|
|
|
|
void CCommandLineInfo::ParseParamNotFlag(const TCHAR* pszParam)
|
|
{
|
|
if (m_strFileName.IsEmpty())
|
|
m_strFileName = pszParam;
|
|
else if (m_nShellCommand == FilePrintTo && m_strPrinterName.IsEmpty())
|
|
m_strPrinterName = pszParam;
|
|
else if (m_nShellCommand == FilePrintTo && m_strDriverName.IsEmpty())
|
|
m_strDriverName = pszParam;
|
|
else if (m_nShellCommand == FilePrintTo && m_strPortName.IsEmpty())
|
|
m_strPortName = pszParam;
|
|
}
|
|
|
|
#ifdef UNICODE
|
|
void CCommandLineInfo::ParseParamNotFlag(const char* pszParam)
|
|
{
|
|
if (m_strFileName.IsEmpty())
|
|
m_strFileName = pszParam;
|
|
else if (m_nShellCommand == FilePrintTo && m_strPrinterName.IsEmpty())
|
|
m_strPrinterName = pszParam;
|
|
else if (m_nShellCommand == FilePrintTo && m_strDriverName.IsEmpty())
|
|
m_strDriverName = pszParam;
|
|
else if (m_nShellCommand == FilePrintTo && m_strPortName.IsEmpty())
|
|
m_strPortName = pszParam;
|
|
}
|
|
#endif
|
|
|
|
void CCommandLineInfo::ParseLast(BOOL bLast)
|
|
{
|
|
if (bLast)
|
|
{
|
|
if (m_nShellCommand == FileNew && !m_strFileName.IsEmpty())
|
|
m_nShellCommand = FileOpen;
|
|
m_bShowSplash = !m_bRunEmbedded && !m_bRunAutomated;
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CWinApp MAC implementation
|
|
|
|
#ifdef _MAC
|
|
BOOL CWinApp::CreateInitialDocument()
|
|
{
|
|
if (m_pMainWnd != NULL)
|
|
m_pMainWnd->SendMessage(WM_COMMAND, ID_FILE_NEW);
|
|
else if (m_pDocManager != NULL)
|
|
{
|
|
POSITION pos = m_pDocManager->GetFirstDocTemplatePosition();
|
|
if (pos != NULL)
|
|
{
|
|
CDocTemplate* pTemplate = m_pDocManager->GetNextDocTemplate(pos);
|
|
|
|
// if MDI, or SDI but we haven't opened any documents yet, open a new one
|
|
if (pTemplate != NULL &&
|
|
(pTemplate->IsKindOf(RUNTIME_CLASS(CMultiDocTemplate)) ||
|
|
m_pDocManager->GetOpenDocumentCount() == 0))
|
|
{
|
|
OnFileNew();
|
|
}
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// required AppleEvent handlers
|
|
|
|
static OSErr MissingParams(AppleEvent* pae)
|
|
{
|
|
OSErr err;
|
|
DescType dtT;
|
|
Size lT;
|
|
|
|
err = AEGetAttributePtr(pae, keyMissedKeywordAttr, typeWildCard,
|
|
&dtT, NULL, 0, &lT);
|
|
|
|
if (err == errAEDescNotFound)
|
|
return noErr;
|
|
else if (err == noErr)
|
|
return errAEEventNotHandled;
|
|
else
|
|
return err;
|
|
}
|
|
|
|
static OSErr HandlerCommon(AppleEvent* pae, long lRefcon, CWinApp*& rpApp)
|
|
{
|
|
OSErr err = MissingParams(pae);
|
|
if (err != noErr)
|
|
return err;
|
|
|
|
rpApp = (CWinApp*) lRefcon;
|
|
ASSERT_VALID(rpApp);
|
|
ASSERT_KINDOF(CWinApp, rpApp);
|
|
|
|
return noErr;
|
|
}
|
|
|
|
OSErr PASCAL _AfxOpenAppHandler(AppleEvent* pae, AppleEvent*, long lRefcon)
|
|
{
|
|
CWinApp* pApp;
|
|
OSErr err = HandlerCommon(pae, lRefcon, pApp);
|
|
if (err == noErr)
|
|
{
|
|
if (pApp->CreateInitialDocument())
|
|
err = noErr;
|
|
else
|
|
err = errAEEventNotHandled;
|
|
}
|
|
AfxOleSetUserCtrl(TRUE);
|
|
return err;
|
|
}
|
|
|
|
OSErr PASCAL _AfxOpenDocHandler(AppleEvent* pae, AppleEvent*, long lRefcon)
|
|
{
|
|
AEDescList docList;
|
|
OSErr err = AEGetParamDesc(pae, keyDirectObject, typeAEList, &docList);
|
|
if (err == noErr)
|
|
{
|
|
CWinApp* pApp;
|
|
err = HandlerCommon(pae, lRefcon, pApp);
|
|
if (err == noErr)
|
|
{
|
|
long cDoc;
|
|
VERIFY(AECountItems(&docList, &cDoc) == noErr);
|
|
|
|
for (int iDoc = 1; iDoc <= cDoc; iDoc++)
|
|
{
|
|
AEKeyword key;
|
|
DescType dt;
|
|
long lcb;
|
|
FSSpec fss;
|
|
|
|
if (AEGetNthPtr(&docList, iDoc, typeFSS, &key, &dt, (Ptr) &fss,
|
|
sizeof(FSSpec), &lcb) == noErr)
|
|
{
|
|
ASSERT(dt == typeFSS);
|
|
ASSERT(lcb == sizeof(FSSpec));
|
|
|
|
char sz[256];
|
|
if (WrapFile(&fss, sz, sizeof(sz)))
|
|
pApp->OpenDocumentFile(sz);
|
|
}
|
|
}
|
|
}
|
|
VERIFY(AEDisposeDesc(&docList) == noErr);
|
|
}
|
|
|
|
AfxOleSetUserCtrl(TRUE);
|
|
return err;
|
|
}
|
|
|
|
OSErr PASCAL _AfxPrintDocHandler(AppleEvent* pae, AppleEvent*, long lRefcon)
|
|
{
|
|
AEDescList docList;
|
|
|
|
SetCursor(afxData.hcurArrow);
|
|
OSErr err = AEGetParamDesc(pae, keyDirectObject, typeAEList, &docList);
|
|
if (err == noErr)
|
|
{
|
|
CWinApp* pApp;
|
|
err = HandlerCommon(pae, lRefcon, pApp);
|
|
if (err == noErr)
|
|
{
|
|
long cDoc;
|
|
AEInteractAllowed level;
|
|
BOOL bLevelChanged = TRUE;
|
|
|
|
VERIFY(AECountItems(&docList, &cDoc) == noErr);
|
|
if (AEGetInteractionAllowed(&level) != noErr)
|
|
{
|
|
bLevelChanged = FALSE;
|
|
}
|
|
|
|
for (int iDoc = 1; iDoc <= cDoc; iDoc++)
|
|
{
|
|
AEKeyword key;
|
|
DescType dt;
|
|
long lcb;
|
|
FSSpec fss;
|
|
|
|
if ((iDoc == 2) && (bLevelChanged) &&
|
|
(AESetInteractionAllowed(kAEInteractWithSelf) != noErr))
|
|
{
|
|
bLevelChanged = FALSE;
|
|
}
|
|
|
|
if (AEGetNthPtr(&docList, iDoc, typeFSS, &key, &dt, (Ptr) &fss,
|
|
sizeof(FSSpec), &lcb) == noErr)
|
|
{
|
|
CDocument* pDoc = NULL;
|
|
|
|
ASSERT(dt == typeFSS);
|
|
ASSERT(lcb == sizeof(FSSpec));
|
|
|
|
char sz[256];
|
|
if (WrapFile(&fss, sz, sizeof(sz)))
|
|
pDoc = pApp->OpenDocumentFile(sz);
|
|
|
|
if(pDoc != NULL)
|
|
{
|
|
POSITION pos = pDoc->GetFirstViewPosition();
|
|
CView* pView = pDoc->GetNextView(pos);
|
|
|
|
if(pView != NULL)
|
|
{
|
|
pView->SendMessage(WM_COMMAND, ID_FILE_PRINT);
|
|
}
|
|
pDoc->OnCloseDocument();
|
|
}
|
|
}
|
|
}
|
|
if (bLevelChanged)
|
|
{
|
|
AESetInteractionAllowed(level);
|
|
}
|
|
}
|
|
VERIFY(AEDisposeDesc(&docList) == noErr);
|
|
}
|
|
|
|
AfxOleSetUserCtrl(TRUE);
|
|
return err;
|
|
}
|
|
|
|
OSErr PASCAL _AfxQuitHandler(AppleEvent* pae, AppleEvent*, long lRefcon)
|
|
{
|
|
long newSave;
|
|
DescType dt;
|
|
long lcb;
|
|
|
|
if (AEGetParamPtr(pae, keyAESaveOptions, typeEnumeration, &dt,
|
|
(Ptr) &newSave, sizeof(newSave), &lcb) != noErr)
|
|
newSave = kAEAsk;
|
|
#ifdef _DEBUG
|
|
else
|
|
{
|
|
ASSERT(dt == typeEnumeration);
|
|
ASSERT(lcb == sizeof(newSave));
|
|
}
|
|
#endif
|
|
|
|
CWinApp* pApp;
|
|
OSErr err = HandlerCommon(pae, lRefcon, pApp);
|
|
if (err != noErr)
|
|
return err;
|
|
|
|
CWinApp::SaveOption oldSave = pApp->m_nSaveOption;
|
|
|
|
switch (newSave)
|
|
{
|
|
case kAEYes:
|
|
pApp->m_nSaveOption = CWinApp::saveYes;
|
|
break;
|
|
|
|
case kAENo:
|
|
pApp->m_nSaveOption = CWinApp::saveNo;
|
|
break;
|
|
|
|
case kAEAsk:
|
|
pApp->m_nSaveOption = CWinApp::saveAsk;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
ASSERT(err == noErr); // initial state assumed by the following code
|
|
|
|
if (pApp->m_pMainWnd != NULL)
|
|
{
|
|
pApp->m_pMainWnd->SendMessage(WM_COMMAND, ID_APP_EXIT);
|
|
if (pApp->m_pMainWnd != NULL)
|
|
err = userCanceledErr;
|
|
}
|
|
else
|
|
{
|
|
// Perhaps the app is using a dialog as its UI. Just tell it
|
|
// to quit directly.
|
|
|
|
AfxPostQuitMessage(0);
|
|
}
|
|
pApp->m_nSaveOption = oldSave;
|
|
|
|
return err;
|
|
}
|
|
|
|
#endif //_MAC
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// App termination
|
|
|
|
CWinApp::~CWinApp()
|
|
{
|
|
// free doc manager
|
|
if (m_pDocManager != NULL)
|
|
delete m_pDocManager;
|
|
|
|
// free recent file list
|
|
if (m_pRecentFileList != NULL)
|
|
delete m_pRecentFileList;
|
|
|
|
// free static list of document templates
|
|
if (!afxContextIsDLL)
|
|
{
|
|
if (CDocManager::pStaticList != NULL)
|
|
{
|
|
delete CDocManager::pStaticList;
|
|
CDocManager::pStaticList = NULL;
|
|
}
|
|
if (CDocManager::pStaticDocManager != NULL)
|
|
{
|
|
delete CDocManager::pStaticDocManager;
|
|
CDocManager::pStaticDocManager = NULL;
|
|
}
|
|
}
|
|
|
|
// free printer info
|
|
if (m_hDevMode != NULL)
|
|
AfxGlobalFree(m_hDevMode);
|
|
if (m_hDevNames != NULL)
|
|
AfxGlobalFree(m_hDevNames);
|
|
|
|
// free atoms if used
|
|
if (m_atomApp != NULL)
|
|
::GlobalDeleteAtom(m_atomApp);
|
|
if (m_atomSystemTopic != NULL)
|
|
::GlobalDeleteAtom(m_atomSystemTopic);
|
|
|
|
// free cached commandline
|
|
if (m_pCmdInfo != NULL)
|
|
delete m_pCmdInfo;
|
|
|
|
// cleanup module state
|
|
AFX_MODULE_STATE* pModuleState = _AFX_CMDTARGET_GETSTATE();
|
|
if (pModuleState->m_lpszCurrentAppName == m_pszAppName)
|
|
pModuleState->m_lpszCurrentAppName = NULL;
|
|
if (pModuleState->m_pCurrentWinApp == this)
|
|
pModuleState->m_pCurrentWinApp = NULL;
|
|
|
|
// free various strings allocated with _tcsdup
|
|
free((void*)m_pszAppName);
|
|
free((void*)m_pszRegistryKey);
|
|
free((void*)m_pszExeName);
|
|
free((void*)m_pszHelpFilePath);
|
|
free((void*)m_pszProfileName);
|
|
}
|
|
|
|
void CWinApp::SaveStdProfileSettings()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_pRecentFileList != NULL)
|
|
m_pRecentFileList->WriteList();
|
|
|
|
if (m_nNumPreviewPages != 0)
|
|
WriteProfileInt(szPreviewSection, szPreviewEntry, AfxGetApp()->m_nNumPreviewPages);
|
|
}
|
|
|
|
int CWinApp::ExitInstance()
|
|
{
|
|
if (!afxContextIsDLL)
|
|
SaveStdProfileSettings();
|
|
|
|
// Cleanup DAO if necessary
|
|
if (m_lpfnDaoTerm != NULL)
|
|
{
|
|
// If a DLL, YOU must call AfxDaoTerm prior to ExitInstance
|
|
ASSERT(!afxContextIsDLL);
|
|
|
|
(*m_lpfnDaoTerm)();
|
|
}
|
|
|
|
return m_msgCur.wParam; // returns the value from PostQuitMessage
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#ifdef AFX_CORE1_SEG
|
|
#pragma code_seg(AFX_CORE1_SEG)
|
|
#endif
|
|
|
|
// Main running routine until application exits
|
|
int CWinApp::Run()
|
|
{
|
|
if (m_pMainWnd == NULL && AfxOleGetUserCtrl())
|
|
{
|
|
// Not launched /Embedding or /Automation, but has no main window!
|
|
TRACE0("Warning: m_pMainWnd is NULL in CWinApp::Run - quitting application.\n");
|
|
AfxPostQuitMessage(0);
|
|
}
|
|
return CWinThread::Run();
|
|
}
|
|
|
|
#ifdef AFX_TERM_SEG
|
|
#pragma code_seg(AFX_TERM_SEG)
|
|
#endif
|
|
|
|
void AFXAPI AfxPostQuitMessage(int nExitCode)
|
|
{
|
|
// cleanup OLE libraries
|
|
CWinThread* pThread = AfxGetThread();
|
|
if (pThread != NULL && pThread->m_lpfnOleTermOrFreeLib != NULL)
|
|
(*pThread->m_lpfnOleTermOrFreeLib)(TRUE, TRUE);
|
|
|
|
::PostQuitMessage(nExitCode);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// WinHelp Helper
|
|
|
|
#ifdef AFX_CORE1_SEG
|
|
#pragma code_seg(AFX_CORE1_SEG)
|
|
#endif
|
|
|
|
void CWinApp::WinHelp(DWORD dwData, UINT nCmd)
|
|
{
|
|
CWnd* pMainWnd = AfxGetMainWnd();
|
|
ASSERT_VALID(pMainWnd);
|
|
|
|
// return global app help mode state to FALSE (backward compatibility)
|
|
m_bHelpMode = FALSE;
|
|
pMainWnd->PostMessage(WM_KICKIDLE); // trigger idle update
|
|
|
|
pMainWnd->WinHelp(dwData, nCmd);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Special exception handling
|
|
|
|
LRESULT CWinApp::ProcessWndProcException(CException* e, const MSG* pMsg)
|
|
{
|
|
// handle certain messages in CWinThread
|
|
switch (pMsg->message)
|
|
{
|
|
case WM_CREATE:
|
|
case WM_PAINT:
|
|
return CWinThread::ProcessWndProcException(e, pMsg);
|
|
}
|
|
|
|
// handle all the rest
|
|
UINT nIDP = AFX_IDP_INTERNAL_FAILURE; // generic message string
|
|
LRESULT lResult = 0; // sensible default
|
|
if (pMsg->message == WM_COMMAND)
|
|
{
|
|
if ((HWND)pMsg->lParam == NULL)
|
|
nIDP = AFX_IDP_COMMAND_FAILURE; // command (not from a control)
|
|
lResult = (LRESULT)TRUE; // pretend the command was handled
|
|
}
|
|
if (e->IsKindOf(RUNTIME_CLASS(CMemoryException)))
|
|
{
|
|
e->ReportError(MB_ICONEXCLAMATION|MB_SYSTEMMODAL, nIDP);
|
|
}
|
|
else if (!e->IsKindOf(RUNTIME_CLASS(CUserException)))
|
|
{
|
|
// user has not been alerted yet of this catastrophic problem
|
|
e->ReportError(MB_ICONSTOP, nIDP);
|
|
}
|
|
return lResult; // sensible default return from most WndProc functions
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CWinApp idle processing
|
|
|
|
BOOL CWinApp::OnIdle(LONG lCount)
|
|
{
|
|
if (lCount <= 0)
|
|
{
|
|
CWinThread::OnIdle(lCount);
|
|
|
|
// call doc-template idle hook
|
|
POSITION pos = NULL;
|
|
if (m_pDocManager != NULL)
|
|
pos = m_pDocManager->GetFirstDocTemplatePosition();
|
|
|
|
while (pos != NULL)
|
|
{
|
|
CDocTemplate* pTemplate = m_pDocManager->GetNextDocTemplate(pos);
|
|
ASSERT_KINDOF(CDocTemplate, pTemplate);
|
|
pTemplate->OnIdle();
|
|
}
|
|
}
|
|
else if (lCount == 1)
|
|
{
|
|
VERIFY(!CWinThread::OnIdle(lCount));
|
|
}
|
|
return lCount < 1; // more to do if lCount < 1
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CWinApp idle processing
|
|
|
|
void CWinApp::DevModeChange(LPTSTR lpDeviceName)
|
|
{
|
|
if (m_hDevNames == NULL)
|
|
return;
|
|
|
|
#ifndef _MAC
|
|
LPDEVNAMES lpDevNames = (LPDEVNAMES)::GlobalLock(m_hDevNames);
|
|
ASSERT(lpDevNames != NULL);
|
|
if (lstrcmp((LPCTSTR)lpDevNames + lpDevNames->wDeviceOffset,
|
|
lpDeviceName) == 0)
|
|
{
|
|
HANDLE hPrinter;
|
|
if (!OpenPrinter(lpDeviceName, &hPrinter, NULL))
|
|
return;
|
|
|
|
// DEVMODE changed for the current printer
|
|
if (m_hDevMode != NULL)
|
|
AfxGlobalFree(m_hDevMode);
|
|
|
|
// A zero for last param returns the size of buffer needed.
|
|
int nSize = DocumentProperties(NULL, hPrinter, lpDeviceName,
|
|
NULL, NULL, 0);
|
|
ASSERT(nSize >= 0);
|
|
m_hDevMode = GlobalAlloc(GHND, nSize);
|
|
LPDEVMODE lpDevMode = (LPDEVMODE)GlobalLock(m_hDevMode);
|
|
|
|
// Fill in the rest of the structure.
|
|
if (DocumentProperties(NULL, hPrinter, lpDeviceName, lpDevMode,
|
|
NULL, DM_OUT_BUFFER) != IDOK)
|
|
{
|
|
AfxGlobalFree(m_hDevMode);
|
|
m_hDevMode = NULL;
|
|
}
|
|
ClosePrinter(hPrinter);
|
|
}
|
|
#else
|
|
UNUSED_ALWAYS(lpDeviceName);
|
|
#endif
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// CWinApp diagnostics
|
|
|
|
#ifdef _DEBUG
|
|
void CWinApp::AssertValid() const
|
|
{
|
|
CWinThread::AssertValid();
|
|
|
|
ASSERT(afxCurrentWinApp == this);
|
|
ASSERT(afxCurrentInstanceHandle == m_hInstance);
|
|
|
|
if (AfxGetThread() != (CWinThread*)this)
|
|
return; // only do subset if called from different thread
|
|
|
|
if (m_pDocManager != NULL)
|
|
ASSERT_VALID(m_pDocManager);
|
|
}
|
|
|
|
void CWinApp::Dump(CDumpContext& dc) const
|
|
{
|
|
CWinThread::Dump(dc);
|
|
|
|
dc << "m_hInstance = " << (UINT)m_hInstance;
|
|
dc << "\nm_hPrevInstance = " << (UINT)m_hPrevInstance;
|
|
dc << "\nm_lpCmdLine = " << m_lpCmdLine;
|
|
dc << "\nm_nCmdShow = " << m_nCmdShow;
|
|
dc << "\nm_pszAppName = " << m_pszAppName;
|
|
dc << "\nm_bHelpMode = " << m_bHelpMode;
|
|
dc << "\nm_pszExeName = " << m_pszExeName;
|
|
dc << "\nm_pszHelpFilePath = " << m_pszHelpFilePath;
|
|
dc << "\nm_pszProfileName = " << m_pszProfileName;
|
|
dc << "\nm_hDevMode = " << (UINT)m_hDevMode;
|
|
dc << "\nm_hDevNames = " << (UINT)m_hDevNames;
|
|
dc << "\nm_dwPromptContext = " << m_dwPromptContext;
|
|
#ifdef _MAC
|
|
dc << "\nm_nSaveOption = " << (UINT)m_nSaveOption;
|
|
#endif
|
|
|
|
if (m_pRecentFileList != NULL)
|
|
{
|
|
dc << "\nm_strRecentFiles[] = ";
|
|
int nSize = m_pRecentFileList->GetSize();
|
|
for (int i = 0; i < nSize; i++)
|
|
{
|
|
if ((*m_pRecentFileList)[i].GetLength() != 0)
|
|
dc << "\n\tFile: " << (*m_pRecentFileList)[i];
|
|
}
|
|
}
|
|
|
|
if (m_pDocManager != NULL)
|
|
m_pDocManager->Dump(dc);
|
|
|
|
dc << "\nm_nWaitCursorCount = " << m_nWaitCursorCount;
|
|
dc << "\nm_hcurWaitCursorRestore = " << (UINT)m_hcurWaitCursorRestore;
|
|
dc << "\nm_nNumPreviewPages = " << m_nNumPreviewPages;
|
|
|
|
dc << "\nm_msgCur = {";
|
|
dc << "\n\thwnd = " << (UINT)m_msgCur.hwnd;
|
|
dc << "\n\tmessage = " << (UINT)m_msgCur.message;
|
|
dc << "\n\twParam = " << (UINT)m_msgCur.wParam;
|
|
dc << "\n\tlParam = " << (void*)m_msgCur.lParam;
|
|
dc << "\n\ttime = " << m_msgCur.time;
|
|
dc << "\n\tpt = " << CPoint(m_msgCur.pt);
|
|
dc << "\n}";
|
|
|
|
dc << "\n";
|
|
}
|
|
#endif
|
|
|
|
#ifdef AFX_INIT_SEG
|
|
#pragma code_seg(AFX_INIT_SEG)
|
|
#endif
|
|
|
|
IMPLEMENT_DYNAMIC(CWinApp, CWinThread)
|
|
|
|
#pragma warning(disable: 4074)
|
|
#pragma init_seg(lib)
|
|
|
|
PROCESS_LOCAL(_AFX_WIN_STATE, _afxWinState)
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|