Jump to content
jesu

access violation changing font

Recommended Posts

Hello. Using 12.3 + patch 1. I'm seeing this error: 

Quote

Access violation at address 6F75232A in module 'COMCTL32.dll' (offset 2232A). Read of address 0000000C.

changing font at runtime. This is my code:

 

procedure TFprincipal.FontNameRClick(Sender: TObject);
begin
  ga_TipoLetra := FontNameR.Text;
  Font.Name := ga_TipoLetra;
  gn_FontSize := StrToInt(ComboSize.Text);
  Font.Size := gn_FontSize;
  Screen.MessageFont := Self.Font;
  ToolBar.Font.Size := Min(gn_FontSize, 14);
end;

The error happens at the end of that code in procedure TWinControl.DefaultHandler(var Message); inside VCL.Controls.
Is it a bug or should I do something different?

Thanks

Share this post


Link to post

From the posted code it is not clear what values are passed, for example what is assigned to "Font.name"? You need to find out which value is not right, start disabling some lines to see if the problem disappears.

Share this post


Link to post

I use this procedure to get installed fonts and allow to choose one:


 

procedure TFprincipal.GetFontNames;
var
  DC: HDC;
begin
  DC := GetDC(0);
  EnumFonts(DC, nil, @EnumFontsProc, Pointer(FontNameR.Items));
  ReleaseDC(0, DC);
  FontNameR.Sorted := True;
end;

but the problem seems to happen not when I change font name, but when I increase font size, and it doesn't happen always. If I choose a second time the same font size, the second time it seems to work.

 

Edited by jesu

Share this post


Link to post

try to monitor the values that are given to "font.size", or attach a simple project where we can check

Share this post


Link to post

My guess is that something you are doing elsewhere is corrupting memory and what you are seeing are just secondary errors.

You can probably use madExcept, with memory overrun check enabled, to find the origin of the problem.

Share this post


Link to post
On 5/26/2025 at 7:37 PM, Remy Lebeau said:

Why not use Screen.Fonts instead? 

I don't know. I've used that piece of code for more than 20 years. Maybe Screen.Fonts didn't exist or it didn't return the same.

Ok, I've reduced the program so anyone can test it. Just press F9, change Tamaño to 16 and you should see the error.

Trying to reproduce the error outside of the IDE seems much harder.

BugEditor.zip

error.png

Edited by jesu

Share this post


Link to post

It’s generally not advisable to change the font of a form or visual control directly from within an event handler like OnClick, especially for controls that are part of the form itself. Internally, setting Font.Name or Font.Size can lead to a call to CreateWnd, which may cause issues if it's done while Windows messages are still being processed for the same control—resulting in access violations like the one you're seeing in COMCTL32.dll.

One safe workaround is to defer the font update. You can use a short-delay TTimer for this purpose. Here's an example:

procedure TFprincipal.FontNameRClick(Sender: TObject);
begin
  Timer1.Enabled := True;
end;

procedure TFprincipal.Timer1Timer(Sender: TObject);
begin
  Timer1.Enabled := False; // Disable the timer to prevent repeated calls
  ga_TipoLetra := FontNameR.Text;
  Font.Name := ga_TipoLetra;
  gn_FontSize := StrToInt(ComboSize.Text);
  Font.Size := gn_FontSize;
  Screen.MessageFont := Self.Font;
  ToolBar.Font.Size := Min(gn_FontSize, 14);
end;

Set Timer1.Interval to something small like 10 and make sure it’s initially disabled (Enabled := False). This will safely postpone the font update until the current message queue has been processed.

 

Let me know if that solves the issue for you!

Share this post


Link to post
1 hour ago, Typer2 said:

It’s generally not advisable to change the font of a form or visual control directly from within an event handler like OnClick, especially for controls that are part of the form itself. Internally, setting Font.Name or Font.Size can lead to a call to CreateWnd, which may cause issues if it's done while Windows messages are still being processed for the same control—resulting in access violations like the one you're seeing in COMCTL32.dll.

This is incorrect. Changing font properties in an event handler is fine.

Share this post


Link to post

It seems to be reproducible reliably in the debugger, while without the debugger I can switch the size with or without errors and I was not able to identify a pattern, yet.

Share this post


Link to post

FWIW, madExcept didn't find any memory overwrites but of course caught the exception:

exception class    : EAccessViolation
exception message  : Access violation at address 58C66418 in module 'COMCTL32.dll'. Read of address 0000000C.

main thread ($3be0):
58c66418 +000 COMCTL32.dll
74a25d96 +016 USER32.dll                             CallWindowProcW
00eb193d +131 Editor.exe   Vcl.Controls   11199  +34 TWinControl.DefaultHandler
00eb246a +01a Editor.exe   Vcl.Controls   11505   +1 TWinControl.WMCommand
00eac1b2 +2be Editor.exe   Vcl.Controls    7920  +91 TControl.WndProc
00eb17e7 +6a7 Editor.exe   Vcl.Controls   11154 +178 TWinControl.WndProc
00ece57f +23f Editor.exe   Vcl.StdCtrls    4849  +95 TCustomCombo.WndProc
00ed02e4 +1f0 Editor.exe   Vcl.StdCtrls    5642  +42 TCustomComboBox.WndProc
00e2f31c +014 Editor.exe   System.Classes 19084   +8 StdWndProc
00eb0cac +02c Editor.exe   Vcl.Controls   10823   +3 TWinControl.MainWndProc
00e2f31c +014 Editor.exe   System.Classes 19084   +8 StdWndProc
74a260b8 +048 USER32.dll                             SendMessageW
74a25d96 +016 USER32.dll                             CallWindowProcW
00ed7310 +2bc Editor.exe   Vcl.StdCtrls   11307  +70 TComboBoxStyleHook.ListBoxWndProc
00e2f31c +014 Editor.exe   System.Classes 19084   +8 StdWndProc
74a2620b +00b USER32.dll                             DispatchMessageW
00f760bb +0f3 Editor.exe   Vcl.Forms      13282  +23 TApplication.ProcessMessage
00f760fe +00a Editor.exe   Vcl.Forms      13312   +1 TApplication.HandleMessage
00f7643d +0d1 Editor.exe   Vcl.Forms      13451  +27 TApplication.Run
00ff37a6 +05a Editor.exe   Editor            21   +5 initialization
75f7fcc7 +017 KERNEL32.DLL                           BaseThreadInitThunk

 

Share this post


Link to post
4 hours ago, Typer2 said:

 One safe workaround is to defer the font update. You can use a short-delay TTimer for this purpose

Or, use TThread.ForceQueue() instead, eg:

procedure TFprincipal.FontNameRClick(Sender: TObject);
begin
  TThread.ForceQueue(nil,
   procedure
   begin
     ga_TipoLetra := FontNameR.Text;
     Font.Name := ga_TipoLetra;
     gn_FontSize := StrToInt(ComboSize.Text);
     Font.Size := gn_FontSize;
     Screen.MessageFont := Font;
     ToolBar.Font.Size := Min(gn_FontSize, 14);
  end);
end;

 

Edited by Remy Lebeau

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

×