一、打字功能
1.加入数据成员
选择ClaView,双击CMyView,光标直接停留在类CMyView的定义处。 在类CMyView中加入如下部分: cla CMyView : public CView { protected: // create from serialization only
CMyView();
DECLARE_DYNCREATE(CMyView)
// Attributes public:
CMyDoc* GetDocument();
// Operations public: //代码编写开始
POINT Caret;
//用于存放插入符当前坐标位置 //代码编写结束 // Overrides // ClaWizard generated virtual function overrides //{{AFX_VIRTUAL(CMyView) public: virtual void OnDraw(CDC* pDC); // overridden to draw this view virtual BOOL PreCreateWindow(CREATESTRUCT& cs); protected: virtual BOOL OnPreparePrinting(CPrintInfo* pInfo); virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo); virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo); //}}AFX_VIRTUAL
// Implementation public: virtual ~CMyView(); #ifdef _DEBUG virtual void AertValid() const; virtual void Dump(CDumpContext& dc) const; #endif
protected:
1
// Generated meage map functions protected: //{{AFX_MSG(CMyView) afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; 2.加入消息:WM_CREATE (1)在“查看”菜单中选择“建立类向导”(ClaWizard)命令,打开MFC ClaWizard窗口。
(2)选择 Meage Maps。 (3)分别选择:
Project: 打字
Cla Name: CMyView Objects: CMyView Meges: WM_CREATE (4)单击Add Function按钮。
(5)单击Edit Code按钮。在OnCreate()函数体中加入以下部分。
int CMyView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CView::OnCreate(lpCreateStruct) == -1)
return -1; //代码编写开始
TEXTMETRIC tm;
//声明TEXTMETRIC结构类型对象tm,用于存放字符信息。
CClientDC dc(this);
//生成应用程序窗口设备情景对象
//调用CDC类成员函数GetTextMetrics()取得字符信息,并存入变量tm中。
dc.GetTextMetrics(&tm); //调用CWnd类成员函数CreateSolidCaret()创建黑色矩形条插入符,插入符宽度为tm.tmAveCharWidth/8,高度为tm.tmHeight。
CreateSolidCaret(tm.tmAveCharWidth/8,tm.tmHeight); //设置插入符的初始位置
Caret.x=0;
} Caret.y=tm.tmHeight; SetCaretPos(Caret); //在初始位置显示插入符 ShowCaret(); //代码编写结束 return 0; 3.加入键盘消息:WM_CHAR (1)在“查看”菜单中选择“建立类向导”(ClaWizard)命令,打开MFC ClaWizard窗口。
(2)选择 Meage Maps。 (3)分别选择:
Project: 打字
Cla Name: CMyView Objects: CMyView Meges: WM_CHAR (4)单击Add Function按钮。
(5)单击Edit Code按钮。在OnChar()函数体中加入以下部分。
void CMyView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) {
// TODO: Add your meage handler code here and/or call default
//代码编写开始
SIZE size;
//存放字符的宽度和长度。
static UINT dy=Caret.y;
//声明静态变量dy,存放插入符Y轴坐标。 CString a;
//声明CString类对象a,存放键盘检索到的字符nChar。 a=nChar; CClientDC dc(this);//生成应用程序窗口设备情景对象
} CView::OnChar(nChar, nRepCnt, nFlags); for(UINT i=0;i
} //代码编写结束 HideCaret();
//隐藏光标,使得显示字符使插入符消失。 switch(nChar) { case \'\\r\':
//将插入符移动到下一行的开头
Caret.x=0; Caret.y+=Caret.y; break; default:
} //将插入符移动到字符后面,并显示出来。 SetCaretPos(Caret); ShowCaret(); dc.TextOut(Caret.x,Caret.y,a,1); //输出字符 size=dc.GetTextExtent(a); //获得字符大小
Caret.x+=size.cx; //将字符的宽度加入到插入符的当前坐标位置
二、绘图功能
(一)生成Draw程序框架
(二)鼠标绘图
用鼠标绘制图形,一般分三个环节:
(1) 确定绘图位置:按下鼠标左键,产生WM_LBUTTONDOWN消息 (2) 确定图形显示范围:拖动鼠标,产生WM_MOUSEMOVE消息 (3) 完成图形显示:放开鼠标左键,产生WM_LBUTTONUP消息 1.在视图类CDrawView中加入数据成员
选择ClaView视图,双击CdrawView,光标直接停留在类CdrawView的定义处。在类CdrawView的定义中加入如下代码。
cla CDrawView : public CView { //代码开始编写 protected:
int m_Dragging;
CPoint m_PointOld; CPoint m_PointOrigin; //代码编写结束
protected: // create from serialization only
// Attributes public:
// Operations
5 CDrawView(); DECLARE_DYNCREATE(CDrawView) CDrawDoc* GetDocument(); public:
// Overrides
// Implementation public: virtual ~CDrawView(); // ClaWizard generated virtual function overrides //{{AFX_VIRTUAL(CDrawView) public: virtual void OnDraw(CDC* pDC); // overridden to draw this view virtual BOOL PreCreateWindow(CREATESTRUCT& cs); protected: virtual BOOL OnPreparePrinting(CPrintInfo* pInfo); virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo); virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo); //}}AFX_VIRTUAL #ifdef _DEBUG virtual void AertValid() const; virtual void Dump(CDumpContext& dc) const; #endif
protected:
// Generated meage map functions protected:
//{{AFX_MSG(CDrawView) // NOTEthe ClaWizard will add and remove member functions here.//
DO NOT EDIT what you see in these blocks of generated code ! //}}AFX_MSG DECLARE_MESSAGE_MAP() 21 4.定义函数CdrawDoc::AddLine() 选择FileView,展开SourceFiles,双击DrawDoc.cpp,打开执行文件DrawDoc.cpp,在其末尾,加入以下代码。
//代码编写开始
// AddLine()生成新的Cline对象,并调用CObArray成员函数Add()向m_LineArray添加Cline对象指针。
void CDrawDoc::AddLine(int X1,int Y1,int X2,int Y2) {
} //代码编写结束 CLine *pLine=new CLine(X1,Y1,X2,Y2); m_LineArray.Add(pLine); 5.定义函数CdrawDoc::GetLine() 选择FileView,展开SourceFiles,双击DrawDoc.cpp,打开执行文件DrawDoc.cpp,在其末尾,加入以下代码。
//代码编写开始
// CObArray成员函数GetUpperBound( )返回加入的最后一个指针的索引,即最大的有效索引,CObArray成员函数GetAt( ) 返回对应的CLine指针。如果索引号小于0或大于最大的有效索引号,GetLine( ) 返回0;否则,返回对应的CLine指针。
CLine *CDrawDoc::GetLine(int Index) {
} //代码编写结束 if(Indexm_LineArray.GetUpperBound()) return 0; return (CLine *)m_LineArray.GetAt(Index); 22 6.定义函数CdrawDoc::GetNumLines() 选择FileView,展开SourceFiles,双击DrawDoc.cpp,打开执行文件DrawDoc.cpp,在其末尾,加入以下代码。
//代码编写开始
// 通过调用CObArray成员函数GetSize( ),GetNumLines( )返回m_LineArray当前存放的CLine指针的个数。
int CDrawDoc::GetNumLines() { } //代码编写结束 return m_LineArray.GetSize(); 7.修改函数视图类消息处理函数OnLButtonUp( ) 调用GetDocument( )和AddLine( )来存放新直线。
回到Workspace,选择ClaView,单击CDrawView,展开CdrawView成员变量和成员函数。双击OnLButtonUp( ),在函数OnLButtonUp()中定义后加入以下代码。
void CDrawView::OnLButtonUp(UINT nFlags, CPoint point) { // TODO: Add your meage handler code here and/or call default
int b;
CRect Rect(40,40,600,400); b=Rect.PtInRect(point); if(b) ::SetCursor(m_HCro); else ::SetCursor(m_HArrow); if (m_Dragging&&b) {
23
m_Dragging=0; CClientDC dc(this); dc.SetROP2(R2_NOT);
dc.MoveTo(m_PointOrigin); dc.LineTo(m_PointOld); dc.MoveTo(m_PointOrigin); dc.LineTo(point); //代码开始编写
//调用函数GetDocument( )取得文档类的指针,并存入pDoc中。 CDrawDoc * pDoc=GetDocument();
//通过指针pDoc调用加入的文档类成员函数AddLine( )向m_LineArray加入 Cline类直线对象。
pDoc->AddLine(m_PointOrigin.x,m_PointOrigin.y,point.x,point.y);
// 当一条新的直线绘制完成,视图类OnLButtonUp( nFlags, point)函数通过上面的工作将新绘制的直线存入文档类中。
} } CView::OnLButtonUp(nFlags, point); //代码编写结束
8.修改视图类成员函数OnDraw( ) void CDrawView::OnDraw(CDC* pDC) {
CDrawDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here
pDC->MoveTo(40,40);
pDC->LineTo(600,40);
24
pDC->LineTo(600,400);
pDC->LineTo(40,400);
pDC->LineTo(40,40);
//代码编写结束
} 9.编译、运行 //代码开始编写
int Index=pDoc->GetNumLines(); while(Index--) pDoc->GetLine(Index)->Draw(pDC);
(六)图形的删除
下面向Draw程序加入图形的编辑功能。选择“编辑/撤销”菜单命令就可以删除最近绘制的直线,选择“编辑/全部删除”菜单命令可以清除掉视图窗口中所有的直线。
函数DeleteContents专门负责文档数据的删除工作,可以在文档类中加入该函数删除存放的直线。我们的目的是通过菜单命令答道编辑的功能,因此需要加入“编辑/撤销”和 “编辑/全部删除”菜单命令的消息处理函数,在它们的消息处理函数中调用函数DeleteContents( )。
1. 加入“编辑”菜单命令“全部删除”
(1) 选择ResourceView视图,打开Menu项目下的IDR_MAINFRAME标志符,在Edit菜单下面加入菜单命令 “全部删除”。
ID标志符为:ID_EDIT_CLEAR_ALL, Caption为:全部删除(&A)\\tCtrl+A (2) 双击Accelerator项目下面的IDR_MAINFRAME标志符,打开快捷键编辑器。双击快捷键编辑框底部的空框,在ID文本框中输入ID_EDIT_CLEAR_ALL,在Key文本框中输入A,并选择Ctrl。
2. 加入虚函数DeleteContents( ) 25 (1)在“查看”菜单中选择“建立类向导”(ClaWizard)命令,打开MFC ClaWizard窗口。
(2)选择 Meage Maps。 (3)分别选择: Project: Draw Cla Name: CDrawDoc Objects: CDrawDoc Meges: DeleteContents (4)单击Add Function按钮。
(5)单击Edit Code按钮。在DeleteContents()函数体中加入以下部分。 void CDrawDoc::DeleteContents() {
} 3. 加入ID_EDIT_CLEAR_ALL的COMMAND消息处理函数OnEditClearAll() (1)在“查看”菜单中选择“建立类向导”(ClaWizard)命令,打开MFC ClaWizard窗口。
(2)选择 Meage Maps。 (3)分别选择:
Project: Draw Cla Name: CDrawDoc Objects IDs: ID_EDIT_CLEAR_ALL Meges: COMMAND
26 // TODO: Add your specialized code here and/or call the base cla //代码编写开始
int Index=m_LineArray.GetSize(); while(Index--) delete m_LineArray.GetAt(Index); m_LineArray.RemoveAll(); //代码编写结束
CDocument::DeleteContents(); (4)单击Add Function按钮。
(5)单击Edit Code按钮。在OnEditClearAll()函数体中加入以下部分。 void CDrawDoc::OnEditClearAll() { // TODO: Add your command handler code here //代码编写开始
DeleteContents();
} 4. 加入ID_EDIT_CLEAR_ALL的UPDATE_COMMAND_UI消息处理函数 (1)在“查看”菜单中选择“建立类向导”(ClaWizard)命令,打开MFC ClaWizard窗口。
(2)选择 Meage Maps。 (3)分别选择:
Project: Draw Cla Name: CDrawDoc Objects IDs: ID_EDIT_CLEAR_ALL Meges: UPDATE_COMMAND_UI (4)单击Add Function按钮。
(5)单击Edit Code按钮。在OnUpdateEditClearAll( )函数体中加入以下部分。 void CDrawDoc::OnUpdateEditClearAll(CCmdUI* pCmdUI) {
} 5. 加入ID_EDIT_UNDO的COMMAND消息处理函数
27 UpdateAllViews(0); //代码编写结束
// TODO: Add your command update UI handler code here //代码编写开始
pCmdUI->Enable(m_LineArray.GetSize()); //代码编写结束 (1)在“查看”菜单中选择“建立类向导”(ClaWizard)命令,打开MFC ClaWizard窗口。
(2)选择 Meage Maps。 (3)分别选择:
Project: Draw Cla Name: CDrawDoc Objects IDs: ID_EDIT_UNDO Meges: COMMAND (4)单击Add Function按钮。
(5)单击Edit Code按钮。在OnEditUndo()函数体中加入以下部分。 void CDrawDoc::OnEditUndo() { // TODO: Add your command handler code here //代码编写开始
int Index=m_LineArray.GetUpperBound();
} 6. 加入ID_EDIT_UNDO的UPDATE_COMMAND_UI消息处理函数
(1)在“查看”菜单中选择“建立类向导”(ClaWizard)命令,打开MFC ClaWizard窗口。
(2)选择 Meage Maps。 (3)分别选择:
Project: Draw Cla Name: CDrawDoc Objects IDs: ID_EDIT_UNDO
28 if(Index>-1) {
} UpdateAllViews(0); //代码编写结束 delete m_LineArray.GetAt(Index); m_LineArray.RemoveAt(Index); Meges: UPDATE_COMMAND_UI (4)单击Add Function按钮。
(5)单击Edit Code按钮。在OnUpdateEditUndo ()函数体中加入以下部分。 void CDrawDoc::OnUpdateEditUndo(CCmdUI* pCmdUI) { // TODO: Add your command update UI handler code here //代码编写开始
pCmdUI->Enable(m_LineArray.GetSize()); //代码编写结束
}
(七)图形的存取
(八)滚动窗口
(九)分割窗口
(十)拖放与注册
29
30