Autor Beitrag
Laaeris
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 17

Win XP
Delphi 7
BeitragVerfasst: Di 07.08.07 23:16 
Hallo zusammen,

ich fummel seit einigen Tagen an folgendem Problem rum:
Ich habe eine DB-Tabelle mit mehreren Spalten. Eine der Spalten ist Integer (sie soll einen Status darstellen)
mit 6 möglichen Werten 1 bis 6 und soll sichtbar im TDBGRID dann mit 6 verschiedenen Images ausgestattet werden,
die in einer Imagelist mit dem Namen Images vorliegen (dort sind ca. 56 Images drin).
Leider bekomme ich immer einen Adresszugriffsfehler, egal, ob ich mit GetBitmap oder sogar Loadfromfile arbeite.
ich möchte aber so arbeiten wie unten angegeben, wenn möglich, und keine weiteren Ressourcen nachladen.

BTW: Ja, ich weiss, dass die letzte ELSE-Schleife redundant ist, aber ich wollte die funktionierende Booleanabfrage
im ersten Teil, die funktioniert, und die nicht funktionierende (ab Column=3) voneinander trennen.
Ich bekomme auch bei einem If FieldName='STATUS' anstelle von Column=3 den gleichen Fehler.
Irgendwo habe ich hier einen dummen Bock drin. :-)

Wenn ich auf die gleiche Art wie bei (Column=3)ff vorher das
Booleanfeld fülle (Column.Field.DataType = ftBoolean), funktioniert das malen der beiden Images 30 und 46.
Ich habe schon verschiedene Dinge ausprobiert und brauche einmal
einen genialen Moment von Eurer Seite. Hier kommt der Quelltext:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
procedure TVerwaltung.VertraegeDBGridDrawColumnCell(Sender: TObject;
  const Rect: TRect; DataCol: Integer; Column: TColumn;
  State: TGridDrawState);
var BooleanBitmap : Graphics.TBitmap;
    StatusBitmap  : Graphics.TBitmap;
    BitmapLeft    : Integer;
    Multiplikator : Real;
begin (*of Procedure VertraegeDBGridDrawColumnCell*)
  with (Sender as TDBGrid) do
  begin (*Sender ist das Grid*)
    if (Column.Field.DataType = ftBoolean) then
      begin (*das Booleanfeld*)
        // create our bitmap
        if (BooleanBitmap = nil) then
          BooleanBitmap := Graphics.TBitMap.Create;

        BooleanBitmap.Transparent:=True;

        // wrap try..finally so we don't miss freeing the bitmap
        try

        // get our bitmap according to the value of the logical field
        if Column.Field.AsBoolean
          then
            Images.GetBitmap(30,BooleanBitmap)
          else
            Images.GetBitmap(46,BooleanBitmap);

        // get rid of the standard boolean text by calling fillrect()
        VertraegeDBGrid.Canvas.FillRect(Rect);

        // get the position for the left side of the bitmap
        BitmapLeft := Trunc(Rect.Left +
                        ((Rect.Right-Rect.Left)/2)-
                        (BooleanBitmap.Width/2));

        // draw our bitmap to the canvas
        VertraegeDBGrid.Canvas.Draw(BitmapLeft,
                                 Rect.Top+1,
                                 BooleanBitmap);
        finally
          // free the bitmap
          BooleanBitmap.Free;
        end; (*of try finally*)
      end  (*das Booleanfeld*)
    ELSE
      Begin
        Canvas.Font.Color := clBlack;
        Canvas.FillRect(Rect);
        Canvas.TextOut(Rect.Left + 2, Rect.Top + 1, Column.Field.AsString);
      End;


    IF(Column.Index=3)THEN
      Begin (*Das Statusfeld*)
        StatusBitmap:=nil;

        // wrap try..finally so we don't miss freeing the bitmap
        try
        // get our bitmap according to the value of the logical field
        CASE DataModul.Vertraege.FieldValues['STATUS'] OF
        1:Images.GetBitmap(54,StatusBitmap);
        2:Images.GetBitmap(30,StatusBitmap);
        3:Images.GetBitmap(46,StatusBitmap);
        4:Images.GetBitmap(52,StatusBitmap);
        5:Images.GetBitmap(52,StatusBitmap);
        6:Images.GetBitmap(50,StatusBitmap);
        7:Images.GetBitmap(48,StatusBitmap);
        End; (*of Case*)

        StatusBitmap.Transparent:=True;

        // get rid of the standard boolean text by calling fillrect()
        VertraegeDBGrid.Canvas.FillRect(Rect);

        // get the position for the left side of the bitmap
        BitmapLeft := Trunc(Rect.Left +
                        ((Rect.Right-Rect.Left)/2)-
                        (StatusBitmap.Width/2));

        // draw our bitmap to the canvas
        VertraegeDBGrid.Canvas.Draw(BitmapLeft,
                                 Rect.Top+1,
                                 StatusBitmap);
        finally
          // free the bitmap
          StatusBitmap.Free;
        end; (*of try finally*)
      End;  (*Das Statusfeld*)
  END; (*Sender ist das Grid*)
