创建简单的网格视图应用程序(转)

创建简单的网格视图应用程序: 我们在第5章看到了两种不同的应用程序。第6章说明了如何创建其中的第一种,即窗体视图应用程序。在本节中,我们来看看其中的第二种,即网格视图应用程序。与第6章中一次只浏览查询中的一条记录不同,这回我们要一次看到所有的记录(至少要像屏幕所显示的那样多)。当然,这就要使用网格而不是用编辑框来存储各种记录值了。
你多半会发现,在谈到数据库时,网格给程序员带来了一些特殊的挑战。例如,如果你现在不能马上阅读整个查询的话,就必须跟踪查询已显示了多少记录(有一些查询可能非常巨大,内存不允许创建可以保存所有需要向用户显示的值的网格控件)。你可能还会发现,要管理所有的字段,尤其是像备忘录这样的长文本字段,还需要再做一些工作。冗长或复杂的字段可能要求一些条件或要求使用第二个对话框(与备忘录字段共同出现)。为了使这个示例更简单一些,我们要走在这些问题的前面。但是,如果数据库表包含了带这些类型值的字段,那么记着专门考虑这些字段的处理方式是非常重要的(和第6章一样,我们要研究一些特殊的和日期及货币有关的格式化问题)。
Web链接 你可能会发现,一开始阅读本章就想进行一些额外的训练。Internet上有很多地方提供关于用Visual C++处理ADO,OLE-DB,DAO和ODBC的课程。例如,你会发现,http://www.unisoftinc.com/courses/处的Universal SoftwareSolutions(通用软件解决方案)提供了关于使用Visual C++、关系数据库和更新的Microsoft对象技术如DCOM和COM+的高级课程。另外还有http://www.develop.com/处的DevelopMentor(开发顾问)。它大体提供了各种有关对象技术和Visual C++的课程(包括各种形式的数据库访问)。该公司过去常常提供一些DAO专用的类,但后来停止了这类业务。
创建ADO1工程
启动OLE-DB/ADO网格视图应用程序的过程,有点像在第6章中用到的过程,但是有一些重要的差别,所以要仔细遵循下述的步骤。在下面的过程中假设你已经启动了Visual C++。
1. 使用File|New(文件|视图)命令显示New(新建)对话框。
2. 选择Projects(工程)页上的MFC AppWizard(EXE)条目。
3. 在Project Name(工程名)域中输入ADO1(或任何其它适合需要的名字),然后单击OK。你会看到如下图所示的MFC AppWizard-Step1对话框。
065231209436767.JPG
4. 选择Single Document(单文档)选项,然后单击Next(下一个)。你会看到如下图所示的MFC AppWizard-Step 2 of 6对话框。我们要做的第一件事是为应用程序选择数据库支持层次。
0652312094830091.JPG
5. 在一系列选项中选择Database View Without File Support(无文件支持的数据库视图)(各种选项的概述参见第6章技巧框中的“选择数据库选项”段)。现在要为我们的应用程序选择数据源。请记住,OLE-DB用提供者代替了ODBC使用的机制;因此,我们不需要DSN。
6. 单击Data Source(数据源)按钮。会看到如下图所示的Data Link Properties(数据链接属性)对话框的Provider(提供者)选项卡。
0652312095110702.JPG
我们用这个对话框来选择数据源及其访问方式。在这个示例中我们使用了Access数据库,所以要使用Microsoft Jet 3.51 OLE-DB Provider,不过使用其它OLE-DB提供者也差不多。你会经过相同的步骤,但是在不同选项卡上要求选择的项目会因提供者提供者不同而不同。例如,SQL Server会要求你输入服务器名和其它连接条件,如访问服务器时要使用的 安全类型。在获得数据库访问方面,Microsoft Jet 3.51 OLE-DB Provider所需的信息最少。
7. 选择Microsoft Jet 3.51 OLE-DB Provider选项,然后单击Next(下一个)。你会看到Data Link Properties(数据链接属性)对话框的Connection(连接)选项卡。在这里指定想要访问的数据库的位置以及用户名和口令。
8. 输入访问数据库的完整路径,本示例中使用的路径是DBSampSample.MDB(也可以用Browse(浏览)按钮来搜索硬盘驱动器上的数据库)。
9. 在适当域中输入用户名和口令。示例数据库对这两个值都不作要求。
10. 单击Test Connection(测试连接)按钮。如果在Connection(连接)选项卡中输入了正确的信息,那么你就应该看到Test Connection Succeeded(连接文本成功)对话框。否则,要检查所有提供的值是否都正确。最常见的问题是口令输入错误(这也好办,因为Visual C++可以用星号来代替口令)。
11. 单击OK。现在已经连接数据库了,它并不依赖DSN。
12. 单击OK关闭Database Options(数据库选项)。你应该看到如下图所示的Select Database Tables(选择数据库表)对话框。
0652312095524283.JPG
13. 加亮FoodOrders选项。像第6章中的示例那样,我们也可以在需要时选择某个表。然而,通常我们使用查询来访问数据库的内容,这样才能以希望的顺序提取想要的数据。单击OK。MFC AppWizard-Step 2 of 6对话框现在应该显示已经选择了数据源。
14. 单击Next(下一个)四次。你会看到MFC AppWizard-Step 6 of 6对话框。在这个对话框上不用改变任何设置,但是你要验证一下在Base Class(基类)域中是否选择了COleDBRecordView。这个类提供的功能让你能够更容易地浏览数据库。
15. 单击Finish(完成)。你会看到如下图所示的New Project Information(新工程信息)对话框。
0652312095890833.JPG
16. 单击OK。Visual C++创建新的工程。
设计网格视图窗体
此时,应该看到一个名为IDD_ADO1_FORM的空白对话框。可以在这个窗体上放置任何东西,包括以报表形式查看所有记录的网格,或者查看每个数据字段的分离控件。现在你到了要选择如何查看信息的时候了。在本例中,我们要创建网格,但是,这里并没有任何东西要把你限制在某种视图类型上,这一点很重要。
创建网格视图要做的第一件事是,向控件列表中添加一个网格。幸运的是,已经有了一个特殊的网格被设计成可以应用OLE-DB。很明显,我们需要在窗体上做另外一些工作,但是添加了这个特殊的控件将会为我们节省许多的时间。下面的过程帮助你把该控件添加到Controls(控件) 工具条上,然后再把它添加到IDD_ADO1_FORM对话框中。
1. 用Project|Add To Project|Components and Controls(工程|添加到工程|部件和控件)命令显示Components and Controls Gallery(部件和控件库)。
2. 双击Registered ActiveX Controls(已注册的ActiveX控件)文件夹。
3. 加亮如下图所示的Microsoft DataGrid Control,Version 6.0(OLEDB)条目。
0652312100390761.JPG
4. 单击Insert(插入)。Visual C++显示一个对话框询问是否想插入这个部件。
5. 单击OK。你会看到一个如下图所示的Confirm Classes(确认类)对话框。
0652312100670834.JPG
6. 单击OK。Visual C++把控件添加到Controls(控件) 工具条中。
7. 执行Microsoft ADO Data Control,Version 6.0(OLEDB)的步骤3到6。ADOData Control将通过我们先前创建的OLE-DB连接建立与示例数据库的实际连接。
8. 单击Close(关闭)关闭Components and Controls Gallery(部件和控件库)对话框。
现在我们已经有了两个控件可以使用,把它们放在窗体上并加以配置。不要担心精确调整控件大小的问题棗我们用代码来完成这项工作。你需要把这些控件放置到窗体的角上。下图是示例中使用的窗体。
065231210102467.JPG
在DataGrid1上有几个属性需要更改。只要右击控件,然后从上下文菜单中选择Properties(属性)即可。因为有一些属性不在其它的属性页上出现,所以一定要选择All(全部)选项卡。第一个属性最重要,因为它设置控件的数据源。把DataSource(数据源)属性设成IDC_ADODC1。由于我们想完整地控制数据库以便于彻底地测试应用程序,所以你也要把AllowAddNew和AllowDelete属性设置为True。通常情况下,Data Grid(数据网格)控件被设计成允许查看和修改记录,但不允许添加和删除记录。这也是一种对数据库保护的中等措施。此时,人们可以少许地修改数据库的内容,但不会达到破坏数据库的程度。
现在配置数据源本身。右击ADODC1控件,然后从上下文菜单中选择Properties(属性)。选择Control(控件)选项卡。注意这个选项卡上的UseConnection String(使用连接字符串)域棗如果它还未被选中,那么一定要选中它,这是我们选择数据源的地方(我们在这里选择数据源的过程与本章前面所用的过程相似)。下面是建立连接字符串的过程。
1. 单击Build(建立)。你会看到Data Link Properties(数据链接属性)的Provider(提供者)选项卡。
2. 加亮Microsoft Jet 3.51 OLE-DB Provider选项,然后单击Next(下一个)。你会看到Data Link Properties(数据链接属性)的Connection(连接)选项卡。
3. 在Select or Enter a Database Name(选择或输入数据库名)域中输入数据库的位置。也可以用Browse(浏览)按钮在本地或网络驱动器上定位数据库。示例程序在这个域中填入了DB_SampSample.MDB。
4. 如果需要的话,输入用户名和口令(示例数据库对这两个条目都不做要求)。
5. 单击Test Connection(测试连接)。如果连接信息正确,你就会看到一个Test Connection Succeeded(测试连接成功)对话框。
6. 单击OK两次。完成连接工作。
在应用程序设置完成之前,我们还必须再做一件事。再次打开ADODC1控件的Properties(属性)对话框。这一次选择RecordSource(记录源)选项卡。在这个选项卡的底部会看到Command Text(SQL)字段。在这里输入从刚刚取得连接的数据库中提取数据的命令字符串。输入下面的字符串访问在第5章中设置的FoodOrders(食品订购)查询所提供的所有信息。
Select * from FoodOrders
关闭Properties(属性)对话框。如果现在编译并运行这个应用程序,就能看到网格形式表达的数据。不但如此,还可以在数据库中编辑、删除和添加记录。然而,有些地方我们需要编写一些代码,比如,实现当主窗口调整大小时Data Grid(数据网格)控件也随之调整自身大小的功能。我们会在本章的下一节处理这些任务。
高级技巧
在应用程序中使用两个数据库连接
你可能已经注意到了,为ADO1应用程序使用了两个连接。我们在应用程序的设计过程中创建了第一个连接,第二个连接是在向应用程序添加AdoDC1之后创建的。AdoDC1(第二个连接)是查看窗体时的活动连接。如果你试着使用第一个连接(直到对菜单和 工具条做了更改时才可用),不会看到Data Grid(数据网格)的内容有任何变化。下面是C++应用程序开发者要考虑的问题。没有那么多的控件像ADODC控件那样生来就支持OLE-DB。如果计划向应用程序或报告中添加单记录视图窗体,就可能需要第二个连接来访问数据库中的数据。换言之,即使你没有打算立即使用第二个连接,也要在应用程序中包括它,至少在Microsoft使所有的Visual C++数据绑定控件都与OLE-DB兼容之前是这样。
使用两个或者更多的数据库连接还有另外一个原因。使用两个连接允许你在创建高速应用程序时有更大的灵活性。可以为打印窗口使用一个连接,为数据编辑窗口使用另一个连接。有两个连接意味着,在处理一个窗口时不必担心为另一个窗口所使用的连接状态。连接是分离的,所以每个窗口的连接状态都被保留。
很明显,使用多个连接时存在着平衡问题。毫无疑问,使用多个连接后,应用程序的可靠性会提高一些,或许速度也有所提高。但是,获取这些特性的代价 是使用了更多的内存。如果你在为内存有限的系统编写应用程序,那么就不必奢侈地使用两个或多个数据库连接。内存不足的系统已经比大多数机器都慢了,用户不太可能注意到速度有所降低。然而,你需要添加另外一些代码,以确保两个窗口的连接状态信息被适当地保存,确保用户在进行一些诸如同时打印和编辑数据库操作时,不会粗心地损坏数据库。
向ADO1中添加一些窗体代码
示例程序在很多方面不完整,其中大部分属于可用而不完美这一类。例如,如果你现在调整应用程序的大小,窗体会变得更大,而Data Grid(数据网格)控件不会。出现的另一个问题是,Data Grid(数据网格)控件中的所有列都被设成通用格式,这种格式可以很好地适应大多数想要显示的数据。但是,我们需要为Boolean(布尔)值将格式设成其它的风格,而在使用通用格式时Boolean值显示为数字。
在解决这些问题之前,我们需要创建几个访问这两个控件的变量。按住CTRL键并双击DataGrid1。你会看到如下图所示的Add Member Variable(添加成员变量)对话框。
0652312101296332.JPG
请注意,Category(分类)域选择了Control(控件),Variable Type(变量类型)域包含了CDataGrid。在Member Variable Name(成员变量名)域中输入dataGrid1(完成时应该是m_dataGrid1)。单击OK完成这个过程。现在,为ADODC1进行相同的操作。这一次使用m_adoDC1作为变量名。
现在添加第一个函数。使用View|ClassWizard(视图|类向导)命令打开MFCClassWizard。第一段代码让我们在必要时改变两个控件的位置并调整其大小。在Class Name(类名)域中选择CADO1View,在Object IDs(对象ID)域中选择CADO1View。在Messages(消息)域中找到WM_SIZE消息。单击AddFunction(添加函数),MFC AppWizard对话框看起来应该如下图所示。
0652312101592952.JPG
单击Edit Code(编辑代码),进入刚刚创建的新函数。程序列表7.1显示了当我们改变应用程序窗体的大小时也同时改变控件大小的代码。
0652312102181886.JPG
修复工具条和菜单
工具条和菜单是现在大多数应用程序的一部分,所以MFC AppWizard会自动地创建它们。可惜的是,自动创建过程并非总是很完美,并且在某些情况下也没有人会抱怨出现了故障。如果用AdoDC1控件在记录间移动,我们的应用程序会运行良好,但是如果用户想使用 工具条或菜单的话,会怎么样呢?菜单和 工具条好像不会做任何事情,尽管它们正在为第一个连接移动记录指针。菜单和 工具条当前指向我们用MFC AppWizard创建的第一个连接。我们需要的是指向由AdoDC1提供的第二个连接的菜单和 工具条。
处理菜单和 工具条问题主要分两步。第一,要给它们不同的ID,这样我们才能为它编写代码。第二,要为移动第二个连接的记录指针提供代码。下面的过程帮助你完成第一步的工作(我们从更改 工具条开始)。
1. 在ResourceView(资源视图)中双击Toolbar( 工具条)文件夹内相应项目,打开IDR_MAINFRAME 工具条。
2. 双击First Record(第一个记录)按钮。你会看到如下所示的Toolbar ButtonProperties( 工具条按钮属性)对话框。在这个对话框中无需修改很多信息,只要修改ID字段即可,这样我们才能添加访问第二个数据库连接所需的特殊代码。
0652312102642404.JPG
注 First Record(第一个记录)按钮的图案如下图所示:
3. 在ID字段中输入ID_RECORD_FIRST2。我们向访问第二个连接的任何对象名称中都附加上数字2,使代码更易于阅读。
4. 对Previous Record(前一个记录),Next Record(下一个记录)和Last Record(最后一个记录)按钮执行步骤2和3。
5. 在ResourceView(资源视图)中双击Menu(菜单)文件夹内的相应条目,打开IDR_MAINFRAME菜单。
6. 右击Record|First Record(记录|第一个记录)命令,从上下文菜单中选择Properties(属性)。你会看到如下图所示的Menu Item Properties(菜单项属性)对话框。同样,除了ID域的值,我们不必修改其它内容。
065231210294198.JPG
7. 在ID域中输入ID_RECORD_FIRST2。这个域段中的项目正好匹配 工具条的项目,这一点绝对是必要的。否则, 工具条和菜单不会互相“跟踪”。
技巧 可以这样确保 工具条和菜单名互相匹配,即从下拉列表框中选择正确的ID值,而不是把值输入到ID域中去。然而,在大多数情况下,如果是添加一个数字,就和输入值一样容易。
8. 对Record|Previous Record(记录|前一个记录)、Record|Next Record(记录|下一个记录)和Record|Last Record(记录|最后一个记录)命令重复步骤6到7。
设置过程还没有完成。要用View|ClassWizard(视图|类向导)命令打开MFCClassWizard。为Class Name(类名)选择CADO1View。在Object IDs字段中找到IN_RECORD_FIRST2,然后选择Messages(消息)字段中的COMMAND(命令)。单击Add Function(添加函数),看到Add Member Function(添加成员函数)对话框时单击OK。你刚才已经添加了一个处理First Record(第一个记录)菜单和 工具条项目的函数。对ID_RECORD_LAST2,ID_RECORD_NEXT2和ID_RECORD_PREV2 Object Ids重复这个过程。完成时,MFC AppWizard对话框应该如下图所示。
065231210327314.JPG
此时,你已经为访问为这个程序而创建的第二个连接设置了菜单和 工具条。现在要添加一些使菜单和 工具条项目发挥作用的代码。在MFC AppWizard对话框中单击Edit Code(编辑代码),Visual C++把你带到我们刚刚创建的新函数。程序列表7.2显示了需要添加的代码。请注意,#include指令要和其它的#include指令一起放置在代码文件的开始位置。
0652312103654858.JPG
0652312104049760.JPG
程序列表7.2中的大多数代码都很简单。我们用m_adoDC1内存变量得到对记录集(用户当前正在观看的记录集)的访问。我们一开始访问记录集,就可以把记录指针移到适当的记录位置上。
现在来看看OnRecordPrev2()函数。由于我们在查阅文件起始记录时没有执行任何缺省动作,所以这个函数要求的代码比其它函数要稍微多一些(如果查阅到文件的末尾,应用程序自动向表中添加一个新记录)。所有这些额外的代码帮助你避免可视化问题,它可能会导致调用许多支持。如果记录指针在文件的开始位置遇到了文件结束,那么网格控件上的小型记录指针指示器就会消失。即使网格和ADODC都在正常工作,对用户来说,这可能表示发生了某种错误。要避免这个问题很简单:只要检查文件指示器的开始,并适当改变记录指针的位置。
高级技巧
避免安装问题
数据库应用程序是你可以创建的最复杂的应用程序之一。人们不但希望这些应用程序在稳定性和坚固性方面有更大的提高,而且应用程序本身的整体规模也越来越庞大了。例如,大多数的数据库应用程序要求某种网络的支持。判断出数据库应用程序在要求支持方面比任何程序都多并不难,结果你会发现,即使像我们刚刚创建的这样简单的数据库应用程序,都要求众多的支持文件。
创建一个安装程序时会碰到的第一个问题是,找出所需的全部文件。通常,在获得完整的文件列表之前,要检查多个信息源。必须寻找的两个文件集是,厂商专用的数据库访问驱动程序和操作系统支持文件。可能还需要配置实用程序和依赖于所使用的DBMS的其它程序文件。厂商通常会提供完整的厂商专用文件,它可能隐藏在文档的某些角落中,一定要花些时间把它们都找出来。在某些情况下,厂商还会慷慨地提供一系列通用操作系统文件,但是在假定厂商提供了正确或最新的信息之前,一定要检查一下Microsoft的Web站点,看看有没有最新的驱动程序。表7.1提供了一系列完整的文件,你在处理依赖Microsoft Jet Engine的数据库应用程序时需要它(这个表是特别为DAO设置的,但也可用于其它形式的数据库访问)。
0652312104361537.JPG
0652312104553483.JPG
另一个安装问题是数据库的存放位置。某些程序员会假定用户将需要直接的网络访问,并且管理人员会把数据库放在服务器上的特定位置。不要做这样的假定,尤其是在今天这个Internet主宰的市场中。服务器访问可能要经历一次Internet连接,甚至可能来自存储于数据库中的记录的本地子集。换言之,除非你也可以保证亲自把数据放在预期的位置,否则不要做任何关于数据会存储在哪里的假设(即使这样,管理也可能决定它随时需要Internet的连通性)。
我们再回过头来谈一谈支持文件。你们大多认识到了,在应用程序依赖特定版本的公共支持文件(如MFC运行文件)的时候会有问题出现。创建数据库应用程序时,这个问题会大大增多。首先,你还要考虑MFC的运行。添加到这些支持文件中的是数据库访问所需要的公共操作系统文件和你所需要的厂商专用文件。现在你要及时了解三个产品版本,它们随时都可能会改变。
解决这个问题的办法是,一定要检查安装过程中用户安装在系统上的每一个文件的版本(现在你知道了为什么一些安装程序会工作上几个小时!)。如果一个文件的版本和为这个应用程序所使用的文件不匹配,那就要征得用户的同意,用所需要的文件改写这个文件。现在,有一个问题,用户都乐于假设新版本会更好一些。另一方面,如果应用程序依赖于较早版本的文件,那它有可能在新版本下运行不了。你要特别检查一下新版本的文件,并在消息中放入某种关于应用程序可能在新版本下运行不了的警告(除非你事先就知道它可以运行)。
技巧 每次应用程序启动时,很多的数据库程序员都会执行检查文件版本号的例程。在一些情况下,检查应用程序所使用的每一个文件是没有必要的。但是,检查公共或共享文件的版本号却是一个好主意。用户可以安装另一个应用程序,它改写了你的应用程序所要求的文件版本。确保应用程序可以满足需要的唯一办法是,在程序初始化过程中检查这些文件。在应用程序实际启动之前就中断,比应用程序一启动和数据库一打开程序就崩溃要好一些。
其它的安装问题和通常安装程序的设计方式有关。例如,大多数安装程序假定,如果在用户的硬盘驱动器上有足够的空间来存储应用程序的所有文件,应用程序就会正常运行。可惜的是,在数据库应用程序的情况下,你还必须考虑像记录集的本地拷贝这样的事情,因为记录集可能非常大,内存存储不了。换言之,要在安装程序中适当调大硬盘容量需求以满足应用程序的处理需要,而这一工作在安装大多数其它类型的应用程序时没有必要考虑。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10294527/viewspace-123262/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/10294527/viewspace-123262/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值