Annotation of mstools/mfc/src/window.cpp, revision 1.1.1.3

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: 
                     15: #include "winhand_.h"
                     16: #include "window_.h"
                     17: 
                     18: #ifdef AFX_CORE_SEG
                     19: #pragma code_seg(AFX_CORE_SEG)
                     20: #endif
                     21: 
                     22: #ifdef _DEBUG
                     23: #include "trace_.h"
                     24: #undef THIS_FILE
                     25: static char BASED_CODE THIS_FILE[] = __FILE__;
                     26: #define new DEBUG_NEW
                     27: #endif
                     28: 
                     29: /////////////////////////////////////////////////////////////////////////////
                     30: // CHandleMap implementation
                     31: 
                     32: CObject*
                     33: CHandleMap::FromHandle(HANDLE h)
                     34: {
                     35:        if (h == NULL)
                     36:                return NULL;
                     37: 
                     38:        void* p;
                     39:        if (LookupPermanent(h, p))
                     40:                return (CObject*)p;     // return permanent one
                     41:        else if (LookupTemporary(h, p))
                     42:                return (CObject*)p;     // return last temporary one
                     43: 
                     44:        // This handle wasn't created by us, so we must create a temporary
                     45:        // C++ object to wrap it.  We don't want the user to see this memory
                     46:        // allocation, so we turn tracing off.
                     47: #ifdef _DEBUG
                     48:        BOOL bEnable = AfxEnableMemoryTracking(FALSE);
                     49: #endif
                     50:        CObject* pTemp = NewTempObject(h);
                     51: #ifdef _NTWIN
                     52:        temporaryMap.SetAt((LPVOID)h, pTemp);
                     53: #else
                     54:        temporaryMap.SetAt((WORD)h, pTemp);
                     55: #endif
                     56: #ifdef _DEBUG
                     57:        AfxEnableMemoryTracking(bEnable);
                     58: #endif
                     59:        return pTemp;
                     60: }
                     61: 
                     62: void
                     63: CHandleMap::DeleteTemp()
                     64: {
                     65:        POSITION pos = temporaryMap.GetStartPosition();
                     66:        while (pos != NULL)
                     67:        {
                     68: #ifdef _NTWIN
                     69:                LPVOID h; // not used 
                     70: #else
                     71:                WORD h; // not used 
                     72: #endif
                     73:                void* p;
                     74:                temporaryMap.GetNextAssoc(pos, h, p);
                     75:                DeleteTempObject((CObject*)p);      // free it up
                     76:        }
                     77: 
                     78:        temporaryMap.RemoveAll();       // free up dictionary links etc
                     79: }
                     80: 
                     81: /////////////////////////////////////////////////////////////////////////////
                     82: IMPLEMENT_DYNAMIC(CButton, CWnd)
                     83: IMPLEMENT_DYNAMIC(CListBox, CWnd)
                     84: IMPLEMENT_DYNAMIC(CComboBox, CWnd)
                     85: 
                     86: IMPLEMENT_DYNAMIC(CWnd, CObject)
                     87: 
                     88: 
                     89: char NEAR _afxWnd[] = "AfxWnd";
                     90: char NEAR _afxMDIFrameWnd[] = "AfxMDIFrameWnd";
                     91: char NEAR _afxFrameWnd[] = "AfxFrameWnd";
                     92: 
                     93: 
                     94: /////////////////////////////////////////////////////////////////////////////
                     95: // Special bootstrap globals
                     96: 
                     97: static CWnd* pWndInit = NULL;
                     98: static CDialog* pDlgInit = NULL;
                     99: 
                    100: /////////////////////////////////////////////////////////////////////////////
                    101: // Official way to send message to a CWnd
                    102: 
                    103: struct CLastState
                    104: {
                    105:        MSG msg;
                    106: };
                    107: static CLastState NEAR lastState;
                    108:        // global for last state of call to 'WindowProc'
                    109: 
                    110: LONG _AfxCallWndProc(CWnd* pWnd, HWND hWnd, UINT message,
                    111:        UINT wParam, LONG lParam)
                    112: {
                    113:        LONG lResult;
                    114:        CLastState oldState = lastState;    // save for nesting
                    115: 
                    116:        lastState.msg.hwnd = hWnd;
                    117:        lastState.msg.message = message;
                    118:        lastState.msg.wParam = wParam;
                    119:        lastState.msg.lParam = lParam;
                    120: 
                    121: #ifdef _DEBUG
                    122:        if (afxTraceFlags & 4)
                    123:                AfxTraceMsg("WndProc", &lastState.msg);
                    124: #endif
                    125: 
                    126:        // Catch exceptions thrown outside the scope of a callback
                    127:        // in debug builds and warn the user.
                    128:        TRY
                    129:        {
                    130:                lResult = pWnd->WindowProc(message, wParam, lParam);
                    131:        }
                    132:        CATCH (CException, e)
                    133:        {
                    134:                if (message == WM_CREATE)
                    135:                        lResult = -1;
                    136:                else
                    137:                        lResult = 0;
                    138:                TRACE("Warning: Uncaught exception in WindowProc (returning %ld)\n",
                    139:                        lResult);
                    140:                ASSERT(FALSE);
                    141:        }
                    142:        END_CATCH
                    143: 
                    144:        lastState = oldState;
                    145:        return lResult;
                    146: }
                    147: 
                    148: const MSG* CWnd::GetCurrentMessage()
                    149: {
                    150:        // fill in time and position when asked for
                    151:        lastState.msg.time = ::GetMessageTime();
                    152:        *((DWORD*)&lastState.msg.pt) = ::GetMessagePos();
                    153:        return &lastState.msg;
                    154: }
                    155: 
                    156: LONG CWnd::Default()
                    157:        // call DefWindowProc with the last message
                    158: {
                    159:        return DefWindowProc(lastState.msg.message,
                    160:                        lastState.msg.wParam, lastState.msg.lParam);
                    161: }
                    162: 
                    163: /////////////////////////////////////////////////////////////////////////////
                    164: // Map from HWND to CWnd*
                    165: 
                    166: class NEAR CWndHandleMap : public CHandleMap
                    167: {
                    168: public:
                    169:        CObject* NewTempObject(HANDLE h)
                    170:                                {
                    171:                                        // don't add in permanent
                    172:                                        CWnd* p = new CWnd();
                    173:                                        p->m_hWnd = (HWND)h;      // set after constructed
                    174:                                        return p;
                    175:                                }
                    176:        void DeleteTempObject(CObject* ob)
                    177:                                {
                    178:                                        ASSERT(ob->IsKindOf(RUNTIME_CLASS(CWnd)));
                    179:                                        ((CWnd*)ob)->m_hWnd = NULL; // clear before destructed
                    180:                                        delete ob;
                    181:                                }
                    182:        CWndHandleMap()
                    183:                { }
                    184: };
                    185: static CWndHandleMap NEAR hWndMap;
                    186: 
                    187: CWnd*
                    188: CWnd::FromHandle(HWND hWnd)
                    189: {
                    190:        return (CWnd*)hWndMap.FromHandle(hWnd);
                    191: }
                    192: 
                    193: CWnd*
                    194: CWnd::FromHandlePermanent(HWND hWnd)
                    195: {
                    196:        // only look in the permanent map - does no allocations
                    197:        void* p;
                    198:        return (hWndMap.LookupPermanent(hWnd, p)) ? (CWnd*)p : NULL;
                    199: }
                    200: 
                    201: void
                    202: CWnd::DeleteTempMap()
                    203: {
                    204:        hWndMap.DeleteTemp();
                    205: }
                    206: 
                    207: BOOL
                    208: CWnd::Attach(HWND hWnd)
                    209: {
                    210:        ASSERT(m_hWnd == NULL);     // only attach once, detach on destroy
                    211:        if (hWnd == NULL)
                    212:                return FALSE;
                    213:        hWndMap.SetPermanent(m_hWnd = hWnd, this);
                    214:        return TRUE;
                    215: }
                    216: 
                    217: HWND
                    218: CWnd::Detach()
                    219: {
                    220:        HWND hWnd;
                    221:        if ((hWnd = m_hWnd) != NULL)
                    222:                hWndMap.RemovePermanent(m_hWnd);
                    223:        m_hWnd = NULL;
                    224:        return hWnd;
                    225: }
                    226: 
                    227: 
                    228: /////////////////////////////////////////////////////////////////////////////
                    229: // One main WndProc for all CWnd's and derived classes
                    230: 
                    231: LONG FAR PASCAL AFX_EXPORT
                    232: AfxWndProc(HWND hWnd, UINT message, UINT wParam, LONG lParam)
                    233: {
                    234:        register CWnd* pWnd;
                    235: 
                    236:        pWnd = CWnd::FromHandlePermanent(hWnd);
                    237:        ASSERT(pWnd != NULL);
                    238:        ASSERT(pWnd->m_hWnd == hWnd);
                    239: 
                    240:        LONG lResult = _AfxCallWndProc(pWnd, hWnd, message, wParam, lParam);
                    241: 
                    242:        return lResult;
                    243: }
                    244: 
                    245: // Special case for remaining dialog cases
                    246: // Most messages will go through the window proc (AfxWndProc) of the
                    247: //   subclassed dialog.  Some messages like WM_SETFONT and WM_INITDIALOG
                    248: //   are sent directly to the dialog proc only.  These messages cannot be
                    249: //   passed on to DefWindowProc() or infinite recursion will result!
                    250: // In responding to these messages, you shouldn't call the Default handler
                    251: LONG FAR PASCAL AFX_EXPORT
                    252: _AfxDlgProc(HWND hWnd, register UINT message, UINT wParam, LONG lParam)
                    253: {
                    254:        register CDialog* pDlg;
                    255: 
                    256:        // test for special case (Win 3.0 will call dialog proc instead
                    257:        //  of SendMessage for these two messages).
                    258:        if (message != WM_SETFONT && message != WM_INITDIALOG)
                    259:                return 0L;      // normal handler
                    260: 
                    261:        // assume it is already wired up to a permanent one
                    262:        pDlg = (CDialog*) CWnd::FromHandlePermanent(hWnd);
                    263:        ASSERT(pDlg != NULL);
                    264:        ASSERT(pDlg->m_hWnd == hWnd);
                    265: 
                    266:        // prepare for callback, make it look like message map call
                    267:        LONG lResult = 0;
                    268:        CLastState oldState = lastState;    // save for nesting
                    269: 
                    270:        lastState.msg.hwnd = hWnd;
                    271:        lastState.msg.message = message;
                    272:        lastState.msg.wParam = wParam;
                    273:        lastState.msg.lParam = lParam;
                    274: 
                    275:        TRY
                    276:        {
                    277:                if (message == WM_SETFONT)
                    278:                        pDlg->OnSetFont(CFont::FromHandle((HFONT)wParam));
                    279:                else // WM_INITDIALOG
                    280:                        lResult = pDlg->OnInitDialog();
                    281:        }
                    282:        CATCH (CException, e)
                    283:        {
                    284:                // fall through
                    285:                TRACE("Warning: something went wrong in dialog init\n");
                    286:                pDlg->EndDialog(IDCANCEL);  // something went wrong
                    287:                ASSERT(FALSE);
                    288:        }
                    289:        END_CATCH
                    290: 
                    291:        lastState = oldState;
                    292:        return lResult;
                    293: }
                    294: 
                    295: /////////////////////////////////////////////////////////////////////////////
                    296: // Window creation hook
                    297: #ifdef STRICT
                    298: static HHOOK pfnOldSendMsgHook = NULL;
                    299: #else
                    300: static HOOKPROC pfnOldSendMsgHook = NULL;
                    301: #endif
                    302: 
                    303: #pragma optimize("q", off)    // disable pcode opt (Win 3.0 compatibility)
                    304: 
                    305: void FAR PASCAL AFX_EXPORT
                    306: _AfxSendMsgHook(int code, UINT wParam, LONG lParam)
                    307: {
                    308:        struct HOOKINFO     // Hook info struct passed by send message hook
                    309:        {
                    310:                LONG lParam;
                    311:                UINT wParam;
                    312:                UINT msg;
                    313:                HWND hWnd;
                    314:        };
                    315:        HOOKINFO FAR* hookInfo;
                    316: 
                    317:        if (code < 0)
                    318:        {
                    319:                ::DefHookProc(code, wParam, lParam, &pfnOldSendMsgHook);
                    320:                return;
                    321:        }
                    322: 
                    323:        ASSERT(pWndInit != NULL);
                    324:        hookInfo = (HOOKINFO FAR*)lParam;
                    325:        HWND hWnd = hookInfo->hWnd;
                    326: 
                    327:        // ignore non-creation messages
                    328:        if (hookInfo->msg != WM_GETMINMAXINFO &&
                    329:          hookInfo->msg != WM_NCCREATE)
                    330:        {
                    331:                // not being constructed
                    332:                return;
                    333:        }
                    334: 
                    335:        // Connect the HWND to pWndInit...
                    336:        pWndInit->Attach(hWnd);
                    337: 
                    338:        // Subclass the window by replacing its window proc addr...
                    339:        WNDPROC oldWndProc = (WNDPROC)::SetWindowLong(hWnd, GWL_WNDPROC,
                    340:                (DWORD)AfxWndProc);
                    341:        if (oldWndProc != (WNDPROC)AfxWndProc)
                    342:        {
                    343:                *(pWndInit->GetSuperWndProcAddr()) = oldWndProc; // save if not default
                    344:        }
                    345: 
                    346:        // Unhook the send message hook since we don't need it any more
                    347:        ::UnhookWindowsHook(WH_CALLWNDPROC, (HOOKPROC)_AfxSendMsgHook);
                    348:        pWndInit = NULL;
                    349: }
                    350: 
                    351: #pragma optimize("", on)    // return to default optimizations
                    352: 
                    353: void _AfxHookWindowCreate(register CWnd* pWnd)
                    354: {
                    355: #ifndef _WINDLL
                    356:        if (_afxSetWindowsHookExProc == NULL)
                    357:        {
                    358:                pfnOldSendMsgHook = ::SetWindowsHook(WH_CALLWNDPROC,
                    359:                        (HOOKPROC)_AfxSendMsgHook);
                    360:        }
                    361:        else
                    362:        {
                    363: #ifdef STRICT
                    364: #ifdef _NTWIN
                    365:                pfnOldSendMsgHook = (HHOOK)(*_afxSetWindowsHookExProc)(
1.1.1.3 ! root      366:                        WH_CALLWNDPROC, (HOOKPROC)_AfxSendMsgHook, NULL,
        !           367:                        ::GetCurrentThreadId());
1.1       root      368: #else
                    369:                pfnOldSendMsgHook = (HHOOK)(*_afxSetWindowsHookExProc)(
                    370:                        WH_CALLWNDPROC, (HOOKPROC)_AfxSendMsgHook, AfxGetInstanceHandle(),
                    371:                        GetCurrentTask());
                    372: #endif
                    373: #else
                    374: #ifdef _NTWIN
                    375:                pfnOldSendMsgHook = (HOOKPROC)(*_afxSetWindowsHookExProc)(
1.1.1.3 ! root      376:                        WH_CALLWNDPROC, (HOOKPROC)_AfxSendMsgHook, NULL,
        !           377:                        ::GetCurrentThreadId());
1.1       root      378: #else
                    379:                pfnOldSendMsgHook = (HOOKPROC)(*_afxSetWindowsHookExProc)(
                    380:                        WH_CALLWNDPROC, (HOOKPROC)_AfxSendMsgHook, AfxGetInstanceHandle(),
                    381:                        GetCurrentTask());
                    382: #endif
                    383: #endif
                    384:        }
                    385: #else // _WINDLL
1.1.1.3 ! root      386: #ifndef _NTWIN
1.1       root      387:        pfnOldSendMsgHook = ::SetWindowsHook(WH_CALLWNDPROC,
                    388:                (HOOKPROC)_AfxSendMsgHook);
1.1.1.3 ! root      389: #else
        !           390:        pfnOldSendMsgHook = (HOOKPROC)(*_afxSetWindowsHookExProc)(
        !           391:                WH_CALLWNDPROC, (HOOKPROC)_AfxSendMsgHook, NULL,
        !           392:                ::GetCurrentThreadId());
        !           393: #endif
1.1       root      394: #endif // _WINDLL
                    395: 
                    396:        ASSERT(pWnd != NULL);
                    397:        ASSERT(pWnd->m_hWnd == NULL);   // only do once
                    398: 
                    399:        ASSERT(pWndInit == NULL);       // hook not already in progress
                    400:        pWndInit = pWnd;
                    401: }
                    402: 
                    403: BOOL _AfxUnhookWindowCreate()
                    404:        // return TRUE if already unhooked
                    405: {
                    406:        if (pWndInit == NULL)
                    407:                return TRUE;        // already unhooked => window create success
                    408:        ::UnhookWindowsHook(WH_CALLWNDPROC, (HOOKPROC)_AfxSendMsgHook);
                    409:        pWndInit = NULL;
                    410:        return FALSE;
                    411: }
                    412: 
                    413: /////////////////////////////////////////////////////////////////////////////
                    414: // CWnd creation
                    415: 
                    416: BOOL CWnd::CreateEx(DWORD dwExStyle, LPCSTR lpClassName,
                    417:                LPCSTR lpWindowName, DWORD dwStyle,
                    418:                int x, int y, int nWidth, int nHeight,
                    419:                HWND hWndParent, HMENU nIDorHMenu)
                    420: {
                    421:        _AfxHookWindowCreate(this);
                    422:        HWND hWnd = ::CreateWindowEx(dwExStyle, lpClassName,
                    423:                        lpWindowName, dwStyle, x, y, nWidth, nHeight,
                    424:                        hWndParent, nIDorHMenu, AfxGetInstanceHandle(), NULL);
                    425: 
                    426:        _AfxUnhookWindowCreate();
                    427:        if (hWnd == NULL)
                    428:                return NULL;
                    429:        ASSERT(hWnd == m_hWnd); // should have been set in send msg hook
                    430:        return TRUE;
                    431: }
                    432: 
                    433: // for child windows
                    434: BOOL CWnd::Create(LPCSTR lpClassName,
                    435:        LPCSTR lpWindowName, DWORD dwStyle,
                    436:        const RECT& rect,
                    437:        const CWnd* pParentWnd, UINT nID)
                    438: {
                    439:        ASSERT(pParentWnd != NULL);
                    440: 
                    441:        if (lpClassName == NULL)
                    442:                lpClassName = _afxWnd;
                    443: 
                    444:        return CreateEx(0, lpClassName, lpWindowName,
                    445:                dwStyle | WS_CHILD,
                    446:                rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
                    447:                pParentWnd->GetSafeHwnd(), (HMENU)nID);
                    448: }
                    449: 
                    450: CWnd::~CWnd()
                    451: {
                    452:        DestroyWindow();
                    453: }
                    454: 
                    455: #ifdef _NTWIN
                    456: struct _AFXCTLCOLOR {
                    457:        HWND hWnd;
                    458:        HDC hDC;
                    459:        UINT nCtlType;
                    460: };
                    461: 
                    462: LRESULT CWnd::OnNTCtlColor(WPARAM wParam, LPARAM lParam)
                    463: {
                    464:        struct _AFXCTLCOLOR ctl;
                    465: 
                    466:        ctl.hDC = (HDC)wParam;
                    467:        ctl.hWnd = (HWND)lParam;
                    468:        ctl.nCtlType = GetCurrentMessage()->message - WM_CTLCOLORMSGBOX;
                    469: 
                    470:        ASSERT(ctl.nCtlType >= CTLCOLOR_MSGBOX);
                    471:        ASSERT(ctl.nCtlType <= CTLCOLOR_STATIC);
                    472: 
1.1.1.3 ! root      473:        // NOTE: We call the virtual WindowProc for this window directly,
        !           474:        //  instead of calling _AfxCallWindowProc, so that Default()
        !           475:        //  will still work (it will call the Default window proc with
        !           476:        //      the original NT WM_CTLCOLOR message).
        !           477: 
        !           478:        return WindowProc(WM_CTLCOLOR, 0, (LPARAM)&ctl);
1.1       root      479: }
                    480: #endif
                    481: 
                    482: void CWnd::OnDestroy()
                    483: {
                    484: #ifndef _WINDLL
                    485:        // Automatically quit when the main window is destroyed.
                    486:        if (AfxGetApp()->m_pMainWnd == this)
                    487:                ::PostQuitMessage(0);
                    488: #endif // _WINDLL
                    489:        Default();
                    490: }
                    491: 
                    492: void CWnd::OnNcDestroy()
                    493: {
                    494:        // WM_NCDESTROY is the absolute LAST message sent.
                    495:        if (AfxGetApp()->m_pMainWnd == this)
                    496:                AfxGetApp()->m_pMainWnd = NULL;
                    497: 
                    498:        Default();
                    499:        Detach();
                    500:        ASSERT(m_hWnd == NULL);
                    501: 
                    502:        // call special post-cleanup routine
                    503:        PostNcDestroy();
                    504: }
                    505: 
                    506: void CWnd::PostNcDestroy()
                    507: {
                    508:        // default to nothing
                    509: }
                    510: 
                    511: #ifdef _DEBUG
                    512: void CWnd::AssertValid() const
                    513: {
                    514:        ASSERT(m_hWnd == NULL ||
                    515:                (m_hWnd == (HWND)1 && this == &CWnd::wndBottom) ||
                    516:                ::IsWindow(m_hWnd));
                    517:        void* p;
                    518:        ASSERT(m_hWnd == NULL ||
                    519:                (m_hWnd == (HWND)1 && this == &CWnd::wndBottom) ||
                    520:                hWndMap.LookupPermanent(m_hWnd, p) ||
                    521:                hWndMap.LookupTemporary(m_hWnd, p));
                    522: }
                    523: 
                    524: void CWnd::Dump(CDumpContext& dc) const
                    525: {
                    526:        CObject::Dump(dc);
                    527: 
                    528:        dc << "with window information:\n";
                    529:        dc << "m_hWnd = " << (void NEAR*)m_hWnd;
                    530: 
                    531:        if ((UINT)m_hWnd > 1)
                    532:        {
                    533:                char szBuf [64];
                    534: 
                    535:                GetWindowText(szBuf, sizeof (szBuf));
                    536:                dc << "\ncaption = \"" << szBuf << "\"";
                    537: 
                    538:                ::GetClassName(m_hWnd, szBuf, sizeof (szBuf));
                    539:                dc << "\nclass name = \"" << szBuf << "\"";
                    540: 
                    541:                CRect rect;
                    542:                GetWindowRect(&rect);
                    543:                dc << "\nrect = " << rect;
                    544: 
                    545:                dc << "\nparent CWnd* = " << (void*)GetParent();
                    546: 
                    547:                dc << "\nstyle = " << (void FAR*)::GetWindowLong(m_hWnd, GWL_STYLE);
                    548:                if (::GetWindowLong(m_hWnd, GWL_STYLE) & WS_CHILD)
1.1.1.2   root      549: #ifndef _NTWIN
1.1       root      550:                        dc << "\nid = " << ::GetWindowWord(m_hWnd, GWW_ID);
1.1.1.2   root      551: #else
                    552:                        dc << "\nid = " << ::GetWindowLong(m_hWnd, GWL_ID);
                    553: #endif
1.1       root      554:        }
                    555: }
                    556: #endif
                    557: 
                    558: BOOL
                    559: CWnd::DestroyWindow()
                    560: {
                    561:        if (m_hWnd == NULL)
                    562:                return FALSE;
                    563: 
                    564:        void* p;
                    565:        BOOL bInPermanentMap = hWndMap.LookupPermanent(m_hWnd, p);
                    566:        BOOL bRet = ::DestroyWindow(m_hWnd);
                    567:        // Note that 'this' may have been deleted at this point.
                    568:        if (bInPermanentMap)
                    569:        {
                    570:                // Should have been detached by OnNcDestroy
                    571:                ASSERT(!hWndMap.LookupPermanent(m_hWnd, p));
                    572:        }
                    573:        else
                    574:        {
                    575:                // Detach after DestroyWindow called just in case
                    576:                Detach();
                    577:        }
                    578:        return bRet;
                    579: }
                    580: 
                    581: /////////////////////////////////////////////////////////////////////////////
                    582: // Default CWnd implementation
                    583: 
                    584: LONG CWnd::DefWindowProc(UINT nMsg, UINT wParam, LONG lParam)
                    585: {
                    586:        WNDPROC pfnWndProc;
                    587: 
                    588:        if ((pfnWndProc = *GetSuperWndProcAddr()) == NULL)
                    589:                return ::DefWindowProc(m_hWnd, nMsg, wParam, lParam);
                    590:        else
                    591: #ifdef STRICT
                    592:                return ::CallWindowProc(pfnWndProc, m_hWnd, nMsg, wParam, lParam);
                    593: #else
                    594:                return ::CallWindowProc((FARPROC)pfnWndProc, m_hWnd, nMsg, wParam, lParam);
                    595: #endif
                    596: }
                    597: 
                    598: WNDPROC* CWnd::GetSuperWndProcAddr()
                    599: {
                    600:        static WNDPROC pfnSuper = NULL;
                    601:        ASSERT(pfnSuper == NULL);       // should never be changed !!!
                    602:                                        // if this is non-NULL, then a derived class of CWnd
                    603:                                        //  forgot to override 'superWndProc' as well as 'className'
                    604:        return &pfnSuper;
                    605: }
                    606: 
                    607: BOOL CWnd::PreTranslateMessage(MSG*)
                    608: {
                    609:        // no default processing
                    610:        return FALSE;
                    611: }
                    612: 
                    613: /////////////////////////////////////////////////////////////////////////////
                    614: // CWnd will delegate owner draw messages to self drawing controls
                    615: 
                    616: // Drawing: for all 4 control types
                    617: void CWnd::OnDrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
                    618: {
                    619:        UINT nType;
                    620:        if ((nType = lpDrawItemStruct->CtlType) == ODT_MENU)
                    621:        {
                    622:                CMenu* pMenu = CMenu::FromHandle((HMENU)lpDrawItemStruct->hwndItem);
                    623:                if (pMenu != NULL)
                    624:                {
                    625:                        pMenu->DrawItem(lpDrawItemStruct);
                    626:                        return;
                    627:                }
                    628:        }
                    629:        else
                    630:        {
                    631:                CWnd* pChild = CWnd::FromHandlePermanent(lpDrawItemStruct->hwndItem);
                    632:                if (pChild != NULL)
                    633:                {
                    634:                        if (nType == ODT_BUTTON &&
                    635:                                pChild->IsKindOf(RUNTIME_CLASS(CButton)))
                    636:                        {
                    637:                                ((CButton*)pChild)->DrawItem(lpDrawItemStruct);
                    638:                                return;
                    639:                        }
                    640:                        else if (nType == ODT_LISTBOX &&
                    641:                                pChild->IsKindOf(RUNTIME_CLASS(CListBox)))
                    642:                        {
                    643:                                ((CListBox*)pChild)->DrawItem(lpDrawItemStruct);
                    644:                                return;
                    645:                        }
                    646:                        else if (nType == ODT_COMBOBOX &&
                    647:                                pChild->IsKindOf(RUNTIME_CLASS(CComboBox)))
                    648:                        {
                    649:                                ((CComboBox*)pChild)->DrawItem(lpDrawItemStruct);
                    650:                                return;
                    651:                        }
                    652:                }
                    653:        }
                    654:        // not handled - do default
                    655:        Default();
                    656: }
                    657: 
                    658: // Drawing: for all 4 control types
                    659: int CWnd::OnCompareItem(LPCOMPAREITEMSTRUCT lpCompareItemStruct)
                    660: {
                    661:        CWnd* pChild = CWnd::FromHandlePermanent(lpCompareItemStruct->hwndItem);
                    662:        if (pChild != NULL)
                    663:        {
                    664:                UINT nType = lpCompareItemStruct->CtlType;
                    665:                if (nType == ODT_LISTBOX &&
                    666:                        pChild->IsKindOf(RUNTIME_CLASS(CListBox)))
                    667:                {
                    668:                        return ((CListBox*)pChild)->CompareItem(lpCompareItemStruct);
                    669:                }
                    670:                else if (nType == ODT_COMBOBOX &&
                    671:                        pChild->IsKindOf(RUNTIME_CLASS(CComboBox)))
                    672:                {
                    673:                        return ((CComboBox*)pChild)->CompareItem(lpCompareItemStruct);
                    674:                }
                    675:        }
                    676:        // not handled - do default
                    677:        return (int)Default();
                    678: }
                    679: 
                    680: void CWnd::OnDeleteItem(LPDELETEITEMSTRUCT lpDeleteItemStruct)
                    681: {
                    682:        CWnd* pChild = CWnd::FromHandlePermanent(lpDeleteItemStruct->hwndItem);
                    683:        if (pChild != NULL)
                    684:        {
                    685:                UINT nType = lpDeleteItemStruct->CtlType;
                    686:                if (nType == ODT_LISTBOX &&
                    687:                        pChild->IsKindOf(RUNTIME_CLASS(CListBox)))
                    688:                {
                    689:                        ((CListBox*)pChild)->DeleteItem(lpDeleteItemStruct);
                    690:                        return;
                    691:                }
                    692:                else if (nType == ODT_COMBOBOX &&
                    693:                        pChild->IsKindOf(RUNTIME_CLASS(CComboBox)))
                    694:                {
                    695:                        ((CComboBox*)pChild)->DeleteItem(lpDeleteItemStruct);
                    696:                        return;
                    697:                }
                    698:        }
                    699:        // not handled - do default
                    700:        Default();
                    701: }
                    702: 
                    703: 
                    704: static CMenu* FindPopupMenuFromID(CMenu* pMenu, UINT nID)
                    705: {
                    706:        // walk through all items, looking for ID match
                    707:        UINT nItems = pMenu->GetMenuItemCount();
                    708:        for (int iItem = 0; iItem < (int)nItems; iItem++)
                    709:        {
1.1.1.3 ! root      710:                CMenu* pPopup = pMenu->GetSubMenu(iItem);
        !           711:                if (pPopup != NULL)
1.1       root      712:                {
                    713:                        // recurse to child popup
1.1.1.3 ! root      714:                        pPopup = FindPopupMenuFromID(pPopup, nID);
1.1       root      715:                        // try recursing
                    716:                        if (pPopup != NULL)
                    717:                                return pPopup;
                    718:                }
                    719:                else if (pMenu->GetMenuItemID(iItem) == nID)
                    720:                {
                    721:                        // it is a normal item inside our popup
                    722:                        return pMenu;
                    723:                }
                    724:        }
                    725:        // not found
                    726:        return NULL;
                    727: }
                    728: 
                    729: // Measure item implementation relies on unique control/menu IDs
                    730: void CWnd::OnMeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
                    731: {
                    732:        UINT nType;
                    733:        if ((nType = lpMeasureItemStruct->CtlType) == ODT_MENU)
                    734:        {
                    735:                ASSERT(lpMeasureItemStruct->CtlID == 0);
                    736:                CMenu* pMenu = FindPopupMenuFromID(GetMenu(),
                    737:                        lpMeasureItemStruct->itemID);
                    738:                if (pMenu != NULL)
                    739:                {
                    740:                        pMenu->MeasureItem(lpMeasureItemStruct);
                    741:                        return;
                    742:                }
                    743:                else
                    744:                {
                    745:                        TRACE("Warning: unknown WM_MEASUREITEM request for"
                    746:                                " menu item 0x%04X\n", lpMeasureItemStruct->itemID);
                    747:                }
                    748:        }
                    749:        else
                    750:        {
                    751:                HWND hWndChild = ::GetDlgItem(m_hWnd, lpMeasureItemStruct->CtlID);
                    752:                CWnd* pChild;
                    753:                if (hWndChild != NULL &&
                    754:                        (pChild = CWnd::FromHandlePermanent(hWndChild)) != NULL)
                    755:                {
                    756:                        if (nType == ODT_LISTBOX &&
                    757:                                pChild->IsKindOf(RUNTIME_CLASS(CListBox)))
                    758:                        {
                    759:                                ((CListBox*)pChild)->MeasureItem(lpMeasureItemStruct);
                    760:                                return;
                    761:                        }
                    762:                        else if (nType == ODT_COMBOBOX &&
                    763:                                pChild->IsKindOf(RUNTIME_CLASS(CComboBox)))
                    764:                        {
                    765:                                ((CComboBox*)pChild)->MeasureItem(lpMeasureItemStruct);
                    766:                                return;
                    767:                        }
                    768:                }
                    769:        }
                    770:        // not handled - do default
                    771:        Default();
                    772: }
                    773: 
                    774: /////////////////////////////////////////////////////////////////////////////
                    775: // CFrameWnd
                    776: 
                    777: IMPLEMENT_DYNAMIC(CFrameWnd, CWnd)
                    778: 
                    779: CFrameWnd::CFrameWnd()
                    780: {
                    781:        ASSERT(m_hWnd == NULL);
                    782:        m_hAccelTable = NULL;
                    783: }
                    784: 
                    785: CFrameWnd::~CFrameWnd()
                    786: {
                    787:        if (m_hAccelTable != NULL)
                    788:                ::FreeResource(m_hAccelTable);
                    789: }
                    790: 
                    791: void CFrameWnd::PostNcDestroy()
                    792: {
                    793:        // default for frame windows is to allocate them on the heap
                    794:        //  the default post-cleanup is to 'delete this'.
                    795:        // never explicitly call 'delete' on a CFrameWnd, use DestroyWindow instead
                    796:        delete this;
                    797: }
                    798: 
                    799: #ifdef _DEBUG
                    800: void CFrameWnd::AssertValid() const
                    801: {
                    802:        CWnd::AssertValid();
                    803: }
                    804: 
                    805: void CFrameWnd::Dump(CDumpContext& dc) const
                    806: {
                    807:        CWnd::Dump(dc);
                    808:        dc << "\nm_hAccelTable = " << (UINT) m_hAccelTable;
                    809: }
                    810: #endif
                    811: 
                    812: BOOL CFrameWnd::LoadAccelTable(LPCSTR lpAccelTableName)
                    813: {
                    814:        ASSERT(m_hAccelTable == NULL);  // only do once
                    815:        ASSERT(lpAccelTableName != NULL);
                    816: 
                    817:        m_hAccelTable = ::LoadAccelerators(AfxGetResourceHandle(),
                    818:                lpAccelTableName);
                    819:        return (m_hAccelTable != NULL);
                    820: }
                    821: 
                    822: /////////////////////////////////////////////////////////////////////////////
                    823: // Creation and window tree access
                    824: 
                    825: BOOL CFrameWnd::Create(LPCSTR lpClassName,
                    826:        LPCSTR lpWindowName,
                    827:        DWORD dwStyle, const RECT& rect,
                    828:        const CWnd* pParentWnd,
                    829:        LPCSTR lpMenuName)
                    830: {
                    831:        HMENU   hMenu = NULL;
                    832: 
                    833:        if (lpClassName == NULL)
                    834:                lpClassName = _afxFrameWnd;
                    835: 
                    836:        if (lpMenuName != NULL)
                    837:        {
                    838:                // load in a menu that will get destroyed when window gets destroyed
                    839:                hMenu = ::LoadMenu(AfxGetResourceHandle(), lpMenuName);
                    840:                if (hMenu == NULL)
                    841:                {
                    842:                        TRACE("Warning: failed to load menu for CFrameWnd\n");
                    843:                        return FALSE;
                    844:                }
                    845:        }
                    846: 
                    847:        if (!CreateEx(0L, lpClassName, lpWindowName, dwStyle,
                    848:                rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
                    849:                pParentWnd->GetSafeHwnd(), hMenu))
                    850:        {
                    851:                TRACE("Warning: failed to create CFrameWnd\n");
                    852:                return FALSE;
                    853:        }
                    854:        return TRUE;
                    855: }
                    856: 
                    857: CFrameWnd* CFrameWnd::GetChildFrame()
                    858: {
                    859:        return this;
                    860: }
                    861: 
                    862: CFrameWnd* CFrameWnd::GetParentFrame()
                    863: {
                    864:        return this;
                    865: }
                    866: 
                    867: BOOL CFrameWnd::PreTranslateMessage(MSG* pMsg)
                    868: {
                    869:        return (m_hAccelTable != NULL &&
                    870:          ::TranslateAccelerator(m_hWnd, m_hAccelTable, pMsg));
                    871: }
                    872: 
                    873: 
                    874: /////////////////////////////////////////////////////////////////////////////
                    875: // Additional helpers for WNDCLASS init
                    876: 
                    877: const char* AfxRegisterWndClass(UINT nClassStyle,
                    878:        HCURSOR hCursor, HBRUSH hbrBackground, HICON hIcon)
                    879: {
                    880:        // Returns a temporary string name for the class
                    881:        //  Save in a CString if you want to use it for a long time
                    882:        WNDCLASS wndcls;
                    883:        static char szName[64];     // 1 global string
                    884: 
                    885:        // generate a synthetic name for this class
                    886:        if (hCursor == NULL && hbrBackground == NULL && hIcon == NULL)
                    887:                wsprintf(szName, "Afx:%x", nClassStyle);
                    888:        else
                    889:                wsprintf(szName, "Afx:%x:%x:%x:%x", nClassStyle,
                    890:                        (UINT) hCursor, (UINT) hbrBackground, (UINT) hIcon);
                    891: 
                    892:        // see if the class already exists
                    893:        if (::GetClassInfo(AfxGetInstanceHandle(), szName, &wndcls))
                    894:        {
                    895:                // already registered, assert everything is good
                    896:                ASSERT(wndcls.style == nClassStyle);
1.1.1.3 ! root      897:                
        !           898:                // NOTE: We have to trust that the hIcon, hbrBackground, and the
        !           899:                //  hCursor are semantically the same, because sometimes Windows does 
        !           900:                //  some internal translation or copying of those handles before 
        !           901:                //  storing them in the internal WNDCLASS retrieved by GetClassInfo.
1.1       root      902:                return szName;
                    903:        }
                    904: 
                    905:        // otherwise we need to register a new class
                    906:        wndcls.style = nClassStyle;
                    907:        wndcls.lpfnWndProc  = AfxWndProc;
                    908:        wndcls.cbClsExtra = wndcls.cbWndExtra = 0;
                    909:        wndcls.hInstance = AfxGetInstanceHandle();
                    910:        wndcls.hIcon = hIcon;
                    911:        wndcls.hCursor = hCursor;
                    912:        wndcls.hbrBackground = hbrBackground;
                    913:        wndcls.lpszMenuName = NULL;
                    914:        wndcls.lpszClassName = szName;
                    915:        if (!::RegisterClass(&wndcls))
                    916:                AfxThrowResourceException();
                    917:        return szName;
                    918: }
                    919: 
                    920: 
                    921: 
                    922: /////////////////////////////////////////////////////////////////////////////
                    923: // Dialogs have 2-phase construction
                    924: 
                    925: IMPLEMENT_DYNAMIC(CDialog, CWnd)
                    926: 
                    927: CDialog::CDialog()
                    928: {
                    929:        ASSERT(m_hWnd == NULL);
                    930: 
                    931:        m_hBrushCtlBk = NULL;
                    932:        VERIFY(SetCtlBkColor(::GetSysColor(COLOR_BTNFACE)));
                    933: }
                    934: 
                    935: CDialog::~CDialog()
                    936: {
                    937:        if (m_hBrushCtlBk != NULL)
                    938:                ::DeleteObject(m_hBrushCtlBk);
                    939:        m_hBrushCtlBk = NULL;
                    940: }
                    941: 
                    942: #ifdef _DEBUG
                    943: void
                    944: CDialog::AssertValid() const
                    945: {
                    946:        CWnd::AssertValid();
                    947:        ASSERT(m_hWnd != (HWND)1);
                    948: }
                    949: #endif
                    950: 
                    951: // Modeless
                    952: BOOL
                    953: CDialog::Create(LPCSTR lpTemplateName, CWnd* pParentWnd)
                    954: {
                    955:        if (pParentWnd == NULL)
                    956:                pParentWnd = AfxGetApp()->m_pMainWnd;
                    957: 
                    958:        _AfxHookWindowCreate(this);
                    959:        HWND hWnd = ::CreateDialog(AfxGetResourceHandle(),
                    960:                lpTemplateName, pParentWnd->GetSafeHwnd(),
                    961:                (DLGPROC)_AfxDlgProc);
                    962:        _AfxUnhookWindowCreate();
                    963: 
                    964:        return (m_hWnd = hWnd) != NULL;
                    965: }
                    966: 
                    967: BOOL
                    968: CDialog::CreateIndirect(const void FAR* lpDialogTemplate,
                    969:                CWnd* pParentWnd)
                    970: {
                    971:        if (pParentWnd == NULL)
                    972:                pParentWnd = AfxGetApp()->m_pMainWnd;
                    973: 
                    974:        _AfxHookWindowCreate(this);
1.1.1.3 ! root      975: #ifndef _NTWIN
1.1       root      976:        HWND hWnd = ::CreateDialogIndirect(AfxGetResourceHandle(),
1.1.1.3 ! root      977:                lpDialogTemplate, pParentWnd->GetSafeHwnd(),
1.1       root      978:                (DLGPROC)_AfxDlgProc);
                    979: #else
                    980:        HWND hWnd = ::CreateDialogIndirect(AfxGetResourceHandle(),
1.1.1.3 ! root      981:                (LPCDLGTEMPLATE)lpDialogTemplate, pParentWnd->GetSafeHwnd(),
1.1       root      982:                (DLGPROC)_AfxDlgProc);
                    983: #endif
                    984:        _AfxUnhookWindowCreate();
                    985: 
                    986:        return (m_hWnd = hWnd) != NULL;
                    987: }
                    988: 
                    989: void
                    990: CDialog::OnSetFont(CFont*)
                    991: {
                    992:        // ignore it
                    993: }
                    994: 
                    995: BOOL
                    996: CDialog::OnInitDialog()
                    997: {
                    998:        return TRUE;    // set focus to first one
                    999: }
                   1000: 
                   1001: 
                   1002: BOOL 
                   1003: CDialog::SetCtlBkColor(COLORREF clrCtlBk)
                   1004: { 
                   1005:        if (m_hBrushCtlBk != NULL)
                   1006:                ::DeleteObject(m_hBrushCtlBk);
                   1007:        m_hBrushCtlBk = NULL;
                   1008: 
                   1009:        if (clrCtlBk == 0xFFFFFFFF)
                   1010:        {
                   1011:                // -1 means do not handle any WM_CTLCOLOR messages
                   1012:                ASSERT(m_hBrushCtlBk == NULL);
                   1013:                return TRUE;
                   1014:        }
                   1015: 
                   1016:        m_hBrushCtlBk = ::CreateSolidBrush(clrCtlBk);
                   1017:        return m_hBrushCtlBk != NULL ? TRUE : FALSE;
                   1018: }
                   1019: 
                   1020: HBRUSH 
                   1021: CDialog::OnCtlColor(CDC* pDC, CWnd* /* pWnd */, UINT nCtlColor)
                   1022: {
                   1023:        if (m_hBrushCtlBk == NULL || 
                   1024:                        nCtlColor == CTLCOLOR_LISTBOX ||
                   1025:                        nCtlColor == CTLCOLOR_EDIT || 
                   1026:                        nCtlColor == CTLCOLOR_MSGBOX)
                   1027:                return (HBRUSH)Default();
                   1028: 
                   1029:        // Use new look AFX colors
                   1030:        // Set the background color for controls
                   1031:        LOGBRUSH logbrush;
                   1032:        if (::GetObject(m_hBrushCtlBk, sizeof(LOGBRUSH), (LPSTR)&logbrush) != 0) 
                   1033:        {
                   1034:                pDC->SetBkColor(logbrush.lbColor);
                   1035:        }
                   1036:        else
                   1037:        {
                   1038:                TRACE("Warning: couldn't set background color for CTLCOLOR\n");
                   1039:        }
                   1040:        return m_hBrushCtlBk;
                   1041: }
                   1042: 
                   1043: BEGIN_MESSAGE_MAP(CDialog, CWnd)
                   1044:        ON_WM_CTLCOLOR()
                   1045: END_MESSAGE_MAP()
                   1046: 
                   1047: /////////////////////////////////////////////////////////////////////////////
                   1048: // Dialog Proc support
                   1049: 
                   1050: BOOL
                   1051: CDialog::PreTranslateMessage(MSG* pMsg)
                   1052: {
                   1053:        // for modeless processing (or modal)
                   1054:        ASSERT(m_hWnd != NULL);
                   1055: 
                   1056:        // filter both messages to dialog and from children
                   1057:        return ::IsDialogMessage(m_hWnd, pMsg);
                   1058: }
                   1059: 
                   1060: WNDPROC*
                   1061: CDialog::GetSuperWndProcAddr()
                   1062: {
                   1063:        static WNDPROC pfnSuper;
                   1064:        return &pfnSuper;
                   1065: }
                   1066: 
                   1067: /////////////////////////////////////////////////////////////////////////////
                   1068: // CModalDialog
                   1069: 
                   1070: IMPLEMENT_DYNAMIC(CModalDialog, CDialog)
                   1071: 
                   1072: BEGIN_MESSAGE_MAP(CModalDialog, CDialog)
                   1073:        ON_COMMAND(IDOK, OnOK)
                   1074:        ON_COMMAND(IDCANCEL, OnCancel)
                   1075: END_MESSAGE_MAP()
                   1076: 
                   1077: // Constructors just save parameters
                   1078: CModalDialog::CModalDialog(LPCSTR lpTemplateName, CWnd* pParentWnd)
                   1079: {
                   1080:        m_lpDialogTemplate = lpTemplateName;
                   1081:        m_hDialogTemplate = NULL;
                   1082:        m_pParentWnd = pParentWnd;
                   1083: }
                   1084: 
                   1085: CModalDialog::CModalDialog(UINT nIDTemplate, CWnd* pParentWnd)
                   1086: {
                   1087:        m_lpDialogTemplate = MAKEINTRESOURCE(nIDTemplate);
                   1088:        m_hDialogTemplate = NULL;
                   1089:        m_pParentWnd = pParentWnd;
                   1090: }
                   1091: 
                   1092: BOOL
                   1093: CModalDialog::CreateIndirect(HANDLE hDialogTemplate)
                   1094: {
                   1095:        // must be called on an empty constructed CModalDialog
                   1096:        ASSERT(m_lpDialogTemplate == NULL);
                   1097:        ASSERT(m_hDialogTemplate == NULL);
                   1098: 
                   1099:        m_hDialogTemplate = hDialogTemplate;
                   1100:        return TRUE;        // always ok (DoModal actually brings up dialog)
                   1101: }
                   1102: 
                   1103: #ifdef _DEBUG
                   1104: void
                   1105: CModalDialog::AssertValid() const
                   1106: {
                   1107:        CDialog::AssertValid();
                   1108: }
                   1109: 
                   1110: void
                   1111: CModalDialog::Dump(CDumpContext& dc) const
                   1112: {
                   1113:        CDialog::Dump(dc);
                   1114:        dc << "\nm_lpDialogTemplate = " << m_lpDialogTemplate << "\n";
                   1115:        dc << "m_hDialogTemplate = " << m_hDialogTemplate << "\n";
                   1116:        dc << "m_pParentWnd = " << (void *)m_pParentWnd;
                   1117: }
                   1118: #endif
                   1119: 
                   1120: int
                   1121: CModalDialog::DoModal()
                   1122: {
                   1123:        HWND    hWndParent;
                   1124:        int     nResult;
                   1125: 
                   1126:        // can be constructed with a resource template or CreateIndirect
                   1127:        ASSERT(m_lpDialogTemplate != NULL || m_hDialogTemplate != NULL);
                   1128: 
                   1129:        // find parent HWND
                   1130:        if (m_pParentWnd != NULL)
                   1131:                hWndParent = m_pParentWnd->m_hWnd;
                   1132:        else
                   1133:                hWndParent = AfxGetApp()->m_pMainWnd->GetSafeHwnd();
                   1134: 
                   1135:        _AfxHookWindowCreate(this);
                   1136:        if (m_lpDialogTemplate != NULL)
                   1137:        {
                   1138:                nResult = ::DialogBox(AfxGetResourceHandle(), m_lpDialogTemplate,
                   1139:                        hWndParent, (DLGPROC)_AfxDlgProc);
                   1140:        }
                   1141:        else
                   1142:        {
1.1.1.3 ! root     1143: #ifndef _NTWIN
1.1       root     1144:                nResult = ::DialogBoxIndirect(AfxGetResourceHandle(), m_hDialogTemplate,
                   1145:                        hWndParent, (DLGPROC)_AfxDlgProc);
1.1.1.3 ! root     1146: #else
        !          1147:                nResult = ::DialogBoxIndirect(AfxGetResourceHandle(),
        !          1148:                        (LPCDLGTEMPLATE)m_hDialogTemplate,
        !          1149:                        hWndParent, (DLGPROC)_AfxDlgProc);
1.1       root     1150: #endif
                   1151:        }
                   1152: 
                   1153:        _AfxUnhookWindowCreate();   // just in case
                   1154:        Detach();               // just in case
                   1155:        return nResult;
                   1156: }
                   1157: 
                   1158: /////////////////////////////////////////////////////////////////////////////
                   1159: // Standard CModalDialog implementation
                   1160: 
                   1161: void
                   1162: CModalDialog::OnOK()
                   1163: {
                   1164:        EndDialog(IDOK);
                   1165: }
                   1166: 
                   1167: void
                   1168: CModalDialog::OnCancel()
                   1169: {
                   1170:        EndDialog(IDCANCEL);
                   1171: }
                   1172: 
                   1173: /////////////////////////////////////////////////////////////////////////////
                   1174: // CRect for creating windows with the default position/size
                   1175: const CRect NEAR CFrameWnd::rectDefault(CW_USEDEFAULT, CW_USEDEFAULT,
                   1176:        0 /* 2*CW_USEDEFAULT */, 0 /* 2*CW_USEDEFAULT */);
                   1177: 
                   1178: // CWnds for setting z-order with SetWindowPos's pWndInsertAfter parameter
                   1179: const CWnd NEAR CWnd::wndTop((HWND)0);
                   1180: const CWnd NEAR CWnd::wndBottom((HWND)1);
                   1181: const CWnd NEAR CWnd::wndTopMost((HWND)-1);
                   1182: const CWnd NEAR CWnd::wndNoTopMost((HWND)-2);
                   1183: 
                   1184: /////////////////////////////////////////////////////////////////////////////
                   1185: // Message table implementation
                   1186: 
                   1187: CMessageMap CWnd::messageMap =
                   1188: {
                   1189:        NULL,           // end of chain of message maps
                   1190:        (CMessageEntry FAR*) &CWnd::_messageEntries
                   1191: };
                   1192: 
                   1193: CMessageMap* CWnd::GetMessageMap() const
                   1194: {
                   1195:        return &CWnd::messageMap;
                   1196: }
                   1197: 
                   1198: 
                   1199: CMessageEntry BASED_CODE CWnd::_messageEntries[] =
                   1200: {
                   1201:        ON_WM_COMPAREITEM()
                   1202:        ON_WM_MEASUREITEM()
                   1203:        ON_WM_DRAWITEM()
                   1204:        ON_WM_DELETEITEM()
                   1205:        ON_WM_CTLCOLOR()
                   1206:        ON_WM_DESTROY()
                   1207:        ON_WM_NCDESTROY()
                   1208: #ifdef _NTWIN
                   1209:        ON_MESSAGE(WM_CTLCOLORMSGBOX, OnNTCtlColor)
                   1210:        ON_MESSAGE(WM_CTLCOLOREDIT, OnNTCtlColor)
                   1211:        ON_MESSAGE(WM_CTLCOLORLISTBOX, OnNTCtlColor)
                   1212:        ON_MESSAGE(WM_CTLCOLORBTN, OnNTCtlColor)
                   1213:        ON_MESSAGE(WM_CTLCOLORDLG, OnNTCtlColor)
                   1214:        ON_MESSAGE(WM_CTLCOLORSCROLLBAR, OnNTCtlColor)
                   1215:        ON_MESSAGE(WM_CTLCOLORSTATIC, OnNTCtlColor)
                   1216: #endif
                   1217: 
                   1218:        { 0, 0, AfxSig_end, (AFX_PMSG)0 }
                   1219: };
                   1220: 
                   1221: union MessageMapFunctions
                   1222: {
                   1223:        AFX_PMSG pfn;   // generic member function pointer
                   1224: 
                   1225:        // specific type safe variants
                   1226:        BOOL    (CWnd::*pfn_bD)(CDC *);
                   1227:        BOOL    (CWnd::*pfn_bb)(BOOL);
                   1228:        BOOL    (CWnd::*pfn_bWww)(CWnd*, UINT, UINT);
                   1229:        HBRUSH  (CWnd::*pfn_hDWw)(CDC *, CWnd*, UINT);
                   1230:        int     (CWnd::*pfn_iwWw)(UINT, CWnd*, UINT);
                   1231:        int     (CWnd::*pfn_iWww)(CWnd*, UINT, UINT);
                   1232:        int     (CWnd::*pfn_is)(LPSTR);
                   1233:        LONG    (CWnd::*pfn_lwl)(UINT, LONG);
                   1234:        LONG    (CWnd::*pfn_lwwM)(UINT, UINT, CMenu *);
                   1235:        void    (CWnd::*pfn_vv)(void);
                   1236: 
                   1237:        void    (CWnd::*pfn_vw)(UINT);
                   1238:        void    (CWnd::*pfn_vww)(UINT, UINT);
                   1239:        void    (CWnd::*pfn_vvii)(int, int);
                   1240:        void    (CWnd::*pfn_vwww)(UINT, UINT, UINT);
                   1241:        void    (CWnd::*pfn_vwii)(UINT, int, int);
                   1242:        void    (CWnd::*pfn_vwl)(UINT, LONG);
                   1243:        void    (CWnd::*pfn_vbWW)(BOOL, CWnd*, CWnd*);
                   1244:        void    (CWnd::*pfn_vD)(CDC *);
                   1245:        void    (CWnd::*pfn_vM)(CMenu *);
                   1246:        void    (CWnd::*pfn_vMwb)(CMenu *, UINT, BOOL);
                   1247: 
                   1248:        void    (CWnd::*pfn_vW)(CWnd*);
                   1249:        void    (CWnd::*pfn_vWww)(CWnd*, UINT, UINT);
                   1250:        void    (CWnd::*pfn_vWh)(CWnd*, HANDLE);
                   1251:        void    (CWnd::*pfn_vwW)(UINT, CWnd*);
                   1252:        void    (CWnd::*pfn_vwWb)(UINT, CWnd*, BOOL);
                   1253:        void    (CWnd::*pfn_vwwW)(UINT, UINT, CWnd*);
                   1254:        void    (CWnd::*pfn_vs)(LPSTR);
                   1255:        UINT    (CWnd::*pfn_wp)(CPoint);
                   1256:        UINT    (CWnd::*pfn_wv)(void);
                   1257:        BOOL    (CWnd::*pfn_bh)(HANDLE);
                   1258:        void    (CWnd::*pfn_vPOS)(WINDOWPOS FAR*);
                   1259:        void    (CWnd::*pfn_vCALC)(NCCALCSIZE_PARAMS FAR*);
                   1260: #ifdef _NTWIN
                   1261:        void    (CWnd::*pfn_vwp)(UINT, CPoint);
                   1262:        void    (CWnd::*pfn_vwwh)(UINT, UINT, HANDLE);
                   1263: #endif
                   1264: };
                   1265: 
                   1266: /////////////////////////////////////////////////////////////////////////////
                   1267: // Routines for fast search of message maps
                   1268: 
                   1269: 
                   1270: // Hand tuned routine
                   1271: 
                   1272: #pragma optimize("qgel", off) // assembler cannot be globally optimized
                   1273: 
                   1274: #ifdef _NTWIN
                   1275: // C versions of search routines
                   1276: static inline CMessageEntry FAR*
                   1277: FindMessageEntry(CMessageEntry FAR* lpEntry, UINT nMsg, UINT nID)
                   1278: {
                   1279:        while (lpEntry->nSig != AfxSig_end)
                   1280:        {
                   1281:                if (lpEntry->nMessage == nMsg && lpEntry->nID == nID)
                   1282:                        return lpEntry;
                   1283:                lpEntry++;
                   1284:        }
                   1285:        return NULL;    // not found
                   1286: }
                   1287: 
                   1288: #else
                   1289: static CMessageEntry FAR* NEAR
                   1290: FindMessageEntry(CMessageEntry FAR* lpEntry, UINT nMsg, UINT nID)
                   1291: {
                   1292:        _asm
                   1293:        {
                   1294:                                LES     BX,lpEntry
                   1295:                                MOV     AX,nMsg
                   1296:                                MOV     DX,nID
                   1297:                __loop:
                   1298:                                MOV     CX,WORD PTR ES:[BX+4]   ; nSig (0 => end)
                   1299:                                JCXZ    __failed
                   1300:                                CMP     AX,WORD PTR ES:[BX]     ; nMessage
                   1301:                                JE      __found_1
                   1302:                __next:
                   1303:                                ADD     BX,SIZE CMessageEntry
                   1304:                                JMP     __loop
                   1305:                __found_1:
                   1306:                                CMP     DX,WORD PTR ES:[BX+2]   ; nID
                   1307:                                JNE     __next
                   1308:                // found a match
                   1309:                                MOV     WORD PTR lpEntry,BX
                   1310:                                MOV     WORD PTR lpEntry+2,ES
                   1311:                                JMP     __end
                   1312:                __failed:
                   1313:                                XOR     AX,AX
                   1314:                                MOV     WORD PTR lpEntry,AX
                   1315:                                MOV     WORD PTR lpEntry+2,AX
                   1316:                __end:
                   1317:        }
                   1318:        return lpEntry;
                   1319: }
                   1320: #endif //_NTWIN
                   1321: 
                   1322: #pragma optimize("", on)    // return to default optimizations
                   1323: 
                   1324: 
                   1325: /////////////////////////////////////////////////////////////////////////////
                   1326: 
                   1327: #ifndef iHashMax
                   1328: // iHashMax must be a power of two
                   1329:        #ifdef _NEARDATA
                   1330:                #define iHashMax 64
                   1331:        #else
                   1332:                #define iHashMax 256
                   1333:        #endif
                   1334: #endif
                   1335: 
                   1336: struct MsgCache
                   1337: {
                   1338:        UINT nMsg;
                   1339:        CMessageEntry FAR* lpEntry;
                   1340:        CMessageMap* pMessageMap;
                   1341: };
                   1342: 
                   1343: MsgCache _afxMsgCache[iHashMax];
                   1344: 
                   1345: LONG
                   1346: CWnd::WindowProc(UINT nMsg, UINT wParam, LONG lParam)
                   1347: {
                   1348:        register CMessageMap* pMessageMap;
                   1349:        CMessageEntry FAR* lpEntry;
                   1350: 
                   1351:        if (nMsg == WM_COMMAND) // special case for commands
                   1352:        {
                   1353:                if (OnCommand(wParam, lParam))
                   1354:                        return 1L; // command handled
                   1355:                else 
                   1356:                        return (LONG)DefWindowProc(nMsg, wParam, lParam); // call default handler
                   1357:        }
                   1358: 
                   1359:        pMessageMap = GetMessageMap();
                   1360:        UINT iHash = (_AFX_FP_OFF(pMessageMap) ^ nMsg) & (iHashMax-1);
                   1361:        MsgCache& msgCache = _afxMsgCache[iHash];
                   1362: 
                   1363:        if (nMsg == msgCache.nMsg && pMessageMap == msgCache.pMessageMap)
                   1364:        {
                   1365:                // Cache hit
                   1366:                lpEntry = msgCache.lpEntry;
                   1367:                if (lpEntry == NULL)
                   1368:                        return (LONG)DefWindowProc(nMsg, wParam, lParam);
                   1369:                else if (nMsg < 0xC000)
                   1370:                        goto LDispatch;
                   1371:                else
                   1372:                        goto LDispatchRegistered;
                   1373:        }
                   1374:        else
                   1375:        {
                   1376:                // not in cache, look for it
                   1377:                msgCache.nMsg = nMsg;
                   1378:                msgCache.pMessageMap = pMessageMap;
                   1379: 
                   1380:                for (/* pMessageMap already init'ed */; pMessageMap != NULL;
                   1381:                        pMessageMap = pMessageMap->pBaseMessageMap)
                   1382:                {
                   1383:                        // This may loop forever if the message maps are not properly
                   1384:                        // chained together.  Make sure each window class's message map
                   1385:                        // points to the base window class's message map.
                   1386: 
                   1387:                        if (nMsg < 0xC000)
                   1388:                        {
                   1389:                                // constant window message
                   1390:                                if ((lpEntry = FindMessageEntry(pMessageMap->lpEntries,
                   1391:                                        nMsg, 0)) != NULL)
                   1392:                                {
                   1393:                                        msgCache.lpEntry = lpEntry;
                   1394:                                        goto LDispatch;
                   1395:                                }
                   1396:                        }
                   1397:                        else
                   1398:                        {
                   1399:                                // registered windows message
                   1400:                                lpEntry = pMessageMap->lpEntries;
                   1401: 
                   1402:                                while ((lpEntry = FindMessageEntry(lpEntry, 0xC000, 0)) != NULL)
                   1403:                                {
                   1404:                                        UINT NEAR* pnID = (UINT NEAR*)(lpEntry->nSig);
                   1405:                                        ASSERT(*pnID >= 0xC000);
                   1406:                                                // must be successfully registered
                   1407:                                        if (*pnID == nMsg)
                   1408:                                        {
                   1409:                                                msgCache.lpEntry = lpEntry;
                   1410:                                                goto LDispatchRegistered;
                   1411:                                        }
                   1412:                                        lpEntry++;      // keep looking past this one
                   1413:                                }
                   1414:                        }
                   1415:                }
                   1416: 
                   1417:                msgCache.lpEntry = NULL;
                   1418:                return DefWindowProc(nMsg, wParam, lParam);
                   1419:        }
                   1420:        ASSERT(FALSE);      // not reached
                   1421: 
                   1422: 
                   1423: LDispatch:
                   1424:        ASSERT(nMsg < 0xC000);
                   1425:        union MessageMapFunctions mmf;
                   1426:        mmf.pfn = lpEntry->pfn;
                   1427: 
                   1428:        switch (lpEntry->nSig)
                   1429:        {
                   1430:        default:
                   1431:                ASSERT(FALSE);
                   1432:                return 0;
                   1433: 
                   1434:        case AfxSig_bD:
                   1435:                return (this->*mmf.pfn_bD)(CDC::FromHandle((HDC)wParam));
                   1436: 
                   1437:        case AfxSig_bb:
                   1438:                return (this->*mmf.pfn_bb)((BOOL)wParam);
                   1439: 
                   1440:        case AfxSig_bWww:
                   1441:                return (this->*mmf.pfn_bWww)(CWnd::FromHandle((HWND)wParam),
1.1.1.2   root     1442:                        (short)LOWORD(lParam), HIWORD(lParam));
1.1       root     1443: 
                   1444: #ifdef _NTWIN
                   1445:        case AfxSig_hDWw:
                   1446:                {
                   1447:                        ASSERT(nMsg == WM_CTLCOLOR);
                   1448:                        struct _AFXCTLCOLOR* pCtl = (struct _AFXCTLCOLOR*)lParam;
                   1449:                        return (LONG)((this->*mmf.pfn_hDWw)( CDC::FromHandle(pCtl->hDC),
                   1450:                                CWnd::FromHandle(pCtl->hWnd), pCtl->nCtlType));
                   1451:                }
                   1452: #else
                   1453:        case AfxSig_hDWw:
                   1454:                return (LONG)(UINT)(this->*mmf.pfn_hDWw)(CDC::FromHandle((HDC)wParam),
                   1455:                        CWnd::FromHandle((HWND)LOWORD(lParam)), HIWORD(lParam));
                   1456: #endif
                   1457: 
                   1458: #ifndef _NTWIN
                   1459:        case AfxSig_iwWw:
                   1460:                return (this->*mmf.pfn_iwWw)(wParam, CWnd::FromHandle((HWND)LOWORD(lParam)),
                   1461:                        HIWORD(lParam));
                   1462: #else
                   1463:        case AfxSig_iwWw:
                   1464:                return (this->*mmf.pfn_iwWw)(LOWORD(wParam), 
                   1465:                        CWnd::FromHandle((HWND)lParam),
                   1466:                        HIWORD(wParam));
                   1467: #endif
                   1468: 
                   1469:        case AfxSig_iWww:
                   1470:                return (this->*mmf.pfn_iWww)(CWnd::FromHandle((HWND)wParam),
1.1.1.2   root     1471:                        (short)LOWORD(lParam), HIWORD(lParam));
1.1       root     1472: 
                   1473:        case AfxSig_is:
                   1474:                return (this->*mmf.pfn_is)((LPSTR)lParam);
                   1475: 
                   1476:        case AfxSig_lwl:
                   1477:                return (this->*mmf.pfn_lwl)(wParam, lParam);
                   1478: 
                   1479: #ifndef _NTWIN
                   1480:        case AfxSig_lwwM:
                   1481:                return (this->*mmf.pfn_lwwM)(wParam, LOWORD(lParam),
                   1482:                        CMenu::FromHandle((HMENU)HIWORD(lParam)));
                   1483: #else
                   1484:        case AfxSig_lwwM:
                   1485:                return (this->*mmf.pfn_lwwM)((UINT)LOWORD(wParam), (UINT)HIWORD(wParam),
                   1486:                        (CMenu*)CMenu::FromHandle((HMENU)lParam));
                   1487: #endif
                   1488: 
                   1489:        case AfxSig_vv:
                   1490:                (this->*mmf.pfn_vv)();
                   1491:                return 0;
                   1492: 
                   1493: 
                   1494:        case AfxSig_vw: // AfxSig_vb:
                   1495:                (this->*mmf.pfn_vw)(wParam);
                   1496:                return 0;
                   1497: 
                   1498:        case AfxSig_vww:
                   1499: #ifndef _NTWIN
                   1500:                (this->*mmf.pfn_vww)(wParam, LOWORD(lParam));
                   1501: #else
                   1502:                (this->*mmf.pfn_vww)(wParam, lParam);
                   1503: #endif
                   1504:                return 0;
                   1505: 
                   1506:        case AfxSig_vvii:
                   1507:                (this->*mmf.pfn_vvii)(LOWORD(lParam), HIWORD(lParam));
                   1508:                return 0;
                   1509: 
                   1510: #ifdef _NTWIN
                   1511:        case AfxSig_vwwh:
                   1512:                (this->*mmf.pfn_vwwh)(LOWORD(wParam), HIWORD(wParam), (HANDLE)lParam);
                   1513:                return 0;
                   1514: #endif
                   1515: 
                   1516:        case AfxSig_vwww:
                   1517:                (this->*mmf.pfn_vwww)(wParam, LOWORD(lParam), HIWORD(lParam));
                   1518:                return 0;
                   1519: 
                   1520:        case AfxSig_vwii:
                   1521:                (this->*mmf.pfn_vwii)(wParam, LOWORD(lParam), HIWORD(lParam));
                   1522:                return 0;
                   1523: 
                   1524:        case AfxSig_vwl:
                   1525:                (this->*mmf.pfn_vwl)(wParam, lParam);
                   1526:                return 0;
                   1527: 
                   1528: #ifndef _NTWIN
                   1529:        case AfxSig_vbWW:
                   1530:                (this->*mmf.pfn_vbWW)((BOOL)wParam,
                   1531:                        CWnd::FromHandle((HWND)LOWORD(lParam)),
                   1532:                        CWnd::FromHandle((HWND)HIWORD(lParam)));
                   1533:                return 0;
                   1534: #else
                   1535:        case AfxSig_vbWW:
                   1536:                (this->*mmf.pfn_vbWW)(m_hWnd == (HWND)lParam,
                   1537:                        CWnd::FromHandle((HWND)lParam),
                   1538:                        CWnd::FromHandle((HWND)wParam));
                   1539:                return 0;
                   1540: #endif
                   1541: 
                   1542:        case AfxSig_vD:
                   1543:                (this->*mmf.pfn_vD)(CDC::FromHandle((HDC)wParam));
                   1544:                return 0;
                   1545: 
                   1546:        case AfxSig_vM:
                   1547:                (this->*mmf.pfn_vM)(CMenu::FromHandle((HMENU)wParam));
                   1548:                return 0;
                   1549: 
                   1550:        case AfxSig_vMwb:
                   1551:                (this->*mmf.pfn_vMwb)(CMenu::FromHandle((HMENU)wParam),
                   1552:                        LOWORD(lParam), (BOOL)HIWORD(lParam));
                   1553:                return 0;
                   1554: 
                   1555: 
                   1556:        case AfxSig_vW:
                   1557:                (this->*mmf.pfn_vW)(CWnd::FromHandle((HWND)wParam));
                   1558:                return 0;
                   1559: 
                   1560:        case AfxSig_vWww:
                   1561:                (this->*mmf.pfn_vWww)(CWnd::FromHandle((HWND)wParam), LOWORD(lParam),
                   1562:                        HIWORD(lParam));
                   1563:                return 0;
                   1564: 
                   1565: #ifndef _NTWIN
                   1566:        case AfxSig_vWh:
                   1567:                (this->*mmf.pfn_vWh)(CWnd::FromHandle((HWND)wParam),
                   1568:                                (HANDLE)LOWORD(lParam));
                   1569:                return 0;
                   1570: #else
                   1571:        case AfxSig_vWh:
                   1572:                (this->*mmf.pfn_vWh)(CWnd::FromHandle((HWND)wParam),
                   1573:                                (HANDLE)lParam);
                   1574:                return 0;
                   1575: #endif
                   1576: 
                   1577: #ifndef _NTWIN
                   1578:        case AfxSig_vwW:
                   1579:                (this->*mmf.pfn_vwW)(wParam, CWnd::FromHandle((HWND)LOWORD(lParam)));
                   1580:                return 0;
                   1581: #else
                   1582:        case AfxSig_vwW:
                   1583:                (this->*mmf.pfn_vwW)(wParam, CWnd::FromHandle((HWND)lParam));
                   1584:                return 0;
                   1585: #endif
                   1586: 
                   1587: #ifndef _NTWIN
                   1588:        case AfxSig_vwWb:
                   1589:                (this->*mmf.pfn_vwWb)(wParam, CWnd::FromHandle((HWND)LOWORD(lParam)),
                   1590:                        (BOOL)HIWORD(lParam));
                   1591:                return 0;
                   1592: #else
                   1593:        case AfxSig_vwWb:
                   1594:                (this->*mmf.pfn_vwWb)((UINT)(LOWORD(wParam)), 
                   1595:                        CWnd::FromHandle((HWND)lParam),
                   1596:                        (BOOL)(!(!(HIWORD(wParam)))));
                   1597:                return 0;
                   1598: #endif //_NTWIN
                   1599: 
                   1600: #ifndef _NTWIN
                   1601:        case AfxSig_vwwW:
                   1602:                (this->*mmf.pfn_vwwW)(wParam, LOWORD(lParam),
                   1603:                        CWnd::FromHandle((HWND)HIWORD(lParam)));
                   1604:                return 0;
                   1605: #else
                   1606:        case AfxSig_vwwW:
1.1.1.2   root     1607:                (this->*mmf.pfn_vwwW)((short)LOWORD(wParam), (short)HIWORD(wParam),
1.1       root     1608:                        CWnd::FromHandle((HWND)lParam));
                   1609:                return 0;
                   1610: #endif
                   1611: 
                   1612:        case AfxSig_vs:
                   1613:                (this->*mmf.pfn_vs)((LPSTR)lParam);
                   1614:                return 0;
                   1615: 
                   1616: #ifndef _NTWIN
                   1617:        case AfxSig_wp:
                   1618:                return (this->*mmf.pfn_wp)(*(CPoint*)&lParam);
                   1619: #else
                   1620:        case AfxSig_wp:
                   1621:                {
                   1622:                        CPoint point((DWORD)lParam);
                   1623:                        return (this->*mmf.pfn_wp)(point);
                   1624:                }
                   1625: 
                   1626:        case AfxSig_vwp:
                   1627:                {
                   1628:                        CPoint point((DWORD)lParam);
                   1629:                        (this->*mmf.pfn_vwp)(wParam, point);
                   1630:                        return 0;
                   1631:                }
                   1632: #endif
                   1633: 
                   1634:        case AfxSig_wv: // AfxSig_bv, AfxSig_wv
                   1635:                return (this->*mmf.pfn_wv)();
                   1636: 
                   1637:        case AfxSig_bh:
                   1638:                return (this->*mmf.pfn_bh)((HANDLE)wParam);
                   1639: 
                   1640:        case AfxSig_vCALC:
                   1641:                (this->*mmf.pfn_vCALC)((NCCALCSIZE_PARAMS FAR*)lParam);
                   1642:                return 0;
                   1643: 
                   1644:        case AfxSig_vPOS:
                   1645:                (this->*mmf.pfn_vPOS)((WINDOWPOS FAR*)lParam);
                   1646:                return 0;
                   1647:        }
                   1648:        ASSERT(FALSE);      // not reached
                   1649: 
                   1650: LDispatchRegistered:    // for registered windows messages
                   1651:        ASSERT(nMsg >= 0xC000);
                   1652:        mmf.pfn = lpEntry->pfn;
                   1653:        return (this->*mmf.pfn_lwl)(wParam, lParam);
                   1654: }
                   1655: 
                   1656: BOOL CWnd::OnCommand(UINT wParam, LONG lParam)
                   1657: {
                   1658: #ifdef _NTWIN
                   1659:        UINT nID = LOWORD(wParam);
                   1660:        HWND hWndCtrl = (HWND)lParam;
                   1661:        UINT nNotifyCode = HIWORD(wParam);      // control specific
                   1662: #else  
                   1663:        UINT nID = wParam;
                   1664:        HWND hWndCtrl = (HWND)LOWORD(lParam);
                   1665:        UINT nNotifyCode = HIWORD(lParam);  // control specific
                   1666: #endif
                   1667:        if (nID == 0)
                   1668:                return FALSE;       // 0 control IDs are not allowed !
                   1669: 
                   1670:        // default routing for command messages (through closure table)
                   1671:        if (hWndCtrl == NULL)
                   1672:                nNotifyCode = 0;        // accelerators are not special
                   1673: 
                   1674:        // check in message map table for matching control ID
                   1675:        register CMessageMap* pMessageMap;
                   1676:        register CMessageEntry FAR* lpEntry;
                   1677: 
                   1678:        for (pMessageMap = GetMessageMap(); pMessageMap != NULL;
                   1679:          pMessageMap = pMessageMap->pBaseMessageMap)
                   1680:        {
                   1681:                if ((lpEntry = FindMessageEntry(pMessageMap->lpEntries,
                   1682:                  nNotifyCode, nID)) != NULL)
                   1683:                {
                   1684: #ifdef _DEBUG
                   1685:                        // diagnostic trace reporting of command notifications
                   1686:                        if (afxTraceFlags & 8)  // if command reporting
                   1687:                        {
                   1688:                                if (nNotifyCode == 0)
                   1689:                                {
                   1690:                                        TRACE("SENDING command %d to %s window\n", nID,
                   1691:                                                GetRuntimeClass()->m_pszClassName);
                   1692:                                }
                   1693:                                else if (afxTraceFlags & 4) // if verbose windows messages
                   1694:                                {
                   1695:                                        TRACE("SENDING control notification %d from control id %d "
                   1696:                                                "to %s window\n", nNotifyCode, nID,
                   1697:                                                GetRuntimeClass()->m_pszClassName);
                   1698:                                }
                   1699:                        }
                   1700: #endif
                   1701:                        // dispatch it
                   1702:                        (this->*lpEntry->pfn)();
                   1703:                        return TRUE;    // handled
                   1704:                }
                   1705:        }
                   1706: 
                   1707: #ifdef _DEBUG
                   1708:        if (afxTraceFlags & 8)
                   1709:        {
                   1710:                if (nNotifyCode == 0)
                   1711:                {
                   1712:                        TRACE("IGNORING command %d sent to %s window\n", nID,
                   1713:                                        GetRuntimeClass()->m_pszClassName);
                   1714:                }
                   1715:                else if (afxTraceFlags & 4) // if verbose windows messages
                   1716:                {
                   1717:                        TRACE("IGNORING control notification %d from control id %d "
                   1718:                                "to %s window\n", nNotifyCode, nID,
                   1719:                                GetRuntimeClass()->m_pszClassName);
                   1720:                }
                   1721:        }
                   1722: #endif
                   1723: 
                   1724:        return FALSE;       // not handled
                   1725: }
                   1726: 
                   1727: 
                   1728: 
                   1729: /////////////////////////////////////////////////////////////////////////////

unix.superglobalmegacorp.com

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