Difference between revisions of "VirtualTreeview Example for Lazarus/pl"

From Lazarus wiki
Jump to navigationJump to search
(tłumaczenie na j. polski)
(aktualizacja linku do dokumentacji)
 
(20 intermediate revisions by the same user not shown)
Line 1: Line 1:
{{Przykłady VirtualTreeview dla Lazarusa}}
+
{{Example for VirtualTreeview on Lazarus}}
  
 
Oto kilka przykładów użycia [[VirtualTreeview]] dla Lazarusa (testowane na win32). Są one w większości zebrane z sieci, napisane dla Delphi oraz z samouczka/dokumentacji autorstwa Philippa Frenzela i Mike'a Lischke.
 
Oto kilka przykładów użycia [[VirtualTreeview]] dla Lazarusa (testowane na win32). Są one w większości zebrane z sieci, napisane dla Delphi oraz z samouczka/dokumentacji autorstwa Philippa Frenzela i Mike'a Lischke.
  
Samouczek/dokumenty można pobrać ze strony http://www.soft-gems.net. Tutaj znajdziesz tylko szybki sposób korzystania z VirtualTreeview na Lazarus, a nie wyjaśnienia. Aby uzyskać wyjaśnienia i wiele innych funkcji/metod, pobierz oficjalne dokumenty i samouczek.
+
Samouczek/dokumenty dostępne kiedyś były na stronie http://www.soft-gems.net. Obecnie dokumentację w pliku pdf można pobrać ze strony [https://documentation.help/VirtualTreeview/documentation.pdf documentation.help]. Tutaj znajdziesz tylko szybki sposób korzystania z VirtualTreeview na Lazarus, a nie wyjaśnienia. Aby uzyskać wyjaśnienia i wiele innych funkcji/metod, pobierz oficjalne dokumenty i samouczek.
  
 
=Podstawowe Drzewo Listview z 3 Kolumnami=
 
=Podstawowe Drzewo Listview z 3 Kolumnami=
Line 32: Line 32:
  
 
10. Przewiń w dół, aby ustawić Header -> Style na hsFlatButtons.
 
10. Przewiń w dół, aby ustawić Header -> Style na hsFlatButtons.
 +
 +
[[Image:ExempleVirtualtreeView1.jpg|center]]
  
 
11. Przewiń w dół do TreeOptions (rozwiń) -> MiscOptions (rozwiń) i ustaw toEditable na True. Ustaw toGridExtensions na True.
 
11. Przewiń w dół do TreeOptions (rozwiń) -> MiscOptions (rozwiń) i ustaw toEditable na True. Ustaw toGridExtensions na True.
Line 40: Line 42:
  
 
14. Kliknij Button1, w Inspectorze obiektów zmień Caption na AddRoot. Kliknij Button2, zmień podpis na AddChild. Zmień podpis przycisku Button3 na Delete.
 
14. Kliknij Button1, w Inspectorze obiektów zmień Caption na AddRoot. Kliknij Button2, zmień podpis na AddChild. Zmień podpis przycisku Button3 na Delete.
 +
 +
[[Image:ExempleVirtualtreeView2.jpg|center]]
  
 
15. Zachowaj to tutaj i przejdź do edytora źródeł (naciśnij F12). W edytorze źródeł zamień wiersz:
 
15. Zachowaj to tutaj i przejdź do edytora źródeł (naciśnij F12). W edytorze źródeł zamień wiersz:
Line 70: Line 74:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
18. Scroll to onFocusChanged. Double click and paste the following:
 
 
18. Przewiń do opcji onFocusChanged. Kliknij dwukrotnie i wklej następujący kod:
 
18. Przewiń do opcji onFocusChanged. Kliknij dwukrotnie i wklej następujący kod:
  
Line 148: Line 151:
 
23. Naciśnij klawisz F9, aby uruchomić projekt w celu sprawdzenia. Kliknij AddRoot, aby dodać węzeł. Jeśli jest w porządku, węzeł zostanie dodany na VST.
 
23. Naciśnij klawisz F9, aby uruchomić projekt w celu sprawdzenia. Kliknij AddRoot, aby dodać węzeł. Jeśli jest w porządku, węzeł zostanie dodany na VST.
  
24. Stop execution. On the Form Designer double click the AddChild captioned button. Paste the following:
+
[[Image:ExempleVirtualtreeView3.jpg|center]]
 +
 
 +
24. Zatrzymaj wykonywanie. W formularzu kliknij dwukrotnie przycisk podpisany jako AddChild. Wklej następujący kod:
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 170: Line 175:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
25. On the Form Designer double click the Delete captioned button. Paste the following:
+
25. W formularzu kliknij dwukrotnie przycisk podpisany jako Delete. Wklej następujący kod:
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 179: Line 184:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
26. Run the project by pressing F9 to check. Add some node, child and delete them.
+
26. Uruchom projekt, naciskając klawisz F9, aby sprawdzić program. Dodaj węzeł, dziecko i usuń je.
  
27. Try to edit a node. Select a node and press F2, write new value. If you can see what you are typing then it is OK. Else, read below "If Cell Editing Can't Be Seen".
+
[[Image:ExempleVirtualtreeView4.jpg|center]]
  
28. To get VST show the new value entered after editing, go to the Form Designer, select VST. On Object Inspector -> Events -> OnNewText combobox double click. Paste the following:
+
27. Spróbuj edytować węzeł. Wybierz węzeł i naciśnij F2, wpisz nową wartość. Jeśli widzisz, co piszesz, to jest OK. W przeciwnym razie przeczytaj poniżej „Nie można zobaczyć edycji komórki”.
 +
 
 +
28. Aby VST pokazywał nową wartość wprowadzoną po edycji, przejdź do Projektanta formularzy, wybierz VST. W Inspektorze obiektów -> Zdarzenia -> zdarzenie OnNewText kliknij dwukrotnie. Wklej następujący kod:
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 200: Line 207:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
So far, example for basic use ends here. You may drop few more buttons on the form to test few more commands given below. Next would be, showing checkbox, image, font colour and adding combobox on node.  
+
Na tym przykład podstawowego zastosowania kończy się. Możesz upuścić kilka dodatkowych przycisków na formularz, aby przetestować kilka innych poleceń podanych poniżej. Następnymi krokami byłoby pokazanie pola wyboru, obrazu, koloru czcionki i dodanie combobox w węźle.
  
*Another Way To Add Root Node
+
* Inny sposób na dodanie węzła głównego
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 212: Line 219:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
*Another Way To Add Child
+
* Inny sposób na dodanie dziecka
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 222: Line 229:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
*Determine & Delete Children Of A Node
+
* Wybierz i usuń dzieci węzła
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 240: Line 247:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
*Delete Node
+
* Usunięcie węzeł
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 252: Line 259:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
*Search And Select Node
+
* Wyszukaj i wybierz węzeł
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 277: Line 284:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
*Determine Parent
+
* Wybierz rodzica
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 297: Line 304:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
*Search All
+
* Wyszukaj wszystko
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 322: Line 329:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
*Search next
+
* Wyszukaj następny
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 353: Line 360:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
*Insert Node
+
* Wstaw węzeł
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 370: Line 377:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
*Set Node Height
+
* Ustaw wysokość węzła
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 380: Line 387:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
*Save And Load
+
* Zapisz i załaduj
  
