library OSDialog;uses
  ComServ,
  ShareMem,
  Dialogs,
  SysUtils;function ShowOpenDialog():PChar;stdcall;
var
  OpenDialog: TOpenDialog;
begin
  Result := PChar('');
  OpenDialog := TOpenDialog.Create(nil);
  OpenDialog.Filter := 'NOTES数据库|*.nsf';  if OpenDialog.Execute() then
  begin
    if Pos('nsf',LowerCase(OpenDialog.FileName)) = 0 then
      begin
        Result := PChar(OpenDialog.FileName+'.nsf');
      end
    else
      Result := PChar(OpenDialog.FileName);
  end;
end;function ShowSaveDialog():PChar;stdcall;
var
  SaveDialog: TSaveDialog;
begin
  Result := PChar('');
  SaveDialog := TSaveDialog.Create(nil);
  SaveDialog.Filter := 'NOTES数据库|*.nsf';  if SaveDialog.Execute() then
  begin
    if Pos('nsf',LowerCase(SaveDialog.FileName)) = 0 then
      begin
        Result := PChar(SaveDialog.FileName+'.nsf');
      end
    else
      Result := PChar(SaveDialog.FileName);
  end;
end;exports
  ShowOpenDialog,
  ShowSaveDialog,
  DllGetClassObject,
  DllCanUnloadNow,
  DllRegisterServer,
  DllUnregisterServer;{$R *.RES}begin
end.我先在Delphi中写好该程序编译好后,我在VB中调用的时候能正常返回选择的文件名,但是我关闭主窗口的时候就报错了,我不知道这该这么解决?没有释放VCL吗?但我在程序中加了也是一样的。请高手指教,谢谢!

解决方案 »

  1.   

    都改成如下:function ShowOpenDialog(FileName: PChar):boolean;stdcall;
      

  2.   

    function ShowOpenDialog(FileName: PChar):boolean;stdcall
    你是用它来返回值的,那你的返回类型肯定是Boolean类型的了
    所以应该这样写
      

  3.   

    function ShowOpenDialog(FileName: PChar):boolean;stdcall;
      

  4.   

    OpenDialog := TOpenDialog.Create(nil);后面没有free?
    如果free了:
    Result := PChar(OpenDialog.FileName);这一句不会分配内存的,等到TOpenDialog销毁之后,返回的PChar就成了无效的指针,所以要function ShowOpenDialog(FileName: PChar):boolean;stdcall
    在VB中调用ShowOpenDialog前先为filename分配内存,在dll中将OpenDialog.FileName拷贝进去
      

  5.   

    我找到了解决方法,代码如下:
    unit OSDialogLib;interfaceuses
      Windows,SysUtils,Dialogs,Forms;function ShowOpenDialog():PChar;stdcall;
    function ShowSaveDialog():PChar;stdcall;implementation//显示打开文件对话框
    function ShowOpenDialog():PChar;stdcall;
    var
      OpenDialog: TOpenDialog;
      FileName: String;
    begin
      Result := PChar('');
      Application.Handle := GetActiveWindow();
      OpenDialog := TOpenDialog.Create(Application);
      OpenDialog.Filter := 'NOTES数据库(*.nsf)|*.nsf';
      //设置路径和文件必须存在
      OpenDialog.Options := OpenDialog.Options + [ofPathMustExist, ofFileMustExist];  if OpenDialog.Execute() then
      begin
        FileName := OpenDialog.FileName;
        if Pos('nsf',FileName) <= 0 then FileName := FileName + '.nsf';
        Result := PChar(FileName);
        OpenDialog.Free;
      end;
    end;//保存打开文件对话框
    function ShowSaveDialog():PChar;stdcall;
    var
      SaveDialog: TSaveDialog;
      FileName: String;
    begin
      Result := PChar('');
      Application.Handle := GetActiveWindow();
      SaveDialog := TSaveDialog.Create(Application);
      SaveDialog.Filter := 'NOTES数据库(*.nsf)|*.nsf';  if SaveDialog.Execute() then
      begin
        FileName := SaveDialog.FileName;
        if Pos('nsf',FileName) <= 0 then FileName := FileName + '.nsf';
        Result := PChar(FileName);
        SaveDialog.Free;
      end;
    end;end.
      

  6.   

    再次修改后的代码:
    unit OSDialogLib;interfaceuses
      Windows,SysUtils,Dialogs,Forms;function ShowOpenFileDialog(const DialogPrompt:PChar;
                                const DefaultFileName:PChar;
                                const FileFilter:PChar):PChar; stdcall;
    function ShowSaveFileDialog(const DialogPrompt:PChar;
                                const DefaultFileName:PChar;
                                const FileFilter:PChar):PChar; stdcall;implementation//显示打开文件对话框
    function ShowOpenFileDialog(const DialogPrompt:PChar;
                                const DefaultFileName:PChar;
                                const FileFilter:PChar):PChar; stdcall;
    var
      OpenFileDialog: TOpenDialog;
      FileNameA: String;
      FileName: String;
    begin
      Result := PChar('');
      Application.Handle := GetActiveWindow();
      OpenFileDialog := TOpenDialog.Create(Application);
      OpenFileDialog.Filter := StrPas(FileFilter);
      OpenFileDialog.Title := StrPas(DialogPrompt);
      if OpenFileDialog.Title = '' then OpenFileDialog.Title := '打开';
      //设置路径和文件必须存在
      OpenFileDialog.Options := OpenFileDialog.Options + [ofPathMustExist, ofFileMustExist];
      FileNameA := StrPas(DefaultFileName);
      if FileNameA <> '' then OpenFileDialog.FileName := FileNameA;  if OpenFileDialog.Execute() then
      begin
        FileName := OpenFileDialog.FileName;
        if Pos('nsf',FileName) <= 0 then FileName := FileName + '.nsf';
        Result := PChar(FileName);
        OpenFileDialog.Free;
      end;
    end;//保存打开文件对话框
    function ShowSaveFileDialog(const DialogPrompt:PChar;
                                const DefaultFileName:PChar;
                                const FileFilter:PChar):PChar; stdcall;
    var
      SaveFileDialog: TSaveDialog;
      FileNameA: String;
      FileName: String;
    begin
      Result := PChar('');
      Application.Handle := GetActiveWindow();
      SaveFileDialog := TSaveDialog.Create(Application);
      SaveFileDialog.Filter := StrPas(FileFilter);
      SaveFileDialog.Title := StrPas(DialogPrompt);
      if SaveFileDialog.Title = '' then SaveFileDialog.Title := '另存为';
      //设置提示用户文件已经存在
      SaveFileDialog.Options := SaveFileDialog.Options + [ofOverwritePrompt];
      FileNameA := StrPas(DefaultFileName);
      if FileNameA <> '' then SaveFileDialog.FileName := FileNameA;  if SaveFileDialog.Execute() then
      begin
        FileName := SaveFileDialog.FileName;
        if Pos('nsf',FileName) <= 0 then FileName := FileName + '.nsf';
        Result := PChar(FileName);
        SaveFileDialog.Free;
      end;
    end;end.