end; (*of Procedure VertraegeDBGridDrawColumnCell*)


Für jede Hilfe bin ich sehr dankbar! HILFE :-)

Vielen Dank,

David

Moderiert von user profile iconUGrohne: Code- durch Delphi-Tags ersetzt

_________________
Lieber gut machen statt besser wissen.
Andreas Schilling
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 128
Erhaltene Danke: 1

WIN XP, WIN 7
Delphi 5 Ent, Delphi 2007 Pro, XE4
BeitragVerfasst: Mo 13.08.07 13:21 
Zeile 56 "StatusBitmap:=nil;" und danach wird darauf zugegriffen. Das muss doch krachen.
Laaeris Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 17

Win XP
Delphi 7
BeitragVerfasst: Mi 15.08.07 20:24 
Hallo Andreas,

das stimmt allerdings. Leider ist da das falsche Codeschnipsel reingewandert.
Ich habe das umgebaut und vereinfacht, der stürzt mir aber schon bei der Abfrage,
ob es sich um eine Booleanspalte handelt, mit einer Ausnahmeverletzung ab (Zeile 11).

Es ist frustrierend:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
procedure TVerwaltung.VertraegeDBGridDrawColumnCell(Sender: TObject;
  const Rect: TRect; DataCol: Integer; Column: TColumn;
  State: TGridDrawState);
var BooleanBitmap : Graphics.TBitmap;
    BitmapLeft    : Integer;
