MainFun.pas
上传用户:tj00001
上传日期:2007-01-07
资源大小:672k
文件大小:14k
源码类别:

行业应用

开发平台:

Delphi

  1. //---------------------------------------------------------------------------
  2. //(R)CopyRight KivenSoft International ,inc 1999
  3. //单元名称:主窗口附属单元
  4. //程序名称:电子书库
  5. //作    者:李会文
  6. //开始时间:1997.07.01
  7. //最后修改:1999.07.15
  8. //备注:此单元定义了主窗口一些实用函数段
  9. //---------------------------------------------------------------------------
  10. unit MainFun;
  11. interface
  12. function SaveItem:boolean;            //储存当前节点的变动内容
  13. function SaveIndex:boolean;           //储存变动后的索引内容
  14. function SaveSrm:boolean;             //保存主窗口中的数据库
  15. function CloseSrm:boolean;            //关闭数据库
  16. function CloseSrmQuery:boolean;       //是否保存对数据库的改动
  17. function OpenSrm(Fn:string):boolean;  //打开数据库文件在主窗口中并装入索引
  18. function BrowseFolder:string;         //目录浏览,返回被选择的目录,空为无选择
  19. function GetLastPathName(var Pn:string):string;//提取最后的路径名
  20. procedure SetOpenSrmWithApp(Value:boolean);//在注册表文件中设置SRM文件关联或取消
  21. procedure ImportDir(var Dir,Mask:string);  //引入目录下文件
  22. function FormatTreeNodeString(Value:string):string;
  23.                                       //格式化树形视图节点字符串防止无效字符
  24. implementation
  25. uses
  26.   Classes, SysUtils, Controls, Windows, Registry, Forms, ComCtrls, CommCtrl,
  27.   Messages, FileCtrl, ShlObj, MainUnit, SrmConst, SrmUnit, InputPw, RegUnit;
  28. //储存当前节点的变动内容--------------------------------------
  29. function SaveItem:boolean;
  30. var
  31.   Ms:TMemoryStream;
  32.   pInt:^integer;
  33. begin
  34.   Result:=true;
  35.   if Srm=nil then Exit;
  36.   with SrmForm do
  37.   begin
  38.     if TreeView.Selected=nil then exit;  //要保存的节点为空时退出
  39.     if (Srm.ItemHeadChanged) or (TreeView.Selected.Data=pointer(-1)) then
  40.                                           //标题属性有改变或是新增节点时
  41.       with Srm.DataHead do
  42.       begin
  43.         ContextAuthorEdit.GetTextBuf(Author,16);
  44.         ContextPasswordEdit.GetTextBuf(Password,12);
  45.         ContextIndexEdit.GetTextBuf(SearchKey,52);
  46.         pInt:=@DataType;
  47.         pInt^:=TreeView.Selected.ImageIndex;
  48.       end;
  49.     if (SrmForm.RichEdit.Modified) or
  50.     (SrmForm.TreeView.Selected.Data=pointer(-1)) then
  51.                                           //内容有改变或是新增节点时
  52.     begin
  53.       with Srm.DataHead do
  54.         if (RichEdit.GetTextLen<>0) then Num:=1 else Num:=0;
  55.       TreeView.Selected.Data:=pointer(Srm.AddItemHead);
  56.       Srm.IndexChanged:=true;             //索引改变
  57.       if RichEdit.GetTextLen<>0 then
  58.       begin
  59.         Ms:=TMemoryStream.Create;
  60.         Ms.SetSize(RichEdit.GetTextLen+1);
  61.         RichEdit.GetTextBuf(Ms.Memory,Ms.Size);
  62.         Srm.AddItemData(Ms);
  63.         Ms.Free;
  64.       end;
  65.     end;
  66.     if (Srm.ItemHeadChanged) and (not Srm.ItemDataChanged) and
  67.         (not RichEdit.Modified) then      //已有节点属性改变但内容不变时
  68.     begin
  69.       Srm.EditItemHead(integer(TreeView.Selected.Data));
  70.     end;
  71.     RichEdit.Modified:=false;             //置相应的标志复位
  72.     Srm.ItemHeadChanged:=false;
  73.     Srm.ItemDataChanged:=false;
  74.   end;
  75. end;
  76. //储存变动后的索引内容-----------------------------------
  77. function SaveIndex:boolean;
  78. var
  79.   Msh,Msd:TMemoryStream;
  80.   i,n:integer;
  81.   p:PTreeData;
  82.   AList:TStringList;
  83.   ANode:TTreeNode;
  84. begin
  85.   Result:=true;
  86.   if Srm=nil then Exit;
  87.   if not Srm.IndexChanged then Exit;      //索引没改变时
  88.   Msh:=TMemoryStream.Create;
  89.   Msd:=TMemoryStream.Create;
  90.   AList:=TStringList.Create;
  91.   Msd.SetSize(sizeof(TTreeData)*SrmForm.TreeView.Items.Count);
  92.   p:=Msd.Memory;
  93.   n:=SrmForm.TreeView.Items.Count -1;
  94.   ANode:=SrmForm.TreeView.Items.GetFirstNode;
  95.   with ANode do
  96.   begin
  97.     for i:=0 to n do                      //添加相应级别的TAB字符
  98.     begin
  99.       AList.Add(StringOfChar(#9,Level)+Text);
  100.       p^.Pos:=integer(Data);
  101.       p^.DataType:=ImageIndex;
  102.       ANode:=GetNext;
  103.       p:=pointer(integer(p)+sizeof(TTreeData));
  104.     end;
  105.   end;
  106.   AList.SaveToStream(Msh);
  107.   AList.Free;
  108.   Srm.SaveIndex(Msh,Msd);
  109.   Srm.IndexChanged:=false;
  110.   Msh.Free;
  111.   Msd.Free;
  112. end;
  113. //保存主窗口中的数据库-------------------------------------
  114. function SaveSrm:boolean;
  115. begin
  116.   Result:=true;
  117.   if Srm=nil then Exit;
  118.   SaveItem;
  119.   SaveIndex;
  120.   if Srm.DbChanged then                   //如果数据库属性有变动
  121.   begin
  122.     with Srm.FileHead,SrmForm do
  123.     begin
  124.       DbAuthorEdit.GetTextBuf(Author,16);
  125.       DbPasswordEdit.GetTextBuf(Password,12);
  126.       Srm.SaveSrmFile;
  127.       Srm.IndexChanged:=false;
  128.       Srm.DbChanged:=false;
  129.     end;
  130.   end;
  131. end;
  132. //关闭数据库-------------------------------------------
  133. function CloseSrm:boolean;
  134. begin
  135.   Result:=true;
  136.   if Srm<>nil then
  137.   begin
  138.     SaveSrm;
  139.     Srm.Free;
  140.     Srm:=nil;
  141.   end;
  142.   SrmForm.SearchListBox.Items.Clear;//*清空查找栏
  143.   with SrmForm.TreeView do  //清空树形视图
  144.   begin
  145.     SendMessage(Handle,TVM_SELECTITEM,TVGN_CARET,LPARAM(0));
  146.     SendMessage(Handle,WM_SETREDRAW,0,0);
  147.                                             //禁止重绘
  148.     SendMessage(Handle, TVM_DELETEITEM, 0, Longint(TVI_ROOT));
  149.                                             //删除所有节点
  150.     SendMessage(Handle,WM_SETREDRAW,-1,0);
  151.                                             //允许重绘
  152.     Selected:=nil;
  153.   end;
  154.   with SrmForm do          //编辑框和其它的清空
  155.   begin
  156.     RichEdit.Text:='';
  157.     DbAuthorEdit.Text:='';
  158.     DbPasswordEdit.Text:='';
  159.     DbBuildDateEdit.Text:='';
  160.     DbEditDateEdit.Text:='';
  161.     ContextAuthorEdit.Text:='';
  162.     ContextPasswordEdit.Text:='';
  163.     ContextPubDateEdit.Text:='';
  164.     ContextIndexEdit.Text:='';
  165.     ContextTypeRadioGroup.ItemIndex:=-1;
  166.   end;
  167. end;
  168. //是否保存对数据库的改动------------------------------------------
  169. function CloseSrmQuery:boolean;
  170. begin
  171.   Result:=true;
  172.   if Srm=nil then Exit;                   //没有打开的数据文件
  173.   if not AppIni.DelRecordQuery then exit; //不提示即保存
  174.   if (SrmForm.RichEdit.Modified or Srm.ItemDataChanged or Srm.ItemHeadChanged or
  175.       Srm.IndexChanged or Srm.DbChanged) then
  176.   begin
  177.     case MessageBox(SrmForm.Handle,csSaveQuery,csAppName,MB_YESNOCANCEL or
  178.                     MB_ICONQUESTION) of
  179.       IDYES:Result:=true;
  180.       IDNO:
  181.       begin
  182.         Result:=true;
  183.         SrmForm.RichEdit.Modified:=false;
  184.         Srm.ItemHeadChanged:=false;
  185.         Srm.ItemDataChanged:=false;
  186.         Srm.IndexChanged:=false;
  187.         Srm.DbChanged:=false;
  188.       end;
  189.       IDCANCEL:Result:=false;
  190.     end;
  191.   end;
  192. end;
  193. //打开数据库文件在主窗口中并装入索引--------------------------
  194. function OpenSrm(Fn:string):boolean;
  195. var
  196.   Ps,UserPs:string;
  197.   Msh,Msd:TMemoryStream;
  198.   i,j,n:integer;
  199.   p:PTreeData;
  200.   AList: TStringList;
  201.   ALevel,AOldLevel:integer;
  202.   AParentNode:TTreeNode;
  203.   StrBuf:PChar;
  204. begin
  205.   Result:=true;
  206.   Application.ProcessMessages;            //恢复原窗口
  207.   Srm:=TSrmObject.Create(Fn,fmOpenReadWrite);
  208.  if Srm.FileHead.Password[0]<>#0 then    //密码保护
  209.   begin
  210.     InPwForm:=TInPwForm.Create(SrmForm);
  211.     with InPwForm do
  212.     begin
  213.       Caption:=csAppName;
  214.       InputLabel.Caption:=csPasswordTitle;
  215.       if ShowModal=mrCancel then
  216.       begin
  217.         Srm.Free;
  218.         Srm:=nil;
  219.         Free;
  220.         Result:=false;
  221.         Exit;
  222.       end;
  223.       Ps:=Edit.Text;
  224.       UserPs:=string(Srm.FileHead.Password);
  225.       if Ps<>UserPs then
  226.       begin
  227.         if ModalResult<>mrCancel then
  228.           Application.MessageBox(csAppName,csPasswordError,MB_OK);
  229.         Srm.Free;
  230.         Srm:=nil;
  231.         Result:=false;
  232.         Free;
  233.         Exit;
  234.       end;
  235.       Free;
  236.     end;
  237.   end;
  238.   Screen.Cursor:=crHourGlass;
  239.   Msh:=TMemoryStream.Create;
  240.   Msd:=TMemoryStream.Create;
  241.   Srm.LoadIndex(Msh,Msd);                 //装入索引
  242.   AList := TStringList.Create;
  243.   SrmForm.TreeView.Items.BeginUpdate;
  244.   AList.LoadFromStream(Msh);              //装入到字符串列表中
  245.   SendMessage(SrmForm.TreeView.Handle, TVM_DELETEITEM, 0, Longint(TVI_ROOT));
  246.   AOldLevel := 0;
  247.   AParentNode := nil;
  248.   n:=AList.Count-1;
  249.   p:=Msd.Memory;
  250.   for i:=0 to n do                        //根据TAB的多少得到相应级别
  251.   begin
  252.     StrBuf:=PChar(AList.Strings[i]);
  253.     ALevel:=0;
  254.     while StrBuf^=#9 do                   //得该项所在层数
  255.     begin
  256.       Inc(StrBuf);
  257.       Inc(ALevel);
  258.     end;
  259.     if (ALevel<AOldLevel) or (AParentNode<>nil) then
  260.     begin                                 //返回该项的上级节点
  261.       for j:=AOldLevel downto ALevel do
  262.       begin
  263.         AParentNode:=AParentNode.Parent;
  264.       end;
  265.     end;
  266.     AParentNode:=SrmForm.TreeView.Items.AddChildObject(AParentNode,StrBuf,
  267.                                       pointer(p.Pos));
  268.     AParentNode.ImageIndex:=p.DataType;   //得该节点类型
  269.     AOldLevel:=ALevel;
  270.     p:=pointer(integer(p)+sizeof(TTreeData));
  271.   end;
  272.   SrmForm.TreeView.Items.EndUpdate;
  273.   AList.Free;
  274.   Msd.Free;
  275.   Msh.Free;
  276.   with Srm.FileHead,SrmForm do            //显示文件属性
  277.   begin
  278.     DbAuthorEdit.Text:=String(Author);
  279.     DbPasswordEdit.Text:=String(Password);
  280.     DbBuildDateEdit.Text:=DateToStr(BuildDate);
  281.     DbEditDateEdit.Text:=DateToStr(EditDate);
  282.   end;
  283.   SrmForm.TreeView.Selected:=nil;         //置当前选择项为空
  284.   with Srm do
  285.   begin
  286.     DbChanged:=false;                     //数据库变动标志复原
  287.     IndexChanged:=false;                  //索引变动标志复原
  288.     ItemHeadChanged:=false;
  289.     ItemDataChanged:=false;
  290.   end;
  291.   Screen.Cursor:=crDefault;
  292. end;
  293. //目录浏览,返回被选择的目录,空为无选择---------------------------
  294. function BrowseFolder:string;
  295. var
  296.   Info:TBrowseInfo;
  297.   Dir:array[0..260] of char;
  298.   ItemId:PItemIDList;
  299. begin
  300.   with Info do
  301.   begin
  302.     hwndOwner:=SrmForm.Handle;
  303.     pidlRoot:=nil;
  304.     pszDisplayName:=nil;
  305.     lpszTitle:=csBrowseFolderInfo;
  306.     ulFlags:=0;
  307.     lpfn:=nil;
  308.     lParam:=0;
  309.     iImage:=0;
  310.   end;
  311.   ItemId:=SHBrowseForFolder(Info);
  312.   if ItemId<>nil then
  313.   begin
  314.   SHGetPathFromIDList(ItemId,@Dir);
  315.   Result:=string(Dir);
  316.   end;
  317. end;
  318. //提取最后的路径名----------------------------------------------
  319. function GetLastPathName(var Pn:string):string;
  320. var
  321.   Size:integer;
  322. begin
  323.   Result:=Pn;
  324.   if Result[Length(Result)]='' then Delete(Result,Length(Result),1);
  325.   repeat
  326.     Size:=Pos('',Result);
  327.     if Size>0 then Delete(Result,1,Size);
  328.   until Size=0;
  329. end;
  330. //在注册表文件中设置SRM文件关联或取消-----------------------------
  331. procedure SetOpenSrmWithApp(Value:boolean);
  332. var
  333.   s:string;
  334. begin
  335.   with TRegistry.Create do
  336.   begin
  337.     RootKey:=HKEY_CLASSES_ROOT;
  338.     s:=csSrmFileType;
  339.     if Value then                         //建立相应的键值
  340.     begin
  341.       OpenKey(s,true);                    //s:='.srm'
  342.       Delete(s,1,2);
  343.       WriteString('',s);                  //:s='srm'
  344.       Insert('',s,1);
  345.       OpenKey(s,true);                    //s:='srm';
  346.       WriteString('',csSrmFileDescribe);
  347.       OpenKey(csSrmCommand,true);
  348.       WriteString('','"'+Application.ExeName+'" %1');
  349.     end
  350.     else                                  //删除相应的键值
  351.     begin
  352.       DeleteKey(s);
  353.       Delete(s,2,1);
  354.       DeleteKey(s);                       //s:='srm'
  355.     end;
  356.     Free;
  357.   end;
  358. end;
  359. //从目录中引入--------------------------------------------------------------
  360. procedure ImportDir(var Dir,Mask:string);
  361. var
  362.   SRec: TSearchRec;
  363.   ANode,OldNode:TTreeNode;
  364.   Path,Fn:string;
  365.   retval,oldlen:integer;
  366.   SubFlag,ItemFlag:boolean;
  367. begin
  368.   Path:=Dir;  //搜索路径
  369.   oldlen := Length(Dir);
  370.   retval := FindFirst( Dir+Mask,faAnyFile,SRec);
  371.   ItemFlag:=true;
  372.   SubFlag:=true;
  373.   OldNode:=SrmForm.TreeView.Selected;
  374.   ANode:=nil;
  375.   While retval=0 Do
  376.   Begin
  377.     If (SRec.Attr and (faDirectory or faVolumeID)) = 0 Then //是文件
  378.     begin
  379.       Fn:=SRec.Name;
  380.       Delete(Fn,Length(Fn)-3,4);
  381.       if ItemFlag then
  382.       begin
  383.         ItemFlag:=false;
  384.         ANode:=SrmForm.TreeView.Items.AddChildObjectFirst
  385.                        (SrmForm.TreeView.Selected,Fn,pointer(-1));
  386.       end
  387.       else
  388.         ANode:=SrmForm.TreeView.Items.AddObjectFirst
  389.                        (SrmForm.TreeView.Selected,Fn,pointer(-1));
  390.       ANode.ImageIndex:=2;  //初始化添加数据
  391.       with Srm.DataHead do
  392.       begin
  393.         DataType:=2;
  394.         Author[0]:=#0;
  395.         Password[0]:=#0;
  396.       end;
  397.       SrmForm.TreeView.Selected:=ANode;
  398.       SrmForm.RichEdit.Lines.LoadFromFile(Dir+SRec.Name);
  399.     end;
  400.     retval := FindNext(SRec);
  401.   End;
  402.   SysUtils.FindClose(SRec);
  403.   if not ItemFlag then SrmForm.TreeView.Selected:=ANode.Parent;
  404.   retval:=FindFirst(path+'*.*',faDirectory,SRec); //目录搜索
  405.   While retval=0 Do
  406.   Begin
  407.     If (SRec.Attr and faDirectory)<>0 Then //是目录
  408.       If (SRec.Name <> '.') and (SRec.Name <> '..') Then
  409.       Begin
  410.         Path:=Path+SRec.Name+'';
  411.         if SubFlag then
  412.         begin
  413.           SubFlag:=false;
  414.           ANode:=SrmForm.TreeView.Items.AddChildObjectFirst
  415.                      (SrmForm.TreeView.Selected,GetLastPathName(Path),
  416.                       pointer(-1));
  417.         end
  418.         else
  419.           ANode:=SrmForm.TreeView.Items.AddObjectFirst
  420.                      (SrmForm.TreeView.Selected,GetLastPathName(Path),
  421.                       pointer(-1));
  422.         ANode.ImageIndex:=1;
  423.         with Srm.DataHead do
  424.         begin
  425.           DataType:=1;
  426.           Author[0]:=#0;
  427.           Password[0]:=#0;
  428.         end;
  429.         SrmForm.TreeView.Selected:=ANode;
  430.         SrmForm.RichEdit.Modified:=true;
  431.         ImportDir(path,mask);
  432.         Delete(path,oldlen+1,260);
  433.       End;
  434.     retval := FindNext(SRec);
  435.   End;
  436.   SysUtils.FindClose(SRec);
  437.   SrmForm.TreeView.Selected:=OldNode;
  438. end;
  439. //格式化树形视图节点字符串防止无效字符-----------------------------------
  440. function FormatTreeNodeString(Value:string):string;
  441. var
  442.   Ap,At:pchar;
  443. begin
  444.   Value:=TrimLeft(Value);
  445.   Value:=TrimRight(Value);
  446.   Ap:=pchar(Value);
  447. //  while Ap^ in [#1..#32] do inc(Ap);      //去掉开头小于等于空格的字符
  448.   At:=Ap;
  449.   while At^<>#0 do
  450.   begin
  451.     if At^ in [#1..#31] then At^:=#32;    //将小于空格的无效字符替换成空格
  452.     inc(At);
  453.   end;
  454.   Result:=string(Ap);
  455. end;
  456. end.