Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic GUI creation using configuration files

Is is possible to create GUI for a Delphi application using an configuration pattern from an xml etc... file. Any frameworks exist for such an operation. It is easy with scripting like languages but can we simulate this behaviour in Delphi?

I need free library.

like image 690
user114285 Avatar asked Jun 05 '09 15:06

user114285


6 Answers

Take a look at XI Library or EControl.

like image 198
ErvinS Avatar answered Sep 29 '22 22:09

ErvinS


Yes, it is possible. The pseudocode for this is something like this

var
  AParent:Tpanel;
  Edit:TControl;

for i := 0 to ConfigItems.Count - 1 do
begin
  if (ConfigItems[i].Type = 0) then Edit := TEdit.Create(AParent) as TControl
  else Edit := TAnotherEditOrAnotherControlType.Create(APanel) as TControl;
  //assume 20 pixels for each control, so thay will be placed one below another
  Edit.Top := i * 20; 
  //Left in this case can be fixed
  Edit.Left := 10;
  Edit.Parent := AParent;
 end;

This will create few TEdit or some other control (say, TAnotherEditOrAnotherControlType but if you declare Edit variable as a TControl, you can create any control you need) on TPanel declared as AParent. Of course instead of IF clause, you can declare big CASE statement, and create controls of appropriate type. Important lines are

  • add Parent as a parameter for dynamic control constructor (so that dynamic control can be freed automatically)
  • set dynamic controls Parent to our AParent panel - this line actually places control on parent panel.
like image 40
smok1 Avatar answered Sep 29 '22 22:09

smok1


Glade also uses XML files to describe a GUI which is then created at runtime. Don't know whether it can be used with Delphi, though.

like image 35
sleske Avatar answered Sep 30 '22 22:09

sleske


You can save and load dfm files from streams and files. You can save/load an entire form, or just a component and it's children.

Eg

As binary:

AStream.WriteComponent(AComponent);
MyComponent:=    Result:= AStream.ReadComponent(AComponent);

As text:

procedure WriteComponentAsText(AStream: TStream; AComponent: TComponent);
var
  BinStream:TMemoryStream;
begin
  BinStream := TMemoryStream.Create;
  try
    BinStream.WriteComponent(AComponent);
    BinStream.Seek(0, soFromBeginning);
    ObjectBinaryToText(BinStream, AStream);
  finally
    BinStream.Free
  end;
end;

function ReadComponentAsText(AStream: TStream; AComponent: TComponent): TComponent;
var
  BinStream:TMemoryStream;
begin
  BinStream := TMemoryStream.Create;
  try
    ObjectTextToBinary(AStream, BinStream);
    BinStream.Seek(0, soFromBeginning);
    Result:= BinStream.ReadComponent(AComponent);
  finally
    BinStream.Free
  end;
end;

You need to register any classes that you want to save or load with RegisterClass:

RegisterClass(TPanel);
like image 39
SeanX Avatar answered Oct 01 '22 22:10

SeanX


Yes, have a look at TMS Scripter Studio Pro by TMS Software.

Add the ultimate flexibility and power into your applications with native Pascal or Basic scripting and full IDE (Integrated Development Environment) with visual form designer, object inspector, and more.

Scripter Studio Pro

like image 33
stukelly Avatar answered Oct 01 '22 22:10

stukelly


Yes we can :) I have done this for a page designer that uses only Textboxes, Rules(lines) and Graphics but it should work for all registered controls.

[Off the cuff code approximation]

    var
      i, itemCount: Integer;
      AClassName: string;
      AnItemClass: TSomeBaseClass;
      AnItem: TSomeDrivedBaseClass
      ARect: TRect;
    begin
      // just so we have an initail size
      ARect.Left := 100;
      ARect.Top := 100;
      ARect.Bottom := 200;
      ARect.Right := 200;
      // Alist is a specialised TStringList
      for i  := 0 to itemCount - 1 do
      begin
        AClassName := Alist.ByKey['Class' + IntToStr(i)]; // locate class name 
        AnItemClass := TSomeBaseClass(GetClass(AClassName));  // ClassName must be registered
        AnItem := AnItemClass.Create(OwnerComponent, ARect, AParent);
        AnItem.LoadFromFile(IntToStr(i), AList);  // specialised loader that reads and sets all necessary properties
        AddItemToComponentList(AnItem);  // Add to form / frame / panel whatever
      end;
    end;

Of course you first need a "Form designer" that can save the design initially - the saving is just the reverse of the above...I'll leave that as an exercise for the Reader. wWth a little modification you could use Delphi and read the DFM file :)

like image 20
Despatcher Avatar answered Oct 01 '22 22:10

Despatcher