• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 181
  • Last Modified:

changing the captions of all controls on a form during runtime wiht some out of a file

Hi


I have a file with the following structure:

Control_type  Contol_Name  Control_Caption
------------  -----------  ----------------
Label         MyLabel1     Label1_Caption_something
Label         MyLabel2     Label2_Caption_something
Label         MyLabel3     Label3_Caption_something
MainMenu      MyMainMenu   MainMenu_Caption
MenuItem      MyMenuItem   MenuItem_Caption
GroupBox      MyGroupBox   GroupBox_Caption

etc.


Here is my question:

How can I modify during the runtime the captions of each control that is mentioned in that file (or other external source) ?

Does anyone have a short procedure ?

I start thinking to complex now (after 2 nights triying to find a simple solution) !


Thanks


Ismet
0
gulki
Asked:
gulki
1 Solution
 
AvonWyssCommented:
You can use the Form's FindComponent method to find the component by its name. Then, you have to check what kind of component it is (edit, label, groupbox, ...) and assign its caption accordingly.

Note: you may also use a dirty trick, since the Caption property is defined in TControl, so that ALL TControl descendands do have it (even if it is hidden):

type
     TCaptionAccess=class(TControl);

[...]
     TCaptionAccess(Form1.FindComponent(YourComponentName) as TControl).Caption:=YourCaption;
[...]
0
 
wimmeyvaertCommented:
Is this file a textfile ? If so, I recommend to use a schema-file (.SCH) to define your file's record-structure.
If this is done, then you can link your text file to a normal TTable. This has the advantage that you can easily locate record in the file.

Maybe you can write a procedure which loops all the controls on the form (using a fil-loop with ControlCount), looks up the ClassName + Name in your textfile and returns the caption of it.

I'll work out a procedure and let you know.


PS : Maybe another possibility is to use a Resource-File, but I'm not sure if these can be used at runtime to, in your case, fill the captions of all the components.


I'll be back ...

The Mayor.
0
 
GwenaCommented:
I guess you want to modify the running exe by changing the captions?  How about Label1.Caption := 'My New Caption'; or is that not what you want?

If you need to permanently change the caption...like to change it's language then you need to permanently alter the exe .. you can do this at runtime by altering the disk sectors directly (but I recommend against this!)

OR you can use a small unit I wrote to change it at runtime...this requires a quick re-start but it only takes half a second or so and if done correctly the user might not even notice.

Changing the captions in another exe is easy... but you will be limited by the length of the current captions.. you can make the caption shorter..but not longer!  well you could make it longer but you will have to do surgery on the exe :-)



You can find the caption data inside the exe file.. for instance the caption of label 1 if it has 'Hello world!!!' as a caption will look like this

Label1<bh:04>Left<bh:02><bh:0e><bh:03>Top<bh:02><bh:18><bh:05>Width<bh:02>@<bh:06>Height<bh:02>
<bh:07>Caption<bh:06><bh:0f>Hello world!!!!


Label1  then some hex bytes
top     then hex bytes
width   then hex bytes
height  then hex bytes
Caption 2 hex bytes and then the caption

so just alter the caption directly... you could load the exe into a stream from disk and then find and change the proper bytes to change the caption.

I could write a small demo for you to show some of this if you like :-)
0
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
gulkiAuthor Commented:
Hey AvonWys

Thanks a lot for that simple statement !

It works perfectly well and within a short loop I can modify any control caption I need in runtime !


Great !!


Ismet
0
 
neldCommented:
Hi,

are you particularly stuck on that file format ?  would an ini file be easier. e.g.

[TLABEL]
MyLabel1=Label1_Caption_something
MyLabel2=Label2_Caption_something
MyLabel3=Label3_Caption_something

[TMAINMENU]
MyMainMenu=MainMenu_Caption

[TMENUITEM]
MyMenuItem=MenuItem_Caption

[TGROUPBOX]
MyGroupBox=GroupBox_Caption


then your code could work like this.

