[Delphi] GUI element doorgeven aan een klasse

Pagina: 1
Acties:

  • Rodyman
  • Registratie: November 2001
  • Laatst online: 08-06-2024
Ik ben met een projectje bezig waarvoor ik een stringgrid heb op mijn form. Bij dit stringgrid heb ik op de drawcell event een functie zitten die kijkt of de cell een bepaalde kleur nodig heeft.
Dit ziet er als volgt uit:
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
procedure TForm1.sgrCalendarDrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
var
  dx: Integer;
begin
  with (Sender as TStringGrid) do
  begin
    // Don't change color for first Column, first row
    if (ACol = 0) or (ARow = 0) then
      Canvas.Brush.Color := clBtnFace
    else
    begin
      // Draw the color
      if calendar.GetColor(ACol, ARow) <> 0 then
        Canvas.Brush.Color := calendar.GetColor(ACol, ARow);

      Canvas.TextRect(Rect, Rect.Left + 2, Rect.Top + 2, cells[acol, arow]);
      Canvas.FrameRect(Rect);
    end;
  end;
end;

Waarbij calendar.GetColor(ACol, ARow) dus de kleur ophaalt uit een calendar object wat ik daarvoor aan heb gemaakt.
In het calendar object worden de kleuren dan ook in een dubbele array bijgehouden.

Daarnaast gebruik ik methodes in calendar die de stringgrid meekrijgen. Bijvoorbeeld:
Delphi:
1
calendar.SetLookAndFeel(stringgrid);

Nu treden er soms onverklaarbare access violations op, waarbij ik denk dat het komt door het gebruiken van gui componenten in de calendar klasse en door het gebruik van het calendar object in de GUI drawcell methode.

Hoe zou ik dit het beste kunnen oplossen, is dit makkelijk af te vangen op een bepaalde manier?

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Je zou eerst de oorzaak van je probleem moeten achterhalen voordat je kan gaan bedenken wat een oplossing zou kunnen zijn. Even debuggen dus. Zet "Use Debug DCUs" aan in je project options, loop stap voor stap door je code, zet breakpoints, bekijk de waarde van je variablen en houdt de call stack in de gaten. De code die je laat zien zou geen problemen moeten geven.

[ Voor 11% gewijzigd door LordLarry op 28-12-2005 12:43 ]

We adore chaos because we like to restore order - M.C. Escher


  • Rodyman
  • Registratie: November 2001
  • Laatst online: 08-06-2024
het gaat fout in de calendar.SetLookAndFeel(stringgrid) methode op de volgende plaats:
Delphi:
1
2
3
4
5
  procedure MonthCalendar.SetLookAndFeel( grid: TStringGrid );
  begin
    grid.ColCount := _days+1;  // <----- hier gaat het fout. 
    grid.RowCount := _nrOfPersons+1;
    ...

Het vreemde is, dat hij er de eerste keer wanneer het form gecreate wordt wel doorheen komt. Maar wanneer ik naar de volgende maand wil gaan en het stringgrid aangepast moet worden crashed ie er daar met een access violation uit.

Als ik weinig tot geen kleuren toevoeg, doet hij het op die plek wel goed. Vandaar dat ik dacht aan een synchronisatie probleem van gui en MonthCalendar klasse.

[ Voor 8% gewijzigd door Rodyman op 28-12-2005 13:27 ]


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Ok, je hebt nu gevonden waar en wanneer het fout gaat, maar nog niet wat en waarom. Als je Debug DCUs hebt gebruikt moet je vast kunnen zien op welke regel het in het grid het fout gaat. Of misschien is de variable grid wel helemaal nooit netjes gecreerd? Of misschien al weer vrijgegeven? Debug eens verder en zoek eens uit wat er precies fout gaat en waarom.

Zolang er niet meer als 1 thread is zijn het geen synchronisatie problemen.

We adore chaos because we like to restore order - M.C. Escher


  • Rodyman
  • Registratie: November 2001
  • Laatst online: 08-06-2024
Jup, het gaat fout in de volgende methode:
Delphi:
1
function ResizeInPlace(p: Pointer; newSize: Integer): Boolean;


en dan op deze regel:
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
...
    end else begin
      n := PUsed(PChar(u) + oldSize);
      if n.sizeFlags and cThisUsedFlag = 0 then begin
        f := PFree(n);
        Inc(blkSize, f.size);
        DeleteFree(f);
      end;
      if blkSize >= sizeof(TFree) then begin
        n := PUsed(PChar(u) + newSize);
        n.sizeFlags := blkSize or cThisUsedFlag;   // <---- hier gaat het fout
        InternalFreeMem(PChar(n) + sizeof(TUsed));
      end else
        newSize := oldSize;
    end;
...

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

ResizeInPlace? Welke Delphi versie gebruik je? Dit ziet er uit als een memory manager. Dan zit je een beetje te diep. Bekijk de call stack eens en loop eens wat functies omhoog. Bekijk die code, debug daar eens wat rond en probeer te achterhalen wat er precies fout gaat en waarom?

We adore chaos because we like to restore order - M.C. Escher


  • Rodyman
  • Registratie: November 2001
  • Laatst online: 08-06-2024
Ik gebruik delphi 2005.
Het is inderdaad een memory manager.
Ik denk trouwens nu na jou bericht gelezen te hebben dat het ligt aan het feit dat ik een variabele array gebruik voor de kleuren in op te slaan en ik vermoed dat ik die niet overal netjes 'vul' om het zo maar te zeggen. Dat zou ook de vreemde plaats van foutmeldingen verklaren.

Ik ga eens even wat code doorlopen.. alvast bedankt in ieder geval!

  • Rodyman
  • Registratie: November 2001
  • Laatst online: 08-06-2024
En daar lag het inderdaad aan... gewoon een index out of bounds die raar begon te doen. Waarom geeft de debugger dat gewoon niet aan ipv een access violation?

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Bij een dynamisch array weet de compiler dat niet altijd. Misschien is het beter en veiliger om TList of TObjectList te gebruiken ipv een dynamisch array.

We adore chaos because we like to restore order - M.C. Escher

Pagina: 1