Dynamiczne ładowanie DFM

Dynamiczne ładowanie DFM
Pociech
  • Rejestracja:około 20 lat
  • Ostatnio:ponad 9 lat
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 :)

flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 3 godziny
  • Lokalizacja:Tuchów
  • Postów:12175
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;


Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
abrakadaber
abrakadaber
  • Rejestracja:ponad 12 lat
  • Ostatnio:9 miesięcy
  • Postów:6610
0
Kopiuj
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 :)...


Chcesz pomocy - pokaż kod - abrakadabra źle działa z techniką.
edytowany 1x, ostatnio: abrakadaber
crowa
  • Rejestracja:prawie 19 lat
  • Ostatnio:około 8 lat
  • Lokalizacja:Poznań
  • Postów:295
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).


Tomasz Andrzejewski
Delphi (XE3-XE7) framework engineer @ InterLan
MCP: Microsoft SQL Server 2008, Implementation and Maintenance
Pociech
  • Rejestracja:około 20 lat
  • Ostatnio:ponad 9 lat
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?

flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 3 godziny
  • Lokalizacja:Tuchów
  • Postów:12175
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;


Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
olesio
  • Rejestracja:około 17 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Szczecin
  • Postów:4191
0

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


Pozdrawiam.
crowa
  • Rejestracja:prawie 19 lat
  • Ostatnio:około 8 lat
  • Lokalizacja:Poznań
  • Postów:295
0

da sie :)

Kopiuj
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.


Tomasz Andrzejewski
Delphi (XE3-XE7) framework engineer @ InterLan
MCP: Microsoft SQL Server 2008, Implementation and Maintenance
edytowany 1x, ostatnio: crowa

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.