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