Zapisy PRepository
i ^TRepository
są równoznaczne na poziomie języka, jednak mogą mylić;
Z drugiej strony tak patrzę na ten tutorial z podanego linka i mam wątpliwości... Birąc pod lupę poniższy kod:
Kopiuj
var
Data: PWirtualnyRekord;
begin
Data := Sender.GetNodeData(Node);
if Length(Data.Caption) = 0 then
Data.Caption := 'Wiersz ' + IntToStr(Sender.AbsoluteIndex(Node)+1);
CellText := Data.Caption;
end;
już na pierwszy rzut oka widać błędy; Jeśli PWirtualnyRekord
jest wskażnikiem na rekord typu TWirtualnyRekord
, to odwołanie do zmiennej Data
jako wskaźnika w sposób Data.Caption
jest niepoprawne i taki kod powinien walić błędami Access Violation; Prawidłowym zapisem było by Data^.Caption
;
Dlatego też jeśli wrzucasz wskaźnik do danych węzła, to po jego pobraniu powinieneś się odwoływać do jego składowych za pomocą operatora ^
; @olesio pokazał Ci przykład z wykorzystaniem obiektu, a nie rekordu, więc musisz analizować podawane kody i rozumieć jak działają;</del>
Dobrze jest jednak - zapomniałem że brak operatora ^
w Delphi jest dopuszczalny; Przesiadłem się na FPC, a tam bez daszka kod się nie skompiluje;
Obstawiałbym, że poniższy kod:
Kopiuj
procedure TfrmRepository.VSTNodeClick(Sender: TBaseVirtualTree;
const HitInfo: THitInfo);
var
ObjPtr : ^TRepository;
begin
ObjPtr := VST.GetNodeData(HitInfo.HitNode);
Image1.Picture.Icon:= ObjPtr.ProcessIcon;
end;
powinien wyglądać coś w ten deseń:
Kopiuj
procedure TfrmRepository.VSTNodeClick(Sender: TBaseVirtualTree; const HitInfo: THitInfo);
var
ptrRep : PRepository;
begin
ptrRep := PRepository(VST.GetNodeData(HitInfo.THitInfo));
Image1.Picture.Icon := ptrRep^.ProcessIcon;
end;
Napisałem "w ten deseń", bo składniowo było by poprawnie, jednak nie mam jak tego przetestować; No i musisz pamiętać, że jeśli korzystasz ze wskaźników, to rekordy na które wskaźniki wskazują muszą posiadać zaalokowaną pamięć; Bez względu na to czy istnieją one w jakichś zmiennych, polach klasy, macierzach, czy alokowane dynamicznie, za pomocą np. GetMem; Osobiście wybrałbym dynamiczną alokację i trzymanie wskaźników na ich pamięć tylko w danych elementów; Dzięki temu przy tworzeniu nowego elementu drzewa, alokowałoby się pamięć dla nowego rekordu i przypisywało wskaźnik do zaalokowanej pamięci, a przy usuwaniu zwalniałoby się ją;
Jak widzisz korzystanie ze wskaźników daje ciekawe możliwości, ale ich obsługa nie jest taka prosta i łatwo się pogubić, przez co kod może nie działać prawidłowo, a program generować wycieki pamięci; Jeśli jeszcze motasz się ze wskaźnikami, to poćwicz sobie wcześniej na dedykowanym jedynie dla testów programie - mniej będziesz miał później problemów.
ProcessIcon: hIcon; ... Image1.Picture.Bitmap.Handle := Data.ProcessIcon;