Pošlu tedy celý zdroják.
Trošku jsem to upravil, něco začalo fungovat, něco nefunguje dále. První problém je na začátku: pokud je pole prázdné, jeví se jako nil. Při tom je samozřejmě problém přidat první položku protože PotvrzeniDialoguPridatBajt skončí hned na začátku testem na nil. Když přidám nějakou první položku ručně (přímo SetLength(Registr_X, 1); Registr_X[0].Adresa = ..., tak pak začnou některé funkce, resp. většina funkcí fungovat. Prázdné pole ale není totéž co nil, ne? Má tam být odkaz na pole které má 0 položek a tedy to lze zjistit, případně s tím odkazovaným polem pracovat, např. přidat do něj tu první položku.
Druhý problém je pak nejspíše v tom, že když si deklaruji v nějaké funkci var ToArray: TArrRegistr takto:
procedure TRegistry.PotvrzeniDialoguPridatBajt;
var
ToArray: TArrRegistr;
begin
...
ZnakRegistruToArray(DlgRegistr.CB_Registr.Text, ToArray);
if ToArray = NIL then Exit;
...
end;
tak když už to neskončí u prázdného pole na nil, bude se dále v celé funkci pracovat s místní kopií pole, a předpokládám že by mělo na konci být něco, co z ToArray přehraje data zpět do jednoho z Registrů, což mi celkově přijde jako špatný návrh, protože ve chvíli kdy pole bude skutečně rozsáhlé, budou se z něho odvozovat stejně velké kopie a zase skládat zpět což zabere čas i prostor, místo aby se pracovalo nad vybraným polem pouze pomocí odkazů.
celý zdroj zde:
unit U_Registry;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Spin, Grids, Buttons, ExtCtrls, ComCtrls, StrUtils;
type
TBitRegistru = record
Hodnota: Boolean;
Vyznam: ShortString;
end;
TZaznamRegistru = record
AdresaDEC: Integer;
ArrBity: array [0..7] of TBitRegistru;
end;
TArrRegistr = array of TZaznamRegistru;
type
TRegistry = class
private
{ Private declarations }
public
procedure CallPridatBajt;
procedure PotvrzeniDialoguPridatBajt;
function OveritPlatnouAdresuBajtuVDialogu: Boolean;
function GetIndexByteZRegistru(
AReg: ShortString; Adr: Integer; var FromArray: TArrRegistr): Integer;
procedure PridatNovyByteZDialogu(
AReg: ShortString; Adr: Integer; var ToArray: TArrRegistr);
procedure ZnakRegistruToArray(AReg: ShortString; var ToArray: TArrRegistr);
procedure VypsatRegistr(AReg: ShortString);
end;
var
Registry: TRegistry;
Registr_X: TArrRegistr;
Registr_Y: TArrRegistr;
Registr_R: TArrRegistr;
Registr_S: TArrRegistr;
implementation
uses
U_Main,
U_TestPrijmu,
U_DlgRegistr,
U_Spolecne,
U_NavaraAE;
{ TRegistry }
function TRegistry.OveritPlatnouAdresuBajtuVDialogu: Boolean;
begin
Result := True;
if DlgRegistr.SE_Adresa.Text = ''
then begin Result := False; Exit; end;
if NvrConversions.JeCislo(DlgRegistr.SE_Adresa.Text) = False
then begin Result := False; Exit; end;
if DlgRegistr.SE_Adresa.Value < 0
then begin Result := False; Exit; end;
if DlgRegistr.SE_Adresa.Value > 65535
then begin Result := False; Exit; end;
end;
procedure TRegistry.ZnakRegistruToArray(AReg: ShortString; var ToArray: TArrRegistr);
begin
ToArray := nil;
if AReg = 'X' then begin ToArray := Registr_X; Exit; end;
if AReg = 'Y' then begin ToArray := Registr_Y; Exit; end;
if AReg = 'R' then begin ToArray := Registr_R; Exit; end;
if AReg = 'S' then begin ToArray := Registr_S; Exit; end;
end;
function TRegistry.GetIndexByteZRegistru(
AReg: ShortString; Adr: Integer; var FromArray: TArrRegistr): Integer;
var
AInt: Integer;
begin
Result := -1;
if FromArray = nil then Exit;
if Length(FromArray) = 0 then Exit;
for AInt := 0 to High(FromArray) do
begin
if FromArray[AInt].AdresaDEC = Adr then
begin
Result := AInt;
Exit;
end;
end;
end;
procedure TRegistry.PridatNovyByteZDialogu(
AReg: ShortString; Adr: Integer; var ToArray: TArrRegistr);
begin
if ToArray = nil then Exit;
SetLength(ToArray, Length(ToArray) +1);
with ToArray[High(ToArray)] do
begin
AdresaDEC := DlgRegistr.SE_Adresa.Value;
end;
end;
procedure TRegistry.PotvrzeniDialoguPridatBajt;
var
ToArray: TArrRegistr;
begin
if OveritPlatnouAdresuBajtuVDialogu = false then
begin
ShowMessage('Adresa byte není platná.');
Exit;
end;
ZnakRegistruToArray(DlgRegistr.CB_Registr.Text, ToArray);
if ToArray = NIL then Exit;
if DlgRegistr.Caption = 'Přidat byte' then
begin
if GetIndexByteZRegistru(
DlgRegistr.CB_Registr.Text,
DlgRegistr.SE_Adresa.Value, ToArray) <> -1 then
begin
Showmessage('Byte s takovou adresou již existuje.');
Exit;
end;
PridatNovyByteZDialogu(
DlgRegistr.CB_Registr.Text,
DlgRegistr.SE_Adresa.Value, ToArray);
DlgRegistr.Close;
Registry.VypsatRegistr(DlgRegistr.CB_Registr.Text);
end;
end;
procedure TRegistry.CallPridatBajt;
begin
DlgRegistr.Caption := 'Přidat byte';
DlgRegistr.SE_Adresa.Text := '0';
DlgRegistr.SetLabel_DecAdresaNaHEX;
DlgRegistr.Showmodal;
end;
procedure TRegistry.VypsatRegistr(Areg: ShortString);
var
AInt: Integer;
ABit: Integer;
LinkaSG: Integer;
ArrReg: TArrRegistr;
begin
NvrGridProc.ClearAllCells(Main.SG_Registry, True, True);
Main.SG_Registry.RowCount := 2;
Main.SetLabels_Registry;
ZnakRegistruToArray(AReg, ArrReg);
if ArrReg = nil then Exit;
if Length(ArrReg) = 0 then Exit;
for AInt := 0 to High(ArrReg) do
begin
for ABit := 0 to 7 do
begin
LinkaSG := NvrGridProc.GetFirstFreeLine(Main.SG_Registry, false, True);
with Main.SG_Registry do
begin
Cells[0, LinkaSG] := Areg;
Cells[1, LinkaSG] := Inttostr(ArrReg[AInt].AdresaDEC);
Cells[2, LinkaSG] := ''; // Areg;
Cells[3, LinkaSG] := Inttostr(ABit);
Cells[4, LinkaSG] := BoolToStr(ArrReg[AInt].ArrBity[ABit].Hodnota);
Cells[5, LinkaSG] := ArrReg[AInt].ArrBity[ABit].Vyznam;
end;
end;
end;
end;
end.