Simple tree (without column) can be saved and loaded as:
+
Proste drzewo (bez kolumn) można zapisać i załadować jako:
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 389: Line 396:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
To save and load the above mentioned example, place 2 buttons on the form, rename caption to "Save" and "Load". Select VST, on Object Inspector -> TreeOptions -> StringOptions make sure toSaveCaptions is set to True. Go to Object Inspector's Events tab. Scroll down to OnLoadNode, double click and then paste:
+
Aby zapisać i załadować powyższy przykład, umieść 2 przyciski w formularzu, zmień nazwę Caption na „Save” i „Load”. Wybierz VST, w Inspektorze obiektów -> TreeOptions -> StringOptions upewnij się, że parametr toSaveCaptions ma wartość True. Przejdź do zakładki Zdarzenia Inspektora obiektów. Przewiń w dół do OnLoadNode, kliknij dwukrotnie, a następnie wklej kod:
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 413: Line 420:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Again on Object Inspector's Events tab - scroll down to OnSaveNode, double click and then paste:
+
Ponownie na karcie Zdarzenia Inspektora obiektów - przewiń w dół do OnSaveNode, kliknij dwukrotnie, i wklej kod:
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 437: Line 444:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
On Form Designer double click Save captioned button, paste:
+
W formularzu kliknij dwukrotnie przycisk "Save" i wklej kod:
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 446: Line 453:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
On Form Designer double click Load captioned button, paste:
+
W formularzu kliknij dwukrotnie przycisk "Load" i wklej kod:
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 455: Line 462:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Now test to save and load tree.
+
Teraz przetestuj zapisywanie i ładowanie drzewa.
  
*Scroll Problem
+
* Problem z przewijaniem
  
The header of the treeview disappears fully or partially when scrolling. I could not find a good solution for this. One way to overcome this is to set the header height to 0, then using general label for columns. This is good while there are few columns, and all are visible without horizontal scrolling. Or, the header height can be set to a higher value like 25 or 30. VST.Refresh can be added to the OnScroll event.
+
<s>Nagłówek widoku drzewa znika całkowicie lub częściowo podczas przewijania. Nie mogłem znaleźć na to dobrego rozwiązania. Jednym ze sposobów rozwiązania tego problemu jest ustawienie wysokości nagłówka na 0, a następnie użycie ogólnej etykiety dla kolumn. Jest to dobre, gdy jest kilka kolumn i wszystkie są widoczne bez przewijania w poziomie. Lub wysokość nagłówka można ustawić na wyższą wartość, np. 25 lub 30. VST.Refresh można dodać do zdarzenia OnScroll.</s><br>
 +
W wersji 5.5.3.1 nie zaobserowałem tego efektu, więc prawdopodobnie został on naprawiony.
  
*Column Resize
+
* Zmiana rozmiaru kolumny
  
It was not possible to resize column by dragging mouse on VST header. May be it is for the header bug or I have missed something. If it is for the header, probably will be fixed on next version of Lazarus. See this link: http://bugs.freepascal.org/view.php?id=11209<br>
+
<s>Nie można zmienić rozmiaru kolumny, przeciągając myszą nagłówek VST. Może to być błąd nagłówka lub coś przeoczyłem. Jeśli dotyczy nagłówka, prawdopodobnie zostanie naprawiony w następnej wersji Lazarus. Zobacz ten link:
Anyway, it is possible to resize column from code. When you press down right mouse button and move mouse-wheel up, the width of the selected column increases and press down the right mouse button and move mouse-wheel down, to decrease the width of the selected column. To do this:
+
http://bugs.freepascal.org/view.php?id=11209</s><br>
 +
W wersji 5.5.3.1 nie zaobserowałem tego efektu, więc prawdopodobnie został on naprawiony.
  
1. Add a variable in the source editor named as CurCol: Integer; So it looks like:
+
'''Poniższy kod może być przydatny dla tych, którzy chcieliby go sprawdzić lub wykorzystać w jakimś innym celu.'''
 +
 
 +
W każdym razie można zmienić rozmiar kolumny z kodu. Po naciśnięciu prawego przycisku myszy i przesunięciu kółka myszy w górę szerokość wybranej kolumny zwiększa się, a następnie naciśnięcie prawego przycisku myszy i przesunięcie kółka myszy w dół, aby zmniejszyć szerokość wybranej kolumny. Aby to zrobić:
 +
 
 +
1. Dodaj zmienną w edytorze źródłowym o nazwie CurCol: Integer; Wygląda to tak:
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 478: Line 491:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
2. On the Form Designer double click the form to generate an event OnCreate. Inside the OnCreate procedure type Form1.OnMouseWheelUp:= and press Ctrl+Shift+C, this will complete the code and make skeleton of the MouseWheelUp event. Now get back to procedure TForm1.FormCreate(Sender: TObject); And add another event for MouseWheelDown. Type Form1.OnMouseWheelDown:= and press Ctrl+Shift+C, to generate the MouseWheelDown event. FormCreate procedure now looks like:
+
2. W Projektancie formularzy kliknij dwukrotnie formularz, aby wygenerować zdarzenie OnCreate. Wewnątrz procedury OnCreate wpisz Form1.OnMouseWheelUp:= i naciśnij Ctrl+Shift+C, spowoduje to uzupełnienie kodu i utworzenie szkieletu zdarzenia MouseWheelUp. Wróć teraz do procedury TForm1.FormCreate(Sender: TObject); i dodaj kolejne wydarzenie dla MouseWheelDown. Wpisz Form1.OnMouseWheelDown:= i naciśnij Ctrl+Shift+C, aby wygenerować zdarzenie MouseWheelDown. Procedura FormCreate wygląda teraz następująco:
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 488: Line 501:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
3. Fill the TForm1.Form1MouseWheelUp procedure as:
+
3. Wypełnij procedurę TForm1.Form1MouseWheelUp w ten sposób:
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 499: Line 512:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
4. Fill the TForm1.Form1MouseWheelDown procedure as:
+
4. Wypełnij procedurę TForm1.Form1MouseWheelDown jak poniżej:
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 510: Line 523:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
5. Go to the Form Designer (press F12), select VST, on Object Inspector's Events tab scroll to OnFocusChanged, double click & paste:
+
5. Przejdź do Projektanta formularzy (naciśnij F12), wybierz VST, na karcie Zdarzenia Inspektora obiektów przewiń do OnFocusChanged, kliknij dwukrotnie i wklej:
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 520: Line 533:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
When you run, click on a column then hold down right mouse button and move wheel up to increase width, wheel down to decrease. You may tune-up the above procedures if needed. Or, add keyboard event with something like "if (key=187) and (ssShift in Shift) then" to watch for Shift + "+".
+
Po uruchomieniu programu kliknij kolumnę, a następnie przytrzymaj prawy przycisk myszy i przesuń kółko w górę, aby zwiększyć szerokość, lub kółko w dół, aby ją zmniejszyć. W razie potrzeby możesz dostosować powyższe procedury. Możesz też dodać zdarzenie klawiatury z czymś takim jak "if (key=187) i (ssShift in Shift) then", aby reagować na naciśnięcie klawiszy Shift + "+".
  
=Checkbox=
+
=Pole wyboru (CheckBox)=
  
 
On Form Designer select VST. Go to:
 
On Form Designer select VST. Go to:
 +
W formularzu wybierz VST i wykonaj:
  
#Object Inspector -> Properties -> CheckImageKind and select ckDarkCheck.
+
#Inspektor obiektów -> Właściwości -> CheckImageKind i wybierz ckDarkCheck.
#Object Inspector -> Properties -> TreeOptions -> MiscOptions -> toCheckSupport and set it to True.
+
#Inspektor obiektów -> Właściwości -> TreeOptions -> MiscOptions -> toCheckSupport i ustaw na True.
  
Now switch to Events tab.
+
Teraz przejdź do zakładki Zdarzenia.
  
*Scroll to OnInitNode. Double click and paste the following:
+
* Przewiń do OnInitNode. Kliknij dwukrotnie i wklej następujący kod:
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 541: Line 555:
 
   Level := VST.GetNodeLevel(Node);
 
   Level := VST.GetNodeLevel(Node);
 
   if Level = 0 then
 
   if Level = 0 then
     Node.CheckType := ctCheckBox;
