日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

深入浅出MFC学习笔记(第三章:MFC六大关键技术之仿真:命令传递) .

發布時間:2023/12/9 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深入浅出MFC学习笔记(第三章:MFC六大关键技术之仿真:命令传递) . 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

命令傳遞(Command?routing

?????消息如果是僅僅從派生類流向父類,那就非常簡單了。然而MFC用來處理消息的C++類,并不是單線發展的。document/view也具有處理消息的能力。因此,消息應該有橫向流動的機會。

?????MFC對消息循環的規定為:

????1:若是一般的windows消息(WM_xx)則一定是由派生類流向基類。

????2:如果是WM_COMMAND消息,就非常復雜了。要區分接受者的類型:

??????1:接受者若為Frame窗口:處理次序為:View->?Frame窗口本身->CWinApp類。

??2:接受者若為View?:處理次序為:View本身->Document;

??3:接受者若為Document:處理次序為:Document本身->Document?template

????因此,接下來我們的任務就是仿真以上的消息傳遞路線。

????以下為需要添加的函數:

????全局函數AfxWndProc,它是整個消息循環的起始點,本來應該在CWinThread::Run中被調用,每調用一次就推送一個消息。模擬windows的disPatch函數。

?LRESULT?AfxWndPro(HWND?hWnd,UINT?nMsg,WPARAM??

????????????????????????wParam,LPARAM?lParam,CWnd?*pWnd)

{

???cout<<"AfxWndProc()"<<endl;

???return??AfxCallWndProc?(pWnd,hWnd,nMsg,wParam,lParam);

}

LRESULT?AfxCallWndProc(CWnd*pWnd,HWND?hWnd,UINT?nMsg,

????????????????????????????WPARAM?wParam,LPARAM?lParam)

{

???cout<<"AfxCallWndProc"<<endl;

LRESULT?lResult=pWnd->windowProc(nMsg,wParam,lParam);

return?lResult;

}

全局函數AfxCallWndProc用于調用接受消息的類的消息處理函數。pWnd->WindowProc調用哪個函數,取決于pWnd指向的對象類型。

如果pWnd指向CMyFrameWnd對象,則調用CFrameWnd::WindowProc。因為CFrameWnd斌沒有改寫WindowProc,因此調用的是CWnd::WindowProc。。

????如果pWnd指向CMyView對象,那么調用CView::windowProc。而CMyView沒有改寫WIndowProc所以調用的是CWnd::WindowProc

????在CWnd::windowProc中,首先判斷消息是否為WM_COMMAND消息,

????如不是,則傳遞給父類進行處理。

????如果是WM_COMMAND消息,CWnd::windowProc調用OnCommand。此函數為虛函數。有以下幾種情況:

???????1:如果this指向CMyFrameWnd對象,則調用的是CFrameWnd::OnComamnd

???????2:如果this指向CMyView對象,那么調用的是CView::OnCommand。因為CView并沒有改寫OnComamnd所以調用的是CWnd::OnCommand

bool?CFrameWnd::OnComamnd(WPARAM?wParam,LPARAM?lParam)

{

???cout<<"CFrameWnd::OnCommand()"<<endl;

???return?CWnd::OnCommand(wParam,lParam);

}

bool?CWnd::OnComamnd(WPARAM?wParam,LPARAM?lParam)

{

???cout<<"CWnd::OnComamnd()"<<endl;

???return?OnCmdMsg(0,0);

}

????OnCmdMsg仍然是虛函數,

????1:如果this指向CMyFrameWnd對象,那么調用的是CFrameWnd::OnCmdMsg

????2:如果this指向CMyView對象,則調用CView::OnCmdMsg

????3:如果this指向CMyDoc對象,則調用CDocument::OnCmdMsg

4:如果this指向CMWinApp對象,則調用CWinApp::??nCmdMsg。因為CWinApp沒有改寫OnCmdMsg因此調用的是CCmdTarget::OnCmdMsg

Bool?CFrameWnd::OnCmdMsg(UINT?nID,int?nCode)
{

cout<<"CFrameWnd::OnCmdMsg()"<<endl;

CView*pView=GetActiveView();

if(pView->OnCmdMsg(nID,nCode))//處理則返回否則繼續傳遞。

???return?true;

if(CWnd::OnCmdMsg(nID,nCode))

??return?true;

CWinApp*pApp=AfxGetApp();

if(pApp->OnCmdMsg(nID,nCode)

???return?true;

return?fasle;

}

bool?CView::OnCmdMsg(UINT?nID,int?nCode)

{

??cout<<"CView::OnCmdMsg()"<<endl;

???if(CWnd::OnCmdMsg(nID,nCode))

?????return?true;

???bool?bHandled=false;

???bHandled=m_pDocument->OnCmdMsg(nID,nCode);

???return?bHandled;

}

Bool?CDocument::OnCmdMsg(UINT?nID,int?nCode)

{

????cout<<"CDocument::OnCmdMsg()"<<endl;

????if(CCmdTarget::OnCmdMsg(nID,nCode))

?????return?true;

????return?false;

}

?????真正的消息傳遞路徑是從OnCmdMsg開始的。在每個類的OnCmdMsg函數中,會調用其他類的OnCmdMsg函數,從而決定每個消息的傳遞路徑。

?????如果消息在前一個OnCmdMsg中被處理,就不會繼續傳遞。如果沒有被處理,則會繼續沿著路徑傳遞下去。無論如何,最終消息的比對是在CCmdTarget類中進行的,只是調用GetMessageMapthis指針不同,會決定調用哪個類的消息映射表。理解這一點很重要!!!

bool?CCmdTarget::OnCmdMsg(UINT?nID,int?nCode)

{

???cout<<"CCmdTarget::OnCmdMsg()"<<endl;

???for(pMessageMap=GetMessageMap();pMessageMap;

?????????????pMessageMap=pMessageMap->pBaseMessageMap()

????{

???????If(找到)

?????????//執行消息處理函數。

????}

}

總結

以上是生活随笔為你收集整理的深入浅出MFC学习笔记(第三章:MFC六大关键技术之仿真:命令传递) .的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。