begin (*of Procedure VertraegeDBGridDrawColumnCell*)
  IF(DataModul.VertraegeQUERY.RecordCount>0)Then
  with (Sender as TDBGrid) do
  begin (*Sender ist das Grid*)
    if (Column.Field.DataType=ftBoolean) then
      begin (*das Booleanfeld*)
        // create our bitmap
        if (BooleanBitmap = nil) then
          BooleanBitmap := Graphics.TBitMap.Create;

        BooleanBitmap.Transparent:=True;

        // wrap try..finally so we don't miss freeing the bitmap
        try

        // get our bitmap according to the value of the logical field
        if Column.Field.AsBoolean
          then
            Images.GetBitmap(30,BooleanBitmap)
          else
            Images.GetBitmap(46,BooleanBitmap);

        // get rid of the standard boolean text by calling fillrect()
        VertraegeDBGrid.Canvas.FillRect(Rect);

        // get the position for the left side of the bitmap
        BitmapLeft := Trunc(Rect.Left +
                        ((Rect.Right-Rect.Left)/2)-
                        (BooleanBitmap.Width/2));

        // draw our bitmap to the canvas
        VertraegeDBGrid.Canvas.Draw(BitmapLeft,
                                 Rect.Top+1,
                                 BooleanBitmap);
        finally
          // free the bitmap
          BooleanBitmap.Free;
        end; (*of try finally*)
      end  (*das Booleanfeld*)
    ELSE IF(Column.Index=2)THEN
      Begin (*Das Vertragsfeld mit wem*)
        Canvas.Font.Color := clBlack;
        Canvas.FillRect(Rect);
        IF(DataModul.VertraegeQUERY.FieldValues['Partei1']=Aktiv_Spieler)THEN
          Canvas.TextOut(Rect.Left + 2, Rect.Top + 1,DataModul.VertraegeQUERY.FieldValues['Partei2'])
        ELSE
          Canvas.TextOut(Rect.Left + 2, Rect.Top + 1,DataModul.VertraegeQUERY.FieldValues['Partei1'])
      End   (*Das Vertragsfeld mit wem*)
    ELSE IF(Column.Index=3)THEN
      Begin (*Das Statusfeld*)
        Canvas.Font.Color := clBlack;
        Canvas.FillRect(Rect);
        CASE DataModul.VertraegeQUERY.FieldValues['STATUS'] OF
        1:Canvas.TextOut(Rect.Left + 2, Rect.Top + 1, 'Offen'); //54
        2:Canvas.TextOut(Rect.Left + 2, Rect.Top + 1, 'Aktiv'); //30
        3:Canvas.TextOut(Rect.Left + 2, Rect.Top + 1, 'Abgelehnt'); //46
        4:Begin
            IF(DataModul.VertraegeQUERY.FieldValues['PARTEI1']=Aktiv_Spieler)THEN
              Canvas.TextOut(Rect.Left + 2, Rect.Top + 1, 'Gekündigt durch uns')//52
            ELSE
              Canvas.TextOut(Rect.Left + 2, Rect.Top + 1, 'Gekündigt durch '
                +DataModul.VertraegeQUERY.FieldValues['PARTEI2'])//52
          End;
        5:Begin
            IF(DataModul.VertraegeQUERY.FieldValues['PARTEI1']=Aktiv_Spieler)THEN
              Canvas.TextOut(Rect.Left + 2, Rect.Top + 1, 'Gekündigt durch '
                +DataModul.VertraegeQUERY.FieldValues['PARTEI2'])//52
            ELSE
              Canvas.TextOut(Rect.Left + 2, Rect.Top + 1, 'Gekündigt durch uns');
          End;
        6:Begin
            IF(DataModul.VertraegeQUERY.FieldValues['PARTEI1']=Aktiv_Spieler)THEN
              Canvas.TextOut(Rect.Left + 2, Rect.Top + 1, 'Verletzt durch uns')
            ELSE
              Canvas.TextOut(Rect.Left + 2, Rect.Top + 1, 'Verletzt durch '
                +DataModul.VertraegeQUERY.FieldValues['PARTEI2']);//50/48
          End;
        7:Begin
            IF(DataModul.VertraegeQUERY.FieldValues['PARTEI1']=Aktiv_Spieler)THEN
              Canvas.TextOut(Rect.Left + 2, Rect.Top + 1, 'Verletzt durch '
                +DataModul.VertraegeQUERY.FieldValues['PARTEI2'])//50/48
            ELSE
              Canvas.TextOut(Rect.Left + 2, Rect.Top + 1, 'Verletzt durch uns');
          End;
        End; (*of Case*)
      End   (*Das Statusfeld*)
    ELSE
      Begin
        Canvas.Font.Color := clBlack;
        Canvas.FillRect(Rect);
        Canvas.TextOut(Rect.Left + 2, Rect.Top + 1, Column.Field.AsString);
      End;
  END; (*Sender ist das Grid*)
end; (*of Procedure VertraegeDBGridDrawColumnCell*)


Ich bin für jede Hilde dankbar!

David

Moderiert von user profile iconUGrohne: Code- durch Delphi-Tags ersetzt

_________________
Lieber gut machen statt besser wissen.
Andreas Schilling
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 128
Erhaltene Danke: 1

WIN XP, WIN 7
Delphi 5 Ent, Delphi 2007 Pro, XE4
BeitragVerfasst: Mo 20.08.07 14:57 
Ich habs mal getestet. Du hast wahrscheinlich Gridspalten ohne zugeordnete Datenquellenfelder. Dann tritt bei mir auch eine Zugriffsverletzung auf.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
if Column.field <> nil
then begin
  if (Column.Field.DataType=ftBoolean) then  
  begin (*das Booleanfeld*)  
    ...
  end
end

Mit der Abfrage ob das Field nil ist vermmeidest du den Fehler.