1. 程式人生 > >MFC模態對話方塊程式不響應OnIdle

MFC模態對話方塊程式不響應OnIdle

從程式碼分析原因吧:

OnIdle函式在MFC的CWinThread::Run函式中被呼叫,如下

// main running routine until thread exits
int CWinThread::Run()
{
    ASSERT_VALID(this);
    _AFX_THREAD_STATE* pState = AfxGetThreadState();

    // for tracking the idle time state
    BOOL bIdle = TRUE;
    LONG lIdleCount = 0;

    // acquire and dispatch messages until a WM_QUIT message is received.
for (;;) { // phase1: check to see if we can do idle work while (bIdle && !::PeekMessage(&(pState->m_msgCur), NULL, NULL, NULL, PM_NOREMOVE)) { // call OnIdle while in bIdle state if (!OnIdle(lIdleCount++)) bIdle
= FALSE; // assume "no idle" state } // phase2: pump messages while available do { // pump message, but quit on WM_QUIT if (!PumpMessage()) return ExitInstance(); // reset "no idle" state after pumping "normal" message
//if (IsIdleMessage(&m_msgCur)) if (IsIdleMessage(&(pState->m_msgCur))) { bIdle = TRUE; lIdleCount = 0; } } while (::PeekMessage(&(pState->m_msgCur), NULL, NULL, NULL, PM_NOREMOVE)); } }

CWinThread::Run又在AfxWinMain中被呼叫,

/////////////////////////////////////////////////////////////////////////////
// Standard WinMain implementation
//  Can be replaced as long as 'AfxWinInit' is called first

int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    _In_ LPTSTR lpCmdLine, int nCmdShow)
{
    ASSERT(hPrevInstance == NULL);

    int nReturnCode = -1;
    CWinThread* pThread = AfxGetThread();
    CWinApp* pApp = AfxGetApp();

    // AFX internal initialization
    if (!AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow))
        goto InitFailure;

    // App global initializations (rare)
    if (pApp != NULL && !pApp->InitApplication())
        goto InitFailure;

    // Perform specific initializations
    if (!pThread->InitInstance())
    {
        if (pThread->m_pMainWnd != NULL)
        {
            TRACE(traceAppMsg, 0, "Warning: Destroying non-NULL m_pMainWnd\n");
            pThread->m_pMainWnd->DestroyWindow();
        }
        nReturnCode = pThread->ExitInstance();
        goto InitFailure;
    }
    nReturnCode = pThread->Run();

InitFailure:
#ifdef _DEBUG
    // Check for missing AfxLockTempMap calls
    if (AfxGetModuleThreadState()->m_nTempMapLock != 0)
    {
        TRACE(traceAppMsg, 0, "Warning: Temp map lock count non-zero (%ld).\n",
            AfxGetModuleThreadState()->m_nTempMapLock);
    }
    AfxLockTempMaps();
    AfxUnlockTempMaps(-1);
#endif

    AfxWinTerm();
    return nReturnCode;
}

要執行CWinThread::Run,則需要pThread->InitInstance返回才行,但模態對話方塊程式有點特殊,會直接阻塞在DoMoDal函式中,然後執行自己的訊息迴圈(程式碼如下),CXXXApp::InitInstace在程式沒結束時,不會返回,故OnIdle不會得到執行

