Jump to content
Gary

App crash on close when windows style = windows

Recommended Posts

Hello all,

 

I have an app that dynamically changes the style. On close it saves style to ini and reloads on startup.

Changing style and closing is fine with any style except if the app has changed style to windows. App crashes after writing to ini, so if app starts with windows style and closes without changing all is fine. I logged the OnClose of the Main form and get no errors.

Debug shows the problem in the TStyleEngine.DoUnregisterStyleHook call and jumps to System here:

 

function _IsClass(const Child: TObject; Parent: TClass): Boolean;
begin
  Result := (Child <> nil) and Child.InheritsFrom(Parent);
end;

 

I have included the EurekaLog file.

 

Any help?

Gary

EurekaLog.txt

Share this post


Link to post

I had issues like this when I used a combo box to change the style of the application in the OnChange handler. I suppose it had to do something with the dropdown window still visible.

 

On the other hand don't be surprised, VCL themes are quite unstable. Since upgrading to 11.2 my main application started to throw similar AVs upon closure, but coming from DBGrid's style hook.

Share this post


Link to post
37 minutes ago, aehimself said:

Since upgrading to 11.2 my main application started to throw similar AVs upon closure, but coming from DBGrid's style hook.

You should file a bug report at https://quality.embarcadero.com You should write the smalest possible test application demonstrating the issue.

 

Share this post


Link to post

Hi,

 

did you find a fix for your problem?

I've exactly the same problem with one application, exception logged with madExcept:

 

exception number   : 1
exception class    : EAccessViolation
exception message  : Zugriffsverletzung bei Adresse 004090BC in Modul 'NikonDecoder.exe'. Lesen von Adresse 0030FFF0.

main thread ($4cd0):
004090bc +04 NikonDecoder.exe System          67 +0 TObject.InheritsFrom
00408fa6 +0e NikonDecoder.exe System          67 +0 @IsClass
007104bf +43 NikonDecoder.exe Vcl.Styles            TStyleEngine.DoUnregisterStyleHook
00710716 +1a NikonDecoder.exe Vcl.Styles            TStyleEngine.Notification
00667aef +f3 NikonDecoder.exe Vcl.Themes            TCustomStyleEngine.UnRegisterStyleHook

 

Share this post


Link to post

For me this works flawless:

unit uMain;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Menus, Vcl.Themes, System.IniFiles;

type
  TfrmMain = class(TForm)
    mmMain: TMainMenu;
    miVcl: TMenuItem;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormCreate(Sender: TObject);
  strict private
    FMenuItem: TMenuItem;
  private
    procedure AddNativeStyle(const AMenuItem: TMenuItem);
  public
    procedure NativeStyleClick(Sender: TObject);
  end;

var
  frmMain: TfrmMain;

implementation

{$R *.dfm}

procedure TfrmMain.FormCreate(Sender: TObject);
var
  ini: TIniFile;
  fn: string;
  Stylename: string;
  i: Integer;
begin
  AddNativeStyle(miVcl);
  fn := ChangeFileExt(ParamStr(0), '.ini');
  ini := TIniFile.Create(fn);
  try
    Stylename := ini.ReadString('Options', 'Theme', 'Windows');
    for i := 0 to Pred(miVcl.Count) do
      if StripHotkey(miVcl.Items[i].Caption) <> Stylename then
        miVcl.Items[i].Checked := False
        else
        miVcl.Items[i].Checked := True;
    TStyleManager.TrySetStyle(StyleName, True);
  finally
    ini.Free;
  end;
end;

procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
var
  ini: TIniFile;
  fn: string;
  i: Integer;
  StyleName: String;
begin
  fn := ChangeFileExt(ParamStr(0), '.ini');
  ini := TIniFile.Create(fn);
  try
    for i := 0 to Pred(miVcl.Count) do
      if miVcl.Items[i].Checked then
        begin
          StyleName := StripHotkey(miVcl.Items[i].Caption);
          Break;
        end;
    ini.WriteString('Options', 'Theme', StyleName);
  finally
    ini.Free;
  end;
end;

procedure TfrmMain.AddNativeStyle(const AMenuItem: TMenuItem);
  procedure AddMenuEntry(const ACaption: string; const AValue: Integer);
  var
    Item: TMenuItem;
  begin
    Item := TMenuItem.Create(FMenuItem);
    Item.Caption := ACaption;
    Item.OnClick := NativeStyleClick;
    Item.AutoCheck := False;
    Item.RadioItem := False;
    Item.Checked :=  TStyleManager.ActiveStyle.Name = ACaption;
    if ((AValue) mod 50) = 0 then
      Item.Break := mbBarBreak;
    FMenuItem.Add(Item);
  end;
var
  Arr: TArray<string>;
  SystemStyle: string;
  FoundStyle: String;
  i: Integer;
begin
  FMenuItem := AMenuItem;
  FMenuItem.Clear;
  FMenuItem.AutoLineReduction := maAutomatic;
  Arr := TStyleManager.StyleNames;
  SystemStyle := TStyleManager.SystemStyle.Name;
  AddMenuEntry(SystemStyle, 0);
  i := 1;
  for FoundStyle in Arr do
  begin
    if FoundStyle <> SystemStyle then
    begin
      AddMenuEntry(FoundStyle, i);
      Inc(i);
    end;
  end;
end;

procedure TfrmMain.NativeStyleClick(Sender: TObject);
var
  StyleName: String;
  i: Integer;
begin
  StyleName := StripHotkey((Sender as TMenuItem).Caption);
  TStyleManager.TrySetStyle(StyleName, True);
  (Sender as TMenuItem).Checked := True;
  for i := 0 to Pred(FMenuItem.Count) do
    if (not FMenuItem.Items[i].Equals(Sender)) then
      FMenuItem.Items[i].Checked := False;
end;

end.

Tested with Alexandria 11.2

Share this post


Link to post

Fyi, D11.3 (in theory) solved some issues with UnregisterStyleHook.

Can not confirm, though.

Share this post


Link to post

I can confirm that Delphi 11.3 has the issue fixed.

No more exception on close when the default style "Windows" was used/changed during runtime.

  • Thanks 2

Share this post


Link to post
51 minutes ago, GPRSNerd said:

I can confirm that Delphi 11.3 has the issue fixed.

No more exception on close when the default style "Windows" was used/changed during runtime.

Did you manage to consistently reproduce the issue?

At me it seemed random, popped up once or twice before disappearing for days.

Share this post


Link to post

Yeah, it was reproducible.

I added a functionality to switch the embedded styles in my app on runtime.

When I start the app and switch styles and in this procedure once the default Windows style was set, then the app throws the exception on close.

It is not necessarily the "Windows" style which has to be set last before closing.

Edited by GPRSNerd

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×