+
     Node^.CheckType := ctCheckBox;
  
 
   if Level = 2 then
 
   if Level = 2 then
     Node.CheckType := ctRadioButton;
+
     Node^.CheckType := ctRadioButton;
  
 
   if Level = 1 then
 
   if Level = 1 then
 
   begin
 
   begin
     Node.CheckType  := ctTriStateCheckBox;
+
     Node^.CheckType  := ctTriStateCheckBox;
     Node.CheckState := csCheckedNormal;
+
     Node^.CheckState := csCheckedNormal;
 
   end;
 
   end;
  
 
   if Level = 3 then
 
   if Level = 3 then
     Node.CheckType := ctButton;
+
     Node^.CheckType := ctButton;
 
end;
 
end;
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Run the program, add rootnode and child then child of the child, and check if you can check and uncheck properly. If not, close the program. Go to the Object Inspector's Events tab.
+
Uruchom program, dodaj węzeł i dziecko, a następnie dodaj dziecko do dziecka, i sprawdź, czy możesz poprawnie zaznaczyć i odznaczyć pola wyboru. Jeśli nie, zamknij program. Przejdź do zakładki Zdarzenia Inspektora obiektów.
  
*Scroll to OnChecked, double click and paste:
+
* Przewiń do OnChecked, kliknij dwukrotnie i wklej:
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 568: Line 582:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
*Scroll to OnChecking, double click and paste:
+
* Przewiń do opcji OnChecking, kliknij dwukrotnie i wklej:
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 578: Line 592:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Hope now it is ok. To determine checkbox state use like:
+
Mam nadzieję, że teraz jest ok. Aby określić stan pola wyboru, użyj:
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 585: Line 599:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Other states are:
+
Inne stany to:
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
csUncheckedNormal = unchecked and not pressed
+
csUncheckedNormal = niezaznaczone i nie wciśnięte
csUncheckedPressed = unchecked and pressed
+
csUncheckedPressed = niezaznaczone i wciśnięte
csCheckedNormal = checked and not pressed
+
csCheckedNormal = zaznaczone i nie wciśnięte
csCheckedPressed = checked and pressed
+
csCheckedPressed = zaznaczone i wciśnięte
csMixedNormal = 3-state check box and not pressed
+
csMixedNormal = 3-stanowe pole wyboru i nie wciśnięte
csMixedPressed = 3-state check box and pressed
+
csMixedPressed = 3-stanowe pole wyboru i wciśnięte
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Other types are:
+
Inne typy to:
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 604: Line 618:
 
ctRadioButton
 
ctRadioButton
 
ctButton</syntaxhighlight>
 
ctButton</syntaxhighlight>
*To Catch Checkbox's Button (ctButton) Click
+
 
Go to Object Inspector's Events tab. Scroll to OnChecked, double click and paste:
+
* Aby przechwycić przycisk pola wyboru (ctButton) Click
 +
Przejdź do zakładki Zdarzenia Inspektora obiektów. Przewiń do OnChecked, kliknij dwukrotnie i wklej kod:
 +
 
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
 
procedure TForm1.VSTChecked(Sender: TBaseVirtualTree; Node: PVirtualNode);
 
procedure TForm1.VSTChecked(Sender: TBaseVirtualTree; Node: PVirtualNode);
 
begin
 
begin
   if Node.CheckType = ctButton then
+
   if Node^.CheckType = ctButton then
 
     ShowMessage('Ok.');
 
     ShowMessage('Ok.');
 
   VST.Refresh;
 
   VST.Refresh;
Line 615: Line 631:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
End of checkbox.<br>
+
Koniec pola wyboru.<br>
  
=Images=
+
=Obrazy=
  
To show image on VST nodes, a list of image should be created.
+
Aby wyświetlić obrazy w węzłach VST, należy utworzyć listę obrazów.
  
*Go to the Component Palette -> Common Controls. Select and drop a TImageList component on the form. Right click on the component icon and select ImageList Editor. Click on Add button and and select some images (at least 3 for now), then click on tick button to accept and close the ImageList Editor. By the way, there are some nice images you can download from http://www.famfamfam.com/lab/icons/silk/  
+
* Przejdź do palety komponentów -> Common Controls. Wybierz i upuść składnik TImageList na formularzu. Kliknij prawym przyciskiem myszy ikonę komponentu i wybierz ImageList Editor. Kliknij przycisk Dodaj i wybierz kilka zdjęć (na razie co najmniej 3), a następnie kliknij przycisk wyboru, aby zaakceptować i zamknąć Edytor ImageList. Nawiasem mówiąc, istnieje kilka fajnych zdjęć, które można pobrać ze strony http://www.famfamfam.com/lab/icons/silk/
  
*Now on the Form Designer select VST, and on Object Inspector's Properties tab, scroll to Images and select ImageList1
+
* Teraz w Projektancie formularzy wybierz VST, a na karcie Właściwości Inspektora obiektów przewiń do Images i wybierz ImageList1
  
*On Object Inspector's Events tab scroll to OnGetImageIndex, double click and paste:
+
* Na karcie Zdarzenia Inspektora obiektów przewiń do OnGetImageIndex, kliknij dwukrotnie i wklej kod:
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 632: Line 648:
 
   var ImageIndex: Integer);
 
   var ImageIndex: Integer);
 
begin
 
begin
   if Kind in [ikNormal , ikSelected] then // Either Selected or not
+
   if Kind in [ikNormal , ikSelected] then // Zarówno wybrane jak i nie
 
   begin
 
   begin
     if Column = 0 then                    // if 1st Column
+
     if Column = 0 then                    // jeśli to pierwsza kolumna
       ImageIndex := 0;                    // 1st Image of the ImageList1
+
       ImageIndex := 0;                    // pierwszy obraz z listy ImageList1
  
     if Column = 1 then                    // if 2nd Column
+
     if Column = 1 then                    // jeśli to druga kolumna
       ImageIndex := 1;                    // 2nd Image of the ImageList1
+
       ImageIndex := 1;                    // drugi obraz z listy ImageList1
  
     if Sender.FocusedNode = Node then    // Only show if Focused
+
     if Sender.FocusedNode = Node then    // Pokaż tylko, jeśli wybrany
       if Column = 2 then                  // if 3rd Column
+
       if Column = 2 then                  // jeśli to trzecia kolumna
         ImageIndex := 2;                  // 3rd Image of the ImageList1
