WTL的訊息機制 (轉)

gugu99發表於2007-08-15
WTL的訊息機制 (轉)[@more@]

WTL的訊息機制

/">高歌

 

一、SDI流程

Run全域性執行緒

 1、 Module.AddMessageL(&theLoop), 儲存CMessageLoop與一個執行緒id的對應,Module是全域性變數。

 2、 wndMain的構造,初始化變數

  3、  wndMain的CreateEx

  wndMain的Create

    註冊視窗類(視窗過程的地址是StartWindowProc)

    基類CframeWindowImplBase的Create:namespace prefix = o ns = "urn:schemas--com::office" />

    儲存例項的this到_module中_Module.AddCreateWndData(&m_thunk.cd, this);

 的CreateWindow

CreateWindow將觸發第一個WM_XXX訊息,從而呼叫StartWindowProc

StartWindowProc主要是初始化一個thunk程式碼,並將視窗過程修改為thunk的開始處,thunk程式碼先將堆疊中儲存HWND的位值中放入this指標,然後用jmp跳到WndProc函式進行處理

  4、呼叫wndMain.ShowWindow(nCmdShow);

  5、int nRet = theLoop.Run();

 6、_Module.RemoveMessageLoop();

執行緒結束

 

二、訊息迴圈

// theLoop.Run();

  int Run()

  {

  BOOL bDoIdle = TRUE;

  int nIdleCount = 0;

  BOOL bRet;

  for(;;)

  {

    //檢測佇列中有無訊息

while(!::PeekMessage(&m_msg, NULL, 0, 0, PM_NOREMOVE) && bDoIdle)

  {

    if(!OnIdle(nIdleCount++))

      bDoIdle = FALSE;

  }

  //得到訊息並從佇列中去除

    bRet = ::GetMessage(&m_msg, NULL, 0, 0);

    if(bRet == -1)

  {

    ATLTRACE2(atlTraceUI, 0, _T("::GetMessage returned -1 (error) "));

    continue;  // error, don't process

  }

    //bRet是0表示收到WM_QUIT

    else if(!bRet)

  {

    ATLTRACE2(atlTraceUI, 0, _T("CMessageLoop::Run - exiting "));

    break;    // WM_QUIT, exit message loop

  }

 

    //PreTranslateMessage遍歷CMessageFilter如果有一個則呼叫並返回TRUE

  //如果在視窗類中定義這個函式並且加入了filter他將不被髮到視窗過程中去。

  //注意這個函式是虛擬函式

    if(!PreTranslateMessage(&m_msg))

  {

    ::TranslateMessage(&m_msg);

    ::DispatchMessage(&m_msg);

  }

    if(IsIdleMessage(&m_msg))

  {

    bDoIdle = TRUE;

    nIdleCount = 0;

  }

  }

  return (int)m_msg.wParam;

  }

 

三、ProcessMessage

ProcessMessage是一個虛擬函式,由派生類中透過宏定義實現被

WndProc呼叫。

 

 

參考文章

 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10748419/viewspace-959093/,如需轉載,請註明出處,否則將追究法律責任。

相關文章