VC入門筆記

1.MFC框架結构

vc程序啟動過程:
第一步:构建CMyApp對象
第二步:調用WinMain,WinMain找到CMyApp對象,
第三步:執行CMyApp對象的的成員函數InitInstance,初始化框架Frame
第四步:執行Run

vc程序退出過程:
第一步:刪除CMyFrame對象
第二步:退出Run
第三步:退出WinMain
第四步:刪除CMyApp對象

MFC庫消息映射:
第一步:在.h文件中聲明函數
afx_msg void OnLButtonDown(UINT nFlags,CPoint point);
第二步:在.cpp文件中BEGIN_MESSAGE_MAP与END_MESSAGE_MAP之間聲明消息
ON_WM_LBUTTONDOWN()
第三步:在.cpp文件中實現函數
void CMyFrame::OnLButtonDown(UINT nFlags,CPoint point)
{
//
}
示例1:
新增一專案,選擇Single Document,其它都為默認,然后修改OnDraw函數如下:
void CChap3View::OnDraw(CDC* pDC)
{
 CChap3Doc* pDoc = GetDocument();
 ASSERT_VALID(pDoc);

 //加上下面這句代碼,第一個程序就完成了.
 pDC->TextOutW(30,30,_T("Hello World!"));
}

2.GDI
GDI是一個圖形設備接口,它使得開發圖形應用程序時不用考慮顯卡的類型是CGA,EGA,還是VGA,SVGA等等.對于具体的設備只需再開發相應的設備驅動程序就可以了.


設備描述表分為四种類型:顯示器型,打印机型,內存型及信息型.
應用程序不能直接訪問設備描述表,但可以通過函數調用檢取設備描述表的句柄,從而間接地訪問設備描述表.

2.1 GDI常用函數:
(1). CDC* CWnd::GetDC()
用于獲取指定窗口的工作區的顯示器設備描述表.
對于公共設備描述表,GetDC()為每一次被檢取的設備描述表指定缺省屬性.
對于私有設備場境,GetDC()保持它先前所具有的屬性不變.

當類在注冊時,如果指定有CS_CLASSDC,CS_OWNDC,CS_PARENTDC等風格,則GetDC()返回屬于CWnd類的設備場境.

CWnd::GetWindowDC()用于獲取整個窗口的設備描述表,
GetSystemMetrics()用于檢取窗口非客戶區域中各元件的几何尺寸.

(2).int ReleaseDC(CDC *pDC);
用于釋放一個設備描述表.
除非設備描述表屬于窗口類,否則在完成繪圖后,都要調用Release釋放.

(3).CDC* CWnd::BeginPaint(LPPAINTSTRUCT lpPaint);
用于為在指定窗口中畫圖作准備工作.并將畫圖的有關信息寫到PAINTSTRUCT結构中.

(4).BOOL CWnd::EndPaint(CONST PAINTSTRUCT* lpPaint);
用于結束指定窗口中的畫圖過程,返回值總是true

(5).SelectObject()
用于把一個對象選擇進設備描述表.
CPen* CDC::SelectObject(CPen* pPen);
CBrush* CDC::SelectObject(CBrush* pBrush);
virtual CFont* CDC::SelectObject(CFont* pFont);
CBitmap* CDC::SelectObject(CBitmap* pBitmap);
int CDC::SelectObject(CRgn* pRgn);

(6).BOOL CDC::DeleteObject(HGDIOBJ hObject);
用于刪除邏輯畫筆,畫刷,字体,位圖,區域或調色板的句柄.

2.2 GDI對象:
(1).畫筆
庫存畫筆:BLACK_PEN,WHITE_PEN,NULL_PEN
可使用GetStockObject()來取出庫存畫筆

創建畫筆
BOOL CPen::CreatePen(int nPenStyle,int nWidth,COLORREF crColor)
BOOL CPen::CreatePenIndirect(LPLOGPEN lpLogPen)

