Solved

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

Posted on 2002-05-18
7
175 Views
Last Modified: 2010-04-04
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
Comment
Question by:gulki
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
7 Comments
 
LVL 14

Accepted Solution

by:
AvonWyss earned 350 total points
ID: 7018197
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
 
LVL 6

Expert Comment

by:wimmeyvaert
ID: 7018202
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
 
LVL 5

Expert Comment

by:Gwena
ID: 7018213
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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 

Author Comment

by:gulki
ID: 7018219
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
 

Expert Comment

by:neld
ID: 7018228
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
 
LVL 6

Expert Comment

by:wimmeyvaert
ID: 7018247
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
 
LVL 14

Expert Comment

by:AvonWyss
ID: 7018463
Thanks for the feedback. Glad to help! :-)
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
NetCrunch network monitor is a highly extensive platform for network monitoring and alert generation. In this video you'll see a live demo of NetCrunch with most notable features explained in a walk-through manner. You'll also get to know the philos…
Visualize your data even better in Access queries. Given a date and a value, this lesson shows how to compare that value with the previous value, calculate the difference, and display a circle if the value is the same, an up triangle if it increased…
Suggested Courses
Course of the Month6 days, 19 hours left to enroll

622 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question