[gelöst] GridDrawCell -> taLeftJustify funktioniert nicht

Rund um die LCL und andere Komponenten
Antworten
Michl
Beiträge: 2513
Registriert: Di 19. Jun 2012, 12:54

[gelöst] GridDrawCell -> taLeftJustify funktioniert nicht

Beitrag von Michl »

Hallo allerseits,

Ich wollt mir bei einer Zelle in einem DBGrid den Inhalt selber zeichnen und bin dabei auf ein Problem gestoßen, was auch in einem normalen StringGrid (letzter gemeinsamer Vorfahr: TCustomGrid) nachzustellen ist (Bugeintrag oder ein Forumeintrag habe ich nicht finden können):

Versuche ich mit TextRect einen Text in das Rect zu schreiben, funktioniert dies nur, wenn der TextStyle.Alignment <> taLeftJustify ist:

Code: Alles auswählen

procedure TForm1.StringGrid1DrawCell(Sender: TObject; aCol,
  aRow: Integer; aRect: TRect; aState: TGridDrawState);
var
  aTextStyle: TTextStyle;
begin
  if (aCol=2) and (aRow>0) then begin
    aTextStyle:=TStringGrid(Sender).Canvas.TextStyle;
//    aTextStyle.Alignment:=taRightJustify;       //funktioniert
//    aTextStyle.Alignment:=taCenter;             //funktioniert
    aTextStyle.Alignment:=taLeftJustify;          //funktioniert nicht !!!
    TStringGrid(Sender).Canvas.TextRect(aRect, 0, 0, 'Test', aTextStyle);
  end;
end; 
Weiss jemand, ob ich da gerade wieder was versemmel oder ob das ein ungewolltes Verhalten ist?!

Ich habe getestet: Win7 64bit, Lazarus 32bit: Lazarus 1.2.2 r44758 FPC 2.6.4 i386-win32-win32/win64 und Lazarus 1.3 r45318M FPC 2.7.1 i386-win32-win32/win64

kleines Bsp. anbei
Dateianhänge
Drawcell.zip
(3.18 KiB) 58-mal heruntergeladen
Zuletzt geändert von Michl am Di 3. Jun 2014, 21:56, insgesamt 1-mal geändert.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Benutzeravatar
theo
Beiträge: 11080
Registriert: Mo 11. Sep 2006, 19:01

Re: GridDrawCell -> taLeftJustify funktioniert nicht

Beitrag von theo »

Kann ich bestätigen. Ist auf win32 (wine), gtk2 und qt so.
Hast du mal eine ältere Revision gecheckt? Das müsste doch eig. aufgefallen sein, wenn das schon länger so wäre.

wp_xyz
Beiträge: 5319
Registriert: Fr 8. Apr 2011, 09:01

Re: GridDrawCell -> taLeftJustify funktioniert nicht

Beitrag von wp_xyz »

Du darfst die x/y Koordinaten im DrawText nicht relativ zur Zelle nehmen, sondern du musst aRect mitnehmen:

Code: Alles auswählen

 
TStringGrid(Sender).Canvas.TextRect(aRect, aRect.Left, aRect.Top, 'Test', aTextStyle);
 
Ich glaube, die Frage ist eher, warum die anderen Fälle funktionieren.

Michl
Beiträge: 2513
Registriert: Di 19. Jun 2012, 12:54

Re: GridDrawCell -> taLeftJustify funktioniert nicht

Beitrag von Michl »

theo hat geschrieben:Kann ich bestätigen. Ist auf win32 (wine), gtk2 und qt so.
Hast du mal eine ältere Revision gecheckt? Das müsste doch eig. aufgefallen sein, wenn das schon länger so wäre.
Muss mal später schauen, ob irgendwo noch eine ältere Version rumliegen hab, werd, wenn ich dann Zeit habe, einen Bugreport dazu machen.

@wp_xyz: Danke, habe meinen Fehler korrigiert. Bei anderen selbstgezeichneten Controls mache ich das ja auch so :oops: - war verwirrt, da das mit x=y=0 funktioniert hatte. Funktioniert jetzt.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Benutzeravatar
theo
Beiträge: 11080
Registriert: Mo 11. Sep 2006, 19:01

Re: GridDrawCell -> taLeftJustify funktioniert nicht

Beitrag von theo »

wp_xyz hat geschrieben:Du darfst die x/y Koordinaten im DrawText nicht relativ zur Zelle nehmen, sondern du musst aRect mitnehmen:
Stimmt natürlich, da habe ich mich jetzt auch in die Irre führen lassen.. :roll:

Michl
Beiträge: 2513
Registriert: Di 19. Jun 2012, 12:54

Re: GridDrawCell -> taLeftJustify funktioniert nicht

Beitrag von Michl »

wp_xyz hat geschrieben:Ich glaube, die Frage ist eher, warum die anderen Fälle funktionieren.
Das dürfte an einer Bereichsprüfung liegen, da selbst

Code: Alles auswählen

    TStringGrid(Sender).Canvas.TextRect(aRect, -1, -1, 'Test', aTextStyle);  
funktioniert, außer mit "taLeftJustify".

Oder das Setzen eines anderen Aligns hebelt die eigenen gesetzten Koordinaten aus.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

wp_xyz
Beiträge: 5319
Registriert: Fr 8. Apr 2011, 09:01

Re: GridDrawCell -> taLeftJustify funktioniert nicht

Beitrag von wp_xyz »

... warum die anderen Fälle funktionieren ...
Im Quellcode von TCanvas.TextRect sieht man, dass die x-Koordinate nur bei taLeftJustify verwendet wird (die y-Koordinate nur für tlTop (Layout)). Bei taRightJustify wird das Textrechteck automatisch nach rechts geschoben, bei taCenter in ARect zentriert, so dass x nicht mehr benötigt wird. Hat alles seine Logik.

Code: Alles auswählen

 
  Options := 0;
  case Style.Alignment of
    taRightJustify : Options := DT_RIGHT;
    taCenter : Options := DT_CENTER;
  end;
  case Style.Layout of
    tlCenter : Options := Options or DT_VCENTER;
    tlBottom : Options := Options or DT_BOTTOM;
  end;
....
  // calculate text rectangle
  fRect := ARect;
  if Style.Alignment = taLeftJustify then
    fRect.Left := X;
  if Style.Layout = tlTop then
    fRect.Top := Y;
 
  if (Style.Alignment in [taRightJustify,taCenter]) or
    (Style.Layout in [tlCenter,tlBottom]) then
  begin
    DrawText(DC, pChar(Text), Length(Text), fRect, DT_CALCRECT or Options);
    case Style.Alignment of
      taRightJustify : OffsetRect(fRect, ARect.Right - fRect.Right, 0);
      taCenter : OffsetRect(fRect, (ARect.Right - fRect.Right) div 2, 0);
    end;
    case Style.Layout of
      tlCenter : OffsetRect(fRect, 0,
               ((ARect.Bottom - ARect.Top) - (fRect.Bottom - fRect.Top)) div 2);
      tlBottom : OffsetRect(fRect, 0, ARect.Bottom - fRect.Bottom);
    end;
  end;   
...
  DrawText(DC, pChar(Text), Length(Text), fRect, Options);   
 

Michl
Beiträge: 2513
Registriert: Di 19. Jun 2012, 12:54

Re: GridDrawCell -> taLeftJustify funktioniert nicht

Beitrag von Michl »

Danke für die Hilfsbereitschaft und sorry für den Aufwand!

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Antworten