BOOL CXXXApp::InitInstance()
{
    // 如果一個執行在 Windows XP 上的應用程式清單指定要
    // 使用 ComCtl32.dll 版本 6 或更高版本來啟用視覺化方式,
    //則需要 InitCommonControlsEx()。否則,將無法建立視窗。
    INITCOMMONCONTROLSEX InitCtrls;
    InitCtrls.dwSize = sizeof(InitCtrls);
    // 將它設定為包括所有要在應用程式中使用的
    // 公共控制元件類。
    InitCtrls.dwICC = ICC_WIN95_CLASSES;
    InitCommonControlsEx(&InitCtrls);

    CWinApp::InitInstance();


    AfxEnableControlContainer();

    // 建立 shell 管理器,以防對話方塊包含
    // 任何 shell 樹檢視控制元件或 shell 列表檢視控制元件。
    CShellManager *pShellManager = new CShellManager;

    // 啟用“Windows Native”視覺管理器,以便在 MFC 控制元件中啟用主題
    CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));

    // 標準初始化
    // 如果未使用這些功能並希望減小
    // 最終可執行檔案的大小,則應移除下列
    // 不需要的特定初始化例程
    // 更改用於儲存設定的登錄檔項
    // TODO: 應適當修改該字串,
    // 例如修改為公司或組織名
    SetRegistryKey(_T("應用程式嚮導生成的本地應用程式"));

    CXXXDlg dlg;
    m_pMainWnd = &dlg;
    INT_PTR nResponse = dlg.DoModal();
    if (nResponse == IDOK)
    {
        // TODO: 在此放置處理何時用
        //  “確定”來關閉對話方塊的程式碼
    }
    else if (nResponse == IDCANCEL)
    {
        // TODO: 在此放置處理何時用
        //  “取消”來關閉對話方塊的程式碼
    }
    else if (nResponse == -1)
    {
        TRACE(traceAppMsg, 0, "警告: 對話方塊建立失敗,應用程式將意外終止。\n");
        TRACE(traceAppMsg, 0, "警告: 如果您在對話方塊上使用 MFC 控制元件,則無法 #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS。\n");
    }

    // 刪除上面建立的 shell 管理器。
    if (pShellManager != NULL)
    {
        delete pShellManager;
    }

    // 由於對話方塊已關閉,所以將返回 FALSE 以便退出應用程式,
    //  而不是啟動應用程式的訊息泵。
    return FALSE;
}

由程式碼可知,MFC的模態對話方塊程式的OnIdle函式是不會被呼叫到的

相關推薦

MFC對話方塊程式響應OnIdle

從程式碼分析原因吧: OnIdle函式在MFC的CWinThread::Run函式中被呼叫,如下 // main running routine until thread exits int CWinThread::Run() { ASSERT_VALID(this); _AFX_THRE

MFC對話方塊和非對話方塊

下面是一個我的手寫的模態對話方塊和非模態對話方塊圖: 模態對話方塊是指當其顯示時,程式會暫停執行,直到關閉這個模態對話方塊後,才能繼續執行程式中其他任務。非模態對話方塊是指當其顯示時,允許轉而執行程式中其他任務,而不用關閉這個對話方塊。      模態對話方塊的建立:

MFC——對話方塊和非對話方塊

一、模態對話方塊 如果你需要做一個模態對話方塊,簡單的說就是你點一個按鈕,彈出一個對話方塊,之後你只能在彈出的對話方塊上操作的這麼一個過程。實驗的過程很簡單,跟著我做吧。 下面開始模態對話方塊實驗 在資源檢視新建一個對話方塊資源,修改其ID為IDD_DIAL

MFC——對話方塊與非對話方塊釋放資源的小總結

        對於模態對話方塊,其實它是在堆上建立的物件,當函式結束後會自動釋放其資源。但對於非模態對話方塊資源的釋放就沒這麼直接,原因: (1) 它是在堆上建立的。(2) 在當前的使用函式內是不能直

MFC】 如何通過主對話方塊的按鈕響應建立非對話方塊

1.首先新建一個對話方塊IDD_DIALOG_Create, 並新增類CDialog_Create。 //在工程中會新生成一個Dialog_Create.h標頭檔案和一個Dialog_Create.CPP原始檔。 2.在主對話方塊的標頭檔案SerialDlg.h

VC++6.0 MFC顯示對話方塊和非對話方塊

1、模態對話方塊 #include "AddDataDlg.h"//新增標頭檔案 CAddDataDlg AddData_Dialog;//在標頭檔案中定義對話方塊物件(CAddDataDlg為該對話方塊對應的類) int nReturn = AddData_Dialog.DoModal

C#裡面MessageBox能亂用,阻塞和非阻塞,對話方塊和非

我一開始以為這個MessageBox跟Delphi裡面的ShowMessage是一樣的,程式裡可以隨便放,因為C#裡面就TM這一個封裝好的彈出對話方塊提示訊息函式,可以直接用的。 結果實習做程式測試被坑爹了,發現我錯了,C#這個MessageBox預設是模態對話方塊,是阻塞的,也就是說你不

MFC】基於對話方塊程式選單欄更新

