p***@childcaremanager.com
2007-01-08 22:36:57 UTC
I have been working to update the look and feel of my forms in Delphi 7
and I am looking for a way to automatically update the font (to, say,
"Tahoma" for XP or "Segoe UI" for Vista) for all controls on a form.
Since any change to a control's font sets all of the information
(including name and size), this prevents the controls' fonts being set
simply by changing the form's font.
What I would like to do is recurse through all of the controls on a
form and set the font. However, as in the case of the TLabel control,
while the Font property is defined in the TControl class, it is not
published until TLabel. Thus, I have to cast it to a TLabel to get
access to the font.
I would like to avoid writing a massive set of if statements including
every type of component that is on any of the forms in the program.
However, my attempts at dynamic casting aren't working. Here is the
first try at what I'm doing.
I should hope that most of the code below is pretty self-explanatory.
I have a class defined (TComponentUpdater) which has two overloaded
procedures (called SetFont). The hope is that, if SetFont is called
for a component other than a TLabel, it will call the empty SetFont.
Otherwise, it will cast it to the appropriate type (i.e. TLabel) and
call that version of SetFont. TSetFontFlags is a set of enumerations
to indicate what font properties should be set.
If I can get this to work, I will probably break out the code where the
font properties are being set into a different procedure to reduce code
duplication. That said, here's the code:
procedure SetChildrenFonts(const formToUpdate : TCustomForm);
var
cmpChild : TComponent;
nComponent : Integer;
begin
for nComponent := 0 to (formToUpdate.ComponentCount - 1) do
begin
if (formToUpdate.Components[nComponent] is TCustomForm) then
...
else begin
cmpChild := formToUpdate.Components[nComponent];
TComponentUpdater.SetFont(cmpChild as cmpChild.ClassType,
formToUpdate.Font, [sfName, sfSize]);
end;
end;
end;
class procedure TComponentUpdater.SetFont(cmpToUpdate : TComponent;
fntInfo : TFont; sfFlags : TSetFontFlags);
begin
// Do nothing. We can't set the font for a TComponent. This
prevents errors.
end;
class procedure TComponentUpdater.SetFont(lblToUpdate : TLabel; fntInfo
: TFont; sfFlags : TSetFontFlags);
begin
if (sfCharset in sfFlags) then
lblToUpdate.Font.Charset := fntInfo.Charset;
if (sfColor in sfFlags) then
lblToUpdate.Font.Color := fntInfo.Color;
if (sfName in sfFlags) then
lblToUpdate.Font.Name := fntInfo.Name;
if (sfPitch in sfFlags) then
lblToUpdate.Font.Pitch := fntInfo.Pitch;
if (sfSize in sfFlags) then
lblToUpdate.Font.Size := fntInfo.Size;
if (sfStyle in sfFlags) then
lblToUpdate.Font.Style := fntInfo.Style;
end;
and I am looking for a way to automatically update the font (to, say,
"Tahoma" for XP or "Segoe UI" for Vista) for all controls on a form.
Since any change to a control's font sets all of the information
(including name and size), this prevents the controls' fonts being set
simply by changing the form's font.
What I would like to do is recurse through all of the controls on a
form and set the font. However, as in the case of the TLabel control,
while the Font property is defined in the TControl class, it is not
published until TLabel. Thus, I have to cast it to a TLabel to get
access to the font.
I would like to avoid writing a massive set of if statements including
every type of component that is on any of the forms in the program.
However, my attempts at dynamic casting aren't working. Here is the
first try at what I'm doing.
I should hope that most of the code below is pretty self-explanatory.
I have a class defined (TComponentUpdater) which has two overloaded
procedures (called SetFont). The hope is that, if SetFont is called
for a component other than a TLabel, it will call the empty SetFont.
Otherwise, it will cast it to the appropriate type (i.e. TLabel) and
call that version of SetFont. TSetFontFlags is a set of enumerations
to indicate what font properties should be set.
If I can get this to work, I will probably break out the code where the
font properties are being set into a different procedure to reduce code
duplication. That said, here's the code:
procedure SetChildrenFonts(const formToUpdate : TCustomForm);
var
cmpChild : TComponent;
nComponent : Integer;
begin
for nComponent := 0 to (formToUpdate.ComponentCount - 1) do
begin
if (formToUpdate.Components[nComponent] is TCustomForm) then
...
else begin
cmpChild := formToUpdate.Components[nComponent];
TComponentUpdater.SetFont(cmpChild as cmpChild.ClassType,
formToUpdate.Font, [sfName, sfSize]);
end;
end;
end;
class procedure TComponentUpdater.SetFont(cmpToUpdate : TComponent;
fntInfo : TFont; sfFlags : TSetFontFlags);
begin
// Do nothing. We can't set the font for a TComponent. This
prevents errors.
end;
class procedure TComponentUpdater.SetFont(lblToUpdate : TLabel; fntInfo
: TFont; sfFlags : TSetFontFlags);
begin
if (sfCharset in sfFlags) then
lblToUpdate.Font.Charset := fntInfo.Charset;
if (sfColor in sfFlags) then
lblToUpdate.Font.Color := fntInfo.Color;
if (sfName in sfFlags) then
lblToUpdate.Font.Name := fntInfo.Name;
if (sfPitch in sfFlags) then
lblToUpdate.Font.Pitch := fntInfo.Pitch;
if (sfSize in sfFlags) then
lblToUpdate.Font.Size := fntInfo.Size;
if (sfStyle in sfFlags) then
lblToUpdate.Font.Style := fntInfo.Style;
end;