|
|
1.1 ! root 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: #include "window_.h" ! 15: ! 16: #ifndef _NTWIN ! 17: #include "penwin.h" // MFC Apps are PenAware by default ! 18: #endif ! 19: ! 20: #ifdef AFX_CORE_SEG ! 21: #pragma code_seg(AFX_CORE_SEG) ! 22: #endif ! 23: ! 24: #ifdef _DEBUG ! 25: #include "trace_.h" ! 26: #undef THIS_FILE ! 27: static char BASED_CODE THIS_FILE[] = __FILE__; ! 28: #endif ! 29: ! 30: ///////////////////////////////////////////////////////////////////////////// ! 31: // Define global state in ordinary "C" globals ! 32: ! 33: extern "C" ! 34: { ! 35: CWinApp* afxCurrentWinApp = NULL; ! 36: HANDLE afxCurrentInstanceHandle = NULL; ! 37: HANDLE afxCurrentResourceHandle = NULL; ! 38: const char* afxCurrentAppName = NULL; ! 39: } ! 40: ! 41: ///////////////////////////////////////////////////////////////////////////// ! 42: // other globals (internal library use) ! 43: ! 44: // Proc addresses for Win3.1 specifics ! 45: #ifndef _WINDLL ! 46: HOOKPROC (WINAPI* _afxSetWindowsHookExProc)(int, HOOKPROC, HINSTANCE, HTASK); ! 47: static void (FAR PASCAL *_afxRegisterPenAppProc)(UINT, BOOL); ! 48: #endif //!_WINDLL ! 49: ! 50: ///////////////////////////////////////////////////////////////////////////// ! 51: ! 52: IMPLEMENT_DYNAMIC(CWinApp, CObject) ! 53: ! 54: #ifdef _DEBUG ! 55: void CWinApp::AssertValid() const ! 56: { ! 57: CObject::AssertValid(); ! 58: ASSERT(afxCurrentWinApp == this); ! 59: ASSERT(afxCurrentInstanceHandle == m_hInstance); ! 60: } ! 61: ! 62: void CWinApp::Dump(CDumpContext& dc) const ! 63: { ! 64: CObject::Dump(dc); ! 65: dc << "\nm_hInstance = " << (UINT)m_hInstance; ! 66: dc << "\nm_hPrevInstance = " << (UINT)m_hPrevInstance; ! 67: dc << "\nm_lpCmdLine = " << m_lpCmdLine; ! 68: dc << "\nm_nCmdShow = " << m_nCmdShow; ! 69: dc << "\nm_pMainWnd = " << m_pMainWnd; ! 70: } ! 71: #endif ! 72: ! 73: inline void CWinApp::SetCurrentHandles() ! 74: { ! 75: ASSERT(this == afxCurrentWinApp); ! 76: afxCurrentInstanceHandle = m_hInstance; // for instance tagging ! 77: afxCurrentResourceHandle = m_hInstance; // for resource loading ! 78: ! 79: if (m_pszAppName == NULL) ! 80: { ! 81: // get name/path of executable ! 82: char szName[256]; ! 83: ::GetModuleFileName(m_hInstance, szName, sizeof(szName)-1); ! 84: m_pszAppName = _strdup(szName); ! 85: } ! 86: afxCurrentAppName = m_pszAppName; ! 87: ASSERT(afxCurrentAppName != NULL); ! 88: } ! 89: ! 90: ///////////////////////////////////////////////////////////////////////////// ! 91: ! 92: CWinApp::CWinApp(const char* pszAppName) ! 93: { ! 94: m_pszAppName = pszAppName; ! 95: // in non-running state until WinMain ! 96: m_hInstance = NULL; ! 97: m_pMainWnd = NULL; ! 98: ! 99: ASSERT(afxCurrentWinApp == NULL); // only one CWinApp object please ! 100: afxCurrentWinApp = this; // hook for WinMain ! 101: ! 102: #ifdef _DEBUG ! 103: m_nDisablePumpCount = 0; ! 104: #endif ! 105: } ! 106: ! 107: #ifdef _DEBUG ! 108: void CWinApp::EnablePump(BOOL bEnable) ! 109: { ! 110: if (bEnable) ! 111: m_nDisablePumpCount--; ! 112: else ! 113: m_nDisablePumpCount++; ! 114: ASSERT(m_nDisablePumpCount >= 0); ! 115: } ! 116: #endif // _DEBUG ! 117: ! 118: ! 119: BOOL CWinApp::PumpMessage() ! 120: { ! 121: #ifdef _DEBUG ! 122: if (m_nDisablePumpCount != 0) ! 123: { ! 124: TRACE("Error: CWinApp::PumpMessage() called when not permitted\n"); ! 125: ASSERT(FALSE); ! 126: } ! 127: #endif ! 128: ! 129: if (!::GetMessage(&m_msgCur, NULL, NULL, NULL)) ! 130: { ! 131: #ifdef _DEBUG ! 132: if (afxTraceFlags & 2) ! 133: TRACE("PumpMessage - Received WM_QUIT\n"); ! 134: m_nDisablePumpCount++; // application must die ! 135: // NOTE: prevents calling message loop things in 'ExitInstance' ! 136: // will never be decremented ! 137: #endif ! 138: return FALSE; ! 139: } ! 140: ! 141: #ifdef _DEBUG ! 142: if (afxTraceFlags & 2) ! 143: AfxTraceMsg("PumpMessage", &m_msgCur); ! 144: #endif ! 145: ! 146: // process this message ! 147: if (!PreTranslateMessage(&m_msgCur)) ! 148: { ! 149: ::TranslateMessage(&m_msgCur); ! 150: ::DispatchMessage(&m_msgCur); ! 151: } ! 152: return TRUE; ! 153: } ! 154: ! 155: int CWinApp::Run() ! 156: { ! 157: /* Acquire and dispatch messages until a WM_QUIT message is received. */ ! 158: ! 159: while (1) ! 160: { ! 161: LONG lIdleCount = 0; ! 162: // check to see if we can do idle work ! 163: while (!::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE) && ! 164: OnIdle(lIdleCount++)) ! 165: { ! 166: // more work to do ! 167: } ! 168: ! 169: // either we have a message, or OnIdle returned false ! 170: ! 171: if (!PumpMessage()) ! 172: break; ! 173: } ! 174: ! 175: return ExitInstance(); ! 176: } ! 177: ! 178: ///////////////////////////////////////////////////////////////////////////// ! 179: // Stubs for standard initialization ! 180: ! 181: BOOL CWinApp::InitApplication() ! 182: { ! 183: return TRUE; ! 184: } ! 185: ! 186: BOOL CWinApp::InitInstance() ! 187: { ! 188: return TRUE; ! 189: } ! 190: ! 191: ///////////////////////////////////////////////////////////////////////////// ! 192: // Stubs for standard implementation ! 193: ! 194: BOOL CWinApp::PreTranslateMessage(MSG* pMsg) ! 195: { ! 196: register HWND hWnd; ! 197: register CWnd* pWnd; ! 198: ! 199: // walk from the target window up to the desktop window seeing ! 200: // if any window wants to translate this message ! 201: for (hWnd = pMsg->hwnd; hWnd != NULL; hWnd = ::GetParent(hWnd)) ! 202: { ! 203: if ((pWnd = CWnd::FromHandlePermanent(hWnd)) != NULL) ! 204: { ! 205: // target window is a C++ window ! 206: if (pWnd->PreTranslateMessage(pMsg)) ! 207: return TRUE; // trapped by target window (eg: accelerators) ! 208: ! 209: if (pWnd == m_pMainWnd) ! 210: return FALSE; // got to our main window without interest ! 211: } ! 212: } ! 213: ! 214: // in case of modeless dialogs, last chance route through main window's ! 215: // accelerator table ! 216: if (m_pMainWnd != NULL && m_pMainWnd->PreTranslateMessage(pMsg)) ! 217: return TRUE; // trapped by main window (eg: accelerators) ! 218: ! 219: return FALSE; // no special processing ! 220: } ! 221: ! 222: ! 223: BOOL CWinApp::OnIdle(LONG /*lCount*/) ! 224: { ! 225: CGdiObject::DeleteTempMap(); ! 226: CDC::DeleteTempMap(); ! 227: CMenu::DeleteTempMap(); ! 228: CWnd::DeleteTempMap(); ! 229: return FALSE; // no more processing (sleep please) ! 230: } ! 231: ! 232: int CWinApp::ExitInstance() ! 233: { ! 234: return m_msgCur.wParam; // Returns the value from PostQuitMessage ! 235: } ! 236: ! 237: ///////////////////////////////////////////////////////////////////////////// ! 238: // Standard init called by WinMain ! 239: ! 240: static BOOL NEAR RegisterWithIcon(register WNDCLASS* pWndCls, ! 241: const char* szClassName, UINT nIDIcon) ! 242: { ! 243: pWndCls->lpszClassName = szClassName; ! 244: if ((pWndCls->hIcon = ::LoadIcon(pWndCls->hInstance, ! 245: MAKEINTRESOURCE(nIDIcon))) == NULL) ! 246: { ! 247: // use default icon ! 248: pWndCls->hIcon = ::LoadIcon(NULL, IDI_APPLICATION); ! 249: } ! 250: return RegisterClass(pWndCls); ! 251: } ! 252: ! 253: ///////////////////////////////////////////////////////////////////////////// ! 254: ! 255: extern "C" ! 256: BOOL AfxWinInit(HINSTANCE hInstance, HINSTANCE hPrevInstance, ! 257: LPSTR lpCmdLine, int nCmdShow) ! 258: { ! 259: register CWinApp* pApp = AfxGetApp(); ! 260: ! 261: ASSERT(pApp != NULL); // must have one ! 262: ! 263: // fill in the initial state for the application ! 264: pApp->m_hInstance = hInstance; ! 265: pApp->m_hPrevInstance = hPrevInstance; ! 266: pApp->m_lpCmdLine = lpCmdLine; ! 267: pApp->m_nCmdShow = nCmdShow; ! 268: pApp->SetCurrentHandles(); ! 269: ! 270: // Windows version specific initialization ! 271: #ifndef _WINDLL ! 272: WORD wVersion = LOWORD(::GetVersion()); ! 273: if (LOBYTE(wVersion) > 3 || HIBYTE(wVersion) >= 10) ! 274: { ! 275: #ifndef _NTWIN ! 276: HINSTANCE hPenWin; ! 277: if ((hPenWin = (HINSTANCE)GetSystemMetrics(SM_PENWINDOWS)) != NULL) ! 278: { ! 279: static char BASED_CODE szRegisterPenApp[] = "RegisterPenApp"; ! 280: _afxRegisterPenAppProc = (void (WINAPI*)(UINT, BOOL)) ! 281: ::GetProcAddress(hPenWin, szRegisterPenApp); ! 282: if (_afxRegisterPenAppProc != NULL) ! 283: (*_afxRegisterPenAppProc)(RPA_DEFAULT, TRUE); ! 284: } ! 285: #endif //!_NTWIN ! 286: ! 287: // Windows 3.1 or better - use SetWindowsHookEx (USER.291) ! 288: static char BASED_CODE szUSER[] = "USER"; ! 289: _afxSetWindowsHookExProc = ! 290: (HOOKPROC (WINAPI*)(int, HOOKPROC, HINSTANCE, HTASK)) ! 291: ::GetProcAddress(::GetModuleHandle(szUSER), MAKEINTRESOURCE(291)); ! 292: } ! 293: #endif //!_WINDLL ! 294: ! 295: if (hPrevInstance == NULL) // one instance initialization ! 296: { ! 297: // register basic WndClasses ! 298: WNDCLASS wndcls; ! 299: memset(&wndcls, 0, sizeof(WNDCLASS)); // start with NULL defaults ! 300: ! 301: // common initialization ! 302: wndcls.lpfnWndProc = AfxWndProc; ! 303: wndcls.hInstance = hInstance; ! 304: wndcls.hCursor = ::LoadCursor(NULL, IDC_ARROW); ! 305: wndcls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW; ! 306: ! 307: // Child windows - no brush, no icon ! 308: wndcls.lpszClassName = _afxWnd; ! 309: if (!::RegisterClass(&wndcls)) ! 310: return FALSE; ! 311: ! 312: // MDI Frame windows ! 313: if (!RegisterWithIcon(&wndcls, _afxMDIFrameWnd, AFX_IDI_STD_MDIFRAME)) ! 314: return FALSE; ! 315: ! 316: // SDI Frame or MDI Child windows - normal colors ! 317: wndcls.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1); ! 318: if (!RegisterWithIcon(&wndcls, _afxFrameWnd, AFX_IDI_STD_FRAME)) ! 319: return FALSE; ! 320: } ! 321: ! 322: return TRUE; ! 323: } ! 324: ! 325: extern "C" ! 326: void AfxWinTerm(void) ! 327: { ! 328: // These static CWnd objects refer to HWNDs that don't exist ! 329: // so let's not call ::DestroyWindow when CWnd::~CWnd() is invoked. ! 330: ((CWnd&)CWnd::wndTop).m_hWnd = NULL; ! 331: ((CWnd&)CWnd::wndBottom).m_hWnd = NULL; ! 332: ((CWnd&)CWnd::wndTopMost).m_hWnd = NULL; ! 333: ((CWnd&)CWnd::wndNoTopMost).m_hWnd = NULL; ! 334: ! 335: #ifndef _WINDLL ! 336: #ifndef _NTWIN ! 337: // if we registered ourself with PenWin, deregister now ! 338: if (_afxRegisterPenAppProc != NULL) ! 339: (*_afxRegisterPenAppProc)(RPA_DEFAULT, FALSE); ! 340: #endif //!_NTWIN ! 341: #endif //!_WINDLL ! 342: } ! 343: ! 344: ///////////////////////////////////////////////////////////////////////////// ! 345: // force WinMain or LibMain inclusion ! 346: ! 347: #ifdef _WINDLL ! 348: extern "C" int PASCAL LibMain(HINSTANCE, WORD, WORD, LPSTR); ! 349: static FARPROC linkAddr = (FARPROC) &LibMain; ! 350: #else ! 351: extern "C" int PASCAL WinMain(HINSTANCE, HINSTANCE, LPSTR, int); ! 352: static FARPROC linkAddr = (FARPROC) &WinMain; ! 353: #endif //!_WINDLL ! 354: ! 355: /////////////////////////////////////////////////////////////////////////////
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.