5
votes

Using Delphi XE2, you have the option to embed custom styles (skins) to a VCL project.
Everything works fine. Now I have some forms into a separated dll that I show dynamically.
Of course those are not skinned. How can I rectify that?

I guess I must do some call to TVisualStyle somehow, but no luck.

The host:

procedure TForm1.Button1Click(Sender: TObject); 
var   
  l: THandle;   
  p: procedure (const h: THandle); stdcall; 
begin   
 l:= LoadLibrary('project1.dll');   
 if l > 0 then   
 begin
        @p:= GetProcAddress(l,'ShowIt');
        p(Application.Handle);
        FreeLibrary(l);   
  end; 
end;

The dll:

procedure ShowIt(const h: THandle);stdcall;
var
  form: TForm;
  b: TButton;
  han: THandle;
begin
  han:= Application.Handle;
  Application.Handle:= h;
  form :=Tform.Create(Application);
  b:= TButton.Create(form);
  b.Parent:= form;
  b.Caption:= 'ytes';
  b.Left:= 2;
  b.Top:= 2;
  form.ShowModal;
  form.Release;
  Application.Handle:= han;
end;

exports ShowIt ;
begin
end.

Pretty standard stuff. Now, what exactly must be done to make the dll form use the host's style theme?

2
Did you recompile the DLL with XE2?Jerry Gagnon
It's a DLL rather than a package?David Heffernan
Yes. But it doesn't pick the original theme up.Lobuno
You've not given any details of how the VCL is shared (if at all) and how the exe and DLL are separated - what goes where.David Heffernan
Do not call Form.Release there. That posts a message to the application's message queue, and that message won't get processed until the thread next processes messages, which isn't until after the DLL function returns to the caller. The caller unloads the DLL, so now you're stuck with a message on the queue addressed to a window that still exists, but whose code has already been unloaded from memory. Call Free instead. Release is for when an object wants to free itself from within one of its own message handlers.Rob Kennedy

2 Answers

14
votes

You have two distinct instances of the VCL. You have set the style in the StyleServices instance owned by the executable, but your DLL has no knowledge of that. You could solve this by either:

  1. Passing the style settings to a function in your DLL that applies those settings to the other StyleServices instance.
  2. Use packages so that you only have a single VCL instance.
0
votes

I had a lot of trouble with this and it was because I was using themes rather than VCL.THEMES and VCL.STYLES.

Delphi was throwing up a customeStyleException saying "style not found" or EcustomStyleException "Feature not supported by this style"