procedure TForm1.PopulateCaptions(const AFileName: string);
var
  Comp: TComponent;
  IniFile: TIniFile;
  I: Integer;
begin
  IniFile := TIniFile.Create(AFileName);
  try
    for I := 0 to ComponentCount -1 do
    begin
      Comp := Components[I];
      Comp.Caption := IniFile.ReadString(Comp.Classname, Comp.Name, Comp.Caption);  
    end;
  finally
    IniFile.Free;
  end;
end;

basically open the inifile, loop through all components on the form, and try to read its caption from the inifile.  The 3 params on the read string method are SectionName (in the inifile Classname is sectionname), ValueName (in the inifile the component name is the valuename) and lastly default value should the read fail, so if the read fails the component will keep its caption as its default value.

if you include the typInfo unit in your uses clauses you could also do this to optimize the code slightly, code belongs between for loops  begin and end.

  Comp := Components[I];
  if IsPublishedProp(Comp, 'Caption') then
    Comp.Caption := IniFile.ReadString(Comp.Classname,                                              Comp.Name, Comp.Caption);  

You could also read the file item by item and do:  
 Comp := FindComponent(Comp_Name);
 Comp.Caption := Comp_Caption

I would go for the first option particularly if there is other things you wish to apply to all components on the form, if there isn't well either, depending on how important performance is ?

Derrick
0
 
wimmeyvaertCommented:
Although the questions is already answered, I will post my code here :


unit Unit_GlobalFunctions;

interface

uses Controls;


procedure UpdateControlCaptions(WinCtrl: TWinControl ; ReadFile : String);


implementation

uses DbTables, StdCtrls, Dialogs;


procedure UpdateControlCaptions(WinCtrl: TWinControl ; ReadFile : String);
var
  x             : integer;
  lkp           : TTable;
  varKeyValues     : Variant;

  procedure UpdateCaption(ClsName, NewCaption: String ; Ctrl: TControl);
  begin
    if ClsName = 'TButton' then (Ctrl as TButton).Caption := NewCaption
    else if ClsName = 'TLabel' then (Ctrl as TLabel).Caption := NewCaption
    else ShowMessage('Component not supported for updating Caption : ' + ClsName);
  end;
begin
  Try
    lkp := TTable.Create(nil);
    lkp.TableType := ttASCII;
    lkp.TableName := ReadFile;
    lkp.Open;
    for x := 0 to WinCtrl.ControlCount-1 do
    begin
      With lkp do
      begin
                    varKeyValues := VarArrayOf([WinCtrl.Controls[x].ClassName,WinCtrl.Controls[x].Name]);
        If Locate('Class;Name' , varKeyValues , []) then
        begin
          UpdateCaption(WinCtrl.Controls[x].ClassName, FieldByName('Caption').AsString, WinCtrl.Controls[x]);
        end;
      end;
    end;
    lkp.Close;
  except
    ShowMessage('ERROR DURING "UpdateControlCaptions"');
  end;
end;


end.




P.S. You can save this code as xxxxxxx.pas
It's a unit that contains 1 procedure : UpdateControlCaptions
You have to give the parent of the controls you want to change the Caption of. You also have to give the name of the file you keep the captions in.
This procedure uses a textfile as a normal TTable. You also have to put a SCH-File in the same directoy as you Captions-File.

Here you find the contents of the SCH-File :
[CONTROLS]
FileType=FIXED
Delimiter=
Separator=
CharSet=ascii
Field1=Class,CHAR,15,0,0
Field2=Name,CHAR,15,0,15
Field3=Caption,CHAR,30,0,30
Field4=CRLF,CHAR,2,0,60


Hope te be of some help anyway ...

The Mayor.
0
 
AvonWyssCommented:
Thanks for the feedback. Glad to help! :-)
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: Amazon Web Services - Basic

Are you thinking about creating an Amazon Web Services account for your business? Not sure where to start? In this course you’ll get an overview of the history of AWS and take a tour of their user interface.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now