Delphi - DBGrid-ben lévő kép és logikai típusú mezők grafikus megjelenítése

forráskód letöltése
Ha olyan adatbázis táblát jelenítünk meg DBGrid-ben, amely logikai mezőket, illetve képeket is tartalmaz, akkor meglehetősen kiábrándító képet kapunk. A logikai mezők helyén "True" vagy "False" látható, míg a kép helyett csak egy "(GRAPHIC)" felirat. Ebben a példában egy kicsit módosítottuk a DBGrid komponenst, ennek következtében mostantól olvashatóbb formában is megjeleníthetünk ilyen táblákat. A mellékelt példaprogram megnyitása előtt a DBGridEx.pas-ban lévő komponenst telepítenie kell a Delphi alá.

Olyan komponens, amely megjelenítette a képeket is a DBGrid-ben már lapunkban is megjelent. Ez most csak annyiban módosult, hogy a kép méretarányosan kicsinyítve jelenik meg úgy, hogy beleférjen a DBGrid cellájába, ráadásul még a cella igazítását is figyelembe veszi, tehát lehet balra, jobbra, vagy középre igazítani a képet. A logikai mezőkben a "True" és "False" helyett egy pipa, vagy egy "-"-jel jelenik meg, szintén figyelembe véve a cella igazítását.

A mellékelt példaprogramban jól látszik a TDBGrid és a TDBGridEx komponensek közötti különbség.

Mindezekhez a módosításokhoz csupán a DrawDataCell eljárást kell felülírnunk.
procedure TDBGridEx.DrawDataCell(const Rect: TRect; Field: TField; State: TGridDrawState);
var
  bmp: TBitmap;  x, y, w, h, pw, ph: integer;  r: TRect;
begin
  with Canvas do  begin
A w és h változókban eltároljuk a megrajzolandó cella szélességét és magasságát, majd a FillRect metódussal töröljük a cellát.
    w:=Rect.Right-Rect.Left;  h:=Rect.Bottom-Rect.Top;
    FillRect(Rect);
Ha a cellához tartozó mező típusa ftGraphic, akkor a mező képet tartalmaz. Ebben az esetben kiolvassuk a képet, és eltároljuk a bmp változóban. A pw és ph változóban eltároljuk a kép szélességét és magasságát. Ellenőrizzük, hogy a kép magassága nem nagyobb-e a cella magasságánál. Ha nagyobb, akkor arányosan csökkentjük a pw és ph változók értékét. Ezután ellenőrizzük, hogy a kép szélessége (pw) nem nagyobb-e, mint a cella szélessége. Ha nagyobb, akkor megint csökkentjük a méreteket.
    if Field.DataType=ftGraphic then begin
      bmp:=TBitmap.Create;
      bmp.Assign(Field);
      pw:=bmp.Width;  ph:=bmp.Height;
      if ph>h then begin
        pw:=round(pw*h/ph);  ph:=h;
      end;
      if pw>w then begin
        ph:=round(ph*w/pw);  pw:=w;
      end;
Az x és y változókba kiszámoljuk a kép koordinátáit a cella igazításától (Field.Alignment) függően, majd az r TRect típusú változóban eltároljuk a kép befoglaló négyzetének koordinátáit. Most már csak a megrajzolás van hátra, amit a StretchDraw eljárással végzünk el.
      
      x:=Rect.Left;  y:=h div 2-ph div 2;
      case Field.Alignment of
        taCenter:       x:=w div 2 - pw div 2;
        taRightJustify: x:=w-pw-1;
      end;
      r.Left:=Rect.Left+x;   r.Top:=Rect.Top+y;  r.Right:=r.Left+pw;  r.Bottom:=r.Top+ph;
      StretchDraw(r, bmp);
      bmp.Free;
    end else
Ha a mező típus ftBoolean, akkor egy logikai adatokat tartalmazó mezőhöz van szerencsénk. Ennek háromféle értéke lehet: igaz (true), hamis (false) vagy nem meghatározott. Ez utóbbi két esetben egy "-" jelet, igaz esetén pedig egy pipát jelenítünk meg a cellában. A képeket a DBGridEx.res resource fájlban tároljuk, és onnan fogjuk kiolvasni. Az x és y változókba kiszámoljuk a kép koordinátáit a cella igazításától függően, majd a Draw eljárással megrajzoljuk a képet.
    if Field.DataType=ftBoolean then begin
      bmp:=TBitmap.Create;
      if (Field as TBooleanField).AsBoolean then
        bmp.Handle:=LoadBitmap(HInstance, 'TRUE')
      else
        bmp.Handle:=LoadBitmap(HInstance, 'FALSE');
      y:=Rect.Top+h div 2 - bmp.Height div 2;  x:=Rect.Left;          
      case Field.Alignment of
        taCenter:       x:=Rect.Left+w div 2 - bmp.Width div 2;
        taRightJustify: x:=Rect.Right-bmp.Width-1;
      end;
      Draw(x, y, bmp);
      bmp.Free;
    end else begin
Ha a mező típusa nem kép vagy logikai, akkor a DefaultDrawDataCell eljárás meghívásával rajzoltatjuk meg a cella tartalmát.
      DefaultDrawDataCell(Rect, Field, State);
    end;
  end;
  inherited;
end;