版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第7章 框架窗口、文档和视图,7.1框架窗口 7.2文档及其序列化 作业1 7.3视图及视图类 7.4文档视图结构 作业2,7.1框架窗口,7.1.1主窗口和文档窗口 主窗口是应用程序直接放置在桌面上的那个窗口,每个应用程序只能有一个主窗口,主窗口的标题栏上往往显示应用程序的名称。 文档窗口对于SDI程序来说,它和主窗口是一致的,即主窗口就是文档窗口;而对于MDI程序,文档窗口是主窗口的子窗口,如图。文档窗口一般都有相应的可见边框,它的客户区是由相应的视图来构成的,因此可以说视图是文档窗口内的子窗口。文档窗口时刻跟踪当前处于活动状态的视图的变化,并将用户或系统产生的命令消息传递给当前活动视图。
2、而主窗口负责管理各个用户交互对象并根据用户操作相应地创建或更新文档窗口及其视图。,7.1框架窗口,7.1.2窗口风格的设置 窗口风格 窗口风格通常有一般和扩展两种形式。这两种形式的窗口风格可在函数CWnd:Create或CWnd:CreateEx参数中指定,CreateEx函数可同时支持以上两种风格,而CWnd:Create只能指定窗口的一般风格。需要说明的是,对于控件和对话框这样的窗口来说,它们的窗口风格可直接通过其属性对话框来设置。 需要说明的是,除了上述风格外,框架窗口还有以下三个自己的风格。它们都可以在PreCreateWindow重载函数中指定。 FWS_ADDTOTITLE 该风格
3、指定相关的信息如文档名添加到框架窗口标题的后面。 FWS_PREFIXTITLE 该风格使得框架窗口标题中的文档名显示在应用程序名之前。 FWS_SNAPTOBARS 该风格用来调整窗口的大小,使它刚好包含了框架窗口中的控制栏。,7.1框架窗口,用MFC AppWizard设置,图7.2 MFC AppWizard的窗口风格设置,7.1框架窗口,修改CREATESTRUCT结构 窗口创建之前,系统自动调用PreCreateWindow虚函数。在用MFC AppWizard创建SDI/MDI应用程序结构时,MFC已为主窗口或文档窗口类自动重载了该虚函数。可以在此函数中通过修改CREATESTRU
4、CT结构来设置窗口的绝大多数风格。 例如,在SDI程序中,框架窗口默认的风格是WS_OVERLAPPEDWINDOW和FWS_ADDTOTITLE的组合,更改风格代码: BOOL CMainFrame:PreCreateWindow(CREATESTRUCT ,7.1框架窗口,使用ModifyStyle和ModifyStyleEx CWnd类中的成员函数ModifyStyle和ModifyStyleEx也可用来更改窗口的风格,其中ModifyStyleEx还可更改窗口的扩展风格。这两个函数具有相同的参数,其含义如下。 BOOL ModifyXXXX( DWORD dwRemove, DWORD
5、 dwAdd, UINT nFlags = 0 ); 参数dwRemove用来指定需要删除的风格,dwAdd用来指定需要增加的风格,nFlags表示SetWindowPos的标志,0(默认)表示更改风格的同时不调用SetWindowPos函数。 由于框架窗口在创建时不能直接设定其扩展风格,因此只能通过调用ModifyStyle函数来进行。,7.1框架窗口,例Ex_Vscroll 多文档(MDI)的子文档窗口增加垂直滚动条。 (1)用MFC AppWizard创建一个多文档应用程序。 (2)用ClassWizard为子文档窗口类CChildFrame添加OnCreateClient消息处理,并增
6、加下列代码: BOOL CChildFrame:OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) ModifyStyle(0, WS_VSCROLL, 0); return CMDIChildWnd:OnCreateClient(lpcs, pContext); (3)编译并运行,如图。,图7.3 为文档子窗口添加垂直滚动条,7.1框架窗口,设置TopMost窗口风格 最顶(TopMost)窗口是指那些始终出现在桌面的最前方且不会被其他窗口覆盖的窗口。如果要创建这样的一个最顶窗口,则在运行时必须指定WS_EX_TOPMO
7、ST扩展窗口风格。此风格的设置是在CWnd:SetWindowPos函数中进行;作为技巧,我们可以先调用CWnd:GetExStyle函数来确定是否已经设置了WS_EX_TOPMOST风格。例如下面的代码: void SetWindowTopMost(CWnd* pWnd) ASSERT_VALID(pWnd); pWnd-SetWindowPos(pWnd-GetExStyle() 函数SetWindowPos具体的使用方法将在下一节中介绍。,7.1框架窗口,7.1.3窗口状态的改变 用ShowWindow改变窗口的显示状态 当一个新的应用程序创建之后,InitInstance函数总会调用S
8、howWindow函数来显示窗口 想要改变改变窗口显示状态,只需根据上表选择所需的参数值,调用ShowWindow函数就可达到目的。当然,也可对CWinApp的公有型(public)成员变量m_nCmdShow进行赋值,同样能达到效果。下面的代码是将窗口的初始状态设置为“最小化”: BOOL CEx_SdiApp:InitInstance() . m_nCmdShow = SW_SHOWMINIMIZED; / 由于CEx_SdiApp类继承了基类CWinApp的特性,因此也可在派生类 / CEx_SdiApp使用这个公有型成员变量m_nCmdShow。 m_pMainWnd-ShowWind
9、ow(m_nCmdShow); m_pMainWnd-UpdateWindow(); return TRUE; ,7.1框架窗口,用SetWindowPos或MoveWindow改变窗口的大小和位置 SetWindowPos不仅可以改变窗口的大小、位置,还可以改变所有窗口在堆栈排列的次序(Z次序),这个次序是根据它们在屏幕出现的先后来确定的。 函数CWnd:MoveWindow也可用来改变窗口的大小和位置,用户必须在MoveWindow函数中指定窗口的大小。 void MoveWindow( int x, int y, int nWidth, int nHeight, BOOL bRepain
10、t = TRUE ); void MoveWindow( LPCRECT lpRect, BOOL bRepaint = TRUE ); 参数x和y表示窗口新的左上角坐标,nWidth和nHeight表示窗口新的宽度和高度,bRepaint用于指定窗口是否重绘,lpRect表示窗口新的大小和位置。 使用上述两个函数把主窗口移动到屏幕的(100,100)处(代码添在CEx_SdiApp:InitInstance中return TRUE语句之前)。 / 使用SetWindowPos函数的示例 m_pMainWnd-SetWindowPos(NULL,100,100,0,0,SWP_NOSIZE|S
11、WP_NOZORDER); CRect rcWindow; / 使用MoveWindow函数的示例 m_pMainWnd-GetWindowRect(rcWindow); m_pMainWnd-MoveWindow(100,100,rcWindow.Width(),rcWindow.Height(),TRUE); 改变窗口的大小和位置的CWnd成员函数还不止以上两个。例如CenterWindow函数是使窗口居于父窗口中央,就像下面的代码: CenterWindow(CWnd:GetDesktopWindow();/ 将窗口置于屏幕中央 AfxGetMainWnd()-CenterWindow(
12、);/ 将主框架窗口居中,7.2文档及其序列化,7.2.1单文档和多文档 一个多文档应用程序的示例过程: (1)用MFC AppWizard创建一个多文档应用程序项目Ex_Mdi。由于向导默认创建的就是这种程序类型,因此只要在向导的Step 1对话框中单击Finish按钮即可创建一个默认的多文档应用程序。 (2)打开CEx_MdiApp:InitInstance可看出与默认的单文档应用程序不同的代码是: BOOL CEx_MdiApp:InitInstance() CMultiDocTemplate* pDocTemplate; pDocTemplate = new CMultiDocTemp
13、late( IDR_EX_MDITYPE, RUNTIME_CLASS(CEx_MdiDoc), RUNTIME_CLASS(CChildFrame), / MDI文档子窗口 RUNTIME_CLASS(CEx_MdiView); AddDocTemplate(pDocTemplate); / 创建MDI主框架窗口 CMainFrame* pMainFrame = new CMainFrame; if (!pMainFrame-LoadFrame(IDR_MAINFRAME) return FALSE; m_pMainWnd = pMainFrame; ,7.2文档及其序列化,(3)用Clas
14、sWizard为该项目添加一个CDocument派生类CAnotherDoc,并在CEx_Mdi- App:InitInstance增加下列代码: BOOL CEx_MdiApp:InitInstance() CMultiDocTemplate* pDocTemplate; pDocTemplate = new CMultiDocTemplate(IDR_EX_MDITYPE, RUNTIME_CLASS(CEx_MdiDoc), RUNTIME_CLASS(CChildFrame), / MDI文档子窗口 RUNTIME_CLASS(CEx_MdiView); AddDocTemplate(
15、pDocTemplate); CMultiDocTemplate* pAnother; pAnother = new CMultiDocTemplate(IDR_EX_MDITYPE, RUNTIME_CLASS(CAnotherDoc), RUNTIME_CLASS(CChildFrame), / MDI文档子窗口 RUNTIME_CLASS(CEx_MdiView); AddDocTemplate(pAnother); / 创建MDI主框架窗口 CMainFrame* pMainFrame = new CMainFrame; if (!pMainFrame-LoadFrame(IDR_MA
16、INFRAME) return FALSE; m_pMainWnd = pMainFrame; ,7.2文档及其序列化,(4)在Ex_Mdi.cpp文件的开始处,添加包含CAnotherDoc类的头文件: #include AnotherDoc.h (5)编译并运行后,如图,从中选择一个文档类型。任何时候,选择Ex_Mdi程序的“文件”菜单“新建”命令或单击“新建”工具按钮都将弹出此对话框。 选定第二个文档类型后,单击确定。这时程序出现一个断言错误,这是因为在视图类中有一个GetDocument函数,它的代码如下: CEx_MdiDoc* CEx_MdiView:GetDocument() /
17、 non-debug version is inline ASSERT(m_pDocument-IsKindOf(RUNTIME_CLASS(CEx_MdiDoc); return (CEx_MdiDoc*)m_pDocument; 创建的文档类型是CAnotherDoc时,由于两种类型的文档共用一个视图,调用的GetDocument函数是同一个函数,因此断言不成立,程序不能正常运行。 (6)用ClassWizard为该项目添加一个CView类的派生类CAnotherView,并将InitInstance第二模板pAnother中的CEx_MdiView改成CAnotherView,然后在该源
18、文件前面添加CAnotherView的头文件AnotherView.h。 (7)再次运行,上述问题得到解决。但是,图7.4的文档“新建”对话框中显示的文档类型名称应该怎么修改呢?这时就需要使用文档的字串资源。,图7.4 文档“新建”对话框,7.2文档及其序列化,7.2.2文档的字串资源 通过对文档的字串资源修改可以改变文档窗口标题、文档类型以及通用文件对话框中的某些内容。例如下面的示例过程: (1)打开前面的多文档应用程序项目Ex_Mdi。 (2)打开String Table,将IDR_EX_MDITYPE字串资源复制,复制后的ID为IDR_ANOTHERTYPE,修改这两个字串资源,结果如下
19、表所示。 如果IDR_ANOTHERTYPE的值不等于130,可在其属性对话框中直接给标识赋值,如图。 (3)将InitInstance第二模板pAnother中的资源号IDR_EX_MDITYPE改成IDR_ANOTHERTYPE。,图7.5 指定标识值,7.2文档及其序列化,(4)重新编译并运行,如图。测试后还发现“打开”或“保存”对话框中的“文件类型”框中显示出文档字串资源定义的类型名,如图。 文档资源字串的内容也可在文档应用程序创建时的Advanced Options对话框中指定,如图,图中数字表示该项的含义与表中对应串号的含义相同。,图7.7 Ex_Mdi运行结果,图7.6 “新建”
20、对话框,7.2文档及其序列化,7.2.3 SDI序列化过程 创建空文档 应用程序类的InitInstance函数在调用了AddDocTemplate函数之后,会通过CWinApp: ProcessShellCommand间接调用CWinApp的另一个非常有用的成员函数OnFileNew,并依次完成下列工作: (1)构造文档对象,但并不从磁盘中读数据。 (2)构造主框架类CMainFrame的对象,并创建该主框架窗口,但不显示。 (3)构造视图对象,并创建视图窗口,也不显示。 (4)通过内部机制,使文档、主框架和视图“对象”之间“真正”建立联系。AddDocTemplate函数建立的是“类”之间
21、的联系。 (5)调用文档对象的CDocument:OnNewDocument虚成员函数,并调用CDocument: DeleteContents(清除文档对象的内容)虚函数。 (6)调用视图对象的CView:OnInitialUpdate虚成员函数。 (7)调用框架对象的CFrameWnd:ActiveFrame虚成员函数,以便显示出具有菜单、工具栏、状态栏以及视图窗口的主框架窗口。 MFC AppWizard为用户在文档类中自动产生OnNewDocument虚函数的重载,用户利用此函数框架可以对文档对象进行初始化。,7.2文档及其序列化,打开文档 MFC AppWizard创建应用程序时,它
22、会自动将“文件(File)”菜单中的“打开(Open)”命令(ID号为ID_FILE_OPEN)映射到CWinApp的OnFileOpen成员函数。这一结果可以从应用类(.cpp)的消息入口处得到验证: BEGIN_MESSAGE_MAP(CEx_SdiApp, CWinApp) ON_COMMAND(ID_FILE_NEW, CWinApp:OnFileNew) ON_COMMAND(ID_FILE_OPEN, CWinApp:OnFileOpen) / Standard print setup command ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp:
23、OnFilePrintSetup) END_MESSAGE_MAP() OnFileOpen函数还会进一步完成下列工作: (1)弹出通用“打开”对话框,供用户选择一个文件。 (2)调用文档对象的CDocument: OnOpenDocument虚成员函数。该函数将打开文件,并调用DeleteContents清除文档对象的内容,然后创建一个CArchive对象用于数据的读取,接着又自动调用Serialize函数。 (3)调用视图对象的CView:OnInitialUpdate虚成员函数。,7.2文档及其序列化,MFC为我们重载了Serialize函数,使得我们不必使用CFile类就可以完成相应的
24、文档操作。例如,在文档类中有这样的代码: void CEx_SdiDoc:Serialize(CArchive ,7.2文档及其序列化,保存文档 MFC AppWizard创建应用程序时,会自动将“文件(File)”菜单中的“保存(Save)”命令与文档类CDocument的OnFileSave函数在内部关联起来,在程序框架中看不到相应的代码。OnFileSave函数还会进一步完成下列工作: (1)弹出通用“保存”对话框,让用户提供一个文件名。 (2)调用文档对象的CDocument:OnSaveDocument虚成员函数,接着又自动调用Serialize函数,将CArchive对象的内容保存
25、在文档中。 需要说明的是: 只有在保存文档之前还没有存过盘或读取的文档是“只读”的,OnFileSave函数才会弹出通用“保存”对话框。否则,只执行第二步。 “文件(File)”菜单中还有一个“另存为(Save As)”命令,它是与文档类CDocument的OnFileSaveAs函数相关联。不管文档有没有保存过,OnFileSaveAs都有会执行上述两个步骤。 可以用ClassWizard来重载CDocument:OnSaveDocument函数,并可在Serialize函数体的ar.IsStorinr()为“真”的条件语句处添加代码来在文档中保存用户自己的数据,,7.2文档及其序列化,关闭
26、文档 试图关闭文档时,应用程序会根据文档是否修改进一步完成下列任务: 若文档内容已被修改,则弹出一个消息对话框,询问用户是否需要将文档保存。若用户选择“是”,则应用程序执行OnFileSave过程。 调用CDocument:OnCloseDocument虚成员函数,关闭所有与该文档相关联的文档窗口及相应的视图,调用文档类CDocument的DeleteContents清除文档数据。 MFC应用程序通过CDocument的数据成员m_bModified的逻辑值来判断用户是否对文档进行修改,如果m_bModified为“真”,则表示文档被修改。 protected类型的m_bModified标记是
27、通过CDocument的SetModifiedFlag和IsModified成员函数被访问的。当文档创建、从磁盘中读出以及文档存盘时,文档的这个标记就被置为FALSE(假);而当文档数据被修改时,必须使用SetModifiedFlag函数将该标记置为TRUE。关闭文档时,应用程序才会显示询问消息对话框。,7.2文档及其序列化,7.2.4使用CFile和CArchive类 使用CFile类 (1)文件的打开和关闭 在MFC中,使用CFile打开一个文件通常使用下列两个步骤: 构造一个不带指定任何参数的CFile对象; 调用成员函数Open并指定文件路径以及文件标志。 Open函数的原型如下: B
28、OOL Open( LPCTSTR lpszFileName, UINT nOpenFlags, CFileException* pError = NULL );,7.2文档及其序列化,(2)文件的读写和定位 CFile类支持文件的读、写和定位操作。它们相关函数的原型如下: UINT Read( void* lpBuf, UINT nCount ); 将文件中指定大小的数据读入指定的缓冲区,返回向缓冲区传输的字节数。 void Write( const void* lpBuf, UINT nCount ); 此函数将缓冲区的数据写到文件中。 LONG Seek( LONG lOff, UINT
29、 nFrom ); 定位文件指针的位置,若要定位的位置是合法的,返回从文件开始的偏移量。否则,返回值是不定的且激活一个CFileException对象。 函数void SeekToBegin( )和DWORD SeekToEnd( )分别将文件指针移动到文件开始和结尾位置,对于后者还将返回文件的大小。,7.2文档及其序列化,(3)获取文件的有关信息 BOOL GetStatus( CFileStatus,7.2文档及其序列化,使用CArchive类 (1)CArchive类对象的创建和关闭 创建CArchive对象,有两种方法:一是通过框架隐式创建CArchive对象,另一是显式创建CArch
30、ive 对象。 (2)使用“”运算符 (3)文件文本的读写 CArchive提供成员函数ReadString和WriteString用来从一个文件对象中读写一行文本,它们的原型如下: Bool ReadString(CString,7.2文档及其序列化,7.2.5使用简单数组集合类 简单数组集合类的构造及元素的添加 对简单数组集合类构造的方法都是一样的,都是使用各自的构造函数,它们的原型如下: CByteArray CByteArray( ); CDWordArray CDWordArray( ); CPtrArray CPtrArray( ); CStringArray CStringArr
31、ay( ); CUIntArray CUIntArray( ); CWordArray CWordArray( ); 为了有效使用内存,在使用简单数组集合类之前最好调用成员函数SetSize 设置此数组的大小,与其对应的函数是GetSize,用来返回数组的大小。它们的原型如下: void SetSize( int nNewSize, int nGrowBy = -1 ); int GetSize( ) const; 向简单数组集合类添加一个元素,可使用成员函数Add和Append,它们的原型如下: int Add( CObject* newElement ); int Append( cons
32、t CObArray,7.2文档及其序列化,访问简单数组集合类的元素 在MFC中,一个简单数组集合类元素的访问既可以使用GetAt函数,也可使用“”操作符,例如: / CObArray:operator 示例 CObArray array; CAge* pa;/ CAge是一个用户类 array.Add( new CAge( 21 ) ); / 添加一个元素 array.Add( new CAge( 40 ) ); / 再添加一个元素 pa = (CAge*)array0; / 获取元素0 ASSERT( *pa = CAge( 21 ) ); array0 = new CAge( 30 );
33、 / 替换元素0; ASSERT( *(CAge*) array0 = CAge( 30 ) ); / CObArray:GetAt示例 CObArray array; array.Add( new CAge( 21 ) );/ 元素 0 array.Add( new CAge( 40 ) ); / 元素 1 ASSERT( *(CAge*) array.GetAt( 0 ) = CAge( 21 ) );,7.2文档及其序列化,删除简单数组集合类的元素 删除简单数组集合类中的元素一般需要进行以下几个步骤: (1)使用函数GetSize()和整数下标值访问简单数组集合类中的元素。 (2)若对象
34、元素是在堆中创建的,则使用delete删除每一个对象元素。 (3)调用函数RemoveAll()删除简单数组集合类中的所有元素。 例如,下面代码过程是一个CObArray的删除示例: CObArray array; CAge* pa1; CAge* pa2; array.Add( pa1 = new CAge( 21 ) ); array.Add( pa2 = new CAge( 40 ) ); ASSERT( array.GetSize() = 2 ); for (int i=0;iarray.GetSize();i+) delete array.GetAt(i); array.Remove
35、All(); 函数RemoveAll是删除数组中的所有元素,而函数RemoveAt( int nIndex, int nCount = 1)则表示要删除数组中指定元素开始的指定数目的元素。,作业,1。P376:1,6,10; 2.p434:实验12,7.3视图及视图类,7.3.1一般视图类的使用,图7.9 “Step 6”对话框,7.3视图及视图类,CFormView类 CFormView类是一个非常有用的视图类,它具有许多无模式对话框的特点。像CDiolog的派生类一样,CFormView的派生类也和相应的对话框资源相联系,它也支持对话框数据交换和对话框数据确认(DDX和DDV)。 CFor
36、mView是所有表单视(如CRecordView、CDaoRecordView、CHtmlView等)的基类;一个基于表单的应用程序能让用户在程序中创建和使用一个或多个表单。 创建表单应用程序的基本方法除了在创建SDI/MDI的第六步中选择CFormView作为应用程序视图类的基类外。还可通过相关菜单命令来自动插入一个表单,其步骤如下: (1)切换到ClassView标签项,在项目名称上右击鼠标按钮。从弹出的快捷菜单中选择“New Form”命令,或者直接在主菜单中选择“Insert”“New Form.”菜单命令,弹出如图7.10的“New Form”对话框。 (2)在“New Form”对
37、话框中,键入表单名称。如果想要表单支持“自动化”特性,则选择“Automation”单选框。在“Document Template Information”栏中,指定和表单并联的文档内容。如果想要更改文件扩展名或文档模板字串资源,则可按击Change按钮。 (3)单击OK按钮,这样,一个表单视图派生类的程序框架就被添加到用户程序中;此时,我们就可用对话框编辑器为表单增加一些控件。,7.3视图及视图类,CEditView类 CEditView类对象是一种视图,提供窗口编辑控制功能,可以执行简单文本操作。由于CEditView类自动封装上述功能的映射函数,因此只要在文档模板中使用CEditView
38、类,那么应用程序的“编辑”菜单和“文件”菜单里的菜单项都可自动激活。 但CEditView仍然摆脱不了所有编辑控件的限制,如: CEditView不具有所见即所得编辑功能。 CEditView只能将文本作单一字体的显示,不支持特殊格式的字符。 CEditView可容纳的文本总数有限,在32位Windows中最多不超过1M字节。,图7.10 “New Form”对话框,7.3视图及视图类,CRichEditView类 CRichEditView类使用了复文本编辑控件,因此它支持混合字体格式和更大数据量的文本。CRichEditView类被设计成与CRichEditDoc和CRichEditCnt
39、rItem类一起使用,它们可实现一个完整的ActiveX包容器应用程序。 CHtmlView 类 CHtmlView 类是在文档视图结构中提供WebBrowser控件的功能。WebBrowser控件可以浏览网址,也可以作为本地文件和网络文件系统的窗口,它支持超级链接、统一资源定位(URL)导航器并维护历史列表等。 CScrollView类 CScrollView类不仅能直接支持视图的滚动操作,而且还能管理视口的大小和映射模式,并能响应滚动条消息、键盘消息以及鼠标滚轮消息。 滚动视图第一次被创建时,往往在重载的CView:OnInitialUpdate或CView:OnUpdate中调用CScr
40、ollView成员函数SetScrollSizes来设置相关参数,如映射模式、滚动逻辑窗口的大小、水平或垂直方向的滚动量等。如果仅需要视图具有自动缩放功能(而不具有滚动特性),则用CScrollView:SetScaleToFitSize函数代替SetScrollSizes即可。,7.3视图及视图类,7.3.2列表控件和列表视图 列表控件的风格及其修改,7.3视图及视图类,列表项的基本操作 函数SetImageList用来为列表控件设置一个关联的图像列表,其原型如下: CImageList* SetImageList( CImageList* pImageList, int nImageLis
41、t ); 函数InsertItem用来向列表控件中插入一个列表项。该函数成功时返回新列表项的索引号,否则返回-1。函数原型如下: int InsertItem( const LVITEM* pItem ); int InsertItem( int nItem, LPCTSTR lpszItem ); int InsertItem( int nItem, LPCTSTR lpszItem, int nImage ); pItem用来指定一个指向LVITEM结构的指针,其结构描述如下: typedef struct _LVITEM UINT mask; / 指明哪些参数有效 int iItem;
42、/ 列表项索引 int iSubItem; / 子项索引 UINT state; / 列表项状态 UINT stateMask; / 指明state哪些位是有效的,-1全部有效 LPTSTR pszText; / 列表项文本标签 int cchTextMax; / 文本大小 int iImage; / 在图像列表中列表项图标的索引号。 LPARAM lParam;/ 32位值 intiIndent;/ 项目缩进数量,1个数量等于1个图标的像素宽度 LVITEM, FAR *LPLVITEM;,7.3视图及视图类,函数DeleteItem和DeleteAllItems分别用来删除指定的列表项和全
43、部列表项,函数原型如下: BOOL DeleteItem( int nItem ); BOOL DeleteAllItems( ); 函数FindItem用来查寻列表项,函数成功查找时返回列表项的索引号,否则返回-1。其原型如下: int FindItem( LVFINDINFO* pFindInfo, int nStart = -1 ) const; pFindInfo表示要查找的信息,其结构描述如下: typedef struct tagLVFINDINFO UINT flags;/ 查找方式 LPCTSTR psz;/ 匹配的文本 LPARAMlParam;/ 匹配的值 POINT pt
44、;/ 查找开始的位置坐标。 UINT vkDirection;/ 查找方向,用虚拟方向健值表示。 LVFINDINFO, FAR* LPFINDINFO; 函数Arrange用来按指定方式重新排列列表项,其原型如下: BOOL Arrange( UINT nCode );,7.3视图及视图类,函数InsertColumn用来向列表控件插入新的一列,函数成功调用后返回新的列的索引,否则返回-1。其原型如下: int InsertColumn( int nCol, const LVCOLUMN* pColumn ); int InsertColumn( int nCol, LPCTSTR lpsz
45、ColumnHeading, int nFormat = LVCFMT_LEFT, int nWidth = -1, int nSubItem = -1 ); pColumn表示包含新列信息的LVCOLUMN结构地址,其结构描述如下: typedef struct _LVCOLUMN UINT mask; / 指明哪些参数有效 intfmt; / 列的标题或子项文本格式 int cx; / 列的像素宽度 LPTSTR pszText; / 列的标题文本 int cchTextMax; / 列的标题文本大小 int iSubItem; / 和列相关的子项索引 int iImage;/ 图像列表中
46、的图像索引 int iOrder;/ 列的序号,最左边的列为0 LVCOLUMN, FAR *LPLVCOLUMN; 函数DeleteColumn用来从列表控件中删除一个指定的列,其原型如下: BOOL DeleteColumn( int nCol ); GetItemCount用来返回列表控件中的列表项个数等。它们的原型如下: BOOL SetColumnWidth( int nCol, int cx ); int GetItemCount( );,7.3视图及视图类,列表控件的消息 常用的列表控件消息有: LVN_BEGINDRAG用户按左鼠拖动列表列表项 LVN_BEGINLABELED
47、IT用户对某列表项标签进行编辑 LVN_COLUMNCLICK某列被按击 LVN_ENDLABELEDIT用户对某列表项标签结束编辑 LVN_ITEMACTIVATE用户激活某列表项 LVN_ITEMCHANGED当前列表项已被改变 LVN_ITEMCHANGING当前列表项即将改变 LVN_KEYDOWN某键被按下 在用ClassWizard处理上述这些消息时,其消息处理函数参数中往往会出现NM_LISTVIEW结构,其定义如下: typedef struct tagNMLISTVIEW NMHDR hdr;/ 包含通知消息的结构 int iItem;/ 列表项索引,没有为-1 int iS
48、ubItem;/ 子项索引,没有为0 UINT uNewState;/ 新的项目状态 UINT uOldState;/ 原来的项目状态 UINT uChanged;/ 项目属性更改标志 POINT ptAction;/ 事件发生的地点 LPARAM lParam;/ 用户定义的32位值 NMLISTVIEW, FAR *LPNMLISTVIEW;,7.3视图及视图类,例Ex_Lview 将当前文件夹中的文件用“大图标”、“小图标”、“列表视图”以及“报表视图”四种不同方式在列表视图中显示出来。当双击某个列表项时,还将该项的文本标签内容用消息对话框的形式显示出来。 (1)用MFC AppWzia
49、rd创建一个单文档应用程序Ex_List,在创建的第六步将视图的基类选择为CListView。 (2)为CEx_ListView类添加下列成员函数和成员函数: public: CImageList m_ImageList; CImageList m_ImageListSmall; CStringArray m_strArray; void SetCtrlStyle(HWND hWnd, DWORD dwNewStyle); (3)将项目工作区窗口切换到ResourceView页面,打开Accelerator节点下的IDR_MAINFRAME,为其添加一个键盘加速键Ctrl+Shift+X,其I
50、D号为ID_VIEW_CHANGE。 (4)用ClassWizard为CEx_ListView类添加ID_VIEW_CHANGE的COMMAND消息映射函数,并增加下列代码: void CEx_ListView:OnViewChange() static int nStyleIndex = 1; DWORD style4 = LVS_REPORT, LVS_ICON, LVS_SMALLICON, LVS_LIST ; CListCtrl ,7.3视图及视图类,(5)用ClassWizard为CEx_ListView类添加NM_DBLCLK消息映射函数,增加代码: void CEx_ListV
51、iew:OnDblclk(NMHDR* pNMHDR, LRESULT* pResult) LPNMITEMACTIVATE lpItem = (LPNMITEMACTIVATE)pNMHDR; int nIndex = lpItem-iItem; if (nIndex = 0) CListCtrl,7.3视图及视图类,for (int nCol=0; nCol4; nCol+) listCol.iSubItem = nCol; listCol.pszText = arColsnCol; if (nCol = 1) listCol.fmt = LVCFMT_RIGHT; else listCo
52、l.fmt = LVCFMT_LEFT; m_ListCtrl.InsertColumn(nCol,7.3视图及视图类,for (int i=0; i 1024)str.Format(%dK, dwSize/1024); elsestr.Format(%d, dwSize); m_ListCtrl.SetItemText(nIndex,1,str); m_ListCtrl.SetItemText(nIndex,2,strTypeName); finder.GetLastWriteTime(m_time) ; m_ListCtrl.SetItemText(nIndex,3,m_time.Form
53、at(%Y-%m-%d); nItem+; ,7.3视图及视图类,SetCtrlStyle(m_ListCtrl.GetSafeHwnd(), LVS_REPORT); m_ListCtrl.SetColumnWidth(0, LVSCW_AUTOSIZE);/ 设置列宽 m_ListCtrl.SetColumnWidth(1, 100); m_ListCtrl.SetColumnWidth(2, LVSCW_AUTOSIZE); m_ListCtrl.SetColumnWidth(3, 200); (7)编译并运行,如图。,图7.11 Ex_List运行结果,7.3视图及视图类,7.3.3树
54、控件和树视图 树形视图的风格,7.3视图及视图类,树控件的常用操作 函数InsertItem用来向树控件插入一个新项,操作成功后,函数返回新项的句柄,否则返回NULL。函数原型如下: HTREEITEM InsertItem( UINT nMask, LPCTSTR lpszItem,int nImage, int nSelectedImage, UINT nState, UINT nStateMask, LPARAM lParam, HTREEITEM hParent, HTREEITEM hInsertAfter ); HTREEITEM InsertItem( LPCTSTR lpszI
55、tem, HTREEITEM hParent = TVI_ROOT, HTREEITEM hInsertAfter = TVI_LAST ); HTREEITEM InsertItem( LPCTSTR lpszItem, int nImage, int nSelectedImage, HTREEITEM hParent = TVI_ROOT, HTREEITEM hInsertAfter = TVI_LAST ); 函数DeleteItem和DeleteAllItems分别用来删除指定的项和全部的项。它们的原型如下: BOOL DeleteAllItems( ); BOOL DeleteIt
56、em( HTREEITEM hItem ); 函数Expand用来用来展开或收缩指定父项的所有子项,其原型如下: BOOL Expand( HTREEETEM hItem, UINT nCode );,7.3视图及视图类,树形视图控件的通知消息 树视图可以用ClassWizard映射公共控件消息和树控件消息。常用的树控件消息有: TVN_BEGINDRAG 开始拖放操作 TVN_BEGINLABELEDIT 开始编辑标签 TVN_BEGINRDRAG 鼠标右按钮开始拖放操作 TVN_ENDLABELEDIT 标签编辑结束 TVN_ITEMEXPANDED 含有子项的父项已展开或收缩 TVN_I
57、TEMEXPANDING 含有子项的父项将要展开或收缩 TVN_SELCHANGED 当前选择项发生改变 TVN_SELCHANGING 当前选择项将要发生改变 用ClassWizard处理上述这些消息时,其消息处理函数参数中往往会出现NM_TREEVIEW结构,定义如下: typedef struct tagNMTREEVIEW NMHDR hdr;/ 含有通知代码的信息结构 UINT action; / 通知方式标志 TVITEM itemOld; / 原有项的信息 TVITEM itemNew; / 现在项的信息 POINT ptDrag; / 事件产生时,鼠标的位置 NMTREEVIE
58、W, FAR *LPNMTREEVIEW;,7.3视图及视图类,例Ex_Tree 遍历本地磁盘所有的目录。 (1)用MFC AppWziard创建一个单文档应用程序Ex_Tree,在创建的第六步将视图的基类选择为CTreeView。 (2)按快捷键Ctrl+R,选定资源类型Icon,单击Import按钮,从外部调入六个图标,分别表示“我的电脑”、“软驱”、“硬盘”、“光驱”、“文件夹”以及“打开的文件夹”,相应的ID号设为IDI_MYCOMP、IDI_35FLOPPY、IDI_DRIVE、IDI_CDDRIVE、IDI_CLSDFOLD和IDI_OPENFOLD,如图。,图7.12 从外部调入
59、的图标,7.3视图及视图类,(3)为CEx_TreeView类添加下列成员函数和成员函数: public: CImageList m_ImageList; CString m_strPath;/ 文件夹路径 void InsertFoldItem(HTREEITEM m_hItem); void SetCtrlStyle(HWND hWnd, DWORD dwNewStyle); InsertFoldItem函数的代码如下: void CEx_TreeView:InsertFoldItem(HTREEITEM m_hItem) CFileFind finder; BOOL bWorking = finder.FindFile(m_strPath); CString m_str; while (bWorking) bWorking = finder.FindNextFile(); if (finder.IsDirectory() ,7.3视图及视图类,(4)为C
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026北京机械科学研究总院博士研究生招生47人模拟笔试试题及答案解析
- 地下室负二层底板补漏堵漏施工方案范例
- 深度解析(2026)《GBT 26110-2010锌铝涂层 技术条件》(2026年)深度解析
- 深度解析(2026)《GBT 26044-2010信号传输用单晶圆铜线及其线坯》(2026年)深度解析
- 深度解析(2026)《GBT 25930-2010红外线气体分析器 试验方法》
- 深度解析(2026)《GBT 25896.3-2010设备用图形符号 起重机 第3部分:塔式起重机符号》
- 2025重庆云阳县平安镇中心卫生院招聘1人备考笔试题库及答案解析
- 深度解析(2026)《GBT 25830-2010高温合金盘(环)件通 用技术条件》(2026年)深度解析
- 2025年铜陵市义安区检察院公开招聘编外聘用人员4名考试笔试备考题库及答案解析
- 功利主义与权利论视角下人脸识别门禁的伦理边界
- 2025大理州强制隔离戒毒所招聘辅警(5人)笔试考试备考题库及答案解析
- 2025年安全培训计划表
- 2026年榆林职业技术学院单招职业技能测试题库参考答案详解
- 2025年沈阳华晨专用车有限公司公开招聘笔试历年参考题库附带答案详解
- 2026(苏教版)数学五上期末复习大全(知识梳理+易错题+压轴题+模拟卷)
- 2024广东广州市海珠区琶洲街道招聘雇员(协管员)5人 备考题库带答案解析
- 垃圾中转站机械设备日常维护操作指南
- 蓄电池安全管理课件
- 建筑业项目经理目标达成度考核表
- 2025广东肇庆四会市建筑安装工程有限公司招聘工作人员考试参考题库带答案解析
- 第五单元国乐飘香(一)《二泉映月》课件人音版(简谱)初中音乐八年级上册
评论
0/150
提交评论