Delphi Grid DrawColumnCell can not clear - delphi

I am following examples to put a checkbox in a delphi column cell. I can place a checkbox image in a cell. But the underlying boolean value is longer than the image so the checkmark is over the first two letters of "True" or "False". How can I clear the rectangle in the column cell? I tried printing the original "True" or "False" in no color, or white on white, but the text is always Black no matter what choice I make.
Sample of my code:
procedure TFUpdtLists.TreatGridDrawColumnCell(Sender: TObject;
const Rect: TRect; DataCol: Integer; Column: TColumn; State:
TGridDrawState);
begin
with Column do begin
// TreatGrid.DefaultDrawColumnCell(Rect, DataCol, Column, State); ???
if FieldName = 'Repro' then begin
Canvas.Brush.Color:= TreatGrid.Color;
Canvas.FillRect(Rect);//fails to clear cell, clears another area??
if Field.Value = True then
//#7 a checkmark and # 5 a blank image in the image list:
MainView.ImageList1.Draw(TreatGrid.Canvas,Rect.Left,Rect.Top,7)
else
MainView.ImageList1.Draw(TreatGrid.Canvas,Rect.Left,Rect.Top,5);
TreatGrid.DefaultDrawColumnCell(Rect, DataCol, Column, State);//??
end;
end;
end;
Thanks in advance!

Pay attention to the Canvas you refer to in the code when you paint the background. Since there is no argument called Canvas and also Column doesn't have a Canvas it refers to the Canvas of the TFUpdtLists executing the code.
You have already corrected the code for the mageList1.Draw() methods and added the grids reference (TreatGrid). Do the same for the bg painting.
It appears you have tried calling DefaultDrawColumnCell() in different ways, but you should call it only for the columns that you don't draw yourself.
Let me also suggest that you quit using with ... because it prevents code completion from working and it makes debugging harder as well as increases significantly the risc of coding errors.
With the above mentioned changes the OnDrawColumnCell() procedure looks like this;
procedure TForm19.TreatGridDrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
if Column.FieldName = 'Repro' then
begin
TreatGrid.Canvas.Brush.Color:= TreatGrid.Color;
TreatGrid.Canvas.FillRect(Rect);
if Column.Field.Value then
//#7 a checkmark and # 5 a blank image in the image list:
Form19.ImageList1.Draw(TreatGrid.Canvas,Rect.Left,Rect.Top,1)
else
Form19.ImageList1.Draw(TreatGrid.Canvas,Rect.Left,Rect.Top,0);
end
else
TreatGrid.DefaultDrawColumnCell(Rect, DataCol, Column, State);
end;
You will want to correct the image indexes, which I changed to suit my imagelist in my test.

Related

Why does TDrawGrid.OnDrawCell draw black background when Brush.Style is bsFDiagonal?

I have the following code (assigned to DrawGrid1.OnDrawCell event):
procedure TForm1.DrawGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
begin
DrawGrid1.Canvas.Brush.Style:= bsFDiagonal;
DrawGrid1.Canvas.Brush.Color:= clSkyBlue;
DrawGrid1.Canvas.FillRect(Rect);
end;
It always draws black background even if the DrawGrid1.Color properties has been set to clRed. I also tried to change the Pen and Font properties, no luck.
What did I miss here?
ps: I have checked this code: Diagonal brush style gives me black area.
I have failed to see what is the difference between the question and the answer (apart from the commented line) and that code not working for me, as I mentioned, I already tried to change Pen properties without any result.
All I want is red background with sky blue diagonal lines.
Solved, have to add SetBKColor() before FillRect:
DrawGrid1.Canvas.Brush.Style:= bsFDiagonal;
DrawGrid1.Canvas.Brush.Color:= clSkyBlue;
SetBkColor(DrawGrid1.Canvas.Handle, ColorToRGB(clRed));
DrawGrid1.Canvas.FillRect(Rect);
I still don't know why, but it's working.

Add icons to TTabControl in Firemonkey

First of all I have to say that I've read this question of SO. But actually it wasn't helpful for me.
I want to add icons to TTabControl but it doesn't seems as easy as I can do it in VCL (TPageControl). As you know there is no something like Image Index in TTabControl.
So what's the easiest way to do this?
Thanks for your help.
I would suggest not going down the route of modifying the style given the inherent 'copy and paste "inheritance"' nature of the exercise, which becomes an issue if you're targeting more than one OS (even just Windows 7 and Windows 8.x). Instead, try this:
1) For each item you want an icon on, change its TextAlign property to taTrailing and pad its Text with four leading space characters.
2) Add one TImage to the form per tab, and load small bitmaps into them as desired.
3) Associate each tab item with its image by (for example) assigning its TagObject property to the image control in an OnCreate handler for the form:
procedure TForm1.FormCreate(Sender: TObject);
begin
TabItem1.TagObject := Image1;
//...
end;
4) Assign each tab item's OnPaint event the following shared event handler:
procedure TForm1.TabItemPaint(Sender: TObject; Canvas: TCanvas; const ARect: TRectF);
var
B: TBitmap;
SrcR, DstR: TRectF;
TabItem: TTabItem;
begin
TabItem := (Sender as TTabItem);
B := (TabItem.TagObject as TImage).Bitmap;
SrcR := RectF(0, 0, B.Width, B.Height);
DstR := SrcR;
DstR.Fit(RectF(ARect.Left, ARect.Top, ARect.Left + ARect.Height, ARect.Bottom));
if not TabItem.IsSelected then DstR.Offset(0, 1);
Canvas.DrawBitmap(B, SrcR, DstR, 1);
end;

