Annotation of mstools/mfc/src/winapp.cpp, revision 1.1.1.1

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: /////////////////////////////////////////////////////////////////////////////

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.