在了解GDI的一些基本知识之后,我们就可以着手编写绘图程序了。这个绘图程序可以让读者用鼠标器在窗口内任意涂写,并可以保存所画的内容。这里我们参考了Visual C++的例子Scribble,并作了一些修改和简化。
8.3.1 MDI应用程序框架 首先用AppWizard生成绘图程序的基本框架: 选择File->New,弹出New对话框,选择MFC AppWizard(exe),并指定项目文件名为Draw。 在MFC AppWizard-Step1对话框中指定框架类型为Multiple Document(多文档,这是缺省设置)。 Step2,3按缺省值。在MFC AppWizard Step 4 of 6对话框中,点“Advanced...”按钮,弹出Advanced Options对话框。在File Extension编辑框中指定文件名后缀为.drw,按OK关闭Advanced Options对话框。 Step5按缺省设置。在MFC AppWizard Step 6 of 6中,在应用程序所包含的类列表中选择CDrawView,并为其指定基类为CScrollView,因为绘图程序需要卷滚文档。现在点Finish按钮生成绘图所需的应用程序框架。 在往框架里添加代码实现绘图程序之前,先看看多文档框架与单文档框架的差别。 AppWizard为多文档框架创建了以下类: CAboutDlg:“关于”对话框 CChildFrame:子框架窗口,用于容纳视图 CDrawApp:应用程序类 CDrawDoc:绘图程序视图类 CDrawView:绘图视图类 CMainFrame:主框架窗口,用来容纳子窗口,它是多文档应用程序的主窗口。 在生成的类上,MDI比SDI多了一个CChildFrame子框架窗口类,而且CMainFrame的职责也不同了。 另外,MDI和SDI在初始化应用程序实例上也有所不同。MDI应用程序InitInstance函数如清单8.2定义。 清单8.2 多文档程序的InitInstance成员函数定义 BOOL CDrawApp::InitInstance() { //一些初始化工作...... // Register the application's document templates. Document templates // serve as the connection between documents, frame windows and views. CMultiDocTemplate* pDocTemplate; pDocTemplate = new CMultiDocTemplate( IDR_DRAWTYPE, RUNTIME_CLASS(CDrawDoc), RUNTIME_CLASS(CChildFrame), // custom MDI child frame RUNTIME_CLASS(CDrawView)); AddDocTemplate(pDocTemplate); // create main MDI Frame window CMainFrame* pMainFrame = new CMainFrame; if (!pMainFrame->LoadFrame(IDR_MAINFRAME)) return FALSE; m_pMainWnd = pMainFrame; // Enable drag/drop open m_pMainWnd->DragAcceptFiles(); // Enable DDE Execute open EnableShellOpen(); RegisterShellFileTypes(TRUE); // Parse command line for standard shell commands, DDE, file open CCommandLineInfo cmdInfo; ParseCommandLine(cmdInfo); // Dispatch commands specified on the command line if (!ProcessShellCommand(cmdInfo)) return FALSE; // The main window has been initialized, so show and update it. pMainFrame->ShowWindow(m_nCmdShow); pMainFrame->UpdateWindow(); return TRUE; } 在注册文档模板时,首先创建一个CMultiDocTemplate类型(在SDI下是CSingleDocTemplate)的模板对象,然后用AddDocTemplate()把它加入到文档模板链表中去。 CMultiDocTemplate构造函数带四个参数,第一个参数是文档使用的资源ID定义。第二个是文档类型,第三个是子窗口类型,第四个是视图类型。 与SDI不同,由于MDI的主框架窗口并不直接与文档相对应,因此无法通过创建文档来创建主框架窗口,而需要自己去创建。 //定义一个主窗口类指针,并创建一个窗口的空的实例 CMainFrame* pMainFrame = new CMainFrame; //从资源文件中载入菜单、图标等信息,并创建窗口 if (!pMainFrame->LoadFrame(IDR_MAINFRAME)) return FALSE; //将应用程序对象的主窗口指针数据成员设为当前创建的窗口 m_pMainWnd = pMainFrame;
8.3.2 设计绘图程序的文档类 Draw需要保存用户在屏幕上涂写的每一个笔划。一副画由许多笔划组成,可以把它看作是笔划组成的链表。每一个笔划可以看作一个对象,它由许多点组成。这样,我们可以把绘图文档的数据看作是笔划对象CStroke组成的链表。另外,我们还需要一些数据成员表示当前画图所使用的画笔和画笔的宽度。 修改后的文档类声明文件如清单8-1: 清单8.3文档类声明 // DrawDoc.h : interface of the CDrawDoc class // / #if !defined(AFX_DRAWDOC_H__143330AE_85BC_11D1_9304_444553540000__INCLUDED_) #define AFX_DRAWDOC_H__143330AE_85BC_11D1_9304_444553540000__INCLUDED_ #if _MSC_VER >= 1000 #pragma once #endif // _MSC_VER >= 1000
class CDrawDoc : public CDocument { protected: // create from serialization only CDrawDoc(); DECLARE_DYNCREATE(CDrawDoc) // Attributes
public: UINT m_nPenWidth; // current user-selected pen width CPen m_penCur; // pen created according to // user-selected pen style (width) public: CTypedPtrList<CObList,CStroke*> m_strokeList; //获取当前使用的画笔,为视图所使用 CPen* GetCurrentPen() { return &m_penCur; } protected: CSize m_sizeDoc; public: CSize GetDocSize() { return m_sizeDoc; } // Operations public: //往链表里增加一个笔划 CStroke* NewStroke(); // Operations //用于初始化文档 protected: void InitDocument(); // Overrides / |
vc++笔记之绘图程序
最新推荐文章于 2021-03-18 14:14:34 发布
![](https://img-home.csdnimg.cn/images/20240711042549.png)