chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

電子發(fā)燒友App

硬聲App

掃碼添加小助手

加入工程師交流群

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示
創(chuàng)作
電子發(fā)燒友網(wǎng)>電子資料下載>嵌入式開發(fā)>MFC中Windows消息處理機(jī)制解析

MFC中Windows消息處理機(jī)制解析

2017-11-07 | rar | 0.2 MB | 次下載 | 1積分

資料介紹

Windows程序和DOS程序的主要不同點(diǎn)之一是:Windows程序是以事件為驅(qū)動、消息機(jī)制為基礎(chǔ)
  本人對Windows系統(tǒng)、MFC談不上有深入的了解,但對MFC本身包裝API的機(jī)制很有興趣,特別是讀了候老師的《深入淺出MFC》后,感覺到Visual C++的Application FrameWork十分精制。在以前,我對SDI結(jié)構(gòu)處理消息有一定的認(rèn)識,但對于模式對話框的消息機(jī)制不了解,讀了《深入》一書也沒能得到解決,近日,通過在網(wǎng)友的幫助和查閱MSDN,自認(rèn)為已經(jīng)了解。一時興起,寫下這些文字,沒有其它目的,只是希望讓后來者少走彎路,也希望和我一樣 喜歡“鉆牛角尖”的人共同討論、學(xué)習(xí)。如果你是牛人,那么你現(xiàn)在要慎重考慮有沒有充足的時間讀這些幼稚文字。
  正文:
  Windows程序和DOS程序的主要不同點(diǎn)之一是:Windows程序是以事件為驅(qū)動、消息機(jī)制為基礎(chǔ)。如何理解?
  舉了例子,當(dāng)你CLICK Windows “開始”BUTTON時,為什么就會彈出一個菜單呢?
  當(dāng)你單擊鼠標(biāo)左鍵時,操作系統(tǒng)中與MOUSE相關(guān)的驅(qū)動程序在第一時間內(nèi)得到這個信號[LBUTTONDOWN],然后它通知操作系統(tǒng)―――“嗨,鼠標(biāo)左鍵被單擊了!”,操作系統(tǒng)得到這一信號后,馬上要判斷――用戶單擊鼠標(biāo)左鍵,這是針對哪個窗口呢?如何判斷?這很簡單!當(dāng)前狀態(tài)中,具有焦點(diǎn)的窗口[或控件]就是了[這里當(dāng)然是“開始”BUTTON了]。然后操作系統(tǒng)馬上向這個窗口發(fā)送一條消息到這個窗口所在進(jìn)程的消息隊列,消息內(nèi)容應(yīng)是消息本身的代號、附加參數(shù)、窗口句柄…等等了。那么,只有操作系統(tǒng)才有資格發(fā)送消息至某一窗口的消息隊列嗎?不然,其它程序也有資格。你可以在你的程序中調(diào)用:SendMessage、PostMessage。這樣,被單擊的窗口得到了一條由操作系統(tǒng)發(fā)送的包含CLICK的消息,操作系統(tǒng)已經(jīng)暫時不再管窗口的任何事,因為它還要忙于處理其它事務(wù)。你的程序得到一條消息后如何做呢?Windows對于你在“開始”BUTTON上的單擊事件做出如下反映:彈出一菜單??墒?,得到消息到做出反映這一過程是如何實現(xiàn)的呢?這就是本文討論的主要內(nèi)容[當(dāng)然只是針對MFC了]。
  我首先簡要談一下SDI,然后會花更多文字描述模式對話框。
  對于SDI窗口,你的應(yīng)用程序類的InitInstance()大約如下:
  BOOL CEx06aApp::InitInstance()
  {
  ……………
  CSingleDocTemplate* pDocTemplate;
  pDocTemplate = new CSingleDocTemplate(
  IDR_MAINFRAME,
  RUNTIME_CLASS(CEx06aDoc),
  RUNTIME_CLASS(CMainFrame), // main SDI frame window
  RUNTIME_CLASS(CEx06aView));
  AddDocTemplate(pDocTemplate);
  CCommandLineInfo cmdInfo;
  ParseCommandLine(cmdInfo);
  if (!ProcessShellCommand(cmdInfo))
  return FALSE;
  m_pMainWnd-》ShowWindow(SW_SHOW);
  m_pMainWnd-》UpdateWindow();
  return TRUE;
  }
  完成一些如動態(tài)生成相關(guān)文檔、視,顯示主框架窗口、處理參數(shù)行信息等工作。這些都是顯示在你工程中的“明碼”。我們現(xiàn)在把斷點(diǎn)設(shè)置到return TRUE;一句,跟入MFC源碼中,看看到底MFC內(nèi)部做了什么。
  程序進(jìn)入SRCWinMain.cpp,下一個大動作應(yīng)是:
  nReturnCode = pThread-》Run();
  注意了,重點(diǎn)來了。F11進(jìn)入
  int CWinApp::Run()
  {
  if (m_pMainWnd == NULL && AfxOleGetUserCtrl())
  {
  // Not launched /Embedding or /Automation, but has no main window!
  TRACE0(“Warning: m_pMainWnd is NULL in CWinApp::Run - quitting application. ”);
  AfxPostQuitMessage(0);
  }
  return CWinThread::Run();
  }
  再次F11進(jìn)入:
  int CWinThread::Run()
  {
  ASSERT_VALID(this);
  // 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 && ?。海篜eekMessage(&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))
  {
  bIdle = TRUE;
  lIdleCount = 0;
  }
  } while (::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE));
  }
  ASSERT(FALSE); // not reachable
  }
  BOOL CWinThread::IsIdleMessage(MSG* pMsg)
  {
  // Return FALSE if the message just dispatched should _not_
  // cause OnIdle to be run. Messages which do not usually
  // affect the state of the user interface and happen very
  // often are checked for.
  // redundant WM_MOUSEMOVE and WM_NCMOUSEMOVE
  if (pMsg-》message == WM_MOUSEMOVE || pMsg-》message == WM_NCMOUSEMOVE)
  {
  // mouse move at same position as last mouse move?
  if (m_ptCursorLast == pMsg-》pt && pMsg-》message == m_nMsgLast)
  return FALSE;
  m_ptCursorLast = pMsg-》pt; // remember for next time
  m_nMsgLast = pMsg-》message;
  return TRUE;
  }
  // WM_PAINT and WM_SYSTIMER (caret blink)
  return pMsg-》message != WM_PAINT && pMsg-》message != 0x0118;
  }
  這是SDI處理消息的中心機(jī)構(gòu),但請注意,它覺對不是核心!
  分析一下,在無限循環(huán)FOR內(nèi)部又出現(xiàn)一個WHILE循環(huán)
  while (bIdle &&
 ?。。海篜eekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE))
  {
  // call OnIdle while in bIdle state
  if (!OnIdle(lIdleCount++))
  bIdle = FALSE; // assume “no idle” state
  }
  這段代碼是當(dāng)你程序進(jìn)程的消息隊列中沒有消息時,會調(diào)用OnIdle做一些后備工作,臨時對象在這里被刪除。當(dāng)然它是虛函數(shù)。其中的PeekMessage,是查看消息隊列,如果有消息返回TRUE,如果沒有消息返回FALSE,這里指定PM_NOREMOVE,是指查看過后不移走消息隊列中剛剛被查看
  到的消息,也就是說這里的PeekMessage只起到一個檢測作用,顯然返回FALSE時[即沒有消息],才會進(jìn)入循環(huán)內(nèi)部,執(zhí)行OnIdle,當(dāng)然了,你的OnIdle返回FLASE,會讓程序不再執(zhí)行OnIdle。你可能要問:
  當(dāng)bidle=0或消息隊例中有消息時,程序又執(zhí)行到哪了呢?
  do
  {
  // pump message, but quit on WM_QUIT
  if (!PumpMessage())
  return ExitInstance();
  // reset “no idle” state after pumping “normal” message
  if (IsIdleMessage(&m_msgCur))
  {
  bIdle = TRUE;
  lIdleCount = 0;
  }
  } while (::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE));
  看啊,又進(jìn)入一個循環(huán)!
  其中有個重要的函數(shù),PumpMessage,內(nèi)容如下:
  BOOL CWinThread::PumpMessage()
  {
  ASSERT_VALID(this);
  if (!::GetMessage(&m_msgCur, NULL, NULL, NULL))
  {
  #ifdef _DEBUG
  if (afxTraceFlags & traceAppMsg)
  TRACE0(“CWinThread::PumpMessage - Received WM_QUIT. ”);
  m_nDisablePumpCount++; // application must die
  // Note: prevents calling message loop things in ’ExitInstance’
  // will never be decremented
  #endif
  return FALSE;
  }
  #ifdef _DEBUG
  if (m_nDisablePumpCount != 0)
  {
  TRACE0(“Error: CWinThread::PumpMessage called when not permitted. ”);
  ASSERT(FALSE);
  }
  #endif
  #ifdef _DEBUG
  if (afxTraceFlags & traceAppMsg)
  _AfxTraceMsg(_T(“PumpMessage”), &m_msgCur);
  #endif
  // process this message
  if (m_msgCur.message != WM_KICKIDLE && !PreTranslateMessage(&m_msgCur))
  {
 ?。海篢ranslateMessage(&m_msgCur);
 ?。海篋ispatchMessage(&m_msgCur);
  }
  return TRUE;
  }
  如你所想,這才是MFC消息處理的核心基地[也是我個人認(rèn)為的]。
  GetMessage不同于PeekMessae,它是不得到消息不罷體,PeekMessage如果發(fā)現(xiàn)消息隊列中沒有消息會返回0,而GetMessage如果發(fā)現(xiàn)沒有消息,等,直到有了消息,而且,GetMessage不同于PeekMessage,它會將消息移走[當(dāng)然,PeekMessage也可以做到這點(diǎn)]。我想當(dāng)你讀了這個函數(shù)后,
  你應(yīng)明白PreTranslateMessage函數(shù)的用法了吧[我比較喜歡在程序中充分利用這個函數(shù)]。
 ?。海篢ranslateMessage(&m_msgCur);
 ?。海篋ispatchMessage(&m_msgCur);
  將消息發(fā)送到窗口的處理函數(shù)[它是由窗口類指定的],之后的動作一直到你的程序做出反映的過程,你可以在《深入》一書中得到完美的解釋。我們還是通過reurn
  TRUE;回到CWinThread::Run()中的Do{}while;循環(huán)。然后還是對IDLE的處理,即便剛才你的ONIDLE返回了FALSE,在這里你看到,你的程序還是有機(jī)會執(zhí)行它的。然后又是利用PeekMessage檢測消息隊列:
  如果有消息[這個消息不被移動的原因是因為它要為PumpMessage內(nèi)的GetMessage所利用。]再次進(jìn)入PumpMessage[叫它“消息泵”吧]。
  如果沒有消息,退出DO循環(huán),但它還在FOR內(nèi)部,所以又執(zhí)行第一個While循環(huán)。