(2).畫刷
virtual CGdiObject* CDC::SelectStockObject(int nIndex);
用于選擇畫庫存畫刷
如:pDC->SelectStockObject(DKGRAY_BRUSH)

創建畫刷:
BOOL CBrush::CreateSolidBrush(COLORREF crColor);
BOOL CBrush::CreateHatchBrush(int nIndex,COLORREF crColor);
BOOL CBrush::CreatePatternBrush(CBitmap* pBitmap);
BOOL CBrush::CreateBrushIndirect(const LOGBRUSH* lpLogBrush);


2.3 繪制基本圖形
(1)畫點
COLORREF CDC::SetPixel(int X,int Y,COLORREF crColor);

(2)畫直線
BOOL CDC::LineTo(int nXEnd,int nYEnd);
用于從當前位置畫線到指定坐標點.
BOOL CDC::MoveTo(intX,int Y);
用于移動當前位置

(3)畫折線
BOOL CDC::Polyline(CONST POINT* lppt,int cPoints);
用于畫一條折線
BOOL CDC::PolyPolyline(CONST POINT* lppt,CONST DWORD* lpPolyPoints,DWORD cCount);
用于畫多條折線


(4)畫弧線

示例1:
新增一專案,,選擇Single Document,其它都為默認,然后修改OnDraw函數如下:
void CChap4View::OnDraw(CDC* pDC)
{
 CChap4Doc* pDoc = GetDocument();
 ASSERT_VALID(pDoc);
 if (!pDoc)
  return;

 int i=0;
 //
 //繪制一組彩色點
 //
 pDC->TextOutW(20,20,_T("Point"));
 pDC->SetPixel(100,20,RGB(255,0,0));
 pDC->SetPixel(110,20,RGB(0,255,0));
 pDC->SetPixel(120,20,RGB(0,0,255));
 pDC->SetPixel(130,20,RGB(255,255,0));
 pDC->SetPixel(140,20,RGB(255,0,255));
 pDC->SetPixel(150,20,RGB(0,255,255));
 pDC->SetPixel(160,20,RGB(0,0,0));

 //
 //繪制一組彩色線
 //
 //定義顏色表
 struct tagColor
 {
  int r,g,b; 
 }
 color[7]=
 {
  {255,0,0},
  {0,255,0},
  {0,0,255},
  {255,255,0},
  {255,0,255},
  {0,255,255},
  {0,0,0},
 };
 //定義兩個指向畫筆的指針
 CPen* pNewPen;
 CPen* pOldPen;
 for(i=0;i<7;i++)
 {
  pNewPen=new CPen;
  if(pNewPen->CreatePen(PS_SOLID,2,RGB(color[i].r,color[i].g,color[i].b)))
  {
   //把新畫筆選入設備描述表
   //同時存儲設備描述表中的原有畫筆
   pOldPen=pDC->SelectObject(pNewPen);
   //用新畫筆繪圖
   pDC->MoveTo(20,60+i*10);
   pDC->LineTo(160,60-i*10);
   //恢复設備認描述表中的原有畫筆
   pDC->SelectObject(pOldPen);
  }
  else
  {
   //出錯時給出提示
   AfxMessageBox(_T("CreatePen Error!"));
  }
  //刪除新創建的畫筆,以便再另外分配
  delete pNewPen;

 }
 //
 //用系統缺省筆繪制折線和曲線
 //
 //畫一條折線
 POINT polyline[4]={{20,190},{70,190},{20,240},{70,240}};
 pDC->Polyline(polyline,4);

 //畫多條折線,以下畫4條折線
 POINT polypolyline[9]={{95,160},{120,185},{120,250},{145,160},{120,185},
       {90,185},{150,185},{80,210},{160,210}};
 DWORD dwpolypoints[4]={3,2,2,2};
 pDC->PolyPolyline(polypolyline,dwpolypoints,4);

 //繪制貝齊爾曲線(Bezier)
 POINT polyBezier[4]={{20,310},{70,250},{110,290},{160,330}};
 pDC->PolyBezier(polyBezier,4);
 //
 //繪制圓,圓弧和橢圓
 //
 //畫圓圈線
 for(i=0;i<8;i++)
 {
  //以260,70為圓心
  pDC->Arc(260-5*i,70-5*i,260+5*i,70+5*i,260+5*i,70,260+5*i,70);
 }
 //畫圓弧線
 for(i=4;i<8;i++)
 {
  pDC->Arc(260-10*i,70-10*i,260+10*i,70+10*i,
    (int)260+10*i*cos(60*3.1415926/180),
    (int)70+10*i*sin(60*3.1415926/180),
    (int)260+10*i*cos(60*3.1415926/180),
    (int)70-10*i*sin(60*3.1415926/180));

  pDC->Arc(260-10*i,70-10*i,260+10*i,70+10*i,
    (int)260-10*i*cos(60*3.1415926/180),
    (int)70-10*i*sin(60*3.1415926/180),
    (int)260-10*i*cos(60*3.1415926/180),
    (int)70+10*i*sin(60*3.1415926/180));

 }
 //繪橢圖面
 CBrush* pNewBrush;
 CBrush* pOldBrush;
 for(i=8;i>1;i--)
 {
  pNewBrush=new CBrush;//构造畫刷,然后初始化
  if(pNewBrush->CreateSolidBrush(RGB(color[8-i].r,color[8-i].g,color[8-i].b)))
  {
   //在設備描述表中選擇新創建的畫刷
   //同時存儲設備描述表中原有畫刷
   pOldBrush =pDC->SelectObject(pNewBrush);
   //用畫刷繪橢圖
   pDC->Ellipse(260-10*i,200-5*i,260+10*i,200+5*i);
   //恢复設備描述表的原有畫刷
   pDC->SelectObject(pOldBrush);
  }
  delete pNewBrush;
 }
 //繪矩形和圓角矩形
 pDC->Rectangle(190,270,250,310);
 pDC->RoundRect(260,270,330,310,30,20);

 //繪制弧形
 pDC->Chord(360-80,70-80,360+80,70+80,
  (int)360+80*cos(60*3.1415926/180),
  (int)70+80*sin(60*3.1415926/180),
  (int)360+80*cos(30*3.1415926/180),
  (int)70-80*sin(30*3.1415926/180));
 //繪扇形
 pDC->Pie(480-80,70-80,480+80,70+80,
  (int)480+80*cos(60*3.1415926/180),
  (int)70+80*sin(60*3.1415926/180),
  (int)480+80*cos(30*3.1415926/180),
  (int)70-80*sin(30*3.1415926/180));
 //繪三角形多邊形
 POINT polygon[3]={{400,160},{430,220},{350,210}};
 pDC->Polygon(polygon,3);

 //畫任意多邊形
 int polygonpoints[2]={3,3};
 POINT polypolygon[6]={{450,120},{540,320},{480,280},{403,300},{540,320},{480,280}};
 pDC->PolyPolygon(polypolygon,polygonpoints,2);

}

