• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆 - 47, 文章 - 10, 評(píng)論 - 8, 引用 - 0
            數(shù)據(jù)加載中……

            孫鑫VC++講座筆記-(4)MFC消息映射機(jī)制的剖析

            1,消息響應(yīng)函數(shù):(例:在CDrawView類(lèi)響應(yīng)鼠標(biāo)左鍵按下消息)
            ?1)在頭文件(DrawView.h)中聲明消息響應(yīng)函數(shù)原型。
            1//{{AFX_MSG(CDrawView)???//注釋宏
            2afx_msg?void?OnLButtonDown(UINT?nFlags,?CPoint?point);
            3//}}AFX_MSG???//注釋宏
            說(shuō)明:
            在注釋宏之間的聲明在VC中灰色顯示。afx_msg宏表示聲明的是一個(gè)消息響應(yīng)函數(shù)。
            ?2)在源文件(DrawView.cpp)中進(jìn)行消息映射。
            1BEGIN_MESSAGE_MAP(CDrawView,?CView)
            2?//{{AFX_MSG_MAP(CDrawView)
            3?ON_WM_LBUTTONDOWN()
            4?//}}AFX_MSG_MAP
            5?//?Standard?printing?commands
            6?ON_COMMAND(ID_FILE_PRINT,?CView::OnFilePrint)
            7?ON_COMMAND(ID_FILE_PRINT_DIRECT,?CView::OnFilePrint)
            8?ON_COMMAND(ID_FILE_PRINT_PREVIEW,?CView::OnFilePrintPreview)
            9END_MESSAGE_MAP()
            說(shuō)明:
            在宏BEGIN_MESSAGE_MAP()與END_MESSAGE_MAP()之間進(jìn)行消息映射。
            宏ON_WM_LBUTTONDOWN()把消息WM_LBUTTONDOWN與它的響應(yīng)函數(shù)OnLButtonDown()相關(guān)聯(lián)。這樣一旦有消息的產(chǎn)生,就會(huì)自動(dòng)調(diào)用相關(guān)聯(lián)的消息響應(yīng)函數(shù)去處理。
            宏ON_WM_LBUTTONDOWN()定義如下:
            1#define?ON_WM_LBUTTONDOWN()?\
            2?{?WM_LBUTTONDOWN,?0,?0,?0,?AfxSig_vwp,?\
            3??(AFX_PMSG)(AFX_PMSGW)(void?(AFX_MSG_CALL?CWnd::*)(UINT,?CPoint))&OnLButtonDown?}
            ,
            4?3)源文件中進(jìn)行消息響應(yīng)函數(shù)處理。(DrawView.cpp中自動(dòng)生成OnLButtonDown函數(shù)輪廓,如下)
            5void?CDrawView::OnLButtonDown(UINT?nFlags,?CPoint?point)?
            6{
            7?//?TODO:?Add?your?message?handler?code?here?and/or?call?default
            8?CView::OnLButtonDown(nFlags,?point);
            9}
            說(shuō)明:
            可見(jiàn)當(dāng)增加一個(gè)消息響應(yīng)處理,在以上三處進(jìn)行了修改。可在消息響應(yīng)函數(shù)里添加消息處理代碼完成對(duì)消息的響應(yīng)、處理。

            2,消息響應(yīng)的方式:
            1)在基類(lèi)中針對(duì)每種消息做一個(gè)虛函數(shù),當(dāng)子類(lèi)對(duì)消息響應(yīng)時(shí)候,只要在子類(lèi)中重寫(xiě)這個(gè)虛函數(shù)即可。缺點(diǎn):MFC類(lèi)派生層次很多,如果在基類(lèi)對(duì)每個(gè)消息進(jìn)行虛函數(shù)處理,那么從基類(lèi)派生的每個(gè)子類(lèi)都將背負(fù)一個(gè)龐大的虛表,這樣浪費(fèi)內(nèi)存,故MFC沒(méi)有采取這中方式而采取消息映射方式。
            2)消息映射方式:MFC在后臺(tái)維護(hù)了一個(gè)句柄和C++對(duì)象指針對(duì)照表,當(dāng)收到一個(gè)消息后,通過(guò)消息結(jié)構(gòu)里資源句柄(查對(duì)照表)就可找到與它對(duì)應(yīng)的一個(gè)C++對(duì)象指針,然后把這個(gè)指針傳給基類(lèi),基類(lèi)利用這個(gè)指針調(diào)用WindowProc()函數(shù)對(duì)消息進(jìn)行處理,WindowProc()函數(shù)中調(diào)用OnWndMsg()函數(shù),真正的消息路由及處理是由OnWndMsg()函數(shù)完成的。由于WindowProc()和OnWndMsg()都是虛函數(shù),而且是用派生類(lèi)對(duì)象指針調(diào)用的,由多態(tài)性知最總終調(diào)用子類(lèi)的。在OnWndMsg()函數(shù)處理的時(shí)候,根據(jù)消息種類(lèi)去查找消息映射,判斷所發(fā)的消息有沒(méi)有響應(yīng)函數(shù),具體方式是到相關(guān)的頭文件和源文件中尋找消息響應(yīng)函數(shù)聲明(從注釋宏//{{AFX_MSG(CDrawView)...//}}AFX_MSG之間尋找),消息映射(從宏BEGIN_MESSAGE_MAP(...)....END_MESSAGE_MAP()之間尋找),最終找到對(duì)應(yīng)的消息處理函數(shù)。當(dāng)然,如果子類(lèi)中沒(méi)有對(duì)消息進(jìn)行處理,則消息交由基類(lèi)處理。
            說(shuō)明:

            1virtual?LRESULT?WindowProc(UINT?message,?WPARAM?wParam,?LPARAM?lParam);
            2virtual?BOOL?OnWndMsg(UINT?message,?WPARAM?wParam,?LPARAM?lParam,?LRESULT*?pResult);

            二,有關(guān)繪圖

            1,使用SDK獲取DC句柄:

            1HDC?hdc;
            2hdc=::GetDc(m_hWnd);//獲取DC句柄
            3MoveToEx(hdc,m_ptOrigin.x,m_ptOrigin.y,NULL);
            4LineTo(hdc,point.x,point.y);
            5::ReleaseDC(m_hWnd,hdc);//釋放DC

            2,利用CDC類(lèi)指針和CWin類(lèi)成員函數(shù)獲取DC。
            1CDC?*pDC=GetDC();
            2pDC->MoveTo(m_ptOrigin);
            3pDC->LineTo(point);
            4ReleaseDC(pDC);
            3,利用CClientDC對(duì)象。(CClientDC類(lèi)從CDC類(lèi)派生來(lái)的)
            1CClientDC?dc(this);
            2dc.MoveTo(m_ptOrigin);
            3dc.LineTo(point);
            說(shuō)明:
            The CClientDC class is derived from CDC and takes care of calling the Windows functions GetDC at construction time and ReleaseDC at destruction time. This means that the device context associated with a CClientDC object is the client area of a window.
            4,利用CWindowDC對(duì)象。(CWindowDC類(lèi)從CDC類(lèi)派生來(lái)的)
            1CWindowDC?dc(this);//
            2dc.MoveTo(m_ptOrigin);
            3dc.LineTo(point);
            說(shuō)明:
            The CWindowDC class is derived from CDC. It calls the Windows functionsGetWindowDC at construction time andReleaseDC at destruction time. This means that a CWindowDC object accesses the entire screen area of a CWnd (both client and nonclient areas).

            5,GetParent()得到父窗口指針;GetDesktopWindow()得到屏幕窗口指針。

            6,利用畫(huà)筆改變線(xiàn)條顏色和類(lèi)型:

            1CPen?pen(PS_DOT,1,RGB(0,255,0));//構(gòu)造畫(huà)筆對(duì)象
            2CClientDC?dc(this);CPen?*pOldPen=dc.SelectObject(&pen);//將畫(huà)筆選入DC
            3dc.MoveTo(m_ptOrigin);
            4dc.LineTo(point);
            5dc.SelectObject(pOldPen);//恢復(fù)先前的畫(huà)筆

            7,使用畫(huà)刷(通常利用畫(huà)刷去填充矩形區(qū)域):
            ?1//使用單色畫(huà)刷
            ?2CBrush?brush(RGB(255,0,0));//構(gòu)造畫(huà)刷對(duì)象
            ?3CClientDC?dc(this);
            ?4dc.FillRect(CRect(m_ptOrigin,point),&brush);//用指定的畫(huà)刷去填充矩形區(qū)域
            ?5
            ?6//使用位圖畫(huà)刷
            ?7CBitmap?bitmap;//構(gòu)造位圖對(duì)象(使用前需要初試化)
            ?8bitmap.LoadBitmap(IDB_BITMAP1);//初試化位圖對(duì)象
            ?9CBrush?brush(&bitmap);//構(gòu)造位圖畫(huà)刷
            10CClientDC?dc(this);
            11dc.FillRect(CRect(m_ptOrigin,point),&brush);//用指定的位圖畫(huà)刷去填充矩形區(qū)域
            12
            13//使用透明畫(huà)刷
            14CBrush?*pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));//獲取透明畫(huà)刷對(duì)象指針
            15CClientDC?dc(this);
            16CBrush?*pOldBrush=dc.SelectObject(pBrush);//將透明畫(huà)刷選入DC
            17dc.Rectangle(CRect(m_ptOrigin,point));
            18dc.SelectObject(pOldBrush);//釋放透明畫(huà)刷
            19
            20

            說(shuō)明:
            The GetStockObject function retrieves a handle to one of the predefined stock pens, brushes, fonts, or palettes.
            HGDIOBJ GetStockObject(
            ? int fnObject?? // type of stock object
            );

            Returns a pointer to a CBrush object when given a handle to a Windows HBRUSH object.
            static CBrush* PASCAL FromHandle( HBRUSH hBrush );//FromHandle是一個(gè)靜態(tài)方法,故可用CBrush::FromHandle()形式調(diào)用。
            注意點(diǎn):
            1)靜態(tài)方法不屬于某一個(gè)具體對(duì)象,而屬于類(lèi)本身,在類(lèi)加載的時(shí)候就已經(jīng)為類(lèi)靜態(tài)方法分配了代碼去,故可用CBrush::FromHandle()形式調(diào)用。
            2)靜態(tài)方法中,不能引用非靜態(tài)的數(shù)據(jù)成員和方法。
            3)靜態(tài)數(shù)據(jù)成員需要在類(lèi)外單獨(dú)做初始化,形式如: 變量類(lèi)型 類(lèi)名::變量名=初始值;

            8,CDC::SetROP2方法:
            int SetROP2( int nDrawMode );
            Sets the current drawing mode.

            posted on 2006-04-04 11:08 編程之道 閱讀(183) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): C/C++

            亚洲中文字幕伊人久久无码| 午夜精品久久久久久影视riav| 久久精品国产亚洲AV高清热| 91精品国产91久久综合| 国产精品热久久毛片| 亚洲午夜久久久影院| 爱做久久久久久| 久久久久亚洲AV无码网站| 国产高清国内精品福利99久久| 亚洲精品无码久久久久去q| 中文字幕久久欲求不满| 狠狠色婷婷久久综合频道日韩| 精品国产综合区久久久久久| 三上悠亚久久精品| 性做久久久久久免费观看| 久久青青草原亚洲av无码app | 久久亚洲中文字幕精品一区四| 午夜精品久久久久久99热| 天天影视色香欲综合久久| 97超级碰碰碰碰久久久久| 亚洲国产另类久久久精品| 欧美久久一级内射wwwwww.| 久久精品成人免费看| 国产精品无码久久综合| 国产亚洲精久久久久久无码77777| 久久久久久久久久免免费精品| 四虎国产精品免费久久久| 精品国际久久久久999波多野| 中文字幕乱码人妻无码久久| 欧美日韩精品久久久久| 久久综合鬼色88久久精品综合自在自线噜噜 | 久久人人爽人人爽人人AV东京热 | 亚洲va久久久噜噜噜久久男同 | 亚洲精品乱码久久久久久| 偷偷做久久久久网站| 久久精品国产清自在天天线| 性做久久久久久久久| 久久久无码精品亚洲日韩京东传媒| 热久久国产欧美一区二区精品| 99久久精品久久久久久清纯| 国产精品久久久天天影视香蕉|