4

在一个小应用程序中,我想在创建主窗体之前显示一个打开的文件对话框。我在 *.dpr 中这样做:

begin
  Application.Initialize;
  Init; // <=========================================
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

当我使用以下初始化过程时:

procedure Init;
var
  OpenDialog: TOpenDialog;
begin
  TheFileName := '(nix)';

  OpenDialog := TOpenDialog.Create(nil);
  try
    if OpenDialog.Execute then
      TheFileName := OpenDialog.FileName
    else
      Exit;
  finally
    OpenDialog.Free;
  end;
end;

Windows 7 下没有显示对话框。我可以通过将 UseLatestCommonDialogs 设置为 False 来解决此问题,但我想避免这种情况。将 Init 过程更改为

procedure Init;
var
  OpenDialog: TOpenDialog;
begin
  TheFileName := '(nix)';

  CoInitialize(nil);
  try
    OpenDialog := TOpenDialog.Create(nil);
    try
      if OpenDialog.Execute then
        TheFileName := OpenDialog.FileName
      else
        Exit;
    finally
      OpenDialog.Free;
    end;
  finally
    CoUninitialize;
  end;
end;

作品。但是我不确定我是否正确使用了 CoInitialize/CoUninitialize,例如:

  • 我这么早就调用 CoUninitialize 会搞砸一些事情吗?
  • 必须“知道” TOpenDialog 内部(有时)使用 COM 的事实就像我宁愿避免的泄漏抽象。

编辑:我找到了一个更好的方法:如果我添加ComObj到 dpr 的uses子句中,我可以省略CoInitialize/CoUninitialize调用。当然,泄漏的抽象问题仍然存在。

4

1 回答 1

3

似乎问题在于 COM 没有被初始化。这通常发生在Application.Initialize因为使用ComObj. 但是您在内部的评论中InitProc进行报告,表明该评论未包含在您的项目中。nilApplication.InitializeComObj

因此,您可以通过包含ComObj在您的项目中轻松解决问题。或者,如果您想明确说明,只需CoInitilize(nil)在 .dpr 文件的开头调用即可。

于 2013-05-22T08:24:43.130 回答