3.鼠標
若想知道某個鍵被按下,可用對應有位屏蔽值与nFlags參數作按位邏輯"与"動算,所得結果若為非零,則表示鍵被按下.
如:
if(nFlags & MK_LBUTTON)
{
 AfxMessageBox("LButton is pressed down!");
}
else
{
 AfxMessageBox("LButton up!");
}
鼠標消息的處理
通過重載以下消息映射函數來完成.
OnLButtonDown(UINT nFlags,CPoint point)
{
 //檢測Ctrol和Shift是否按下
 if((wParam& VK_CONTROL) && (wParam & VK_SHIFT))
 break;
};

OnMouseMove(UINT nFlags,CPoint point)
{
}

CWnd::SetCapture();
用于捕捉鼠標
CWnd::ReleaseCapture;
用于釋放鼠標


設定光標:
當光標未被捕捉時從一個窗口移到另一個窗口,將向窗口發送WM_SETCURSOR消息
protected afx_msg BOOL OnSetCursor(CWnd* pWind,UINT nHitTest,UINT message);

例:
BOOL CChap5BView::OnSetCursor(CWnd* pWnd,UINT nHitTest,UINt message)
{
 SetCursor(AfxGetApp()->LoadCursor(IDC_CURSOR1));
 return TRUE;
}
示例1:
一個用鼠標涂鴉的程式.
第一步:在.h文件中聲明變量及函數
protected:
 bool m_bDraw;//是否繪制
