Delphi编程俱乐部

Author: 眼光 Date: 1999年 第46期 13版


  大家好, 在“Delphi论坛”和大家小别的这一段时间里一定让不少人等急了(对不起,实在是不好意思),所以这次眼光是在头上绑了一根写着“必胜”的白布条才一个猛子扎进论坛的数据库的。不为别的,只是希望不让大家失望。 经过两个多小时的打捞,眼光从回收站里伸出的手中攥着以下几个问题和答案:
  问题一:在Win98中右击“我的文档”,选属性,在弹出的“我的文档 属性”窗口中点击“浏览”按钮就会弹出一个“浏览文件夹”对话框。请问这个对话框是怎么做出来的?
  答案:要做这个对话框有三种方法。
  (一)第一种方法是用Delphi提供的组件(在Win 3.1面板上)模仿在上面看到的对话框自己组装一个“浏览文件夹”窗体。具体的做法是:
  1.在你的Project里增加一个BorderStyle为bsDialog的新窗体;
  2.放置一个DirectoryListBox组件;
  3.放置一个DriveComboBox组件,设置DirList为DirectoryListBox1;
  4.然后再放上两个Button。一个“确定”(ModalResult为mrOk),一个“取消”(ModalResult为mrCancel);
  5.最后只要在调用这个浏览文件夹的地方加上一下代码就算大功告成了:
  if Form2.ShowModal = mrOk then
  Memo1.Lines.Add(Form2.DirectoryListBox1.Directory);
  (二)第二种方法,在Delphi中可以通过调用SelectDirectory函数得到这种效果。
  SelectDirectory在Delphi 4中的申明如下(请注意,一共有两个重载的申明):
  type
  TSelectDirOpt = (sdAllowCreate, sdPerformCreate, sdPrompt);
  TSelectDirOpts = set of TSelectDirOpt;
  function SelectDirectory(var Directory: string;
  Options: TSelectDirOpts; HelpCtx: Longint): Boolean; overload;
  function SelectDirectory(const Caption: string; const Root:WideString; out Directory: string): Boolean; overload;
  第一种语法的Options参数指定了“浏览文件夹”对话框的一些选项;参数HelpCtx指定上下文敏感的Help ID;Directory初始化了对话框的值,并且携带返回值。
  第二种语法的Caption参数指定对话框标题(比如′请选择XXX的文件夹′);参数Root指定用来浏览的根目录;所选择文件夹返回在参数Directory中。
  不管是哪种语法,如果在对话框中选择了路径并按下“确定”按钮,SelectDirectory函数返回True;在其它情况下,函数SelectDirectory就返回False。
  (三)第三种方法是比较高明的解决方案。在Windows中已经有一个专门用来处理这种问题的ShellAPI函数——SHBrowseForFolder(事实上,第二种方法的第二种语法就是调用了这个API,这在Delphi的源代码中可以得到证实)。因为它是使用系统已有的API,这样就不会占用太多的系统资源,从而减小代码长度、提高程序运行速度,并且在Windows的不同语言版本中会自动的和Windows相适应。具体代码如下:
  var
  Info: TBrowseInfo;
  Dir: array[0..260] of char;
  ItemId: PItemIDList;
  begin
  with Info do
  begin
  hwndOwner := self.Handle;
  pidlRoot := nil;
  pszDisplayName := nil;
  lpszTitle := ′请选择XXX的文件夹′;
  ulFlags := 0;
  lpfn := nil;
  lParam := 0;
  iImage := 0;
  end;
  ItemId := SHBrowseForFolder(Info);
  if ItemId <> nil then
  begin
  SHGetPathFromIDList(ItemId, @Dir);
  Result := string(Dir);
  end
  else
  Result := ′′;
  end;
  如果你对最后的这种方法感兴趣,以Browsing for Folders为主题在Windows API Help中检索将会得到更多的文档。
  问题二:在许多软件的制作过程中我都遇到文件复制这个问题,但我对文件操作很不熟悉。请问,在Delphi中有简单的方法能够实现这个功能吗?
  答案:实现它的源代码如下:
  var
  DesFile, SourFile: File;
  Buf: Byte;
  begin
  AssignFile(SrcFile, ″c:\autoexec.bat″);
  Reset(SrcFile, 1);// 1 = 逐个字节操作
  AssignFile(DesFile, ″c:\autoexec.bak″);
  Rewrite(DesFile, 1);  // 同上
  while not Eof(SrcFile) do
  begin
  BlockRead(SrcFile, Buf, SizeOf(Byte));   // 从源文件中读出来
  BlockWrite(DesFile, Buf, SizeOf(Byte));  // 写到目标文件中去
  end;
  CloseFile(SrcFile);
  CloseFile(DesFile);
  end;
  另外还有一个高招——直接使用API函数CopyFile。这个API的原型如下:
  BOOL CopyFile(
  LPCTSTR lpExistingFileName,  // pointer to name of an existing file 
  LPCTSTR lpNewFileName,   // pointer to filename to copy to 
  BOOL bFailIfExists   // flag for operation if file exists 
  );
  如:CopyFile( PChar(′c:\autoexec.bat′), PChar(′c:\autoexec.bak′), True);