转至繁体中文版     | 网站首页 | 图文教程 | 资源下载 | 站长博客 | 图片素材 | 武汉seo | 武汉网站优化 | 
最新公告:     敏韬网|教学资源学习资料永久免费分享站!  [mintao  2008年9月2日]        
您现在的位置: 学习笔记 >> 图文教程 >> 软件开发 >> Delphi程序 >> 正文
多层数据库开发十四:剖析几个MIDAS示范程序         ★★★★

多层数据库开发十四:剖析几个MIDAS示范程序

作者:闵涛 文章来源:闵涛的学习笔记 点击数:2893 更新时间:2009/4/23 18:30:21
));
If Fields[I].DataType in [ftADT, ftArray] then
WriteFullNames(TObjectField(Fields[I]).Fields);
End;
End;

Procedure WriteLists(DataSet: TDataSet);
var I: Integer;
Begin
FieldList.Clear;
For I := 0 to DataSet.FieldList.Count - 1 Do
With DataSet.FieldList Do
FieldList.Lines.Add(Format(''''%d) %s'''', [Fields[I].FieldNo, Strings[I]]));
FieldDefList.Clear;
DataSet.FieldDefs.Updated := False;
DataSet.FieldDefList.Update;
For I := 0 to DataSet.FieldDefList.Count - 1 Do
With DataSet.FieldDefList Do
FieldDefList.Lines.Add(Format(''''%d) %s'''', [FieldDefs[I].FieldNo, Strings[I]]));
End;
var DataSet: TDataSet;
Begin
DataSet := DBNavigator1.DataSource.DataSet;
If Assigned(DataSet) and DataSet.Active then
Begin
WriteLists(DataSet)
End
Else
Begin
CheckDatabase(False);
MasterTable.TableName := MasterTableName.Text;
WriteLists(MasterTable);
End;
End;
  首先要说明的是,FieldsPageShow中嵌套了WriteFullNames,其实WriteFullNames完全是多余的。FieldsPageShow先获取当前的数据集。如果当前的数据集已打开的话,就调用WriteLists显示字段对象和字段定义对象的列表。如果当前数据集没有打开,就显示MasterTable中的字段对象和字段定义对象的列表。当用户翻到“Indexes”页,将触发IndexPage(TTabSheet对象)的OnShow事件,此时就把当前数据集中的索引列出来,用户也可以创建新的索引或者删除一个索引。“Indexes”页如图14.10所示。
  图14.10 “Indexes”页
Procedure TDBClientTest.IndexPageShow(Sender: TObject);
Begin
If not Assigned(ActiveDataSet) or not ActiveDataSet.Active then
OpenTable.Execute;
RefreshIndexNames(0);
End;
  IndexPageShow首先检查当前是否打开了一个数据集,如果没有,就执行OpenTable的代码即打开数据集,然后调用RefreshIndexNames函数列出所有的索引名称。
Procedure TDBClientTest.RefreshIndexNames(NewItemIndex: Integer);
var I: Integer;
IndexDefs: TIndexDefs;
Begin
IndexList.Clear;
If ActiveDataSet = MasterTable then
IndexDefs := MasterTable.IndexDefs
Else
IndexDefs := ClientData.IndexDefs;
IndexDefs.Update;
For I := 0 to IndexDefs.Count - 1 Do
If IndexDefs[I].Name = '''''''' then IndexList.Items.Add('''''''')
Else
IndexList.Items.Add(IndexDefs[I].Name);
If IndexList.Items.Count > 0 then
Begin
If NewItemIndex < IndexList.Items.Count then
IndexList.ItemIndex := NewItemIndex
ElseIndexList.ItemIndex := 0;
ShowIndexParams;
End;
End;
  RefreshIndexNames又调用ShowIndexParams检索索引的选项,用这些选项来初始化“Indexes”页上的几个编辑框和复选框。
Procedure TDBClientTest.ShowIndexParams;varIndexDef: TIndexDef;
Begin
If ActiveDataSet = MasterTable then
  IndexDef := MasterTable.IndexDefs[IndexList.ItemIndex]
Else
  IndexDef := ClientData.IndexDefs[IndexList.ItemIndex];
idxCaseInsensitive.Checked := ixCaseInsensitive in IndexDef.Options;idxDescending.Checked := ixDescending in IndexDef.Options;idxUnique.Checked := ixUnique in IndexDef.Options;idxPrimary.Checked := ixPrimary in IndexDef.Options;IndexFields.Text := IndexDef.Fields;
DescFields.Text := IndexDef.DescFields;
CaseInsFields.Text := IndexDef.CaseInsFields;
End;
  如果用户在列表框中选择了另一个索引,就应当相应地刷新这些选项。Procedure TDBClientTest.IndexListClick(Sender: TObject);
Begin
If ActiveDataSet = MasterTable then
MasterTable.IndexName := MasterTable.IndexDefs[IndexList.ItemIndex].Name
Else
ClientData.IndexName := ClientData.IndexDefs[IndexList.ItemIndex].Name;
ShowIndexParams;
End;
  如果要创建一个新的索引,用户必须事先设置索引的选项,然后单击“CreateIndex”按钮。
Procedure TDBClientTest.CreateIndexClick(Sender: TObject);
var IndexName: string;Options: TIndexOptions;
Begin
IndexName := Format(''''Index%d'''', [IndexList.Items.Count+1]);
If InputQuery(''''Create Index'''', ''''Enter IndexName:'''', IndexName) then
Begin
Options := [];
If idxCaseInsensitive.Checked then Include(Options, ixCaseInsensitive);
If idxDescending.Checked then Include(Options, ixDescending);
If idxUnique.Checked then Include(Options, ixUnique);
If idxPrimary.Checked then Include(Options, ixPrimary);
If ActiveDataSet = MasterTable then
Begin
MasterTable.Close;
MasterTable.AddIndex(IndexName,IndexFields.Text,Options,DescFields.Text);
MasterTable.Open;
End
Else
ClientData.AddIndex(IndexName, IndexFields.Text, Options,DescFields.Text, CaseInsFields.Text);
StatusMsg := ''''Index Created'''';
RefreshIndexNames(IndexList.Items.Count);
End;
End;
  CreateIndexClick首先弹出一个输入框,让用户输入索引名称,然后根据用户设置的选项来设置索引的Options属性。
  在调用AddIndex之前,首先要区分当前的数据集是MasterTable还是ClientData,为什么要区分MasterTable和ClientData呢?因为对于一般的数据集构件来说,在创建索引之前必须先关闭数据集,而对于TClientDataSet构件来说,则不必先关闭数据集。
  用户也可以先选择一个索引,然后单击“Delete Index”按钮删除这个索引。
Procedure TDBClientTest.DeleteIndexClick(Sender: TObject);
Begin
If IndexList.ItemIndex > -1 then
If ActiveDataSet = MasterTable then
Begin
MasterTable.Close;
MasterTable.DeleteIndex(MasterTable.IndexDefs[IndexList.ItemIndex].Name);
MasterTable.Open;
End
Else
ClientData.DeleteIndex(ClientData.IndexDefs[IndexList.ItemIndex].Name);
End;
  与调用AddIndex一样,在调用DeleteIndex之前,首先要区分当前的数据集是MasterTable还是ClientData。当用户翻到“Filters”页,就可以设置过滤条件,如图14.11所示。
  图14.11 “Filters”页
  当“Filters”页刚刚打开的时候,将触发OnShow事件,这样就可以初始化“Filter”框。这里运用了一个编程技巧,先从下面的栅格中取出一个字段,然后判断这个字段的数据类型是不是ftString、ftMemo或ftFixedChar中的一种,如果是的话,过滤条件表达式的运算符后面的值要用引号括起来。
Procedure TDBClientTest.FilterPageShow(Sender: TObject);
var Field: TField;LocValue,QuoteChar: String;
Begin
If (Filter.Text = '''''''') and Assigned(ActiveDataSet) and ActiveDataSet.Active then
Begin
Field := MasterGrid.SelectedField;If Field = nil then Exit;
With ActiveDataSet DoTryDisableControls;
MoveBy(3);
LocValue := Field.Value;
First;
Finally
EnableControls;
End;
If Field.DataType in [ftString, ftMemo, ftFixedChar] then
  QuoteChar := ''''''''''''''''
Else QuoteChar := '''''''';
Filter.Text := Format(''''%s=%s%s%1:s'''', [Field.FullName, QuoteChar, LocValue]);
End;
End;
  用户可以在“Filter”框内键入新的过滤条件,当用户按下Enter键或把输入焦点移走,就会把用户输入的过滤条件表达式赋给当前数据集的Filter属性。当用户翻到“FindKey”页,就可以输入一个键值,然后在数据集中搜索特定的记录,如图14.12所示。
  图14.12 “FindKey”页
  当用户单击“Find Key”或“Find Nearest”按钮,就开始搜索特定的记录。
Procedure TDBClientTest.FindKeyClick(Sender: TObject);
Begin
If ActiveDataSet = ClientData then
With ClientData Do
Begin
SetKey;IndexFields[0].AsString := FindValue.Text;
KeyExclusive := Self.KeyExclusive.Checked;If FindPartial.Checked then KeyFieldCount := 0;
If Sender = Self.FindNearest then GotoNearest else
If not GotoKey then StatusMsg := ''''Not found'''';
End
Else
if ActiveDataSet = MasterTable then
With MasterTable Do
Begin
SetKey;
IndexFields[0].AsString := FindValue.Text;
KeyExclusive := Self.KeyExclusive.Checked;
If FindPartial.Checked then KeyFieldCount := 0;
If Sender = Self.FindNearest then GotoNearest
Else
if GotoKey thenStatusMsg := ''''Record Found''''
Else StatusMsg := ''''Not found'''';
End;
End;
  首先,要区分当前数据集是ClientData还是MasterTable,调用SetKey使数据集进入dsSetKey状态,把用户输入的键值赋给索引中的第一个字段。然后根据Sender参数判断用户按下的是“Find Key”按钮还是“Find Nearest”按钮,如果是后者,就调用GotoNearest,如果是前者,就调用GotoKey,最后根据GotoKey的返回值显示有关信息。
  当用户翻到“Locate”页,将触发LocatePage(TTabSheet对象)的OnShow事件,程序就把下面的栅格中选择的字段作为关键字段。“Locate”页如图14.13所示。
  图14.13 “Locate”页
Procedure TDBClientTest.LocatePageShow(Sender: TObject);
var Field: TField;
Begin
If (ActiveDataSet <> nil) and ActiveDataSet.Active then
BeginField := MasterGrid.SelectedField;
If LocateField.Items.Count = 0 then
LocateFieldDropDown(LocateField);
If (LocateField.Text = '''''''')or(LocateField.Items.IndexOf(Field.FieldName) < 1) then
LocateField.Text := Field.FieldName;
With ActiveDataSet Do
Try
DisableControls;
MoveBy(3);
LocateEdit.Text := Field.Value;
First;
Finally
EnableControls;
End;
End;
End;
  用户也可以在“Field”框选择一个关键字段。当用户下拉“Field”框时,触发OnDropDown事件,这样就可以把当前数据集中的字段显示到“Field”框中。
Procedure TDBClientTest.LocateFieldDropDown(Sender: TObject);
Begin
ActiveDataSet.GetFieldNames(LocateField.Items);
End;
  当用户选择了关键字段并且输入了键值,就可以单击“Locate”按钮开始定位记录。
Procedure TDBClientTest.LocateButtonClick(Sender: TObject);varOptions: TLocateOptions;LocateValue: Variant;
Begin
Options := [];
If locCaseInsensitive.Checked then Include(Options, loCaseInsensitive);
If locPartialKey.Checked then Include(Options, loPartialKey);
If LocateNull.Checked then LocateValue := Null
Else
LocateValue := LocateEdit.Text;
If ActiveDataSet.Locate(LocateField.Text, LocateValue, Options) then
StatusMsg := ''''Record Found''''
Else
StatusMsg := ''''Not found'''';
End;
  前面几行代码主要是设置有关选项,其中,如果用户选中“Null Value”复选框的话,就把键值设为Null。然后调用当前数据集的Locate函数定位记录,并根据Locate函数的返回值显示相应的信息。
14.6 一个登录的示范程序
  这一节剖析一个登录示范程序,它可以在C:\Program Files\Borland\Delphi4\Demos\Midas\Login目录中找到。
  这个程序分为应用服务器和客户程序两个部分。应用服务器的主窗体上有一个列表框,用于记载曾经登录到应用服务器上的用户名,如图14.16所示。
  应用服务器上的数据模块如图14.17所示。
  数据模块上只有一个TTable构件,它的DatabaseName属性设为DBDEMOS,TableName属性设为COUNTRY。数据模块上没有TProvider构件,由TTable构件提供IProvider接口。
  这个数据模块的实例方式设为ciMultiInstance,这意味着每当一个客户连接应用服务器时,就会创建数据模块的一个新的实例,当客户不再连接应用服务器时,就删除数据模块的实例。因此,这个程序利用数据模块的OnCreate事件做了一些初始化的工作,利用数据模块的OnDestroy事件从列表框中删除一个用户名。
Procedure TLoginDemo.LoginDemoCreate(Sender: TObject);
Begin
FLoggedIn := False;
End;
  为什么要把FLoggedIn变量设为False呢?其原因后面将解释。
Procedure TLoginDemo.LoginDemoDestroy(Sender: TObject);
Begin
With Form1.ListBox1.Items do Delete(IndexOf(FUserName));
End;
  编译和运行这个应用服务器。打开客户程序的项目,它的主窗体如图14.18所示。
  窗体上的TDCOMConnection构件用于连接应用服务器,它的ServerName属性设为Server.LoginDemo,它的LoginPrompt属性设为True。窗体上的TClientDataSet构件的RemoteServer属性指定了TDCOMConn

上一页  [1] [2] [3] [4]  下一页


[Delphi程序]Delphi5.5的MIDAS编程(客户端)  [Delphi程序]Delphi中MIDAS前台程序如何连到后台(MIDAS之五)
[Delphi程序]Delphi中MIDAS线程模型种类(MIDAS之四)  [Delphi程序]Delphi中MIDAS程序的实例化模型种类(MIDAS之三)
[Delphi程序]Delphi中创建MIDAS服务器并注册(MIDAS之二)  [Delphi程序]Delphi中MIDAS是什么(MIDAS之一)
[Delphi程序]Delphi中MIDAS如何控制前台权限(MIDAS之六)  
教程录入:mintao    责任编辑:mintao 
  • 上一篇教程:

  • 下一篇教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      注:本站部分文章源于互联网,版权归原作者所有!如有侵权,请原作者与本站联系,本站将立即删除! 本站文章除特别注明外均可转载,但需注明出处! [MinTao学以致用网]
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)

    同类栏目
    · C语言系列  · VB.NET程序
    · JAVA开发  · Delphi程序
    · 脚本语言
    更多内容
    热门推荐 更多内容
  • 没有教程
  • 赞助链接
    更多内容
    闵涛博文 更多关于武汉SEO的内容
    500 - 内部服务器错误。

    500 - 内部服务器错误。

    您查找的资源存在问题,因而无法显示。

    | 设为首页 |加入收藏 | 联系站长 | 友情链接 | 版权申明 | 广告服务
    MinTao学以致用网

    Copyright @ 2007-2012 敏韬网(敏而好学,文韬武略--MinTao.Net)(学习笔记) Inc All Rights Reserved.
    闵涛 投放广告、内容合作请Q我! E_mail:admin@mintao.net(欢迎提供学习资源)

    站长:MinTao ICP备案号:鄂ICP备11006601号-18

    闵涛站盟:医药大全-武穴网A打造BCD……
    咸宁网络警察报警平台