public:
 afx_msg void OnLButtonDown(unsigned int nFlags, CPoint point);
 afx_msg void OnLButtonUp(unsigned int nFlags, CPoint point);
 afx_msg void OnMouseMove(unsigned int nFlags, CPoint point);
第二步:在.cpp文件中BEGIN_MESSAGE_MAP与END_MESSAGE_MAP之間添加消息
BEGIN_MESSAGE_MAP(CChap5AView, CView)
 ON_WM_LBUTTONDOWN()
 ON_WM_LBUTTONUP()
 ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()

第三步:在.cpp文件中實現如下函數
CChap5AView::CChap5AView()
{
 //在构造函數中初始化成員變量
 m_bDraw=false;
}
void CChap5AView::OnLButtonDown(unsigned int nFlags, CPoint point)
{
 //左鍵按下時,捕捉鼠標
 SetCapture();
 m_bDraw=true;
}

void CChap5AView::OnLButtonUp(unsigned int nFlags, CPoint point)
{
 //左鍵彈起時釋放鼠標
 ReleaseCapture();
 m_bDraw=false;
}

void CChap5AView::OnMouseMove(unsigned int nFlags, CPoint point)
{
 if(m_bDraw)
 {
  //取得設備描述表
  CDC* pDC=GetDC();
  pDC->SetPixel(point,RGB(0,0,0));
 }
}
示例2:改變光標形狀的程式
第一步:在.h文件中聲明成員變量及成員函數
protected:
 CPoint m_prePoint;
public:
 BOOL OnSetCursor(CWnd* pWnd,UINT nHitTest,UINT message);
 void OnLButtonUp(UINT nFlags,CPoint point);
 void OnMouseMove(UINT nFlags,CPoint point);
第二步:在.h文件中聲明消息
BEGIN_MESSAGE_MAP(CChap5BView, CView)
 ON_WM_SETCURSOR()
 ON_WM_LBUTTONUP()
 ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()

第三步:在.cpp文件中實現成員函數
CChap5BView::CChap5BView()
{
 // TODO: 在此加入建構程式碼
 m_prePoint.x=m_prePoint.y=-2;

}

BOOL CChap5BView::OnSetCursor(CWnd* pWnd,UINT nHitTest,UINT message)
{
 //需先新增一個空白的光標資料IDC_CURSOR1
 SetCursor(AfxGetApp()->LoadCursorW(IDC_CURSOR1));
 return true;
}

void CChap5BView::OnMouseMove(UINT nFlags,CPoint point)
{
 CDC* pDC=GetDC();
 //取當前客戶區大小
 CRect rect;
 GetClientRect(rect);
 //設置繪圖方式為R2_NOTXORPEN
 int nDrawMode=pDC->SetROP2(R2_NOTXORPEN);
 //覆蓋先前的光標線
 pDC->MoveTo(rect.left,m_prePoint.y);
 pDC->LineTo(rect.right,m_prePoint.y);
 pDC->MoveTo(m_prePoint.x,rect.top);
 pDC->LineTo(m_prePoint.x,rect.bottom);
 //繪制新的光標線
 pDC->MoveTo(rect.left,point.y);
 pDC->LineTo(rect.right,point.y);
 pDC->MoveTo(point.x,rect.top);
 pDC->LineTo(point.x,rect.bottom);
 //設置先前的繪圖方式
 pDC->SetROP2(nDrawMode);
 //記錄當前點,以作為下次進入MouseMove的前一個點
 m_prePoint=point;
}
//點鼠標左鍵彈出一個對話框
void CChap5BView::OnLButtonUp(UINT nFlags,CPoint point)
{
 //一個對話框,上面加了很多個按鈕,
 //當鼠標放在按鈕上時,顯示不同的光標形狀.
 CCursorDlg dlg;
 dlg.DoModal();
}
附:CCursorDlg的實現
public:
 BOOL OnSetCursor(CWnd* pWnd,UINT nHitTest,UINT message);

