20. maj 2007 - 20:45 Der er 8 kommentarer og
1 løsning

TCheckBox og FindComponent

Jeg har lavet et program hvor brugerne skal have individuel adgang til programmets funktioner.
For at kunne styre dette, har jeg laver en form (Form92) med 60 CheckBoxes, en CheckBox for hver funktion.
Jeg søger på brugeren i bruger tabellen, og krydser af i de respektive CheckBoxes, og gemmer. Jeg kan se i tabellen, ved hjælp af Database Desktop, at dataene bliver gemt korrekt. På et tidspunkt skal en bruger have ændret i sine beføjelser, så søger jeg igen i bruger tabellen, så vises de foreløbige rettigheder i de respektive CheckBoxes, eller det vil sige, at det skulle de, for her går det galt.
I linien med -> genererer programmet en access violation at address ..., når jeg kører i debug mode kan jeg se at det er i denne linie det går galt.
Jeg har forsøgt at tilføje en label (Label5) til formen, og så tilføje en linie før den med pilen, hvor der står: "Label5.Caption := BoxNr". der står der det fineste tretal.
I routinen "TForm92.Fyld" bruges den nøjagtige samme linie, men der virker det fint.
Hvad gør jeg galt.

procedure TForm92.Fyld(S: Boolean);
var
  X: Integer;
begin
  for X := 1 to 60 do  // Der er 60 checkboxes.
  begin
    TCheckBox(FindComponent('CheckBox' + IntToStr(X))).Checked := S;
  end;
end;

procedure TForm92.FyldBruger(B: LongInt);
var
  BoxNr: String;
begin
  if B = 1 then
  begin  // Administrator.
    Opdater.Enabled := False;
    Fyld(True);
  end
  else
  begin  // Alle andre.
    Opdater.Enabled := True;
    Fyld(False);  // Tøm først alle flueben.
    with Global.Adgang.DataSet do
    begin
      Refresh;
      Global.TAdgang.IndexName := 'AdgangBruger';
      Global.TAdgang.FindNearest([IntToStr(B)]);
      while (not EOF) and
            (FieldByName('Bruger').AsInteger = B) do
      begin  // Sæt derefter flueben i de rigtige felter.
        BoxNr := IntToStr(FieldByName('Rettighed').AsInteger);
->      TCheckBox(FindComponent('CheckBox' + BoxNr)).Checked := True;
        Next;
      end;
    end;
  end;
end;
Avatar billede kroning Nybegynder
21. maj 2007 - 10:17 #1
Er du helt sikker på at BoxNr har værdien 3 når det går galt. Hvis du debugger og stopper på -> linien og peger på BoxNr med musen hvad værdi har den så? Måske er den label5 du indsatte ikke blevet opdateret på skærmen når fejlen kommer.
Avatar billede borrisholt Novice
21. maj 2007 - 12:08 #2
Det kan også være fordi at din checkbox ligger på et panel, så kan du ikke finde den uden at lave rekusion.

Men prøv den her :

function FindControl(aOwner: TWinControl; const ControlName: string): TWinControl;
var
  i: Integer;
  Control : TWinControl;
begin
  Result := nil;
  for i := 0 to aOwner.ControlCount - 1 do
  begin
    if not (aOwner.Controls[i] is TWinControl) then
      continue;

    Control := aOwner.Controls[i] as TWinControl;

    if Control.ControlCount > 0 then
      Result := FindControl(Control, ControlName);

    if Result <> nil then
      exit;
     
    if SameText(ControlName, Control.Name) then
    begin
      Result := Control;
      exit;
    end;
  end;
end;


Hvis du så kalder den med FindControl(Form92, 'CheckBox' + BoxNr)) så skulle du have elimineret den fejl

Så er der kun den mulighed tilbage som  kroning kommer med.

Jens B
Avatar billede kroning Nybegynder
21. maj 2007 - 12:30 #3
borrisholt> FindComponent finder også en checkbox selvom den ligger på et panel eller andet.
Avatar billede borrisholt Novice
21. maj 2007 - 13:43 #4
kroning>> Nope er ikke rekusiv :

function TComponent.FindComponent(const AName: string): TComponent;
var
  I: Integer;
begin
  if (AName <> '') and (FComponents <> nil) then
    for I := 0 to FComponents.Count - 1 do
    begin
      Result := FComponents[I];
      if SameText(Result.FName, AName) then Exit;
    end;
  Result := nil;
end;
Avatar billede kroning Nybegynder
21. maj 2007 - 13:56 #5
Det er muligt men det virker nu fint i Delphi 7.
Hvis jeg et panel der er placeret på et panel der er placeret på et panel og oven på alt det f.eks. et GroupBox så vil FindComponent finde en f.eks. TLabel uanset hvor jeg placere den.
21. maj 2007 - 21:03 #6
Hvis jeg skriver:

TCheckBox(FindComponent('CheckBox1')).Checked := True;

Så får jeg samme fejl, så værdien af BoxNr er irrellevant i denne sammenhæng.
Alle CheckBoxes er placeret direkte på formen.
proceduren "Fyld" tilgår de samme CheckBoxes.
21. maj 2007 - 21:12 #7
Den eneste forskel jeg kunne få øje på var at i "FyldBruger" er linien pakket ind i en with struktur, så da jeg satte en Self ind i den famøse linie, så virkede det.

TCheckBox(Self.FindComponent('CheckBox' + BoxNr)).Checked := True;

Er der nogen som kan forklare mig hvorfor?
Avatar billede kroning Nybegynder
21. maj 2007 - 22:43 #8
Pga. din with svare din linie til dette:
TCheckBox(Global.Adgang.DataSet.FindComponent('CheckBox' + BoxNr)).Checked := True;

Når du sætter en Self foran svarer det til dette:
TCheckBox(Form92.FindComponent('CheckBox' + BoxNr)).Checked := True;
hvilket jo er det korrekte da dine Checkboxe befinder sig på Form92
07. juni 2007 - 19:57 #9
Lukker.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester