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

  • 相关阅读:
    LeetCode OJ 112. Path Sum
    LeetCode OJ 226. Invert Binary Tree
    LeetCode OJ 100. Same Tree
    LeetCode OJ 104. Maximum Depth of Binary Tree
    LeetCode OJ 111. Minimum Depth of Binary Tree
    LeetCode OJ 110. Balanced Binary Tree
    apache-jmeter-3.1的简单压力测试使用方法(下载和安装)
    JMeter入门教程
    CentOS6(CentOS7)设置静态IP 并且 能够上网
    分享好文:分享我在阿里8年,是如何一步一步走向架构师的
  • 原文地址:https://www.cnblogs.com/findumars/p/8306950.html
Copyright © 2011-2022 走看看