按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
#0011 RECT rc;
#0012
#0013 CBrush brush(RGB(255; 0; 0)); // red brush
#0014 CBrush* pOldBrush = pDC…》SelectObject(&brush);
#0015 CPen pen(PS_SOLID; 1; RGB(255; 0; 0)); // red pen
#0016 CPen* pOldPen = pDC…》SelectObject(&pen);
#0017
#0018 cxGraph = 100;
#0019 cyGraph = DATAMAX; // defined in resource。h
#0020
#0021 this…》GetClientRect(&rc);
#0022 pDC…》SetMapMode(MM_ANISOTROPIC);
722
…………………………………………………………Page 785……………………………………………………………
第 13 章 多重文件與多重顯示
#0023 pDC…》SetWindowOrg(0; 0);
#0024 pDC…》SetViewportOrg(10; rc。bottom…10);
#0025 pDC…》SetWindowExt(cxGraph; cyGraph);
#0026 pDC…》SetViewportExt(rc。right…20; …(rc。bottom…20));
#0027
#0028 //长条图的条状物之间距离是条状物宽度的1/3。
#0029 //我们希望条状物能够填充窗口的整个可用空间。
#0030 //所以(bar_spacing + bar_width) * num_bars = graph_width
#0031 //亦即bar_width * 4/3 * num_bars = graph_width
#0032 //亦即bar_width = graph_width / num_bars * 3/4
#0033
#0034 cxBar = (3 * cxGraph) / (4 * DATANUM);
#0035 cxBarSpacing = cxBar/3;
#0036 if (cxBarMoveTo(0; 0);
#0040 pDC…》LineTo(0; cyGraph);
#0041 pDC…》MoveTo(0; 0);
#0042 pDC…》LineTo(cxGraph; 0);
#0043
#0044 //长条图
#0045 for (x=0+cxBarSpacing;y=0;i=0; i《 DATANUM; i++;x+=cxBar+cxBarSpacing)
#0046 pDC…》Rectangle(x; y; x+cxBar; y+pDoc…》m_intArray'i');
#0047
#0048 pDC…》SelectObject(pOldPen);
#0049 pDC…》SelectObject(pOldBrush);
#0050 }
如果你要令三个view 都有打印预视能力,必须在每一个view 类别中改写以
下三个虚拟函数:
virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
virtual void OnBeginPrinting(CDC* pDC; CPrintInfo* pInfo);
virtual void OnEndPrinting(CDC* pDC; CPrintInfo* pInfo);
至于其函数内容,从CGraphView 的同名函数中依样画葫芦拷贝一份过来即可。
本例不示范文件读写动作,所以CGraphDoc 没有改写 Serialize 虚拟函数。
图13…3 是Graph 程序的执行画面。
723
…………………………………………………………Page 786……………………………………………………………
第篇 深入 MFC 程式設計
图13…3 Graph 执行画面。每当选按 【File/New 】 (或工具栏上的对应按
钮)打开一份新文件,其内就有10 笔整数资料。你可选按 【Graph
Data 】 (或工具栏上的对应按钮) 改变资料内容。
静态分裂窗口之观念整理
我想你已经从前述的OnCreateClient 函数中认识了静态分裂窗口的相关函数。我可以用
图13…4 解释各个类别的关系与运用。
基本上图13…4 三个窗口可以视为三个完全独立的view 窗口,有各自的类别,以各自的
方式显示资料。不过,资料倒是来自同一份Document 。试试看预视效果,你会发现,哪
一个窗口为「作用中」,哪一个窗口的绘图动作就主宰预视窗口。你可以利用SetActivePane
设定作用中的窗口,也可以调用GetActivePane 获得作用中的窗口。但是,你会发现,
从外观上很难看出哪一个窗口是「作用中的」窗口。
724
…………………………………………………………Page 787……………………………………………………………
第 13 章 多重文件與多重顯示
CChildFrame 对象(Document Frame 窗口)
CSplitterWnd 对象(类似SDK MDI 程序中的Client 窗口,
用于幕后协调而不显现),图中以虚框表示。
由CSplitterWnd::CreateView 产
生的view 窗口,以CBarView
由CSplitterWnd::CreateView 产生的 为基础。
view 窗口,以CTextView 为基础。
由CSplitterWnd::CreateView 产生
的view 窗口,以CGraphView 为
基础。
图13…4 静态分裂窗口的类别运用 (以Graph 为例)
同源子窗口
虽然我说静态分裂窗口的窗口可视为完全独立的view 窗口,但毕竟它们不是!它们还
框在一个大窗口中。如果你不喜欢分裂窗口(谁知道呢,当初我也不太喜欢),我们来
试点新鲜的。
点子是从【Window/New Window 】开始。这个菜单项目令Framework 为我们做出目前作
用中的view 窗口的另一份拷贝。如果我们能够知道Framework 是如何动作,是不是可
以引导它使用另一个view 类别,以不同的方式表现同一份资料?
这就又有偷窥源代码的需要了。MFC 并没有提供正常的管道让我们这么做,我们需要
MFC 源代码。
725
…………………………………………………………Page 788……………………………………………………………
第篇 深入 MFC 程式設計
CMDIFrameWnd::OnWindowNew
如果你想在程序中设计断点,一步一步找出【Window/New Window 】的动作,就像我
在第12 章对付OnFilePrint 和OnFilePrintPreview 一样,那么你会发现没有着力点,因
为AppWizard 并不会做出像这样的消息映射表格:
BEGIN_MESSAGE_MAP(CScribbleView; CScrollView)
。。。
ON_MAND(ID_FILE_PRINT; CView::OnFilePrint)
ON_MAND(ID_FILE_PRINT_PREVIEW; CView::OnFilePrintPreview)
END_MESSAGE_MAP()
你根本不知道【Window/New Window 】这个命令流到哪里去了