BEGIN_MESSAGE_MAP(CCursorDlg, CDialog)
 ON_WM_SETCURSOR()
END_MESSAGE_MAP()

BOOL CCursorDlg::OnSetCursor(CWnd* pWnd,UINT nHitTest,UINT message)
{
 //const char * nID;
 //LPWSTR  nID;
 WCHAR * nID;
 switch(pWnd->GetDlgCtrlID())
 {
 case IDC_BTN_ARROW: nID=IDC_ARROW;break;
 case IDC_BTN_IBEAM: nID=IDC_IBEAM;break;
 case IDC_BTN_WAIT: nID=IDC_WAIT;break;
 case IDC_BTN_CROSS: nID=IDC_CROSS;break;
 case IDC_BTN_UPARROW: nID=IDC_UPARROW;break;
 case IDC_BTN_SIZE: nID=IDC_SIZE;break;
 case IDC_BTN_SIZEALL: nID=IDC_SIZEALL;break;
 case IDC_BTN_ICON: nID=IDC_ICON;break;
 case IDC_BTN_SIZENWSE: nID=IDC_SIZENWSE;break;
 case IDC_BTN_SIZEWE: nID=IDC_SIZEWE;break;
 case IDC_HELP: nID=IDC_HELP;break;
 case IDC_BTN_NO: nID=IDC_NO;break;
 default:
  return CDialog::OnSetCursor(pWnd,nHitTest,message);
 }
 SetCursor(AfxGetApp()->LoadStandardCursor(nID));
 return true;
}

4.鍵盤与計時器
系統鍵經常由輸入鍵与Alt鍵組合產生,這种鍵一般由Windows系統內部直接處理,如果應用程序處理了這种擊鍵消息,則在處理完后,還應調用DefWindowProc(),以便不影響Windows對它們的處理.

可通過以下虛函數處理鍵盤消息
OnKeyDown(UINT nChar,UINT nRepCnt,UINT nFlags);
OnKeyUp(UINT nChar,UINT nRepCnt,UINT nFlags);
OnSysKeyDown(UINT nChar,UINT nRepCnt,UINT nFlags);
OnSysKeyUp(UINT nChar,UINT nRepCnt,UINT nFlags);

字符消息
當按鍵產生可見的字符時,Windows在發送鍵 盤消息的同時還發送字符消息,而有些鍵只產生鍵盤消息而不產生字符消息,如功能鍵,Shift鍵,Insert鍵,Delete鍵等.
字符消息通過以下函數來映射:
OnChar(UINT nChar,UINT nRepCnt,UINT nFlags);
OnDeadChar(UINT nChar,UINT nRepCnt,UINT nFlags);
OnSysChar(UINT nChar,UINT nRepCnt,UINT nFlags);
OnSysDeadChar(UINT nChar,UINT nRepCnt,UINT nFlags);
其中,WM_CHAR和WM_DEADCHAR是由WM_KEYDOWN消息引出的.而WM_SYSCHAR和WM_SYSDEADCHAR是由WM_SYSKEYDOWN消息引出的.

