1. MFC的消息映射機制:
在每個能接收和處理消息的類中,定義一個消息和消息函數對照表,即消息映射表.在消息映射表中,消息與對應的消息處理函數指針成對出現.某個類能處理的所有消息及其對應的消息處理函數的地址都列在這個類所對應的靜態表中.當有消息需要處理時,程序只要搜索該消息靜態表,查看錶中是否含有該消息,就可知道該類能否處理此消息.如果能處理該消息,則同樣依照靜態表很容易找到並調用對應的消息處理函數.
MFC消息映射機制是針對能接受消息和處理消息的類來定義對應的消息映射表,而不是由父類來定義所有消息對應的虛函數,由子類來覆蓋其函數實現,因爲這樣做會使程序揹着一個很大的虛擬函數表的包袱運行,對內存是一種浪費.
2,類的靜態成員變量必須初始化
3,使用客戶區繪圖類一般用CClientDC,
要訪問整個窗口區域,包括框架窗口客戶區和非客戶區,桌面等用CWindowDC
CWindowDC dc(GetDesktopWindow());//這個可以畫到桌面上其它地方
4,在單文檔中view擋在MainFrame的前面。此時如果編寫針對MainFrame的mouseClick事件,將不會有反應。
5,.消息響應會在3處修改代碼,1處是在頭文件中,
//{{AFX_MSG(CDrawView)
afx_msg void OnLButtonDown(UINT nFlags,CPoint point);
afx_msg void OnLButtonUp(UINT nFlags,CPoint point);
afx_msg void OnMouseMove(UINT nFlags,CPoint point);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
另一處是cpp文件的begin MessageMap和End MessageMap之間,
BEGIN_MESSAGE_MAP(CDrawView, CView)
//{{AFX_MSG_MAP(CDrawView)
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT,CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW,CView::OnFilePrintPreview)
END_MESSAGE_MAP()
最後是要有函數實現的代碼。
void CDrawView::OnLButtonDown(UINT nFlags,CPoint point)
{
// TOD Add your message handler code hereand/or call default
m_ptOrigin=m_ptOld=point;
m_bDraw=TRUE;
CView::OnLButtonDown(nFlags, point);
}
6.畫線:定義一個成員變量保存mouseDown的點m_Point
1)API函數方法畫線用HDC
2)用CDC類成員函數畫線。此時別忘記ReleaseDC
3)用CClientDC
4)用CWindowDC,用它甚至可以整個屏幕區域畫線。
下面是上面4種方法的代碼
/*HDC hdc;
hdc=::GetDC(m_hWnd);
MoveToEx(hdc,m_ptOrigin.x,m_ptOrigin.y,NULL);
LineTo(hdc,point.x,point.y);
::ReleaseDC(m_hWnd,hdc);必須成對使用。*/
/*CDC *pDC=GetDC();
pDC->MoveTo(m_ptOrigin);
pDC->LineTo(point);
ReleaseDC(pDC);必須成對使用。*/
//CClientDC dc(this);
/*CClientDC dc(GetParent());
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);此處不需要ReleaseDC,因爲CClientDC會自動釋放DC*/
//CWindowDC dc(this);
//CWindowDC dc(GetParent());
/*CWindowDC dc(GetDesktopWindow());//此時可以在整個屏幕上畫線。
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);*/
/*CPen pen(PS_DOT,1,RGB(0,255,0));
CClientDC dc(this);
CPen *pOldPen=dc.SelectObject(&pen);
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);
dc.SelectObject(pOldPen);*/
5)用Bitmap填充所畫的矩形。
CBitmap bitmap;
bitmap.LoadBitmap(IDB_BITMAP1);
CBrush brush(&bitmap);
CClientDC dc(this);
dc.FillRect(CRect(m_ptOrigin,point),&brush);
//CBRUSH::FromHandle是靜態成員函數,所以可以用下面的方法調用。
CBrush*pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
CBrush *pOldBrush=dc.SelectObject(pBrush);
dc.Rectangle(CRect(m_ptOrigin,point));
dc.SelectObject(pOldBrush);
m_bDraw=FALSE;
6)用其它顏色畫線
CClientDC dc(this);
CPen pen(PS_SOLID,1,RGB(255,0,0));
CPen *pOldPen=dc.SelectObject(&pen);//選中紅色畫筆
if(m_bDraw==TRUE)
{
dc.SetROP2(R2_BLACK);//設置繪畫模式
dc.MoveTo(m_ptOrigin);
//dc.LineTo(point);
dc.LineTo(m_ptOld);
//dc.MoveTo(m_ptOrigin);
dc.MoveTo(m_ptOld);
dc.LineTo(point);
//m_ptOrigin=point;
m_ptOld=point;
}
dc.SelectObject(pOldPen);
7.MFC中隱式的包含了windows.h。爲什麼?
因爲在AFXV_W32.h文件中:
// This is a part of the MicrosoftFoundation Classes C++ library.
// Copyright (C) 1992-1998 MicrosoftCorporation
// All rights reserved.
在AFXWIN.h中
// Note: WINDOWS.H already included fromAFXV_W32.H
8.如何從句柄獲得對象的指針?
答FromHandle
9.類的靜態成員函數可以由類名直接調用,也可以由對象調用。可以認爲靜態成員函數並不屬於某個對象,它屬於類本身。程序運行伊始,即使沒有實例化類的對象,靜態成員函數和靜態成員變量已然有其內存空間。靜態成員函數不能訪問非靜態成員變量!靜態成員變量必須在類的外部初始化。當然如果並不打算用到靜態成員變量,此時你可以不初始它。