MDI和SDI的区别
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第十七章:读和写文档--MDI应用程序
1,MFC库中C MDIFrameWn d类封装了主框架窗口和MDI客户窗口所有的函数(包含了所有W indows MDI消息的消息控制函数),因而完全可以管理它的子窗口(由CMDI ChildWnd类对象来表示的)。
2,MDI应用程序中,任何时候只有一个子窗口处于活动状态。
MD I应用程序只有以个菜单和工具栏,其上的所有的命令都被传递到当前活动子窗口中。
主窗口的标题栏中显示活动窗口的文档文件名。
3,MDI应用程序在启动次序上和SD I程序大部分相同。
M DI中被派生类中重载的InitInsta nce函数与SDI有所不同。
(具体的不同跟踪下代码或见362页啊,我就不抄了)
4,MDI应用程序实质:一个MDI应用程序可以使用多个文档类型,并允许同时存在不止一个的文档对象。
比较:
SDI中:
CSingleD ocTemplate* pDocTemp late;
pDo cTemplate= new CSin gleDocTemp late(
ID R_MAINFRAM E,
RUNTI ME_CLASS(C StudentDoc),
RUNTI ME_CLASS(C MainFrame), // main SDIframe wind ow
RUNTI ME_CLASS(C StudentVie w));
AddD ocTemplate(pDocTempl ate);
MDI中:
CMulti DocTemplat e* pDocTem plate;
pD ocTemplate = new CMu ltiDocTemp late(
ID R_EX17A TYP E,
RUNTI ME_CLASS(C StudentDoc),
RUNTI ME_CLASS(C ChildFrame), // cust om MDI chi ld frame
RUNTIME_C LASS(CStud entView));
AddDocTe mplate(pDo cTemplate);
//MDI中Ad dDocTempla te(pDocTem plate)的调用使得MDI应用程序能够支持多个子窗口,而每个子窗口都与一个文档对象和一个视图对象相连接。
若干个子窗口(及其相应的视图对象)也可能与一个文档对象相连接。
//MDI动态的创建CChil dFrame对象。
5,SDI只能有一个框架窗口类和一个框架窗口对象(CMai nFrame:CFr ameWnd);MD I应用程序有两个框架窗口类,并且可以有多个框架对象,即:
C MainFrame:CMDIFrameW nd 只有一个对应对象有菜单和控制栏无视图
CChild Frame:CMDI ChildWnd 每个子窗口对应一个对象无菜单和控制栏有视图
对象的创建:CMainFra me对象在应用程序类的InitInsta nce函数中(即CM ainFrame*pMainFrame = new CMa inFrame;);CChildFram e对象是当新的子窗口被打开时,由应用程序框架来创建(MDI中InitInstan ce函数中Proce ssShellCom mand的调用用以创建子框架)。
6,MDI的InitIn stance函数将C WinApp::m_pMainWnd设置成指向应用程序的主框架窗口指针。
因而任何时候可以通过AfxG etApp函数来访问m_pMainWnd。
7,一个MDI程序包含两个独立的字符串资源,分别由ID R_MAINFRAM E和IDR_EX17A TYPE(视具体的项目变化)来标识的。
(详细见P361-362)
8,创建新文档和为现有的文档创建新视图(参见362页,很多条款也不抄了)
9,MDI应用程序每次当文档文件从磁盘中载入的时候,都会构造新的文档对象,并且当子窗口被关闭的时候,相应的文档对象被删除。
(问题:如果多个子窗口与同一个文档对象相连接,那当一个子窗口被关闭,关联的文档对象会不会同时被删除呢?)
10,SDI中不支持多次AddDocTe mplate调用(S DI中在应用程序生存周期内,文档对象、视图对象、框架对象只被创建一次),而MDI中却是通过多次调用A ddDocTempl ate来支持多个文档模板,每个模板可制定不同的文档类、视图类以及MDI子框架类的组合。
(注:本章笔记有点粗糙,实例也只看了看没跟踪多少代码,以后找个好实例再补上,时间关系,笔记暂停了些时日,见谅哦)
/////////////////////////
2006.7.24 01:15 作者:npuwangl ei 收藏| 评论:0
VC 技术内幕(第四版)笔记(第16章)
分类:VC学习
第十六章:读和写文档--SDI应用程序
一,序列化:
1,序列化:对象可以被持续,即当程序退出时候它们被存盘,当程序重启时候
它们又可被恢复,对象这种存盘和恢复处理过程称之为序列化。
注意:MFC库中,不能利用序列化来代替数据库管理系统。
与文档相关的所有对象只能在某个单独的磁盘文件中进行顺序读写,而不支持对象在磁盘文件中随机读写。
2,磁盘文件和归档(Archive s):
1)在MFC库中,磁盘文件是通过CFile类的对象来表示的。
2)如果应用程序不直接利用磁盘I/O,而只依赖于序列化处理过程,则可以避免直接使用CFil e对象。
3)在se rialize函数(序列化函数)与CFi le对象之间,还有一个归档对象(CArc hive 类对象),归档对象为CFile对象缓存数据,同时还保存一个内部标记,用来标示归档存档(写盘)还是载入(读盘)。
4)每次只能有一个活动的归档与文件相连。
应用程序框架会很好管理CFile对象及C Archive对象的创建,为CFile对象打开相应的磁盘文件,并且将相应的归档对象与文件对象相连。
5)关系图:
持续文档对象<--> S erialize <--> CArchi ve对象<-->CFile对象<--> 磁盘
6)当用户选择了File O pen或File S ave命令时,应用程序框架自动调用Ser ialize 函数。
3,使类可序列化:
1)可序列化的类必须直接或间接从COb ject派生,并且在类声明中,必须包括D ECLARE_SER IAL宏调用,在类的实现文件中必须包括I MPLEMENT_S ERIAL宏调用。
2)编写Serial ize函数。
如:
// example for CObje ct::Serial ize
void C Age::Seria lize( CArc hive& ar )
{
CObje ct::Serial ize( ar );
if(ar.IsStori ng() )//Is Storing来判断当前归档是被用来存入还是被用来载入的。
ar << m_years;
else
ar >> m_years;
}
注意一:插入运算符对值重载,析取运算符对应用重载,有时必须强制转换才能适应编译器:
如:m_n Type是枚举类型,则:ar>>(int&)m_nType;ar<<(int)m_nType;
注意二:插入和析取运算符并不适用于CObje ct派生类内嵌对象。
3)大多数序列化函数都需要调用基类的S erialize函数(一般在第一行调用,如CStudent是从CPerson派生,那么CStuden t中Serializ e函数第一行就应该为CPerson::S erialize(a r);)。
CObje ct类Seriali ze是虚函数并且没做任何工作,因而2)
中类子中没调用CObj ect::Seria lize函数。
4)对于CObject派生类的内嵌对象中的S erialize函数中总是需要直接调用内嵌对象的Serial ize函数。
4,使集合序列化:
1)所有的集合类都是从C Object类派生,并且在集合类声明中都包含有DECLARE_SERIAL宏调用,应此可以调用集合类的Serialize成员函数,方便使集合序列化。
2)如调用了由一组对象组成的C Oblist集合的S erialize函数,则COblist集合中每个对象的Ser ialize函数会被依次调用。
3)如果集合中包含了指向不同类对象的指针,则所有的类名都被相应地存储到归档中,以便所有的对象在被创建时都能够调用相应类的构造函数。
4)如果包容对象(如文档)中包含了一个内嵌集合,则被装入的数据会被追加进现存集合中。
(因此有必要在载入前对现存的集合清空。
通常由Dele teContents 函数完成。
)
5)当CObject指针集合被从归档中载入时,集合中的每个对象会被按如下步骤处理:
×指定对象的类。
×为每一个对象分配堆存储空间。
×将对象数据载入到新申请的内存中。
×将新对象的指针存进集合中。
6)当用户选择了File菜单的Save或Ope n菜单项,应用程序框架随即会创建CArc hive对象(以及内部的CFile对象),然后再调用文档类的Serialize函数,并且将CArch ive对象的引用传递给它。
然后派生文档类的Serialize函数会对每一个非临时数据成员进行序列化。
二,SDI应用程序:
1,SDI MFC应用程序的具体启动步骤:
1)W indows将程序装入内存。
2)构造全局对象theApp。
(当程序被载入时候,所有的全局对象都会立刻被创建。
)
3)W indows调用全局函数WinMain。
4)WinMain自动搜索CWinAp p派生类的唯一实例。
5)WinMain调用theApp的I nitInstanc e函数,该函数在派生应用程序中被重载。
6)被重载的Init Instance函数启动文档的载入以及主框架和视图窗口的显示处理过程。
7)Wi nMain调用the App的Run成员函数,启动窗口消息和命令消息的分发处理过程。
还可以对其它的C WinApp成员函数进行重载。
当应用程序被中止,且所有窗口被关闭后,ExitIn stance函数被调用。
2,派生的应用程序类InitIn stance函数中可以看到这样代码:
C SingleDocT emplate* p DocTemplat e;
pDocTe mplate = n ew CSingle DocTemplat e(
IDR_M AINFRAME,
RUNTIME_CLASS(CMy15aDoc),
RUNTIME_CL ASS(CMainF rame), // main SDI frame window
RUNTIME_CL ASS(CMy15a View));
A ddDocTempl ate(pDocTe mplate);
通过这组代码将程序类,文档类,视图窗口类以及主框架类建立类之间的相互关系(注意这里是类之间相互关系)。
(即通过AddDo cTemplate调用将所有的应用程序元素联系在一起)
说明:
1)应用程序对象在模板被创建之前已经存在,但此时文档,视图,以及框架对象还没有被创建。
应用程序框架在以后需要的时候会通过动态创建这些对象,这里是通过适用RU NTIME_CLAS S来实现的。
2)P338页两个图:类之间关系图和对象之间关系图这里掠过,找电子版看看。
3)IDR_MAINFR AME 是用来标示字符串表资源的。
IDR_MAINFRAME所标示的字符串被分成一些以"n"结尾的子字符串。
当应用程序执行时候,这些子字符串会在各种地方出现。
在RC文件Stri ngTable中可以找到IDR_MAIN FRAME串,串的具体对应关系参看P339页。
3,SDI文档多视图两种技术:提供菜单项供用户选择视图,将多视图安排在切分窗口中。
4,创建空文档……CWi nApp::OnFi leNew函数
应用程序类的在调用了Ad dDocTempla te函数之后,通过C WinApp::Pr ocessShell Command函数间接调用了CWinAp p成员函数OnFil eNew完成以下工作:
1)构造文档对象,但并不从磁盘中读取数据。
2)构造主框架对象,并创建主框架窗口,但并不对其显示。
主框架窗口包括ID R_MAINFRAM E菜单,工具栏和状态栏。
3)构造视图对象,并创建视图窗口,但并不对它进行显示。
4)建立文档,主框架和视图对象之间的相互联系(注意这里是对象之间联系)5)调用文档对象的OnNe wDocument虚成员函数。
它会调用D eleteConte nts虚函数。
6)调用视图对象的CVi ew::OnInit iaUpdate虚成员函数。
7)调用框架对象的CFrame Wnd::Activ ateFrame虚成员函数,以便显示出具有菜单,视图窗口和控制栏的主框架窗口。
说明:上面一些函数是通过框架间接调用。
在SDI应用程序中,文档,主框架以及视图对象都仅被创建一次,并且将存在于程序的整个运行过程中。
C WinApp::On FileNew函数被InitInstan ce函数所调用,当用户选择了File N ew 菜
单项的时候也调用(此时不需要再构造文档框架视图对象,而是利用现存的完成上述后三个步骤)。
注意:OnFileNe w函数总是要调用De leteConten ts函数,以便将文档清空。
5,CDo cument::On NewDocumen t
如果SDI应用程序不重新使用相同的文档对象,则也就没必要使用OnNewDoc ument函数(因为可以在文档类构造函数中完成所有的文档初始化工作)。
但一般还是得(必须)对OnNe wDocument函数进行重载,以便每次用户选择File N ew或File Op en时候,都能利用它来初始化文档对象。
说明:
一般,在构造函数里尽量少的做一些工作,构造函数做的工作越少,失败的机会就越小。
象CDocum ent::OnNew Document和C View::OnIn itialUpdat e这样的函数是完成初始化工作的好地方。
6,连接FileOpen与系列化代码………OnFileO pen函数
当App Wizard创建应用程序时,它会自动将F ile Open菜单项映射到CWinAp p的OnFileOp en成员函数。
On FileOpen函数进一步调用一组函数来完成一下工作:
1)提示用户选择一个文件。
2)调用已经存在文档对象的CDocu ment::OnOp enDocument虚成员函数。
该函数将打开文件,调用Del eteContent s函数,再创建一个用于装入数据的CArc hive 对象,然后调用文档的Serial ize函数从归档中载入数据。
3)调用视图的OnInitia lUpdate函数。
除了使用File Open菜单项外,还可以选择使用最近使用过的文件列表。
(框架会记录4个最近使用过的文件,并将它们的名字显示在File菜单中。
这些文件名在程序的运行过程中被记录在Windows的注册表中。
说明:
可以改变最近使用文件数。
(在InitIns tance函数里为L oadStdProf ileSetting函数提供适当参数)
CWinApp::L oadStdProf ileSetting s
void Loa dStdProfil eSettings( UINT nMax MRU = _AFX_MRU_COUNT );
//nMax MRU:The nu mber of re cently use d files to track.
//Call thismember fun ction from within th e InitInst ance membe r function to enable and loadthe list o f most rec ently used(MRU) fil es and las t previewstate. IfnMaxMRU is 0, no MRU list will be mainta ined.
7,C Document::DeleteCont ents
1)当F ile New或Fi le Open菜单项被选中CDocume nt::OnNewD ocument或CD ocument::O nOpenDocum ent函数都要调用C Document::DeleteCont ents函数(清除现存文档对象内容)。
即:当文档对象第一次被创建之后,CDoc ument::Del eteContent s 会被立刻调用,而当文档被关闭,它再次被调用。
2)常在派生类中重载Delet eContents函数完成对文档对象中内容清除工作。
3)CDocument::DeleteCo ntents Called b y the fram ework to d elete thedocument’s data with out destro ying the C Document o bject itse lf. It iscalled jus t before t he documen t is to be destroyed. It is al so calledto ensurethat a doc ument is e mpty befor e it is re used. This is partic ularly imp ortant for an SDI ap plication, which use s only one document; the docum ent is reu sed whenev er the use r createsor opens a nother doc ument. Cal l this fun ction to i mplement a n ―Edit Cl ear All‖ o r similarcommand th at deletes all of th e document’s data. T he default implement ation of t his functi on does no thing. Ove rride this functionto deletethe data i n your doc ument.
8,将File Save和File Sav e As与系列化代码相连接:
1)当Ap pWizard在创建应用程序时,将Fil e Save菜单项映射到CDocumen t类的OnFileS ave成员函数。
2)OnFileSav e函数调用CDocu ment::OnSa veDocument函数,OnSaveD ocument 函数使用归档对象(存入)来调用文档的Saria lize函数。
3)File SaveAs菜单象以类似方式处理。
映射CDocu ment::OnFi leSaveAs函数,OnFileSav eAs函数会调用On SaveDocume nt函数。
4)文档存盘的必要的文件管理工作都是由应用程序框架来完成。
注意:
File New和F ile Open被映射到应用程序类成员函数,而File Sa ve和File Sa ve As 则被映射到文档类成员函数。
9,文档的‘胀’标志
许多面向文档的应用程序跟踪用户对文档的修改,当用户试图关闭文档或退出时候,应用程序弹出对话框询问是否需要将文档保存。
1)MFC通过CDo cument::m_bModified来支持这种功能。
文档被修改(变胀了)则m_bModified=TRUE,否则为FA LSE。
2)m_b Modified为p rotected类型,可以通过CDocu ment类中的Set ModifiedFl ag 和IsModif ied成员函数来访问。
(注意:在MSDN中不能查出CDocu ment类m_bMo dified数据成员,不过追踪CDocu ment类定义可以发现如下定义:prot ected: BOO L m_bModif ied; )
3)C Document::SetModifie dFlag
voi d SetModif iedFlag( B OOL bModif ied = TRUE );
CDocu ment::IsMo dified
BO OL IsModif ied( );
10,程序注册
1)利用AppWizard在程序创建Step-4使用Advance d选项为程序添加文件扩展名(或在Stri ngTable里ID R_MAINFRAM E里添加)
2)在I nitInstanc e函数里加入下列代码行:Register ShellFileT ypes(TRUE);(注意添加的位置在AddDocTemp late函数之后!)
11,允许程序的拖放:
如果希望运行中的程序可以打开拖到其上的文件,则必须在主程序框架窗口中调用CWnd的DragA cceptFiles函数。
在InitI nstance函数中(函数未)添加下列代码:m_pMainW nd->DragAc ceptFiles();
2006.7.24 01:14作者:npuwang lei 收藏| 评论:0
VC 技术内幕(第四版)笔记(第15章)
分类:VC学习
第十五章:文档与视图的分离
1,SDI应用程序文档类由CDocumen t类派生,一个文档类可以有一个或多个由C View类派生的视图类。
2,重要成员函数:
1)CVi ew::GetDoc ument
CDoc ument* Get Document() const;
//文档对象是用来保存数据的,而视图对象则是用来显示数据的。
//一个视图对象只有一个与之相关连的文档对象。
//Retu rn A point er to theCDocumentobject ass ociated wi th the vie w.Return N ULL if the view is n ot attache d to a doc ument.
//C all this f unction to get a poi nter to th e view’s d ocument. T his allows you to ca ll the doc ument’s me mber funct ions.
2)C Document::UpdateAllV iews
void UpdateAll Views( CVi ew* pSende r, LPARAMlHint = 0L, CObject*pHint = N ULL );
//当文档数据发生修改的时候,调用该函数通知所有的视图对所显示的数据进行相应得更新。
//pSender:Points tothe view t hat modifi ed the doc ument, orNULL if al l views ar e to be up dated.
//如果在派生文档类中调用UpdateAllV iews函数,则pS ender应该设置为NULL;如果Upd ateAllView s函数在派生视图类成员函数中调用,则pS ender参数应该设置成this(如:G etDocument()->Update AllViews(t his);)
3)CView::OnU pdate
vir tual voidOnUpdate(CView* pSe nder, LPAR AM lHint,CObject* p Hint );
//当应用程序调用了CD ocument::U pdateAllVi ews函数时,会调用OnUpdate函数更新视图显示。
//通常视图类OnUpd ate函数先对文档进行访问,读取文档的数据,然后对视图的数据成员或控制进行更新,以反应文档的变化。
//可以利用OnUp date函数使视图的某部分无效,以触发视图的OnDraw函数调用,从而利用文档数据来重绘对应的视图窗口。
//默认的On Update函数使得整个窗口矩形无效。
//当程序调用CDo cument::Up dateAllVie ws函数,如果pSe nder参数指向了某个特定的视图对象,则除了该指定的视图之外,文档的所有其它视图的OnUpdate函
数都会被调用。
4)CView::On InitialUpd ate
virtu al void On InitialUpd ate( );
//当应用程序被启动,或当用户从File菜单选择了New时候,或当用户从File 菜单选择了Open时候,该虚函数都会被自动调用。
//CView基类中的OnInit ialUpdate函数除调用OnUpda te函数中没做其它任何事情。
如果在派生类中重载该函数一定要调用基类的OnInit ialUpdate函数,或调用派生类的O nUpdate函数。
//当应用程序启动时,框架调用视图类的OnCreate函数之后立即调用OnIn itialUpdat e函数。
OnCrea te函数只能被调用一次,而OnIniti alUpdate可以被调用多次。
//可以通过在派生重载On InitialUpd ate函数,在其中对视图对象进行初始化。
5)CDocum ent::OnNew Document
virtual BO OL OnNewDo cument( );
//Calledby the fra mework aspart of th e File New command.The defaul t implemen tation ofthis funct ion callsthe Delete Contents m ember func tion to en sure thatthe docume nt is empt y and then marks the new docum ent as cle an. Overri de this fu nction toinitialize the datastructurefor a newdocument.Y ou should call thebase class version o f this fun ction from your over ride.
//If the userchooses th e File New command i n an SDI a pplication, the fram ework uses this func tion to re initialize the exist ing docume nt, rather than crea ting a new one. If t he user ch ooses File New in amultiple d ocument in terface (M DI) applic ation, the framework creates a new docum ent each t ime and th en calls t his functi on to init ialize it. Y ou mustplace your initializ ation code in this f unction in stead of i n the cons tructor fo r the File New comma nd to be e ffective i n SDI appl ications.
3,简单文档视图交互应用程序步骤(单文档单视图):
1)在派生文档类中定义文档的数据成员,用以保存程序中数据。
为了方便派生视图类的访问可以将这些数据成员定义成公有类型或将派生视图类定义为派生文档类的友元类。
2)在派生视图类中对OnIn itialUpdat e虚成员函数进行重载。
当文档数据被初始化或被从磁盘中读出后,框架会自动调用OnI nittialUpd ate函数。
该函数对视图进行更新,以便放映出当前的文档数据。
3)在派生视图类中,让窗口消息控制函数和命令消息控制函数直接读取和更新文档数据成员,利用GetDo cument函数对文档对象进行访问。
对应事件发生次序:
程序启动:CMyD ocument对象被创建-》CMyVie w对象被创建-》视图窗口被创建-》CMy View::OnCr eate函数被调用(如果被映射)-》CM yDocument::OnNewDocu ment函数被调用-》
CMyView::OnInitial Update函数被调用-》视图对象被初始化-》视图窗口无效
-》CMyView:O nDraw函数被调用
用户编辑数据:C MyView类中函数对CMyDocume nt数据成员进行更新
退出程序:CMy View对象被删除-》CMyDocume nt对象被删除
4,CFormVie w类
CFormVi ew类具有许多无模式对话框的特点,其派生类也和相应的对话框资源相联系,也支持DD X和DDV等。
CF ormView类对象可以直接接收来之本身的控制通告消息,也可接收来自框架窗口的命令消息。
(同时具有许多无模式类对话框和视图类特征)。
派生层次:CView|CS crolView|C FromView
C FormView类虽然不是从CDialo g类派生,但是围绕对话框创建,因而可以使用许多CDialog类成员函数。
(这时只需将CFormVie w指针强制转换成CD ialog类指针即可)如:((CDial og*)this)->GotoDlgCt rl(GetDlgI tem(IDC_NA ME));
5,高级文档视图交互应用程序步骤(单文档多视图):
编写多视图应用程序,只要对其中某一视图编辑改变了文档,则其它的文档需要随之更新,以反映出文档的变化。
步骤:
1)在派生文档类中定义需要的数据成员。
同时设计访问该数据成员的方法,或将视图类设计成文档类的友元类。
2)在派生视图类中,利用向导重载OnUp date虚成员函数。
当文档数据被修改后,应用程序框架会自动调用该函数。
利用重载的OnUpdate函数来完成视图的更新,以反映当前的文档数据。
3)对所有的命令消息判断其哪些是针对文档的哪些是针对视图的,然后将其映射到相应的类中。
4)在派生视图类中,允许对文档数据进行更改,在退出之前,一定要调用CD ocument::U pdateAllVi ews函数更新其它的视图。
使用CView::GetDocum ent获取相关联的文档对象指针。
5)在派生文档类中,允许对文档数据进行修改,修改后退出前要调用Up dateAllVie ws函数更新与其关联的所有视图。
对应发生的事件次序:
应用程序启动:CMyD ocument对象被创建-》CMyVie w对象被创建-》其它视图对象被创建-》视图窗口被创建-》CM yView::OnC reate函数被调用(如果被映射)-》C MyDocument::OnNewDoc ument函数被调用-》CMyView::OnInitial Update函数被调用-》调用CMyVi ew::OnUpda te-》初始化视图
用户编辑数据:视图类中函数对CMyDo cument数据成员进行更新
退出时候调用CDocume nt::Update AllViews函数更新其它的视图
退出程序:视图对象被删除-》CMyDocu ment对象被删除
6,笔记略过内容:诊断信息转储(参见P296-P300),CObList集合类(参见P308-312)
1)选择De bug目标时_DEB UG常量候被定义,程序中的诊断代码会被连到程序中去。
2)选择Release目标,诊断信息转储被禁止,诊断代码也不会被连到程序中去。
由Rel ease目标生成的可执行文件非常小(比使用Debug目标生成的目标文件小很多呢)。
3)CObLis t很重要的特性是可以包含混合指针。
2006.7.24 01:14 作者:np uwanglei 收藏| 评论:0
V C 技术内幕(第四版)笔记(第14章)
分类:VC学习
第十四章:可重用框架窗口类
1, 可重用基类的设计:为某个工程所设计的类应该能够被提取出来,使它进一步一般化后被应用于其他的应用程序。
2, 一些重要函数:
1)CFrame Wnd::Activ ateFrame
virtual vo id Activat eFrame( in t nCmdShow = -1 );
//以nCmdShow作为参数调用CWnd::ShowWind ow函数来显示框架窗口(其菜单视图控制栏窗口也会被同时显示)。
nCmdShow决定窗口是最大化还是最小化等。
//在派生类中重载Activa teFrame ,在nCmdShow传递给CFrameWnd::Activate Frame之前修改n CmdShow的值。
还可以调用CWnd::SetWindow Placement设置框架窗口的位置和尺寸并还可以设置控制栏的可视状态。
2)CWnd::PreC reateWindo w
virtualBOOL PreCr eateWindow( CREA TEST RUCT& cs );
//PreCre ateWindow在调用Activate Frame函数之前被框架调用,用以在窗口显示之前改变其窗口的特性(特性主要参考:CREATESTRU CT结构。
//在派生类中重载它,在CS传给基类之前改变CS结构中值,从而实现定制(显示)窗口。
3)在MDI中,主框架窗口的ShowWin dow函数是由应用程序类InitInst ance函数调用,不是由CFrameWn d::Activat eFrame函数调用。
故要控制MDI主框架窗口的一些特性,应该在应用程序类Ini tInstance函数中添加相应的代码。
3,Window注册表
1)Wind ow注册表是一组系统文件,由Window管理,Windows和其他的应用程序可以在注册表中保存一些永久的信息。
Wind ows 注册表被组织成一个层次的数据库,字符和整型数据可以通过一个多部分键值来访问。
2)操作:
S etRegistry Key Caus es applica tion setti ngs to bestored inthe regist ry instead of .INI f iles.
Ge tProfileIn t Retrie ves an int eger froman entry i n the appl ication’s.INI file. WritePro fileInt W rites an i nteger toan entry i n the appl ication’s.INI file.
GetProfi leString Retrievesa string f rom an ent ry in theapplicatio n’s .INI f ile.
Writ eProfileSt ring Writ es a strin g to an en try in the applicati on’s .INIfile.
说明:
1)vc5开始,A ppWziard在应用程序类的InitI nstance函数中有对CWinApp::SetRegist ryKey函数的调用,如下:
SetR egistryKey(_T("Local AppWizard-Generated Applicati ons"));
该函数的调用使应用程序使用注册表,如果去掉则应用程序不使用注册表,仅在Windows目录下创建一个INI文件,并使用该文件。
SetRegist ryKey的字符串参数建立最上层键,其后的注册表函数定义下面的两层(称为头名和入口名)。
2)为能够使用注册表访问函数,需要一个指向应用实例对象的指针,可以通过AfxGetApp函数获得。
如下:
Af xGetApp()->WriteProf ileString("Text form atting","F ont","Time s Roman"); AfxGetApp()->WriteP rofileInt("Text Form atting","P oints",10);
3)注册表访问函数可以将注册表当成C String对象或无符号整数来处理。
4,CString类中,LPCTSTR并不是一个指向CSt ring对象的指针,而是一个用来代替co nst char*的Unicode版本。
1)CStrin g str;
ch ar ch[]="a bcdefg";
strcpy(str.GetBuffer(strlen(ch)),ch);
s tr.Release Buffer();
pDC->Text Out(0,0,st r);
输出:abc defg
2)CS tring str("abcdefg");
char ch[20];
str cpy(ch,LPC TSTR(str));
pDC->Te xtOut(0,0,ch);
输出:ab cdefg
说明:
char *strc py( char *strDestina tion, cons t char *st rSource );
3)编写带字符串参数的函数原则:
a,如果不改变字符串内容:可以使用const char*形参,可以使用CString&类型形参
b,如果改变字符串内容,可以使用CString&类型形参(当然可以使用指针,但这儿不建议)。
5,获取窗口坐标
GetWin dowPlaceme nt
//Retri eves the s how stateand the no rmal (rest ored), min imized, an d maximize d position s of a win dow.
SetW indowPlace ment(可以返回最大化前的屏幕坐标)
//Sets the show stat e and thenormal (re stored), m inimized,and maximi zed positi ons for awindow.
G etWindowRe ct
//Getsthe screen coordinat es of CWnd.
2006.7.24 01:13作者:npuwang lei 收藏| 评论:0
VC 技术内幕(第四版)笔记(第13章)
分类:VC学习
第十三章:工具栏和状态栏
1,工具栏是CToolB ar类一个对象,状态栏是CStatusB ar类的对象.CTo olBar类和CSt atusBar类均由CControlBa r类派生.CCont rolBar类则由C Wnd类派生.
CC ontrolBar类所支持的控制栏窗口位于主框架窗口内,并且这些控制栏窗口能够随着主框架窗口的尺寸改变或移动自动调整自己的尺寸与位置.
控制栏对象的构造与析构以及窗口的创建都是由应用程序框架来管理的,其向导产生的代码位于框架头文件和代码文件中.
2,工具栏的按钮被按下是会象菜单或加速键一样,发送相应的命令消息(该命令消息会象菜单命令一样进行传递.原因:工具栏对象以及状态栏对象都与主框架窗口联系.).
更新命令UI消息控制函数一方面可以用来更新工具栏中的按钮的状态,另一方面可以用来修改工具栏中的按钮图形.
整个工具栏只有一个位图,每一个按钮在其中占一个高15像素宽16像素的位图片.
注意:不要直接编辑工具栏位图,而是应该使用Deve loperStudi o的特定工具栏编辑工具进行编辑.
3,更新命令消息控件函数主要是用来对菜单项进行禁止和复选的,但也可以作用于工具栏按钮.
1)CCmdUI::Enable
v irtual voi d Enable(BOOL bOn = TRUE );
//bOn: TRUE to enable the item, FALSE todisable it.
//Call t his member functionto enableor disable the user-interfaceitem for t his comman d.
2)CCmdU I::SetChec k
virtual void SetC heck( intnCheck = 1 );
//nChe ck: Specif ies the ch eck stateto set. If 0, unchec ks; if 1,checks; an d if 2, se ts。