zoukankan      html  css  js  c++  java
  • 深入浅出MFC:对话框消息路由

    [appmodul.cpp]

    extern "C" int WINAPI _tWinMain(HINSTANCE hInstance, 
                                    HINSTANCE hPrevInstance,
                                    LPTSTR lpCmdLine, 
                                    int nCmdShow)
    {
        return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    [winmain.cpp]

    int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                          LPTSTR lpCmdLine, int nCmdShow)
    {
        int nReturnCode = -1;
        CWinThread* pThread = AfxGetThread();
        CWinApp* pApp = AfxGetApp();
    
        pApp->InitApplication();
    
        if (!pThread->InitInstance())
        {
            return nReturnCode;
        }
    
        nReturnCode = pApp->Run();
    
        return nReturnCode;
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    CWinApp::InitApplication 
    CWinThread::InitInstance 
    CWinThread::Run 
    均是virtual函数


    [ProjName.cpp]

    BOOL CProjNameApp::InitInstance()
    {
        CWinAppEx::InitInstance();
    
        CTestWYDlg dlg;
        m_pMainWnd = &dlg;
        INT_PTR nResponse = dlg.DoModal();
        if (nResponse == IDOK)
        {
        }
        else if (nResponse == IDCANCEL)
        {
        }
    
        return FALSE;
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    由于该函数返回FALSE,所以在AfxWinMain中函数结束后直接退出, 
    不会运行pApp->Run()


    [dlgcore.cpp]

    INT_PTR CDialog::DoModal()
    {
        AfxHookWindowCreate(this);
        CreateDlgIndirect();
        RunModalLoop();   //消息循环
    
        DestroyWindow();  //销毁了窗口
    
        return;
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    [wincore.cpp]

    int CWnd::RunModalLoop(DWORD dwFlags)
    {
        for (;;)
        {
            if (!AfxPumpMessage())
            {
                AfxPostQuitMessage(0);
                return -1;
            }
        }
    
        return 0;
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    [thrdcore.cpp]

    BOOL AFXAPI AfxPumpMessage()
     {
        CWinThread *pThread = AfxGetThread();
        return pThread->PumpMessage();
     }
    • 1
    • 2
    • 3
    • 4
    • 5

    [thrdcore.cpp]

    BOOL CWinThread::PumpMessage()
    {
        return AfxInternalPumpMessage();
    }
    • 1
    • 2
    • 3
    • 4

    [thrdcore.cpp]

    BOOL AFXAPI AfxInternalPumpMessage()
    {
        MSG msg;
        ::GetMessage(&msg);
        if (!AfxPreTranslateMessage(&msg))
        {
            ::TranslateMessage(&msg);
            ::DispatchMessage(&msg);
        }
        return TRUE;
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    [thrdcore.cpp]

    BOOL AfxPreTranslateMessage(MSG* pMsg)
    {
        CWinThread *pThread = AfxGetThread();
        return pThread->PreTranslateMessage(pMsg);
    }
    • 1
    • 2
    • 3
    • 4
    • 5

    [thrdcore.cpp]

    BOOL CWinThread::PreTranslateMessage(MSG* pMsg)
    {
        return AfxInternalPreTranslateMessage(pMsg);
    }
    • 1
    • 2
    • 3
    • 4

    [thrdcore.cpp]

    BOOL AfxInternalPreTranslateMessage(MSG* pMsg)
    {
        CWnd* pMainWnd = AfxGetMainWnd();
        if (CWnd::WalkPreTranslateTree(pMainWnd->GetSafeHwnd(), pMsg))
            return TRUE;
        return FALSE;
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    [wincore.cpp]

    //
    // 返回TRUE or FALSE
    // 由以上流程得:该函数返回TRUE,则pMsg指向的消息将会被忽略而不处理
    //                    返回FALSE,则会DispatchMessage到对应的窗口过程函数处理
    //
    BOOL PASCAL CWnd::WalkPreTranslateTree(HWND hWndStop, MSG* pMsg)
    {
        //
        // 先调用本窗口对应CWnd类的PreTranslateMessage
        // 再往父窗口层层上溯调用对应CWnd类的PreTranslateMessage直到上溯到hWndStop对应的窗口
        // 若其中的某个PreTranslateMessage返回TRUE, 则函数退出返回TRUE
        // 否则上溯完成返回FALSE
        //
        for (HWND hWnd = pMsg->hwnd; hWnd != NULL; hWnd = ::GetParent(hWnd))
        {
            CWnd* pWnd = CWnd::FromHandlePermanent(hWnd);
            if (pWnd != NULL)
            {
                if (pWnd->PreTranslateMessage(pMsg))                        
                    return TRUE;
            }
            if (hWnd == hWndStop)
                break;
        }
        return FALSE;
    }

    http://blog.csdn.net/hisinwang/article/details/45786757

  • 相关阅读:
    rogue 源码 curses图形库实现的
    FreeBSD命令(抄至网络)
    没动力没精神
    加班无聊逛论坛
    2009年的FreeBSD命令(转载的)
    freebsd上源码安装cmake
    freeBSD中fetch下载工具使用
    Mac 安装HomeBrew 踩坑总结
    mybatis插入数据时,自动获取主键的自增id
    java 8对List的处理
  • 原文地址:https://www.cnblogs.com/findumars/p/8306950.html
Copyright © 2011-2022 走看看