Solved

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

Posted on 2002-05-18
7
172 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
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
Efficient way to get backups off site to Azure

This user guide provides instructions on how to deploy and configure both a StoneFly Scale Out NAS Enterprise Cloud Drive virtual machine and Veeam Cloud Connect in the Microsoft Azure Cloud.

 

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

ScreenConnect 6.0 Free Trial

At ScreenConnect, partner feedback doesn't fall on deaf ears. We collected partner suggestions off of their virtual wish list and transformed them into one game-changing release: ScreenConnect 6.0. Explore all of the extras and enhancements for yourself!

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Convert Jpg /PNG To GIF 5 135
Delphi component that can load a DLL in design time? 8 64
Delphi - replicating a form 8 74
Delphi: Connect to running MS Outlook 4 86
A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
This Micro Tutorial will give you a basic overview how to record your screen with Microsoft Expression Encoder. This program is still free and open for the public to download. This will be demonstrated using Microsoft Expression Encoder 4.
This tutorial gives a high-level tour of the interface of Marketo (a marketing automation tool to help businesses track and engage prospective customers and drive them to purchase). You will see the main areas including Marketing Activities, Design …

777 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