Recent

Author Topic: Application.Handle missing  (Read 9575 times)

tk

  • Sr. Member
  • ****
  • Posts: 386
Application.Handle missing
« on: June 16, 2014, 01:38:07 am »
hello,
I have a main program and a DLL both written in Delphi which I am converting to Lazarus.
Both main program and the DLL use separate VCLs, no runtime packages used.
In a DLL there is a configuration form which I need to show from the main program.
The important code in the DLL is:
Code: [Select]
function TCom.PropConfig(AAppHandle: THandle): Boolean;
var
  AForm: TConfigForm;
begin
  Result := False;
{$IFnDEF FPC}
  Application.Handle := AAppHandle;
{$ENDIF}
  AForm := TConfigForm.Create(Application);
  try
    ConfigToForm(AForm);
    if AForm.ShowModal = mrOk then
    begin
      FormToConfig(AForm);
      Result := True;
    end
  finally
    AForm.Free;
  end;
end;

function PropConfig(AHandle, AAppHandle: THandle): Boolean; stdcall;
begin
  try
    if TObject(AHandle) is TCom then
      Result := TCom(AHandle).PropConfig(AAppHandle)
    else
      Result := False;
  except
    Result := False;
  end
end;

The important code in the main program is:
Code: [Select]
function TPlugin.PropConfig(AHandle, AAppHandle: THandle): Boolean;
begin
  if Assigned(FFuncPropConfig) then
    Result := FFuncPropConfig(AHandle, AAppHandle)
  else
    Result := False;
end;

// somewhere in the main program there is this call:
MyPlugin.PropConfig(PluginHandle, MainForm.Handle);

This works OK in Delphi, but due to the missing Application.Handle property in Lazarus (the first IFDEF) the configuration dialog won't show up.
I am testing on WIndows now but of course I need platform independent solution for this.

tk

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12770
  • FPC developer.
Re: Application.Handle missing
« Reply #1 on: June 16, 2014, 09:53:34 am »
IIRC use WidgetSet.AppHandle

Mike.Cornflake

  • Hero Member
  • *****
  • Posts: 1269
Re: Application.Handle missing
« Reply #2 on: June 16, 2014, 10:18:10 am »
Bleh, this may not be relevant to you, however you may find something of interest...   The words dll and apphandle triggered a vague memory of something I've read on here.   Here's the post - as I say, not sure if you'll find it relevant, it may be worth a read...

http://forum.lazarus.freepascal.org/index.php/topic,22766.msg140959.html
Lazarus Trunk/FPC latest fixes on Windows 11
  I'm getting old and stale.  Slowly getting used to git, I'll get there...

tk

  • Sr. Member
  • ****
  • Posts: 386
Re: Application.Handle missing
« Reply #3 on: June 16, 2014, 11:04:03 am »
IIRC use WidgetSet.AppHandle

Just tried

Code: [Select]
{$IFDEF FPC}
  WidgetSet.AppHandle:= AAppHandle;
{$ELSE}
  Application.Handle := AAppHandle;
{$ENDIF}

without success.

Found also this thread http://forum.lazarus.freepascal.org/index.php/topic,8321.msg58906.html#msg58906.
Might work, I didn't try yet but seems a little bit weird to me.
I would like to keep the entire form calling logic hidden inside of the DLL.

tk

  • Sr. Member
  • ****
  • Posts: 386
Re: Application.Handle missing
« Reply #4 on: June 16, 2014, 01:57:11 pm »
Finally got the form on screen with:
Code: [Select]
{$IFDEF FPC}
  WidgetSet.AppHandle:= AAppHandle;
  Application.Initialize;
{$ELSE}
  Application.Handle := AAppHandle;
{$ENDIF}

but it is not shown as modal form, although ShowModal is called.

tk

  • Sr. Member
  • ****
  • Posts: 386
Re: Application.Handle missing
« Reply #5 on: June 17, 2014, 12:17:49 am »
Finally I realized there is no clean solution for this in Lazarus.
To show a form in a DLL in the context of the main application would need a clean and well defined solution how to link the entire LCL context from the main project (e.g. WidgetSet, Application, Screen etc.)  to the DLL project. If both the DLL and main project are written in Lazarus.

I tried to switch the context, i.e. supplant those static instances I mentioned above from main project into the DLL but this produced exceptions. I am sure those three are not enough, there are many more, going deeply into the particular widget set etc.

Finally I encapsulated the DLL call with Screen's DisableForms and EnableForms methods, which at least disables all forms from the main project before the DLL modal form is shown:
Code: [Select]
function TPlugin.PropConfig(AHandle, AAppHandle: THandle): Boolean;
var
  List: TList;
begin
  if Assigned(FFuncPropConfig) then
  begin
    List := Screen.DisableForms(nil);
    try
    Result := FFuncPropConfig(AHandle, AAppHandle);
    finally
      Screen.EnableForms(List);
    end;
  end
  else
    Result := False;
end;     

It produces some problems when switching programs with ALT+TAB but this is the only at least partially clean solution I could find.

Delphi has no explicit solution as well, but somehow supplanting Application.Handle in the DLL works fine.

 

TinyPortal © 2005-2018