Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 463
  • Last Modified:

TCanvas question

Hi!

I'm drawing on the Canvas property of a StringGrid (well, in fact its the 3rd party TStringAlignGrid object which is pretty much like TStringGrid).  I need to draw some shapes on the canvas and, after a while, erase them.  Nothing complicated.

The thing is that if I call the refresh (or repaint or invalidate) method of the grid THE WHOLE grid gets repainted which make my screen flick like hell.

Is there anyway I can make some region (TRect) or cells to get repainted without getting the whole component refreshed ?  I know that the internal code of the component does that.  For example, After I draw a shape on the canvas, if I select the cell behind it the selected cell gets repainted and the rest of the grid remains ok.  

Any hint ?
0
qas
Asked:
qas
1 Solution
 
beermequikCommented:
The OnDrawCell event may work for you....

Set the DefaultDrawing property to false, and define that event.

I have code for this, I just have to dig it up (Its at home, so I wont be able to get to it till later today)

I will post the code later tonight.
0
 
qasAuthor Commented:
Sorry I dont understand...

I believe that the OnDraCell event will triggered whenever a cell needs to be painted, right ?  What I need is the other way around: not only  I want to trigger this event, I need the grid to actually paint the specified cells when I want it to.

Let me be clearer.  I got a rectangle drawn over multiple cells (lets call it R1) and another rectangle draw over some other cells (R2).  I want to erase R1 without having to erease R2.  

Is this possible ?
0
 
TyrsisCommented:
You can do this by clipping the region of the canvas you want to repaint and calling Invalidate.  There is an example of how to do this in the Delphi Help file - TCanvas,ClipRect

Here is a copy of that example:

This example creates a region and selects this region as the clipping rectangle for the Image component's canvas. It then sets the canvas's brush color to red and calls FillRect using the ClipRect as the area to fill. Lastly, the ClipRect is reset to the original value that it contained by calling SelectClipRect with nil as the second parameter and deletes the region.

procedure Form1.Button1Click(Sender: TObject);
var
    MyRgn: HRGN ;
begin

    MyRgn := CreateRectRgn(100,100,200,200);
    SelectClipRgn(Image1.Canvas.Handle,MyRgn);
    Image1.Canvas.Brush.Color := clRed;
    Image1.Canvas.FillRect(Image1.Canvas.ClipRect);
    Image1.Invalidate;
    SelectClipRgn(Image1.Canvas.Handle,nil);
    DeleteObject(MyRgn);
end;

Hope this helps!

Tyrsis
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
gwalkeriqCommented:
It's just a simple hack, but this might all you need.

Look at the windows API call LockWindowUpdate. It has a serious restriction that you can lock a single windows (which lock child windows recursively to)

Then in repaint event your could might look like:

LockWindowUpdate(Grid.Handle); // Grab the lock

Grid.Paint() // to force repaint of the grid itself
... // your code that draws to the canvas

LockWindowUpdate(0); // finish the update

You did not mention whether repainting without you drawing on the canvas causes massive flicker. If so, you may not get a big advantage

0
 
MolandoCommented:
other option is to do a form1.doublebuffered := true. Though the lockwindowupdate will probably work much better.
0
 
krioCommented:
Try the InvalidateRect API function. I've used it with a TDrawGrid and it worked fine (haven't tried it with a StringGrid).
Example:
rc:=StringGrid1.CellRect(1, 2); // Get the rectangle of cell 1,2
Windows.InvalidateRect(StringGrid1.Handle, @rc, false);

The function takes three parameters, the first one is the handle of the window, the second is a pointer to a rect (the area that should be repainted) and the last one is a bool that specifies if the background should be erased. Check the Win32 help for information on the InvalidateRect function.
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now