// 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" #ifdef _MAC #include #include #include #include #endif #ifdef AFX_INIT_SEG #pragma code_seg(AFX_INIT_SEG) #endif #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// BOOL AFXAPI AfxWinInit(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { ASSERT(hPrevInstance == NULL); // handle critical errors and avoid Windows message boxes SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX); // set resource handles AFX_MODULE_STATE* pState = AfxGetModuleState(); pState->m_hCurrentInstanceHandle = hInstance; pState->m_hCurrentResourceHandle = hInstance; // fill in the initial state for the application CWinApp* pApp = AfxGetApp(); if (pApp != NULL) { // Windows specific initialization (not done if no CWinApp) pApp->m_hInstance = hInstance; pApp->m_hPrevInstance = hPrevInstance; pApp->m_lpCmdLine = lpCmdLine; pApp->m_nCmdShow = nCmdShow; pApp->SetCurrentHandles(); } // initialize thread specific data (for main thread) if (!afxContextIsDLL) AfxInitThread(); // Macintosh-specific initialization #ifdef _MAC long lResult; if (Gestalt(gestaltAppleEventsAttr, &lResult) == noErr && (lResult & (1 << gestaltAppleEventsPresent)) != 0) { _afxPfnOpenApp = NewAEEventHandlerProc(_AfxOpenAppHandler); if (_afxPfnOpenApp != NULL) { AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, _afxPfnOpenApp, (long) pApp, false); } _afxPfnOpenDoc = NewAEEventHandlerProc(_AfxOpenDocHandler); if (_afxPfnOpenDoc != NULL) { AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, _afxPfnOpenDoc, (long) pApp, false); } _afxPfnPrintDoc = NewAEEventHandlerProc(_AfxPrintDocHandler); if (_afxPfnPrintDoc != NULL) { AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, _afxPfnPrintDoc, (long) pApp, false); } _afxPfnQuit = NewAEEventHandlerProc(_AfxQuitHandler); if (_afxPfnQuit != NULL) { AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, _afxPfnQuit, (long) pApp, false); } } #endif return TRUE; } /////////////////////////////////////////////////////////////////////////// // CWinApp Initialization LPCTSTR AFX_CDECL AfxGlobalDupString(LPCTSTR lpszSrc) { UINT nLen = (lstrlen(lpszSrc)+1)*sizeof(TCHAR); LPTSTR lpsz = (LPTSTR)::GlobalAlloc(GMEM_FIXED|GMEM_SHARE, nLen); memcpy(lpsz, lpszSrc, nLen); return lpsz; } void CWinApp::SetCurrentHandles() { ASSERT(this == afxCurrentWinApp); ASSERT(afxCurrentAppName == NULL); AFX_MODULE_STATE* pState = AfxGetModuleState(); pState->m_hCurrentInstanceHandle = m_hInstance; pState->m_hCurrentResourceHandle = m_hInstance; // Note: there are a number of _tcsdup (aka strdup) calls that are // made here for the exe path, help file path, etc. This memory // is not freed and will be reported by various memory diagnostic // utilities. This is not a bug. These strings cannot be freed // because they may be set by the app to anything, even something // that is not on the heap. Furthermore, they may be accessed at // any time, including during destructor calls. Becuase the order // of destructor calls with respect to the CWinApp object and // any other objects in the program is not deterministic, the // CWinApp object cannot free this memory. // get path of executable TCHAR szBuff[_MAX_PATH]; VERIFY(::GetModuleFileName(m_hInstance, szBuff, _MAX_PATH)); #ifndef _MAC LPTSTR lpszExt = _tcsrchr(szBuff, '.'); ASSERT(lpszExt != NULL); ASSERT(*lpszExt == '.'); *lpszExt = 0; // no suffix #endif TCHAR szExeName[_MAX_PATH]; TCHAR szTitle[256]; if (!afxContextIsDLL) { // get the exe title from the full path name [no extension] VERIFY(AfxGetFileName(szBuff, szExeName, _MAX_PATH) == 0); if (m_pszExeName == NULL) { BOOL bEnable = AfxEnableMemoryTracking(FALSE); m_pszExeName = _tcsdup(szExeName); // save non-localized name AfxEnableMemoryTracking(bEnable); } // m_pszAppName is the name used to present to the user if (m_pszAppName == NULL) { BOOL bEnable = AfxEnableMemoryTracking(FALSE); if (AfxLoadString(AFX_IDS_APP_TITLE, szTitle) != 0) m_pszAppName = _tcsdup(szTitle); // human readable title else m_pszAppName = _tcsdup(m_pszExeName); // same as EXE AfxEnableMemoryTracking(bEnable); } } else { // get the exe title from the full path name [no extension] VERIFY(AfxGetFileName(szBuff, szExeName, _MAX_PATH) == 0); if (m_pszExeName == NULL) m_pszExeName = AfxGlobalDupString(szExeName); // m_pszAppName is the name used to present to the user if (m_pszAppName == NULL) { if (AfxLoadString(AFX_IDS_APP_TITLE, szTitle) != 0) m_pszAppName = AfxGlobalDupString(szTitle); // human readable else m_pszAppName = AfxGlobalDupString(m_pszExeName); // same as EXE } } pState->m_lpszCurrentAppName = m_pszAppName; ASSERT(afxCurrentAppName != NULL); // For the Mac, use m_pszAppName instead of the application name when // creating the Help and Preferences file names because it's very likely // that Mac users will change the application name in the Finder, and that // would cause them to lose their preferences and help files. m_pszAppName // is somewhat more permanent. // get path of .HLP file if (m_pszHelpFilePath == NULL) { #ifndef _MAC lstrcpy(lpszExt, _T(".HLP")); BOOL bEnable = AfxEnableMemoryTracking(FALSE); if (!afxContextIsDLL) m_pszHelpFilePath = _tcsdup(szBuff); else m_pszHelpFilePath = AfxGlobalDupString(szBuff); AfxEnableMemoryTracking(bEnable); *lpszExt = '\0'; // back to no suffix #else OFSTRUCT ofs; // If this verify fails, probably what's wrong is that the combined // lengths of m_pszAppName and " Help" are greater than 31, the max // length of a Mac filename. To fix this you should reduce the // length of your AFX_IDS_APP_TITLE string. lstrcpy(szBuff, m_pszAppName); lstrcat(szBuff, _T(" Help")); VERIFY(OpenFile(szBuff, &ofs, OF_PARSE) != HFILE_ERROR); BOOL bEnable = AfxEnableMemoryTracking(FALSE); m_pszHelpFilePath = _tcsdup(ofs.szPathName); AfxEnableMemoryTracking(bEnable); #endif } if (m_pszProfileName == NULL) { #ifndef _MAC lstrcat(szExeName, _T(".INI")); // will be enough room in buffer #else // Just a file name, no path - Profile APIs will automatically place // the prefs file in the Preferences folder in the System Folder. lstrcpy(szExeName, m_pszAppName); lstrcat(szExeName, _T(" Preferences")); #endif BOOL bEnable = AfxEnableMemoryTracking(FALSE); if (!afxContextIsDLL) m_pszProfileName = _tcsdup(szExeName); else m_pszProfileName = AfxGlobalDupString(szExeName); AfxEnableMemoryTracking(bEnable); } } ///////////////////////////////////////////////////////////////////////////// // CFile implementation helpers #ifdef AfxGetFileName #undef AfxGetFileName #endif UINT AFXAPI AfxGetFileName(LPCTSTR lpszPathName, LPTSTR lpszTitle, UINT nMax) { ASSERT(lpszTitle == NULL || AfxIsValidAddress(lpszTitle, _MAX_FNAME)); ASSERT(AfxIsValidString(lpszPathName, FALSE)); // always capture the complete file name including extension (if present) LPTSTR lpszTemp = (LPTSTR)lpszPathName; for (LPCTSTR lpsz = lpszPathName; *lpsz != '\0'; lpsz = _tcsinc(lpsz)) { // remember last directory/drive separator if (*lpsz == '\\' || *lpsz == '/' || *lpsz == ':') lpszTemp = (LPTSTR)_tcsinc(lpsz); } // lpszTitle can be NULL which just returns the number of bytes if (lpszTitle == NULL) return lstrlen(lpszTemp)+1; // otherwise copy it into the buffer provided lstrcpyn(lpszTitle, lpszTemp, nMax); return 0; } /////////////////////////////////////////////////////////////////////////////