示例1:
一個鼠標點在哪,光標就移到哪,并且光標不斷閃爍,在
第一步:在.h文件中聲蝗成員變量及成員函數
protected:
 CPoint m_Position;
 bool m_bCursorOn;
 int m_nCount;

 void MoveCursor(CPoint point);
 afx_msg void OnLButtonUp(UINT nFlags,CPoint point);
 afx_msg void OnChar(UINT nChar,UINT nRepCnt,UINT nFlags);
 afx_msg void OnKeyDown(UINT nChar,UINT nRepCnt,UINT nFlags);

 afx_msg void OnTimer(UINT nIDEvent);
 BOOL Create(LPCTSTR lpszClassName,LPCTSTR lpszWindowName,
       DWORD dwStyle,const RECT& rect,
       CWnd* pParentWnd,UINT nID,
       CCreateContext* pContext);
 BOOL DestroyWindow();

第二步:

BEGIN_MESSAGE_MAP(CChap5CView, CView)
 ON_WM_LBUTTONUP()
 ON_WM_CHAR()
 ON_WM_KEYDOWN()

 ON_WM_TIMER()
END_MESSAGE_MAP()

第三步:
CChap5CView::CChap5CView()
: m_Position(0)
{
 //
 m_Position.x=40;
 m_Position.y=40;
 m_nCount=0;
 m_bCursorOn=true;

}

void CChap5CView::OnDraw(CDC* pDC)
{
 CChap5CDoc* pDoc = GetDocument();
 ASSERT_VALID(pDoc);
 if (!pDoc)
  return;

 //設置R2_NOTXORPEN繪圖方式
 int nDrawMode=pDC->SetROP2(R2_NOTXORPEN);
 //繪制輸入光標
 pDC->MoveTo(m_Position.x,m_Position.y);
 pDC->LineTo(m_Position.x,m_Position.y+16);
 //恢复先前的繪圖方式
 pDC->SetROP2(nDrawMode);
}

void CChap5CView::OnLButtonUp(UINT nFlags,CPoint point)
{
 //設置文本輸入位置
 MoveCursor(point);
}
void CChap5CView::OnChar(UINT nChar,UINT nRepCnt,UINT nFlags)
{
 //將數字轉化為字符串
 //char tbuf[20];
 //sprintf(tbuf,"%c",nChar);

 //一定要顯式轉換
 CString tbuf;
 tbuf+=(char)nChar;

 CDC* pDC=GetDC();
 pDC->TextOutW(m_Position.x+1,m_Position.y,tbuf);
 CSize size=pDC->GetTextExtent(tbuf);//取輸出字符串的大小范圍
 CPoint point=m_Position+CPoint(size.cx+1,0);
 MoveCursor(point);

}
void CChap5CView::OnKeyDown(UINT nChar,UINT nRepCnt,UINT nFlags)
{
 CPoint point;
 switch(nChar)
 {
 case VK_LEFT://向左
  point=m_Position+CPoint(-20*nRepCnt,0);
  MoveCursor(point);
  break;
 case VK_RIGHT://向右
  point=m_Position+CPoint(20*nRepCnt,0);
  MoveCursor(point);
  break;
 case VK_UP://向上
  point=m_Position+CPoint(0,-20*nRepCnt);
  MoveCursor(point);
  break;
 case VK_DOWN://向下
  point=m_Position+CPoint(0,20*nRepCnt);
  MoveCursor(point);
  break;
 default:
  break;


 }
}
void CChap5CView::MoveCursor(CPoint point)
{
 /*CDC* pDC=GetDC();

 //設置R2_NOTXORPEN繪圖方式
 int nDrawMode=pDC->SetROP2(R2_NOTXORPEN);
 //覆蓋先前的光標線
 pDC->MoveTo(m_Position.x,m_Position.y);
 pDC->LineTo(m_Position.x,m_Position.y+16);
 //繪制新的光標線
 m_Position =point;
 pDC->MoveTo(m_Position.x,m_Position.y);
 pDC->LineTo(m_Position.x,m_Position.y+16);
 //恢复先前的繪圖方式
 pDC->SetROP2(nDrawMode);*/

 CDC* pDC=GetDC();

 //設置R2_NOTXORPEN繪圖方式
 int nDrawMode=pDC->SetROP2(R2_NOTXORPEN);
 if(m_bCursorOn)
 {
  //覆蓋先前的光標線
  pDC->MoveTo(m_Position.x,m_Position.y);
  pDC->LineTo(m_Position.x,m_Position.y+16);
 }
 else
 {
  m_bCursorOn=true;
 }
 //繪制新的光標線
 m_Position =point;
 pDC->MoveTo(m_Position.x,m_Position.y);
 pDC->LineTo(m_Position.x,m_Position.y+16);
 //恢复先前的繪圖方式
 pDC->SetROP2(nDrawMode);

}
void CChap5CView::OnTimer(UINT nIDEvent)
{
 CDC* pDC=GetDC();
 switch(nIDEvent)
 {
 case 1://標識為1的計時器
  {
  m_bCursorOn=!m_bCursorOn;
  //設置R2_NOTXORPEN繪圖方式
  int nDrawMode=pDC->SetROP2(R2_NOTXORPEN);
  //覆蓋先前的光標線
  pDC->MoveTo(m_Position.x,m_Position.y);
  pDC->LineTo(m_Position.x,m_Position.y+16);
  pDC->SetROP2(nDrawMode);
  }
  break;
 case 2://標識為2的計時器
  {
  //char tbuf[20];
  //m_nCount+;
  //sprintf(tbuf,"%d",m_nCount);
  CString tbuf;
  tbuf=(char)m_nCount;
  pDC->TextOutW(20,20,tbuf);
  }
  break;
 default:
  break;
 }
}
BOOL CChap5CView::Create(LPCTSTR lpszClassName,LPCTSTR lpszWindowName,
       DWORD dwStyle,const RECT& rect,
       CWnd* pParentWnd,UINT nID,
       CCreateContext* pContext)
{
 int ret=CWnd::Create(lpszClassName,lpszWindowName,dwStyle,rect,pParentWnd,nID,pContext);
 //申請兩個計時器,標識為別為1,2,間隔時間分別為500,1000
 ASSERT(SetTimer(1,500,NULL)!=0);
 ASSERT(SetTimer(2,1000,NULL)!=0);
 return ret;

}

