📄 chap8_3.htm
字号:
<html>
<head>
<title>8.3 绘图程序</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 3.0">
</head>
<body link="#3973DE" alink="#3973DE">
<font SIZE="5"><b><div align="center"><center>
<table border="0" width="615" cellspacing="0" cellpadding="0">
<tr>
</b><td><div align="center"><center><table border="0" width="615" cellpadding="0" cellspacing="0" height="20">
<tr>
<td width="377" bgcolor="#15397D" height="20"></td>
<td width="238" bgcolor="#000000" height="20"><p align="right"></font><span style="text-decoration: none"><a href="../../index.htm"><font color="#FFFFFF">电脑报Visual
C++网络教程</font></a></span></td>
</tr>
</table>
</center></div><font FACE="Times New Roman" SIZE="4"><b><p ALIGN="CENTER"></b></font><font color="#3973DE" FACE="Times New Roman" size="5">8.3 </font><font color="#3973DE" size="5">绘图程序</font><font FACE="Times New Roman" SIZE="4"></p>
<p></font><font SIZE="3">在了解</font><font FACE="Times New Roman" SIZE="3">GDI</font><font SIZE="3">的一些基本知识之后,我们就可以着手编写绘图程序了。这个绘图程序可以让读者用鼠标器在窗口内任意涂写,并可以保存所画的内容。这里我们参考了</font><font FACE="Times New Roman" SIZE="3">Visual C++</font><font SIZE="3">的例子</font><font FACE="Times New Roman" SIZE="3">Scribble</font><font SIZE="3">,并作了一些修改和简化。</font><font FACE="Times New Roman" SIZE="3"><b></p>
<p></b></font><font color="#3973DE" FACE="Times New Roman" SIZE="3">8.3.1 MDI</font><font SIZE="3" color="#3973DE">应用程序框架</font><font FACE="Times New Roman" SIZE="3"></p>
<p></font><font SIZE="3">首先用</font><font FACE="Times New Roman" SIZE="3">AppWizard</font><font SIZE="3">生成绘图程序的基本框架:</font><font FACE="Times New Roman" SIZE="3"></p>
<p></font><font SIZE="3">选择</font><font FACE="Times New Roman" SIZE="3">File->New</font><font SIZE="3">,弹出</font><font FACE="Times New Roman" SIZE="3">New</font><font SIZE="3">对话框,选择</font><font FACE="Times New Roman" SIZE="3">MFC AppWizard(exe)</font><font SIZE="3">,并指定项目文件名为</font><font FACE="Times New Roman" SIZE="3">Draw</font><font SIZE="3">。</font><font FACE="Times New Roman" SIZE="3"></p>
<p></font><font SIZE="3">在</font><font FACE="Times New Roman" SIZE="3">MFC
AppWizard-Step1</font><font SIZE="3">对话框中指定框架类型为</font><font FACE="Times New Roman" SIZE="3">Multiple Document(</font><font SIZE="3">多文档,这是缺省设置</font><font FACE="Times New Roman" SIZE="3">)</font><font SIZE="3">。</font><font FACE="Times New Roman" SIZE="3"></p>
<p>Step2,3</font><font SIZE="3">按缺省值。在</font><font FACE="Times New Roman" SIZE="3">MFC AppWizard Step 4 of 6</font><font SIZE="3">对话框中,点“</font><font FACE="Times New Roman" SIZE="3">Advanced...</font><font SIZE="3">”按钮,弹出</font><font FACE="Times New Roman" SIZE="3">Advanced Options</font><font SIZE="3">对话框。在</font><font FACE="Times New Roman" SIZE="3">File Extension</font><font SIZE="3">编辑框中指定文件名后缀为</font><font FACE="Times New Roman" SIZE="3">.drw</font><font SIZE="3">,按</font><font FACE="Times New Roman" SIZE="3">OK</font><font SIZE="3">关闭</font><font FACE="Times New Roman" SIZE="3">Advanced Options</font><font SIZE="3">对话框。</font><font FACE="Times New Roman" SIZE="3"></p>
<p>Step5</font><font SIZE="3">按缺省设置。在</font><font FACE="Times New Roman" SIZE="3">MFC AppWizard Step 6 of 6</font><font SIZE="3">中,在应用程序所包含的类列表中选择</font><font FACE="Times New Roman" SIZE="3">CDrawView</font><font SIZE="3">,并为其指定基类为</font><font FACE="Times New Roman" SIZE="3">CScrollView</font><font SIZE="3">,因为绘图程序需要卷滚文档。现在点</font><font FACE="Times New Roman" SIZE="3">Finish</font><font SIZE="3">按钮生成绘图所需的应用程序框架。</font><font FACE="Times New Roman" SIZE="3"></p>
<p></font><font SIZE="3">在往框架里添加代码实现绘图程序之前,先看看多文档框架与单文档框架的差别。</font><font FACE="Times New Roman" SIZE="3"></p>
<p>AppWizard</font><font SIZE="3">为多文档框架创建了以下类: </font><font FACE="Times New Roman" SIZE="3"></p>
<p>CAboutDlg</font><font SIZE="3">:“关于”对话框</font><font FACE="Times New Roman" SIZE="3"></p>
<p>CChildFrame</font><font SIZE="3">:子框架窗口,用于容纳视图</font><font FACE="Times New Roman" SIZE="3"></p>
<p>CDrawApp</font><font SIZE="3">:应用程序类</font><font FACE="Times New Roman" SIZE="3"></p>
<p>CDrawDoc</font><font SIZE="3">:绘图程序视图类</font><font FACE="Times New Roman" SIZE="3"></p>
<p>CDrawView</font><font SIZE="3">:绘图视图类</font><font FACE="Times New Roman" SIZE="3"></p>
<p>CMainFrame</font><font SIZE="3">:主框架窗口,用来容纳子窗口,它是多文档应用程序的主窗口。</font><font FACE="Times New Roman" SIZE="3"></p>
<p></font><font SIZE="3">在生成的类上,</font><font FACE="Times New Roman" SIZE="3">MDI</font><font SIZE="3">比</font><font FACE="Times New Roman" SIZE="3">SDI</font><font SIZE="3">多了一个</font><font FACE="Times New Roman" SIZE="3">CChildFrame</font><font SIZE="3">子框架窗口类,而且</font><font FACE="Times New Roman" SIZE="3">CMainFrame</font><font SIZE="3">的职责也不同了。</font><font FACE="Times New Roman" SIZE="3"></p>
<p></font><font SIZE="3">另外,</font><font FACE="Times New Roman" SIZE="3">MDI</font><font SIZE="3">和</font><font FACE="Times New Roman" SIZE="3">SDI</font><font SIZE="3">在初始化应用程序实例上也有所不同。</font><font FACE="Times New Roman" SIZE="3">MDI</font><font SIZE="3">应用程序</font><font FACE="Times New Roman" SIZE="3">InitInstance</font><font SIZE="3">函数如清单</font><font FACE="Times New Roman" SIZE="3">8.2</font><font SIZE="3">定义。<b></p>
<p>清单</font><font FACE="Times New Roman" SIZE="3">8.2 </font><font SIZE="3">多文档程序的</font><font FACE="Times New Roman" SIZE="3">InitInstance</font><font SIZE="3">成员函数定义</font></b><font FACE="Times New Roman" SIZE="3"></p>
<p>BOOL CDrawApp::InitInstance()</p>
<p>{</p>
<p>//</font><font SIZE="3">一些初始化工作</font><font FACE="Times New Roman" SIZE="3">......</p>
<p>// Register the application's document templates. Document templates</p>
<p>// serve as the connection between documents, frame windows and views.</p>
<p>CMultiDocTemplate* pDocTemplate;</p>
<p>pDocTemplate = new CMultiDocTemplate(</p>
<p>IDR_DRAWTYPE,</p>
<p>RUNTIME_CLASS(CDrawDoc),</p>
<p>RUNTIME_CLASS(CChildFrame), // custom MDI child frame</p>
<p>RUNTIME_CLASS(CDrawView));</p>
<p>AddDocTemplate(pDocTemplate);</p>
<p>// create main MDI Frame window</p>
<p>CMainFrame* pMainFrame = new CMainFrame;</p>
<p>if (!pMainFrame->LoadFrame(IDR_MAINFRAME))</p>
<p>return FALSE;</p>
<p>m_pMainWnd = pMainFrame;</p>
<p>// Enable drag/drop open</p>
<p>m_pMainWnd->DragAcceptFiles();</p>
<p>// Enable DDE Execute open</p>
<p>EnableShellOpen();</p>
<p>RegisterShellFileTypes(TRUE);</p>
<p>// Parse command line for standard shell commands, DDE, file open</p>
<p>CCommandLineInfo cmdInfo;</p>
<p>ParseCommandLine(cmdInfo);</p>
<p>// Dispatch commands specified on the command line</p>
<p>if (!ProcessShellCommand(cmdInfo))</p>
<p>return FALSE;</p>
<p>// The main window has been initialized, so show and update it.</p>
<p>pMainFrame->ShowWindow(m_nCmdShow);</p>
<p>pMainFrame->UpdateWindow();</p>
<p>return TRUE;</p>
<p>}</p>
<p></font><font SIZE="3">在注册文档模板时,首先创建一个</font><font FACE="Times New Roman" SIZE="3">CMultiDocTemplate</font><font SIZE="3">类型(在</font><font FACE="Times New Roman" SIZE="3">SDI</font><font SIZE="3">下是</font><font FACE="Times New Roman" SIZE="3">CSingleDocTemplate</font><font SIZE="3">)的模板对象,然后用</font><font FACE="Times New Roman" SIZE="3">AddDocTemplate</font><font SIZE="3">()把它加入到文档模板链表中去。</font><font FACE="Times New Roman" SIZE="3"></p>
<p>CMultiDocTemplate</font><font SIZE="3">构造函数带四个参数,第一个参数是文档使用的资源</font><font FACE="Times New Roman" SIZE="3">ID</font><font SIZE="3">定义。第二个是文档类型,第三个是子窗口类型,第四个是视图类型。</font><font FACE="Times New Roman" SIZE="3"></p>
<p></font><font SIZE="3">与</font><font FACE="Times New Roman" SIZE="3">SDI</font><font SIZE="3">不同,由于</font><font FACE="Times New Roman" SIZE="3">MDI</font><font SIZE="3">的主框架窗口并不直接与文档相对应,因此无法通过创建文档来创建主框架窗口,而需要自己去创建。</font><font FACE="Times New Roman" SIZE="3"></p>
<p>//</font><font SIZE="3">定义一个主窗口类指针,并创建一个窗口的空的实例</font><font FACE="Times New Roman" SIZE="3"></p>
<p>CMainFrame* pMainFrame = new CMainFrame;</p>
<p>//</font><font SIZE="3">从资源文件中载入菜单、图标等信息,并创建窗口</font><font FACE="Times New Roman" SIZE="3"></p>
<p>if (!pMainFrame->LoadFrame(IDR_MAINFRAME))</p>
<p>return FALSE;</p>
<p>//</font><font SIZE="3">将应用程序对象的主窗口指针数据成员设为当前创建的窗口</font><font FACE="Times New Roman" SIZE="3"></p>
<p>m_pMainWnd = pMainFrame;</p>
<p></font><b><font SIZE="3"> </font><font FACE="Times New Roman" SIZE="3"></p>
<p></font></b><font color="#3973DE" FACE="Times New Roman" SIZE="3">8.3.2 </font><font SIZE="3" color="#3973DE">设计绘图程序的文档类</font><font FACE="Times New Roman" SIZE="3"></p>
<p>Draw</font><font SIZE="3">需要保存用户在屏幕上涂写的每一个笔划。一副画由许多笔划组成,可以把它看作是笔划组成的链表。每一个笔划可以看作一个对象,它由许多点组成。这样,我们可以把绘图文档的数据看作是笔划对象</font><font FACE="Times New Roman" SIZE="3">CStroke</font><font SIZE="3">组成的链表。另外,我们还需要一些数据成员表示当前画图所使用的画笔和画笔的宽度。</font><font FACE="Times New Roman" SIZE="3"></p>
<p></font><font SIZE="3">修改后的文档类声明文件如清单</font><font FACE="Times New Roman" SIZE="3">8-1</font><font SIZE="3">:<b></p>
<p>清单</font><font FACE="Times New Roman" SIZE="3">8.3</font><font SIZE="3">文档类声明</font></b><font FACE="Times New Roman" SIZE="3"></p>
<p>// DrawDoc.h : interface of the CDrawDoc class</p>
<p>//</p>
<p>/////////////////////////////////////////////////////////////////////////////</p>
<p>#if !defined(AFX_DRAWDOC_H__143330AE_85BC_11D1_9304_444553540000__INCLUDED_)</p>
<p>#define AFX_DRAWDOC_H__143330AE_85BC_11D1_9304_444553540000__INCLUDED_</p>
<p>#if _MSC_VER >= 1000</p>
<p>#pragma once</p>
<p>#endif // _MSC_VER >= 1000</p>
<p></font><font SIZE="3"> </font><font FACE="Times New Roman" SIZE="3"></p>
<p>class CDrawDoc : public CDocument</p>
<p>{</p>
<p>protected: // create from serialization only</p>
<p>CDrawDoc();</p>
<p>DECLARE_DYNCREATE(CDrawDoc)</p>
<p>// Attributes</p>
<p></font><b><font SIZE="3"> </font><font FACE="Times New Roman" SIZE="3"></p>
<p>public:</p>
<p>UINT m_nPenWidth; // current user-selected pen width</p>
<p>CPen m_penCur; // pen created according to</p>
<p>// user-selected pen style (width)</p>
<p>public:</p>
<p>CTypedPtrList<CObList,CStroke*> m_strokeList; </p>
<p>//</font><font SIZE="3">获取当前使用的画笔,为视图所使用</font><font FACE="Times New Roman" SIZE="3"></p>
<p>CPen* GetCurrentPen() { return &m_penCur; }</p>
<p>protected:</p>
<p>CSize m_sizeDoc;</p>
<p>public:</p>
<p>CSize GetDocSize() { return m_sizeDoc; }</p>
<p>// Operations</p>
<p>public:</p>
<p>//</font><font SIZE="3">往链表里增加一个笔划</font><font FACE="Times New Roman" SIZE="3"></p>
<p>CStroke* NewStroke();</p>
<p>// Operations</p>
<p>//</font><font SIZE="3">用于初始化文档</font><font FACE="Times New Roman" SIZE="3"></p>
<p>protected:</p>
<p>void InitDocument();</b></p>
<p>// Overrides</p>
<p>// ClassWizard generated virtual function overrides</p>
<p>//{{AFX_VIRTUAL(CDrawDoc)</p>
<p>public:</p>
<p>virtual BOOL OnNewDocument();</p>
<p>virtual void Serialize(CArchive& ar);</p>
<p>//}}AFX_VIRTUAL</p>
<p>// Implementation</p>
<p>public:</p>
<p>virtual ~CDrawDoc();</p>
<p>#ifdef _DEBUG</p>
<p>virtual void AssertValid() const;</p>
<p>virtual void Dump(CDumpContext& dc) const;</p>
<p>#endif</p>
<p>protected:</p>
<p>// Generated message map functions</p>
<p>protected:</p>
<p>//{{AFX_MSG(CDrawDoc)</p>
<p>// NOTE - the ClassWizard will add and remove member functions here.</p>
<p>// DO NOT EDIT what you see in these blocks of generated code !</p>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -