Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

TCanvas question

Posted on 2004-08-19
6
Medium Priority
?
452 Views
Last Modified: 2010-04-05
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
Comment
Question by:qas
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
6 Comments
 
LVL 2

Expert Comment

by:beermequik
ID: 11845058
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
 

Author Comment

by:qas
ID: 11845161
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
 
LVL 3

Accepted Solution

by:
Tyrsis earned 400 total points
ID: 11845258
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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 6

Expert Comment

by:gwalkeriq
ID: 11846761
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
 
LVL 2

Expert Comment

by:Molando
ID: 11846834
other option is to do a form1.doublebuffered := true. Though the lockwindowupdate will probably work much better.
0
 

Expert Comment

by:krio
ID: 11910623
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

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
This course is ideal for IT System Administrators working with VMware vSphere and its associated products in their company infrastructure. This course teaches you how to install and maintain this virtualization technology to store data, prevent vuln…
We’ve all felt that sense of false security before—locking down external access to a database or component and feeling like we’ve done all we need to do to secure company data. But that feeling is fleeting. Attacks these days can happen in many w…

721 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question