BOOL CChap5CView::DestroyWindow()
{
 //使計時器1和2停止傳送WM_TIMER消息
 KillTimer(1);
 KillTimer(2);
 return CView::DestroyWindow();
}


5.菜單
SDI程序的命令傳遞順序為:
視->文檔->SDI主框架窗口->應用程序
MDI程序的命令傳遞順序為:
視->文檔->MDI子框架窗口->MDI主框架窗口應用程序.

消息處理命令:
在視類頭文件中添加函數聲明:
afx_msg void OnEditCut();
在實現文件中:
BEGIN_MESSAGE_MAP(CTestView,CView)
ON_COMMAND(ID_EDIT_CUT,OnEditCut)
END_MESSAGE_MAP()
void CTestView::OnEditCut()
{

}

更新命令用戶接口(UI)消息
在視類頭文件中添加函數聲明:
afx_msg void OnUpdateEditCut(CCmdUI* pCmdUI);
在實現文件中:
BEGIN_MESSAGE_MAP(CTestView,CView)
ON_UPDATE_COMMAND_UI(ID_EDIT,OnUpdateEditCut)
END_MESSAGE_MAP()

void CTestView::OnUpdateEditCut(CCmdUI* pCmdUI)
{
 //更新
 pCmdUI->Enable(m_bHaveData);
}

擴展命令和范圍命令的處理
ON_COMMAND_EX(id1,memberFnx)
ON_COMMAND_EX(id2,memberFnx)

ON_COMMAND_RANGE(id1,id2,memberFnx)
ON_UPDATE_COMMAND_UI_RANGE(id1,id2,UpdatememberFnx)

ClassWizard不支持擴展命令消息和范圍命令消息.這些消息要放在//{{AFX_MSG_MAP和//{{AFX_MSG_MAP括號對之外.
程序員必須自已編寫消息映射.

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值