Ik ben bezig een datamodule te converteren d.m.v. code. (Dat scheelt me straks een maand klikken in de objectinspecor). Stream naar dfm.
Ik maak een nieuw component (dataset) aan. Is het mogelijk @runtime de designtime property Left + Top te zetten?
Ik ben bezig een datamodule te converteren d.m.v. code. (Dat scheelt me straks een maand klikken in de objectinspecor). Stream naar dfm.
Ik maak een nieuw component (dataset) aan. Is het mogelijk @runtime de designtime property Left + Top te zetten?
Welke routine gebruik je daarvoor?
De TStream.WriteComponent(const Instance: TComponent) schrijft n.l. wel ook al een Left/Top in de string (naar de stream) voor designtime-componenten.
De makkelijkste oplossing is dus:
*) In die stream kun je daarna dus de Top/Left toevoegen.
Als je verder even in de source duikt zul je zien dat er intern voor elk (T)Component een FDesignInfo bijgehouden wordt.
In de WriteComponent() wordt deze dan ook aangesproken:
Delphi Code:
procedure TComponent.DefineProperties(Filer: TFiler); var Ancestor: TComponent; Info: Integer; begin Info := 0; Ancestor := TComponent(Filer.Ancestor); if Ancestor <> nil then Info := Ancestor.FDesignInfo; Filer.DefineProperty('Left', ReadLeft, WriteLeft, LongRec(FDesignInfo).Lo <> LongRec(Info).Lo); Filer.DefineProperty('Top', ReadTop, WriteTop, LongRec(FDesignInfo).Hi <> LongRec(Info).Hi); end;
FDesignInfo zelf is public.
Delphi Code:
property DesignInfo: TDesignInfo read FDesignInfo write FDesignInfo;
Dus:
Delphi Code:
procedure TForm1.Button1Click(Sender: TObject); var IB1: TIBQuery; NewDesignInfo: LongRec; begin IB1 := TIBQuery.Create(nil); NewDesignInfo.Hi := Word(100); NewDesignInfo.Lo := Word(200); IB1.DesignInfo := Longint(NewDesignInfo); ShowMessage(ComponentToStringProc(IB1)); end;
Geeft:
Code:object TIBQuery BufferChunks = 1000 CachedUpdates = False ParamCheck = True Left = 200 Top = 100 end
Thanks. Misschien kan ik met jouw voorbeeld verder!
Ik gebruik (uit een help voorbeeld van delphi) onderstaande routine.
Code:function ComponentToStringProc(Component: TComponent): string; var BinStream:TMemoryStream; StrStream: TStringStream; s: string; begin BinStream := TMemoryStream.Create; try StrStream := TStringStream.Create(s); try BinStream.WriteComponent(Component); BinStream.Seek(0, soFromBeginning); ObjectBinaryToText(BinStream, StrStream); StrStream.Seek(0, soFromBeginning); Result:= StrStream.DataString; finally StrStream.Free; end; finally BinStream.Free end; end;
Dat is inderdaad met TStreamer.WriteComponent().
Dat moet dan dus wel lukken.
Je kunt er ook even een aparte routine van maken:
Delphi Code:
procedure SetTopLeft(Comp: TComponent; ATop, ALeft: Integer); var NewDesignInfo: LongRec; begin NewDesignInfo.Hi := Word(ATop); NewDesignInfo.Lo := Word(ALeft); Comp.DesignInfo := Longint(NewDesignInfo); end; //... SetTopLeft(Jouw_component, 100, 200);
Of zelfs integreren in je ComponentToStringProc():
Delphi Code:
function ComponentToStringProc(Component: TComponent; Top, Left: Integer): string; var BinStream:TMemoryStream; StrStream: TStringStream; s: string; NewDesignInfo: LongRec; begin NewDesignInfo.Hi := Word(ATop); NewDesignInfo.Lo := Word(ALeft); Component.DesignInfo := Longint(NewDesignInfo); BinStream := TMemoryStream.Create; try StrStream := TStringStream.Create(s); try BinStream.WriteComponent(Component); BinStream.Seek(0, soFromBeginning); ObjectBinaryToText(BinStream, StrStream); StrStream.Seek(0, soFromBeginning); Result:= StrStream.DataString; finally StrStream.Free; end; finally BinStream.Free end; end;
GREAT! Ik laat hier weten wat de resultaten zijn :-)
Ik ben wel een beetje nieuwsgierig waarom je in runtime de designtime properties wilt zetten. Ga je weer nieuwe dfm's genereren vanuit je code? Anders zie ik niet hoe dat nuttig kan zijn..
1+1=b
Dat is het. Ik heb nu TSQLQuery + TDataProvider + TClientDataSet. Deze moeten vervangen worden door TFDQuery. In 30 a 40 schermen volgestouwd met datasets.
Dat doe ik runtime door de datamodule te creeeren en een TFDQuery aan te maken. Deze neemt de diverse properties inclusief velden over. Daarna free ik de dbExpress componenten, rename de FDQuery en maak dan een nieuwe DFM aan.
Ook parse ik daarna nog de bijbehorende pas-file.
Natuurlijk in een kloon van het gehele project. Het is de snelste - en slimste denk ik :-) - manier om het bulk-werk geautomatiseerd te doen.
Out of the box idee.
Ja dat klopt. Ik ben een @runtime-fan. Maar dan ben ik *veel* teveel tijd kwijt met het ombouwen van het programma. De bedoeling is in eerste instantie zoveel mogelijk intact te houden en DbExpress uit te faseren.
Natuurlijk hebben de mensen in het verleden alles in elkaar geklikt. Dus forms / controls verwijzen @designtime naar de datamodules / datasets / fieldnames :-(
There are currently 1 users browsing this thread. (0 members and 1 guests)
Bookmarks