Dynamiczne ładowanie DFM

0

Potrzebuję stworzyć graficzne narzędzie ładujące plik DFM z formatką, a następnie na jego podstawie tworzące pliki XML (gdyby kogoś interesowało - chodzi o wersje językowe programu, tłumaczenia są zapisywane w XML). Oczywiście wystarczy do tego celu zwykły parser odczytujący wartości z pliku DFM i grid do uzupełniania wartości, ale fajniejszym rozwiązaniem byłoby załadowanie designu formatki i "graficzna" edycja po kliknięciu danego elementu (np. Label). Istnieje jakiś w miarę prosty sposób żeby dynamicznie załadować i wyświetlić plik DFM w programie? Nie musi posiadać żadnej funkcjonalności, wystarczy sam wygląd. Wiem, że można to zrobić "na piechotę", ale zanim spróbuję, wolę się zorientować czy nie można tego zrobić prościej :)

0
Pociech napisał(a)

Potrzebuję stworzyć graficzne narzędzie ładujące plik DFM z formatką, a następnie na jego podstawie tworzące pliki XML (gdyby kogoś interesowało - chodzi o wersje językowe programu, tłumaczenia są zapisywane w XML).

Czyli chcesz zrobić coś takiego jak jest w kompilatorze? Czytasz plik *.dfm i na jego podstawie chcesz narysować (...?) formularz i na jego podstawie edytować zawartość?

Pociech napisał(a)

Oczywiście wystarczy do tego celu zwykły parser odczytujący wartości z pliku DFM i grid do uzupełniania wartości

No parser to i tak trzeba będzie napisać, ale wykorzystując Grid'a zrobić można coś w rodzaju Object Inspector - lista obiektów, ich właściwości i wartości przedstawiona jasno i zwięźle + łatwa ich modyfikacja; Jednak lista kontrolek może być dość długa, stąd przy większej ich ilości trzeba będzie dłużej szukać...

Pociech napisał(a)

ale fajniejszym rozwiązaniem byłoby załadowanie designu formatki i "graficzna" edycja po kliknięciu danego elementu (np. Label).

Na pewno fajniejszym, zawsze szybciej kliknąć na wybraną kontrolkę i edytować jej zawartość, niż grzebać w liście obiektów i szukać odpowiedniej pozycji;

Pociech napisał(a)

Istnieje jakiś w miarę prosty sposób żeby dynamicznie załadować i wyświetlić plik DFM w programie?

Ciężko powiedzieć... Przede wszystkim parser do plików *.dfm będziesz i tak musiał napisać w pierwszej kolejności; Do przedstawienia wyglądu kontrolek możesz wykorzystać dynamiczne (lub statyczne) tworzenie okien - tworzysz okienko (lub wyświetlasz, np. MDI lub zwykłe - jak wolisz) i ustawiasz jego właściwości bazując na tych załadowanych z pliku; Następnie wykorzystując całe drzewo z informacjami o kontrolkach tworzysz w pętli komponenty (jako rodzic ustawiasz nowo utworzone okno) i modyfikujesz ich właściwości;

W momencie modyfikacji właściwości zmieniasz odpowiednie informacje w drzewie i na koniec bazując na nim zapisujesz je do pliku już w wyjściowej formie; Sposób może nie najszybszy, ale ciekawy; Zawsze możesz utworzyć jeszcze dodatkową listę właściwości i ich wartości tylko dla aktywnego elementu (jak OI w Delphi) i po kliknięciu na daną kontrolkę wyświetlić je;

Najpierw jednak napisałbym sam parser i zaprogramował ładowanie informacji z pliku do własnoręcznie przygotowanej drzewiastej struktury, potem zastanawiałbym się jak te informacje graficznie przedstawić użytkownikowi;

0
var
  dfm: TFileStream;
  s: TMemoryStream;
  MojaForma: TForm;
begin
  dfm := TFileStream.Create('c:\forma.dfm', fmOpenRead);
  dfm.Seek(0, soFromBeginning);
  s := TMemoryStream.Create;

  ObjectTextToBinary(dfm, s);
  s.Seek(0, soFromBeginning);

  MojaForma := TForm.Create(nil);
  MojaForma.DestroyComponents;
  s.ReadComponent(MojaForma);

  dfm.Free;
  s.Free;
  MojaForma.ShowModal;
end;

ma to jednak kilka wad. Po pierwsze aby można było tak wczytać dfma, w którym komponenty/forma mają przypisane zdarzenia to klasa formy, którą tworzysz, też musi mieć te zdarzenia. Następnie musisz mieć w uses dodane moduły, w których są komponenty. Pokombinuj, może coś Ci się uda zrobić z tym :)

EDIT: chociaż myślę, że gotowiec będzie lepszy http://www.bitwisemag.com/2/add-a-runtime-form-designer-to bo oczywiście szukałeś i oczywiście nigdzie nie było :)...

0

jesli chesz robic edycje wersji jezykowej formularza to zobacz na komponent z pakietu Jedi - TJvInspector
Ten komponent ma mozliwosc dodania tylko konkretnych property (mozesz wyswietlic np tylko property Caption, Text itp).

0

Super, o takie coś mi właśnie chodziło. Pozostaje jeden, chyba dość poważny, problem. Te formy wielokrotnie dziedziczą z innych form, więc będzie trochę zabawy ze scaleniem wszystkiego :)
Wpadłem na jeszcze jeden pomysł. Może po prostu będę pobierał dane komponentów z działającego programu przez WinAPI. Odpadnie wtedy zabawa z designerem. Tylko czy przez WinAPI uda mi się wyciągnąć nazwę jaką kontrolka ma w DFMie?

0
Pociech napisał(a)

Tylko czy przez WinAPI uda mi się wyciągnąć nazwę jaką kontrolka ma w DFMie?

Przecież dana kontrolka ma jedną nazwę, taką samą w pliku *.dfm i podczas działania programu; W tym pliku są jedynie informacje na temat ustawień danego formularza i kontrolek - są one potrzebne jedynie kompilatorowi by mógł poprawnie wczytać wszystkie komponenty oraz ustawić właściwości formularza w dizajnerze;

0

O ile się orientuje przez funkcję WinAPI na pewno wyciągniesz nazwę klasy danego komponentu po jego uchwycie.

0

da sie :)

var
  FClassName: string;
begin
  SetLength(FClassName, 255);
  SetLength(FClassName, GetClassName(AHandle, PWideChar(FClassName), Length(FClassName)));
end;

Ps. JvInspector ma property InspectObject - mozesz sterowac edycja property okreslajac czy dana klasa wywodzi sie z innej.

1 użytkowników online, w tym zalogowanych: 0, gości: 1