Extending DBGrid with some row colors

I want to extend DbGrid functionality to add colors on odd and even rows. So i wrote this
procedure TGridx.DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState);
var
row : Integer;
begin
inherited;
row := Self.DataSource.DataSet.RecNo;
if (row mod 2 = 0) then
Self.Canvas.Brush.Color := FColor1 //some color
else
Self.Canvas.Brush.Color := FColor2; //some color
end;
What i am doing wrong ?
The event you want is called DBGridDrawColumnCell, and you need to decide whether to turn the DefaultDrawing property on or off, and the way you handle DBGridDrawColumnCell changes accordingly. For your case, you just set the colors, but leave DefaultDrawing true, and don't do any other canvas.Text or GDI drawing.
A recent question I asked here showed that in later Delphi versions (2010,Xe,Xe2) you ALSO sometimes need to call Canvas.Refresh for both TDBGRID and TListView, when changing canvas properties in ownerdraw events but that doesn't apply to delphi 7.
you should try also 3d party solution which are free, and extends already a lot the DBGrid, like the ones provided by the Jedi project
Opc0de, may be you should override not the "DrawCell" method but "DrawCellBackground"?
Try drawing the cell as well after the brush color is defined:
Self.Canvas.FillRect(ARect);

How to Clip Text in a TTreeview (Continued)

I have taken the advice, or at least I think I have, that I got in my previous question.
To summarize, I replaced the THTMLTreeList from TMS with a TTreeList and made two columns in it. I set the first column to 150 pixels and I overrode the AdvancedCustomDrawItem event with this code:
procedure TForm1.trXMLAdvancedCustomDrawItem(Sender: TCustomTreeView;
Node: TTreeNode; State: TCustomDrawState; Stage: TCustomDrawStage;
var PaintImages, DefaultDraw: Boolean);
var hContext: HDC;
s: PChar;
iLength: Integer;
uRect: TRect;
begin
DefaultDraw := False;
hContext := trXML.Canvas.Handle;
s := PChar(Node.Text);
iLength := Length(Node.Text);
uRect := Node.DisplayRect(True);
DrawText(hContext, s, iLength, uRect, DT_END_ELLIPSIS);
end;
I got the result I expected, that is, when I draw the tree, the text in the first column is clipped. And when I change the size of the first column, the text is appropriately clipped. But when the TreeList is not wide enough and has a scroll bar on the bottom and I scroll to the right, the text now extends into the second column by the same amount as the scroll bar has been moved. It's like the text is drawn relative to the client area of the TreeList rather than the partially hidden first column so it always extends 150 pixels into the TreeList.
It seems to me that I am using the wrong thing for the device context handle or the TRect but I do very little graphic type programming so I don't know what to change. Any help would be appreciated.
I just checked TMS's source code and
TTreeList already uses the DT_END_ELLIPSIS flag
and does per-column clipping of drawn text when the DefaultDraw parameter is set to True, so you don't need to draw the text yourself manually.

Delphi: paint column of list view

I draw a list view with OwnerDraw. I need to paint the first column. But I cannot understand how.
I tried:
procedure TFrame6.DownloadListCustomDraw(Sender: TCustomListView;
const ARect: TRect; var DefaultDraw: Boolean);
var
R: TRect;
begin
DefaultDraw := False;
Sender.Canvas.Brush.Color := $F7F7F7;
Sender.Canvas.Brush.Style := bsSolid;
R := ARect;
R.Right := ListView_GetColumnWidth(DownloadList.Handle, DownloadList.Columns[0].Index);
Sender.Canvas.FillRect(R);
DefaultDraw := True;
end;
But I draw over items. How to draw correctly, items and a background?
Thanks!
Summary from comments:
I suggest you to read this delphiDabbler article and hope that it contains enough information to resolve your problem. E.g. Example 1 shows how to change background and Example 4 shows point where item appearance can be changed.
Small tip: don't restore DefaultDraw to True at the end of the handler if you don't want text to be drawn.
I suggest you use VirtualStringTree if you want a lot of customization on the list. Its easy to use and almost anything is possible and most of all freeware. The component can be downloaded at Soft-Gems and few example can be found here

Resources