WINDOWS mfc 消息機(jī)制
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

下載該資料的人也在下載 下載該資料的人還在閱讀
更多 >

評論

查看更多

下載排行

本周

  1. 1MDD品牌三極管BC807數(shù)據(jù)手冊
  2. 3.00 MB   |  次下載  |  免費(fèi)
  3. 2MDD品牌三極管BC817數(shù)據(jù)手冊
  4. 2.51 MB   |  次下載  |  免費(fèi)
  5. 3MDD品牌三極管D882數(shù)據(jù)手冊
  6. 3.49 MB  |  次下載  |  免費(fèi)
  7. 4MDD品牌三極管MMBT2222A數(shù)據(jù)手冊
  8. 3.26 MB  |  次下載  |  免費(fèi)
  9. 5MDD品牌三極管MMBTA56數(shù)據(jù)手冊
  10. 3.09 MB  |  次下載  |  免費(fèi)
  11. 6MDD品牌三極管MMBTA92數(shù)據(jù)手冊
  12. 2.32 MB  |  次下載  |  免費(fèi)
  13. 7STM32G474 HRTIME PWM 丟波問題分析與解決
  14. 1.00 MB   |  次下載  |  3 積分
  15. 8新能源電動汽車高壓線束的銅鋁連接解決方案
  16. 2.71 MB   |  次下載  |  2 積分

本月

  1. 1愛華AIWA HS-J202維修手冊
  2. 3.34 MB   |  37次下載  |  免費(fèi)
  3. 2NB-IoT芯片廠商的資料說明
  4. 0.31 MB   |  22次下載  |  1 積分
  5. 3PC5502負(fù)載均流控制電路數(shù)據(jù)手冊
  6. 1.63 MB   |  22次下載  |  免費(fèi)
  7. 4H110主板CPU PWM芯片ISL95858HRZ-T核心供電電路圖資料
  8. 0.63 MB   |  6次下載  |  1 積分
  9. 5UWB653Pro USB口測距通信定位模塊規(guī)格書
  10. 838.47 KB  |  5次下載  |  免費(fèi)
  11. 6技嘉H110主板IT8628E_BX IO電路圖資料
  12. 2.61 MB   |  4次下載  |  1 積分
  13. 7蘇泊爾DCL6907(即CHK-S007)單芯片電磁爐原理圖資料
  14. 0.04 MB   |  4次下載  |  1 積分
  15. 8蘇泊爾DCL6909(即CHK-S009)單芯片電磁爐原理圖資料
  16. 0.08 MB   |  2次下載  |  1 積分

總榜

  1. 1matlab軟件下載入口
  2. 未知  |  935137次下載  |  10 積分
  3. 2開源硬件-PMP21529.1-4 開關(guān)降壓/升壓雙向直流/直流轉(zhuǎn)換器 PCB layout 設(shè)計
  4. 1.48MB  |  420064次下載  |  10 積分
  5. 3Altium DXP2002下載入口
  6. 未知  |  233089次下載  |  10 積分
  7. 4電路仿真軟件multisim 10.0免費(fèi)下載
  8. 340992  |  191439次下載  |  10 積分
  9. 5十天學(xué)會AVR單片機(jī)與C語言視頻教程 下載
  10. 158M  |  183353次下載  |  10 積分
  11. 6labview8.5下載
  12. 未知  |  81602次下載  |  10 積分
  13. 7Keil工具M(jìn)DK-Arm免費(fèi)下載
  14. 0.02 MB  |  73822次下載  |  10 積分
  15. 8LabVIEW 8.6下載
  16. 未知  |  65991次下載  |  10 積分