Question

In a little app I want to show a open file dialog before the main form is created. I do it like this in the *.dpr:

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

When I use the following Init procedure:

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;

there is no dialog shown under Windows 7. I can fix this by setting UseLatestCommonDialogs to False but I'd like to avoid that. Changing the Init procedure to

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;

works. However I'm not sure If I got the CoInitialize/CoUninitialize right, e.g.:

  • Do I mess something up by calling CoUninitialize so early?
  • Having to "know" the fact that TOpenDialog internally (sometimes) uses COM smells like leaky abstraction that I'd rather avoid.

Edit: I found a slightly better way: If I add ComObj to the dpr's uses clause I can omit the CoInitialize/CoUninitialize calls. The leaky abstraction issue stills holds, of course.

Was it helpful?

Solution

It seems that the issue is that COM is not being initialized. This normally happens in Application.Initialize because of the initialization procedure that is added by using ComObj. But you report in a comment that InitProc is nil inside Application.Initialize which indicates that ComObj is not included in your project.

So, you can solve the issue readily by including ComObj in your project. Or if you want to be explicit about it, just call CoInitilize(nil) at the very start of your .dpr file.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top