4

小さなアプリで、メイン フォームが作成される前にファイルを開くダイアログを表示したいと考えています。*.dpr で次のようにします。

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

次の Init プロシージャを使用すると:

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 を使用しているという事実を「知っておく」必要があるのは、むしろ避けたい漏れやすい抽象化のようなにおいがします。

編集:少し良い方法を見つけました: ComObjdpr の句に追加すると、 /呼び出しusesを省略できます。もちろん、漏れやすい抽象化の問題は依然として残っています。CoInitializeCoUninitialize

4

1 に答える 1

3

COM が初期化されていないことが問題のようです。これは通常Application.Initialize、 を使用して追加された初期化手順が原因で発生しComObjます。ただし、プロジェクトに含まれていないことInitProcを示すnil内部のコメントで報告します。Application.InitializeComObj

したがって、プロジェクトに含めることで問題を簡単に解決できComObjます。または、それについて明示したい場合CoInitilize(nil)は、.dpr ファイルの最初で呼び出すだけです。

于 2013-05-22T08:24:43.130 に答える