環境:win10,vs2017 問題描述: 為mfc對話方塊程式添加了一個托盤選單,但這個托盤選單不響應ON_UPDATE_COMMAND_UI訊息, 並且設定選單項的勾選(SetCheck)時,可以通過程式碼觀察到勾選成功,但選單欄顯示的勾選狀態依然不變。 經過幾天的百度,終於發現

MFC中的對話方塊和非對話方塊

MFC筆記之模態對話方塊和非模態對話方塊 迫於科研的進度壓力,我還是選擇了MFC最為工具去開發裝置除錯軟體,最初想用Qt來創新一下,然而串列埠的通訊一直沒有成功,而且周圍沒有人用Qt使得我在遇到問題無法

微信小程式踩坑(1):wx.showModal對話方塊中content換行

問題:wx.showModal 對話方塊內容不能換行? 如上圖所示,模態對話方塊中content是沒有換行的,但是我們需求中有需要換行提醒的業務,那怎麼辦呢?官方API中並沒有告訴我們怎麼做! 解決方案:使用“\r\n”換行 原始碼 wx.showModal({

MFC對話方塊一閃而過

在訊息函式中用下面的程式碼會出現對話方塊閃一下就不見了的情況 Color_Based_SettingDlg m_ColorBasedSetting; m_ColorBasedSetting.Create(IDD_DIALOG_BASE_COLOR_SE

MFC 建立非對話方塊和銷燬過程

今天專案中遇到的問題,記錄下來,做個總結。 一個簡單的目的是建立一個非模態對話方塊並在對話方塊關閉後將其銷燬。 這裡的銷燬包括:銷燬對話方塊物件資源和對話方塊物件指標; 首先說建立對話方塊: 一、模態對話方塊(model dialog box) 在程式執行的過程中,若出

微信小程式實現對話方塊

模態對話方塊在彈出的時候,使用者如果不關閉這個對話方塊,是無法對其他視窗進行操作的。  思路:需要一個遮蓋層(mask)和一個對話方塊(modal)。  1)模板wxml <text bindtap="introModal">展覽介紹</text&g

MFC對話方塊彈出的對話方塊閃了一下就消失了

CTestDialog *pTestDlg = new CTestDialog(); pTestDlg->Create(IDD_DIALOG_TEST, this); pTestDlg->ShowWindow(SW_SHOW); ///下面三行錯誤 //

微信小程式—自定義對話方塊例項

微信小程式—自定義模態對話方塊例項 由於官方API提供的顯示模態彈窗,只能簡單地顯示文字內容,不能對對話方塊內容進行自定義,欠缺靈活性,所以自己從模態彈窗的原理角度來實現了自定義的模態對話方塊。 wx.showModal(OBJECT) 自定義 模態對話方塊 涉及檔案 介面 wxml 樣式 wxcs

MFC對話方塊的建立及顯示

我們需要在原對話方塊CMFC_Kinect_TrackingDlg設計一個按鈕,點選這個按鈕後彈出一個非模態對話方塊Color_Based_SettingDlg, 並且同時兩個對話方塊都是啟用狀態,都可以自由操作,步驟入下: 1.在標頭檔案MFC_Kinect_Tracki

MFC建立模對話方塊和非對話方塊的方法

在MFC中對話方塊有兩種形式,一個是模態對話方塊(model dialog box),一個是非模態對話方塊(modeless dialog box)。本文對此分別簡述其建立方法。一、模態對話方塊(model dialog box)在程式執行的過程中,若出現了模態對話方塊,那麼

VS2013/MFC程式設計入門之十一(對話方塊:非對話方塊的建立及顯示)

 上一節講了模態對話方塊及其彈出過程,本節接著講另一種對話方塊--非模態對話方塊的建立及顯示。        前面已經說過,非模態對話方塊顯示後,程式其他視窗仍能正常執行,可以響應使用者輸入,還可以相互切換。本文中將上一講中建立的Tip模態對話方塊改為非模態對話方塊,讓

對話方塊對話方塊的區別

以下內容部分摘自百度百科;     Windows應用程式中,對話方塊分為兩種。另一種是模態對話方塊。二者的區別在於當對話方塊開啟時,是否允許使用者進行其他物件的操作。         詳細如下: &nbs

原生對話方塊

<!DOCTYPE html><html lang="en"><head> <meta > <title>模態框實現</title> <link rel="stylesheet" href="css\modal.css" type=