RRUZ / vcl-styles-utils

Extend and improve the Delphi VCL Styles
https://theroadtodelphi.wordpress.com/
329 stars 115 forks source link

Application crashes while using DLL which is setting VCL Style #306

Open mazharnazeer opened 11 months ago

mazharnazeer commented 11 months ago

Hi,

I am upgrading a Delphi application that uses DLL libraries. I have upgraded the application and DLLs from XE2 to 11.3. For this, I included the latest VCL Styles utils. The application and DLLs set styles. I put the set style functionality in a common unit and used it in both applications and DLLs. Following is the function for set style.

`Procedure LoadStyle(); var UserStyle : String; FullUserStyle : String; Begin // Check Style in User Registry. UserStyle := GetLocalUserStyle(); FullUserStyle := Format( '%sStyles\%s.vsf', [ExtractFilePath(Application.ExeName), UserStyle] ); if FileExists( FullUserStyle ) then TStyleManager.SetStyle(TStyleManager.LoadFromFile(FullUserStyle));

End;`

This function is called at initialization of that common unit.

The issue is that my application crashes when a DLL is being used. The DLL has a dialog to show and also has another functionality. Can you please help me to investigate what could be the issue?

lchris789 commented 9 months ago

Hello, I don't think VCL Style utlis can fix this, it is more focused on drawing.

Your application crashes because styles were not designed with DLL in mind.

Styles code refers to an Mainform that does not exist inside the DLL. It s set to nil so you crash when using styles.

But there is a workaround, I successfully uses styles and dll.

You need to create a fake empty mainform like this :

procedure AtaDLLinterface(App: TApplication; WParamAppli: TparamAppli; Wdata: pointer); var AtaMemHandle: HWND; aMainForm: TForm; begin TStyleManager.SystemHooks := TStyleManager.SystemHooks + [shDialogs]; UseLatestCommonDialogs := False;

AtaMemHandle := Application.Handle; try // Application.Initialize; Application.Handle := App.Handle; Application.OnIdle := App.OnIdle; Application.OnMessage := App.OnMessage; Application.CreateForm(TForm, aMainForm);

// Gestion multi moniteurs, rétabli le moniteur actif courant de l'application aMainForm.MakeFullyVisible(App.MainForm.Monitor); aMainForm.WindowState := wsMinimized; aMainForm.Borderstyle := bsNone; aMainForm.Width := 0; aMainForm.Height := 0; aMainForm.Visible := True; aMainForm.Visible := False;

  Application.Icon.Handle := App.icon.handle;
  Application.UpdateFormatSettings := false;
  SetForegroundWindow(Application.Handle);
  FormatSettings.ShortDateFormat := 'dd/mm/yyyy';
  FormatSettings.LongDateFormat := 'dd/mm/yyyy';
  FormatSettings.DateSeparator := '/';

  try

     // affectation des variables globales
     ParamAppli := WparamAppli;

     if ParamAppli.StyleVisuel<>'' then
     begin
        TStyleManager.LoadFromFile(ExtractFilePath(ParamStr(0))+StringReplace(ParamAppli.StyleVisuel, ' ', '', [rfReplaceAll])+'.vsf');
        TStyleManager.TrySetStyle(IFTHEN(ParamAppli.StyleVisuel='', 'Windows', paramAppli.StyleVisuel));
        TStyleManager.SystemHooks := [];
     end;

  try

        // Do Something

     except
        on Eabort do {rien}
        else raise;
     end;
  finally
     // Free Something
  end;

finally Application.handle := AtaMemHandle; end; end;

hope it Helps Best regards