+
         ImageIndex := 2;                  // trzeci obraz z listy ImageList1
 
   end;
 
   end;
   {Sender.NodeHeight[node] := 40; //If Image is big}
+
   {Sender.NodeHeight[node] := 40; //Jeśli obraz jest duży}
 
end;
 
end;
 
</syntaxhighlight>
 
</syntaxhighlight>
  
=Font Colour=
+
=Kolor czcionki=
  
On the Form Designer select VST, and on Object Inspector's Events tab, scroll to OnPaintText, double click and paste:
+
W Projektancie formularzy wybierz VST, a na karcie Zdarzenia Inspektora obiektów przewiń do OnPaintText, kliknij dwukrotnie i wklej kod:
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 661: Line 677:
 
   Data := VST.GetNodeData(Node);
 
   Data := VST.GetNodeData(Node);
 
   
 
   
   if Data^.Column0 = 'sky' then
+
   if Data^.Column0 = 'niebo' then
 
     TargetCanvas.Font.Color := clBlue;
 
     TargetCanvas.Font.Color := clBlue;
 
    
 
    
Line 679: Line 695:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
=Adding A Combobox=
+
Teraz uruchom program. Dodaj jakieś węzły. Zobaczysz, że tekst w drugiej kolumnie jest czerwony. Spróbuj teraz zmienić tekst jakiegoś węzła w pierwszej kolumnie (klawisz F2) wpisując słowo "niebo". Po zatwierdzeniu zmiany tekst powinien stać się niebieski.
 +
 
 +
=Dodanie ComboBox=
  
*I guess you have an open project on Lazarus IDE having VST on it and can edit the nodes. If not see the "Basic Tree Listview With 3 Columns" above, and atleast complete steps 1 to 21.
+
* Myślę, że masz otwarty projekt w Lazarus IDE z VST i możesz edytować węzły. Jeśli nie, zobacz „Podstawowy widok drzewa z 3 kolumnami” powyżej i przynajmniej wykonaj kroki od 1 do 21.
  
*Below there is an unit file named combo. Copy that unit and save as combo.pas inside the project directory. Under your program's uses clause add combo. So it may look like:
+
* Poniżej znajduje się treść pliku modułu o nazwie combo. Skopiuj ten moduł i zapisz jako combo.pas w katalogu projektu. Pod klauzulą '''uses''' programu dodaj nazwę mocułu combo. Może to wyglądać następująco:
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 691: Line 709:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
*The combo.pas unit
+
* Moduł combo.pas
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 822: Line 840:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
*After saving the file, on the Form Designer select VST and on Object Inspector's Properties, scroll to TreeOptions -> MiscOptions, set toEditable to True. Then get to TreeOptions -> SelectionOptions, set toExtendedFocus to True.
+
* Po zapisaniu pliku, w Projektancie formularzy wybierz VST, a we właściwościach Inspektora obiektów przewiń do TreeOptions -> MiscOptions, ustaw wartość na toEditable na True. Następnie przejdź do TreeOptions -> SelectionOptions, ustaw toExtendedFocus na True.
  
*Switch to Object Inspector's Events tab. Scroll to OnCreateEditor, double click and paste:
+
* Przejdź do zakładki Zdarzenia Inspektora obiektów. Przewiń do OnCreateEditor, kliknij dwukrotnie i wklej kod:
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 834: Line 852:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
*On Object Inspector's Events tab. Scroll to OnNewText, double click and paste:
+
* W zakładce Zdarzenia Inspektora obiektów przewiń do OnNewText, kliknij dwukrotnie i wklej kod:
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 851: Line 869:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Run program, select a node and press F2 to get combobox. On pressing Enter new value should appear on the node.
+
Uruchom program, wybierz węzeł i naciśnij F2, aby uzyskać ComboBox. Po naciśnięciu wprowadź nową wartość, a powinna ona pojawić się w węźle.
  
=If Cell Editing Can't Be Seen=
+
=Jeśli nie można zobaczyć edycji komórki=
  
Open VirtualStringTree.pas unit file (if you are still on the above example project, right click on VirtualStringTree  
+
Otwórz plik modułu VirtualStringTree.pas (jeśli nadal pracujesz nad powyższym przykładowym projektem, kliknij prawym przyciskiem myszy VirtualStringTree w obszarze słowa kluczowego '''uses''' i wybierz Znajdź deklarację. Spowoduje to otwarcie pliku na następnej karcie. Przejdź do zakładki tego pliku). Przejdź do „funkcji TStringEditLink.BeginEdit: Boolean; stdcall;.
under Uses clause and select Find Declaration. This opens the file on next tab. Go to that file's tab.). Get to the "function TStringEditLink.BeginEdit: Boolean; stdcall;".
+
To wygląda jak:
It looks like:
 
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 876: Line 893:
 
</syntaxhighlight>     
 
</syntaxhighlight>     
  
Now add "FEdit.Height:=18;". It should look like:
+
Teraz dodaj "FEdit.Height:=18;". Powinno to wyglądać następująco:
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 896: Line 913:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Save the file (press Ctrl + S). If you are on the example project, close this (Project -> Close Project). Click on Tools -> Configure "Build Lazarus" ... Select Clean Up + Build All and then click on the Build button. After compile Lazarus should be restarted. Now open the example project and try to edit node on VST. This time it should be ok.
+
Zapisz plik (naciśnij Ctrl + S). Jeśli korzystasz z przykładowego projektu, zamknij go (Projekt -> Zamknij projekt). Kliknij Narzędzia -> Konfiguruj "Build Lazarusa" ... W Profilu budowania wybierz Czyść + Buduj wszystko, a następnie kliknij przycisk Buduj. Po kompilacji należy ponownie uruchomić Lazarusa. Teraz otwórz przykładowy projekt i spróbuj edytować węzeł na VST. Tym razem powinno być dobrze.
  
=External links=
+
=Linki zewnętrzne=
  
* [http://www.soft-gems.net Virtual Treeview tutorials/docs]
+
* [http://www.soft-gems.net www.soft-gems.net] (obecnie nie mogę znaleźć tutaj tej dokumentacji)
* [http://es.wikibooks.org/wiki/Programaci%C3%B3n_en_Pascal Programando en Pascal] - Spanish tutorial focused on FPC/Lazarus, hosted in Wikibooks.
+
* [https://documentation.help/VirtualTreeview/ Virtual Treeview instruktaże/dokumenty] aktualna lokalizacja ww. dokumentacji
 +
* [https://documentation.help/VirtualTreeview/documentation.pdf Virtual Treeview dokumentacja w pliku pdf]
 +
* [http://es.wikibooks.org/wiki/Programaci%C3%B3n_en_Pascal Programando en Pascal] - Hiszpański samouczek poświęcony FPC/Lazarus, prowadzony w Wikibooks.
 +
* [https://pl.wikibooks.org/wiki/Object_Pascal Kurs Object Pascal] - Polski samouczek poświęcony FPC, prowadzony w Wikibooks.

Latest revision as of 22:54, 7 June 2020

English (en) español (es) français (fr) polski (pl) русский (ru)

Oto kilka przykładów użycia VirtualTreeview dla Lazarusa (testowane na win32). Są one w większości zebrane z sieci, napisane dla Delphi oraz z samouczka/dokumentacji autorstwa Philippa Frenzela i Mike'a Lischke.

Samouczek/dokumenty dostępne kiedyś były na stronie http://www.soft-gems.net. Obecnie dokumentację w pliku pdf można pobrać ze strony documentation.help. Tutaj znajdziesz tylko szybki sposób korzystania z VirtualTreeview na Lazarus, a nie wyjaśnienia. Aby uzyskać wyjaśnienia i wiele innych funkcji/metod, pobierz oficjalne dokumenty i samouczek.

Podstawowe Drzewo Listview z 3 Kolumnami

1. Zainstaluj komponent. Uruchom Lazarusa.

2. Upuść komponent TVirtualStringTree na formę (znajdziesz go w zakładce Virtual Controls).

3. Przejdź do edytora źródeł (naciśnij klawisz F12). W sekcji Uses dodaj moduł o nazwie VirtualTrees (jeśli jeszcze go nie ma i nie jest to VirtualStringTree). Może to wyglądać następująco:

uses
  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs,
  VirtualStringTree, VirtualTrees;

4. Przejdź do projektanta formularzy (naciśnij klawisz F12). Wybierz Virtual Tree Component. Na Inspektorze obiektów kliknij Nazwa, wpisz VST i naciśnij enter. Kliknij Nagłówek (rozwiń go) -> Kolumny, kliknij mały przycisk obok „0 items”. Kliknij 3 razy przycisk Dodaj, aby dodać 3 kolumny. Nie zamykaj tego okna.

5. W oknie Edycja kolumny jest teraz wybrana trzecia kolumna. Dostań się do Inspektora obiektów. Kliknij Options (rozwiń) -> ustaw coAllowClick na False.

6. Kliknij tekst. Wpisz Kolumna2.

7. Kliknij opcję Width, wpisz 100 i naciśnij klawisz Enter.

8. Przejdź do okna Edycja kolumny, wybierz pierwszą i drugą kolumnę i ustaw ich właściwość jak powyżej (w polu tekstowym użyj różnych nazw, np. Kolumna0, Kolumna1).

9. Zamknij okno edycji kolumn. Wybierz komponent Virtual Tree na formie. W Inspektorze obiektów przejdź do Header -> Options (rozwiń). Ustaw hoVisible na True.

10. Przewiń w dół, aby ustawić Header -> Style na hsFlatButtons.

ExempleVirtualtreeView1.jpg

11. Przewiń w dół do TreeOptions (rozwiń) -> MiscOptions (rozwiń) i ustaw toEditable na True. Ustaw toGridExtensions na True.

12. Przewiń w dół do SelectionOptions (rozwiń) -> ustaw toExtendedFocus na True. Ustaw toMultiSelect na True. W formularzu Form Designer zmień rozmiar VST (Virtual Tree Component), aby w razie potrzeby wyświetlić wszystkie kolumny.

13. Teraz dodaj 3 przyciski do formularza. Pobierz je z palety komponentów - Zakładka Standard (ikona z etykietą „Ok”).

14. Kliknij Button1, w Inspectorze obiektów zmień Caption na AddRoot. Kliknij Button2, zmień podpis na AddChild. Zmień podpis przycisku Button3 na Delete.

ExempleVirtualtreeView2.jpg

15. Zachowaj to tutaj i przejdź do edytora źródeł (naciśnij F12). W edytorze źródeł zamień wiersz:

{$mode objfpc}{$H+}

na

{$MODE DELPHI}

16. Pod słowem kluczowym "implementation" wklej następujące wiersze:

type
  PTreeData = ^TTreeData;
  TTreeData = record
    Column0: String;
    Column1: String;
    Column2: String;
  end;

17. Przejdź do projektanta formularzy (naciśnij klawisz F12). Wybierz VST. Przejdź do Inspektora obiektów, wybierz kartę Zdarzenia, przewiń w dół do zdarzenia onChange. Kliknij dwukrotnie combobox. Wklej następujący kod:

procedure TForm1.VSTChange(Sender: TBaseVirtualTree; Node: PVirtualNode);
begin
  VST.Refresh;
end;

18. Przewiń do opcji onFocusChanged. Kliknij dwukrotnie i wklej następujący kod:

procedure TForm1.VSTFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Column: TColumnIndex);
begin
  VST.Refresh;
end;

19. Przewiń do onFreeNode. Kliknij dwukrotnie i wklej następujący kod:

procedure TForm1.VSTFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
var
  Data: PTreeData;
begin
  Data := VST.GetNodeData(Node);
  if Assigned(Data) then begin
    Data^.Column0 := '';
    Data^.Column1 := '';
    Data^.Column2 := '';
  end;
end;

20. Przewiń w dół do onGetNodeDataSize. Kliknij dwukrotnie i wklej następujący kod:

procedure TForm1.VSTGetNodeDataSize(Sender: TBaseVirtualTree; var NodeDataSize: Integer);
begin
  NodeDataSize := SizeOf(TTreeData);
end;

21. Przewiń do onGetText. Kliknij dwukrotnie i wklej następujący kod:

procedure TForm1.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
 Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
var
  Data: PTreeData;
begin
  Data := VST.GetNodeData(Node);
  case Column of
    0: CellText := Data^.Column0;
    1: CellText := Data^.Column1;
    2: CellText := Data^.Column2;
  end;
end;

22. Naciśnij klawisz F12, aby przejść do projektanta formularzy. Kliknij dwukrotnie przycisk AddRoot. Wklej następujący kod:

procedure TForm1.Button1Click(Sender: TObject);
var
  Data: PTreeData;
  XNode: PVirtualNode;
  Rand: Integer;
begin
  Randomize;
  Rand := Random(99);
  XNode := VST.AddChild(nil);
  
  if VST.AbsoluteIndex(XNode) > -1 then
  begin
    Data := VST.GetNodeData(Xnode);
    Data^.Column0 := 'One ' + IntToStr(Rand);
    Data^.Column1 := 'Two ' + IntToStr(Rand + 10);
    Data^.Column2 := 'Three ' + IntToStr(Rand - 10);
  end; 
end;

23. Naciśnij klawisz F9, aby uruchomić projekt w celu sprawdzenia. Kliknij AddRoot, aby dodać węzeł. Jeśli jest w porządku, węzeł zostanie dodany na VST.

ExempleVirtualtreeView3.jpg

24. Zatrzymaj wykonywanie. W formularzu kliknij dwukrotnie przycisk podpisany jako AddChild. Wklej następujący kod:

procedure TForm1.Button2Click(Sender: TObject);
var
  XNode: PVirtualNode;
  Data: PTreeData;
begin
  if not Assigned(VST.FocusedNode) then
    Exit;
    
  XNode := VST.AddChild(VST.FocusedNode);
  Data := VST.GetNodeData(Xnode);
    
  Data^.Column0 := 'Ch 1';
  Data^.Column1 := 'Ch 2';
  Data^.Column2 := 'Ch 3';

  VST.Expanded[VST.FocusedNode] := True;
end;

25. W formularzu kliknij dwukrotnie przycisk podpisany jako Delete. Wklej następujący kod:

procedure TForm1.Button3Click(Sender: TObject);
begin
  VST.DeleteSelectedNodes;
end;

26. Uruchom projekt, naciskając klawisz F9, aby sprawdzić program. Dodaj węzeł, dziecko i usuń je.

ExempleVirtualtreeView4.jpg

27. Spróbuj edytować węzeł. Wybierz węzeł i naciśnij F2, wpisz nową wartość. Jeśli widzisz, co piszesz, to jest OK. W przeciwnym razie przeczytaj poniżej „Nie można zobaczyć edycji komórki”.

28. Aby VST pokazywał nową wartość wprowadzoną po edycji, przejdź do Projektanta formularzy, wybierz VST. W Inspektorze obiektów -> Zdarzenia -> zdarzenie OnNewText kliknij dwukrotnie. Wklej następujący kod:

procedure TForm1.VSTNewText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Column: TColumnIndex; NewText: WideString);
var
  Data: PTreeData;
begin
  Data := VST.GetNodeData(Node);
  case Column of
    0: Data^.Column0 := NewText;
    1: Data^.Column1 := NewText;
    2: Data^.Column2 := NewText;
  end;
end;

Na tym przykład podstawowego zastosowania kończy się. Możesz upuścić kilka dodatkowych przycisków na formularz, aby przetestować kilka innych poleceń podanych poniżej. Następnymi krokami byłoby pokazanie pola wyboru, obrazu, koloru czcionki i dodanie combobox w węźle.

  • Inny sposób na dodanie węzła głównego
procedure TForm1.Button8Click(Sender: TObject);
begin
  with VST do
    RootNodeCount := RootNodeCount + 1;
end;
  • Inny sposób na dodanie dziecka
procedure TForm1.Button9Click(Sender: TObject);
begin
  if Assigned(VST.FocusedNode) then
    VST.ChildCount[VST.FocusedNode] := VST.ChildCount[VST.FocusedNode] + 1;
end;
  • Wybierz i usuń dzieci węzła
procedure TForm1.Button4Click(Sender: TObject);
var
  c: Integer;
begin
  if not Assigned(VST.FocusedNode) then
    Exit;
  if VST.HasChildren[VST.FocusedNode] then
  begin
    c := VST.ChildCount[VST.FocusedNode];
    VST.DeleteChildren(VST.FocusedNode);
    ShowMessage('Number of deleted child:' + #13#10 + IntToStr(c));
  end;
end;
  • Usunięcie węzeł
procedure TForm1.Button5Click(Sender: TObject);
begin
{VST.Clear;  //Delete All Nodes}
  if not Assigned(VST.FocusedNode) then
    Exit;
  VST.DeleteNode(VST.FocusedNode);
end;
  • Wyszukaj i wybierz węzeł
procedure TForm1.Button6Click(Sender: TObject);
bar
  XNode: PVirtualNode;
  Data: PTreeData;
begin
  XNode := VST.GetFirst;

  while XNode <> nil do
  begin
    Data := VST.GetNodeData(XNode);
    if Data^.Column0 = '1' then
    begin
      VST.ClearSelection;
      VST.Selected[XNode] := True;
      VST.SetFocus;
      break;
    end else
    XNode := VST.GetNextSibling(XNode);
  end;
end;
  • Wybierz rodzica
procedure TForm1.Button13Click(Sender: TObject);
var
  XNode: PVirtualNode;
begin
  if not Assigned(VST.FocusedNode) then
    Exit;
  XNode := VST.FocusedNode;
  while VST.GetNodeLevel(XNode) > 0 do
  begin
    XNode := XNode.Parent;
    VST.Selected[XNode] := True;
  end;
  VST.Refresh;
  VST.SetFocus;
end;
  • Wyszukaj wszystko
procedure TForm1.Button7Click(Sender: TObject);
var
  XNode: PVirtualNode;
  Data: PTreeData;
begin
  if VST.GetFirst = nil then Exit;
  XNode := nil;
  repeat
    if XNode = nil then 
      XNode := VST.GetFirst 
    else 
      XNode := VST.GetNext(XNode);
    Data := VST.GetNodeData(XNode);
    if (Data^.Column0 = '1') or (Data^.Column1 = '1') or (Data^.Column2 = '1') then
    begin
      ShowMessage('Found at Node Level : ' + IntToStr(VST.GetNodeLevel(XNode)));
      break;
    end;
  until XNode = VST.GetLast();
end;
  • Wyszukaj następny
procedure TForm1.Button8Click(Sender: TObject);
var
  XNode: PVirtualNode;
  Data: PTreeData;
begin
  if not Assigned(VST.GetFirst) then
    Exit
  else
    XNode := VST.GetFirst;
  repeat
    XNode := VST.GetNext(XNode);
    Data := VST.GetNodeData(XNode);
    if Pos(LowerCase(SearchEdit.Text), LowerCase(Data^.Column0)) > 0 then
    begin
      VST.FocusedNode := XNode;
      VST.Selected[XNode] := True;
      if MessageDlg('Item found?', mtConfirmation, mbYesNo, 0) = mrYes then
      begin
        VST.Expanded[XNode] := True;
        VST.Refresh;
        VST.SetFocus;
        Break;
      end;
    end;
  until XNode = VST.GetLast;
end;
  • Wstaw węzeł
procedure TForm1.Button12Click(Sender: TObject);
var
  XNode: PVirtualNode;
begin
  if Assigned(VST.FocusedNode) then
  begin
    XNode := VST.InsertNode(VST.FocusedNode,amInsertBefore);
    // To Insert After Selected Node.
    {XNode := VST.InsertNode(VST.FocusedNode,amInsertAfter);}
    VST.Refresh;
  end;
end;
  • Ustaw wysokość węzła
procedure TForm1.Button14Click(Sender: TObject);
begin
  if Assigned(VST.FocusedNode) then
    VST.NodeHeight[VST.FocusedNode] := 32;
end;
  • Zapisz i załaduj

Proste drzewo (bez kolumn) można zapisać i załadować jako:

VST.SaveToFile('filename.dat');
VST.LoadFromFile('filename.dat');

Aby zapisać i załadować powyższy przykład, umieść 2 przyciski w formularzu, zmień nazwę Caption na „Save” i „Load”. Wybierz VST, w Inspektorze obiektów -> TreeOptions -> StringOptions upewnij się, że parametr toSaveCaptions ma wartość True. Przejdź do zakładki Zdarzenia Inspektora obiektów. Przewiń w dół do OnLoadNode, kliknij dwukrotnie, a następnie wklej kod:

procedure TForm1.VSTLoadNode(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Stream: TStream);
var
  Data: PTreeData;
  Len: Integer;
begin
  Data := VST.GetNodeData(Node);
  Stream.read(Len, SizeOf(Len));
  SetLength(Data^.Column0, Len);
  Stream.read(PChar(Data^.Column0)^, Len);

  Stream.read(Len, SizeOf(Len));
  SetLength(Data^.Column1, Len);
  Stream.read(PChar(Data^.Column1)^, Len);

  Stream.read(Len, SizeOf(Len));
  SetLength(Data^.Column2, Len);
  Stream.read(PChar(Data^.Column2)^, Len);
end;

Ponownie na karcie Zdarzenia Inspektora obiektów - przewiń w dół do OnSaveNode, kliknij dwukrotnie, i wklej kod:

procedure TForm1.VSTSaveNode(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Stream: TStream);
var
  Data: PTreeData;
  Len: Integer;
begin
  Data := VST.GetNodeData(Node);
  Len := Length(Data^.Column0);
  Stream.write(Len, SizeOf(Len));
  Stream.write(PChar(Data^.Column0)^, Len);

  Len := Length(Data^.Column1);
  Stream.write(Len, SizeOf(Len));
  Stream.write(PChar(Data^.Column1)^, Len);

  Len := Length(Data^.Column2);
  Stream.write(Len, SizeOf(Len));
  Stream.write(PChar(Data^.Column2)^, Len);
end;

W formularzu kliknij dwukrotnie przycisk "Save" i wklej kod:

procedure TForm1.Button10Click(Sender: TObject);
begin
  VST.SaveToFile('C:\vst.dat');
end;

W formularzu kliknij dwukrotnie przycisk "Load" i wklej kod:

procedure TForm1.Button11Click(Sender: TObject);
begin
  VST.LoadFromFile('C:\vst.dat');
end;

Teraz przetestuj zapisywanie i ładowanie drzewa.

  • Problem z przewijaniem

Nagłówek widoku drzewa znika całkowicie lub częściowo podczas przewijania. Nie mogłem znaleźć na to dobrego rozwiązania. Jednym ze sposobów rozwiązania tego problemu jest ustawienie wysokości nagłówka na 0, a następnie użycie ogólnej etykiety dla kolumn. Jest to dobre, gdy jest kilka kolumn i wszystkie są widoczne bez przewijania w poziomie. Lub wysokość nagłówka można ustawić na wyższą wartość, np. 25 lub 30. VST.Refresh można dodać do zdarzenia OnScroll.
W wersji 5.5.3.1 nie zaobserowałem tego efektu, więc prawdopodobnie został on naprawiony.

  • Zmiana rozmiaru kolumny

Nie można zmienić rozmiaru kolumny, przeciągając myszą nagłówek VST. Może to być błąd nagłówka lub coś przeoczyłem. Jeśli dotyczy nagłówka, prawdopodobnie zostanie naprawiony w następnej wersji Lazarus. Zobacz ten link: http://bugs.freepascal.org/view.php?id=11209
W wersji 5.5.3.1 nie zaobserowałem tego efektu, więc prawdopodobnie został on naprawiony.

Poniższy kod może być przydatny dla tych, którzy chcieliby go sprawdzić lub wykorzystać w jakimś innym celu.

W każdym razie można zmienić rozmiar kolumny z kodu. Po naciśnięciu prawego przycisku myszy i przesunięciu kółka myszy w górę szerokość wybranej kolumny zwiększa się, a następnie naciśnięcie prawego przycisku myszy i przesunięcie kółka myszy w dół, aby zmniejszyć szerokość wybranej kolumny. Aby to zrobić:

1. Dodaj zmienną w edytorze źródłowym o nazwie CurCol: Integer; Wygląda to tak:

var
  Form1: TForm1; 
  CurCol: Integer; // <- Add this line only.

implementation

{ TForm1 }

2. W Projektancie formularzy kliknij dwukrotnie formularz, aby wygenerować zdarzenie OnCreate. Wewnątrz procedury OnCreate wpisz Form1.OnMouseWheelUp:= i naciśnij Ctrl+Shift+C, spowoduje to uzupełnienie kodu i utworzenie szkieletu zdarzenia MouseWheelUp. Wróć teraz do procedury TForm1.FormCreate(Sender: TObject); i dodaj kolejne wydarzenie dla MouseWheelDown. Wpisz Form1.OnMouseWheelDown:= i naciśnij Ctrl+Shift+C, aby wygenerować zdarzenie MouseWheelDown. Procedura FormCreate wygląda teraz następująco:

procedure TForm1.FormCreate(Sender: TObject);
begin
  Form1.OnMouseWheelUp   := @Form1MouseWheelUp;
  Form1.OnMouseWheelDown := @Form1MouseWheelDown;
end;

3. Wypełnij procedurę TForm1.Form1MouseWheelUp w ten sposób:

procedure TForm1.Form1MouseWheelUp(Sender: TObject; Shift: TShiftState;
  MousePos: TPoint; var Handled: Boolean);
begin
  if VST.Focused and (ssRight in Shift) then
    VST.Header.Columns[CurCol].Width := VST.Header.Columns[CurCol].Width + 10;
end;

4. Wypełnij procedurę TForm1.Form1MouseWheelDown jak poniżej:

procedure TForm1.Form1MouseWheelDown(Sender: TObject; Shift: TShiftState;
  MousePos: TPoint; var Handled: Boolean);
begin
  if VST.Focused and (ssRight in Shift) then
    VST.Header.Columns[CurCol].Width := VST.Header.Columns[CurCol].Width - 10;
end;

5. Przejdź do Projektanta formularzy (naciśnij F12), wybierz VST, na karcie Zdarzenia Inspektora obiektów przewiń do OnFocusChanged, kliknij dwukrotnie i wklej:

procedure TForm1.VSTFocusChanged(Sender: TBaseVirtualTree;
  Node: PVirtualNode; Column: TColumnIndex);
begin
  CurCol := Column;
end;

Po uruchomieniu programu kliknij kolumnę, a następnie przytrzymaj prawy przycisk myszy i przesuń kółko w górę, aby zwiększyć szerokość, lub kółko w dół, aby ją zmniejszyć. W razie potrzeby możesz dostosować powyższe procedury. Możesz też dodać zdarzenie klawiatury z czymś takim jak "if (key=187) i (ssShift in Shift) then", aby reagować na naciśnięcie klawiszy Shift + "+".

Pole wyboru (CheckBox)

On Form Designer select VST. Go to: W formularzu wybierz VST i wykonaj:

  1. Inspektor obiektów -> Właściwości -> CheckImageKind i wybierz ckDarkCheck.
  2. Inspektor obiektów -> Właściwości -> TreeOptions -> MiscOptions -> toCheckSupport i ustaw na True.

Teraz przejdź do zakładki Zdarzenia.

  • Przewiń do OnInitNode. Kliknij dwukrotnie i wklej następujący kod:
procedure TForm1.VSTInitNode(Sender: TBaseVirtualTree; ParentNode,
  Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
var
  Level: Integer;
begin
  Level := VST.GetNodeLevel(Node);
  if Level = 0 then
    Node^.CheckType := ctCheckBox;

  if Level = 2 then
    Node^.CheckType := ctRadioButton;

  if Level = 1 then
  begin
    Node^.CheckType  := ctTriStateCheckBox;
    Node^.CheckState := csCheckedNormal;
  end;

  if Level = 3 then
    Node^.CheckType := ctButton;
end;

Uruchom program, dodaj węzeł i dziecko, a następnie dodaj dziecko do dziecka, i sprawdź, czy możesz poprawnie zaznaczyć i odznaczyć pola wyboru. Jeśli nie, zamknij program. Przejdź do zakładki Zdarzenia Inspektora obiektów.

  • Przewiń do OnChecked, kliknij dwukrotnie i wklej:
procedure TForm1.VSTChecked(Sender: TBaseVirtualTree; Node: PVirtualNode);
begin
  VST.Refresh;
end;
  • Przewiń do opcji OnChecking, kliknij dwukrotnie i wklej:
procedure TForm1.VSTChecking(Sender: TBaseVirtualTree; Node: PVirtualNode;
  var NewState: TCheckState; var Allowed: Boolean);
begin
  VST.Refresh;
end;

Mam nadzieję, że teraz jest ok. Aby określić stan pola wyboru, użyj:

if XNode.CheckState = csCheckedNormal then
ShowMessage('Checked.');

Inne stany to:

csUncheckedNormal = niezaznaczone i nie wciśnięte
csUncheckedPressed = niezaznaczone i wciśnięte
csCheckedNormal = zaznaczone i nie wciśnięte
csCheckedPressed = zaznaczone i wciśnięte
csMixedNormal = 3-stanowe pole wyboru i nie wciśnięte
csMixedPressed = 3-stanowe pole wyboru i wciśnięte

Inne typy to:

ctNone
ctTriStateCheckBox
ctCheckBox
ctRadioButton
ctButton
  • Aby przechwycić przycisk pola wyboru (ctButton) Click

Przejdź do zakładki Zdarzenia Inspektora obiektów. Przewiń do OnChecked, kliknij dwukrotnie i wklej kod:

procedure TForm1.VSTChecked(Sender: TBaseVirtualTree; Node: PVirtualNode);
begin
  if Node^.CheckType = ctButton then
    ShowMessage('Ok.');
  VST.Refresh;
end;

Koniec pola wyboru.

Obrazy

Aby wyświetlić obrazy w węzłach VST, należy utworzyć listę obrazów.

  • Przejdź do palety komponentów -> Common Controls. Wybierz i upuść składnik TImageList na formularzu. Kliknij prawym przyciskiem myszy ikonę komponentu i wybierz ImageList Editor. Kliknij przycisk Dodaj i wybierz kilka zdjęć (na razie co najmniej 3), a następnie kliknij przycisk wyboru, aby zaakceptować i zamknąć Edytor ImageList. Nawiasem mówiąc, istnieje kilka fajnych zdjęć, które można pobrać ze strony http://www.famfamfam.com/lab/icons/silk/
  • Teraz w Projektancie formularzy wybierz VST, a na karcie Właściwości Inspektora obiektów przewiń do Images i wybierz ImageList1
  • Na karcie Zdarzenia Inspektora obiektów przewiń do OnGetImageIndex, kliknij dwukrotnie i wklej kod:
procedure TForm1.VSTGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: Boolean;
  var ImageIndex: Integer);
begin
  if Kind in [ikNormal , ikSelected] then // Zarówno wybrane jak i nie
  begin
    if Column = 0 then                    // jeśli to pierwsza kolumna
      ImageIndex := 0;                    // pierwszy obraz z listy ImageList1

    if Column = 1 then                    // jeśli to druga kolumna
      ImageIndex := 1;                    // drugi obraz z listy ImageList1

    if Sender.FocusedNode = Node then     // Pokaż tylko, jeśli wybrany
      if Column = 2 then                  // jeśli to trzecia kolumna
        ImageIndex := 2;                  // trzeci obraz z listy ImageList1
  end;
  {Sender.NodeHeight[node] := 40; //Jeśli obraz jest duży}
end;

Kolor czcionki

W Projektancie formularzy wybierz VST, a na karcie Zdarzenia Inspektora obiektów przewiń do OnPaintText, kliknij dwukrotnie i wklej kod:

procedure TForm1.VSTPaintText(Sender: TBaseVirtualTree;
  const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
  TextType: TVSTTextType);
var
  Data: PTreeData;
begin
  Data := VST.GetNodeData(Node);
 
  if Data^.Column0 = 'niebo' then
    TargetCanvas.Font.Color := clBlue;
  
  if Column = 1 then
  begin
    TargetCanvas.Font.Color := clRed;
    TargetCanvas.Font.Style := Font.Style + [fsItalic];
  end;
 
  if Column = 2 then
  begin
//  ImageList1.Draw(Form1.Canvas, -1, -1, 2); {draw top left of form, 3rd image of ImageList1??}
    TargetCanvas.Font.Size  := 9;
    TargetCanvas.Font.Color := clHighlightText;
  end;
end;

Teraz uruchom program. Dodaj jakieś węzły. Zobaczysz, że tekst w drugiej kolumnie jest czerwony. Spróbuj teraz zmienić tekst jakiegoś węzła w pierwszej kolumnie (klawisz F2) wpisując słowo "niebo". Po zatwierdzeniu zmiany tekst powinien stać się niebieski.

Dodanie ComboBox

  • Myślę, że masz otwarty projekt w Lazarus IDE z VST i możesz edytować węzły. Jeśli nie, zobacz „Podstawowy widok drzewa z 3 kolumnami” powyżej i przynajmniej wykonaj kroki od 1 do 21.
  • Poniżej znajduje się treść pliku modułu o nazwie combo. Skopiuj ten moduł i zapisz jako combo.pas w katalogu projektu. Pod klauzulą uses programu dodaj nazwę mocułu combo. Może to wyglądać następująco:
uses
  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs,
  VirtualStringTree, VirtualTrees, combo;
  • Moduł combo.pas
unit combo;

{$mode delphi}

interface

uses
  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs,
  VirtualStringTree, VirtualTrees, messages, windows, StdCtrls;

type
  TStringEditLink = class(TInterfacedObject, IVTEditLink)
  private
    FEdit: TWinControl;
    FTree: TVirtualStringTree;
    FNode: PVirtualNode;
    FColumn: Integer;
  protected
    procedure EditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  public
    destructor Destroy; override;
    function BeginEdit: Boolean; stdcall;
    function CancelEdit: Boolean; stdcall;
    function EndEdit: Boolean; stdcall;
    function GetBounds: TRect; stdcall;
    function PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean; stdcall;
    procedure ProcessMessage(var Message: TMessage); stdcall;
    procedure SetBounds(R: TRect); stdcall;
  end;

implementation

destructor TStringEditLink.Destroy;
begin
  FEdit.Free;
  inherited;
end;

procedure TStringEditLink.EditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  case Key of
    VK_ESCAPE:
      begin
        FTree.CancelEditNode;
        Key := 0;
        FTree.setfocus;
      end;
    VK_RETURN:
      begin
       PostMessage(FTree.Handle, WM_KEYDOWN, VK_DOWN, 0);
       Key := 0;
       FTree.EndEditNode;
       FTree.setfocus;
      end;
  end; //case
end;

function TStringEditLink.BeginEdit: Boolean;
begin
  Result := True;
  //FEdit.Height := (FTree.DefaultNodeHeight - 1); //Needed for editbox. Not combo
  FEdit.Show;
  TComboBox(FEdit).DroppedDown := True;
  FEdit.SetFocus;
end;

function TStringEditLink.CancelEdit: Boolean;
begin
  Result := True;
  FEdit.Hide;
end;

function TStringEditLink.EndEdit: Boolean;
var
  s: String;
begin
  Result := True;
  s := TComboBox(FEdit).Text;
  FTree.Text[FNode, FColumn] := s;

  FTree.InvalidateNode(FNode);
  FEdit.Hide;
  FTree.SetFocus;
end;

function TStringEditLink.GetBounds: TRect;
begin
  Result := FEdit.BoundsRect;
end;

function TStringEditLink.PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean;
begin
  Result := True;
  FTree := Tree as TVirtualStringTree;
  FNode := Node;
  FColumn := Column;

  FEdit.Free;
  FEdit := nil;

  FEdit := TComboBox.Create(nil);
  with FEdit as TComboBox do
    begin
      Visible := False;
      Parent := Tree;
      Items.Add('Google');
      Items.Add('Yahoo');
      Items.Add('Altavista');
      OnKeyDown := EditKeyDown;
    end;
end;

procedure TStringEditLink.ProcessMessage(var Message: TMessage);
begin
  FEdit.WindowProc(Message);
end;

procedure TStringEditLink.SetBounds(R: TRect);
var
  Dummy: Integer;
begin
  FTree.Header.Columns.GetColumnBounds(FColumn, Dummy, R.Right);
  FEdit.BoundsRect := R;
end;

end.
  • Po zapisaniu pliku, w Projektancie formularzy wybierz VST, a we właściwościach Inspektora obiektów przewiń do TreeOptions -> MiscOptions, ustaw wartość na toEditable na True. Następnie przejdź do TreeOptions -> SelectionOptions, ustaw toExtendedFocus na True.
  • Przejdź do zakładki Zdarzenia Inspektora obiektów. Przewiń do OnCreateEditor, kliknij dwukrotnie i wklej kod:
procedure TForm1.VSTCreateEditor(Sender: TBaseVirtualTree;
  Node: PVirtualNode; Column: TColumnIndex; out EditLink: IVTEditLink);
begin
  EditLink := TStringEditLink.Create;
end;
  • W zakładce Zdarzenia Inspektora obiektów przewiń do OnNewText, kliknij dwukrotnie i wklej kod:
procedure TForm1.VSTNewText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Column: TColumnIndex; NewText: WideString);
var
  Data: PTreeData;
begin
  Data := VST.GetNodeData(Node);
  case Column of
    0: Data^.Column0 := NewText;
    1: Data^.Column1 := NewText;
    2: Data^.Column2 := NewText;
  end;
end;

Uruchom program, wybierz węzeł i naciśnij F2, aby uzyskać ComboBox. Po naciśnięciu wprowadź nową wartość, a powinna ona pojawić się w węźle.

Jeśli nie można zobaczyć edycji komórki

Otwórz plik modułu VirtualStringTree.pas (jeśli nadal pracujesz nad powyższym przykładowym projektem, kliknij prawym przyciskiem myszy VirtualStringTree w obszarze słowa kluczowego uses i wybierz Znajdź deklarację. Spowoduje to otwarcie pliku na następnej karcie. Przejdź do zakładki tego pliku). Przejdź do „funkcji TStringEditLink.BeginEdit: Boolean; stdcall;”. To wygląda jak:

function TStringEditLink.BeginEdit: Boolean; stdcall;

// Notifies the edit link that editing can start now. Descentants may cancel node edit
// by returning False.

begin
  Result := not FStopping;
  if Result then
  begin
    FEdit.Show;
    FEdit.SelectAll;
    FEdit.SetFocus;
  end;
end;

Teraz dodaj "FEdit.Height:=18;". Powinno to wyglądać następująco:

function TStringEditLink.BeginEdit: Boolean; stdcall;

// Notifies the edit link that editing can start now. Descentants may cancel node edit
// by returning False.

begin
  Result := not FStopping;
  if Result then
  begin
    FEdit.Show;
    FEdit.SelectAll;
    FEdit.SetFocus;
    FEdit.Height := 18; // <--- Added this line.
  end;
end;

Zapisz plik (naciśnij Ctrl + S). Jeśli korzystasz z przykładowego projektu, zamknij go (Projekt -> Zamknij projekt). Kliknij Narzędzia -> Konfiguruj "Build Lazarusa" ... W Profilu budowania wybierz Czyść + Buduj wszystko, a następnie kliknij przycisk Buduj. Po kompilacji należy ponownie uruchomić Lazarusa. Teraz otwórz przykładowy projekt i spróbuj edytować węzeł na VST. Tym razem powinno być dobrze.

Linki zewnętrzne