Solved

Invalidate() only part of the form in managed Visual C++ .NET

Posted on 2004-08-28
14
530 Views
Last Modified: 2013-12-03
How can only part of the form be invalidated?
0
Comment
Question by:judico
  • 8
  • 6
14 Comments
 
LVL 19

Expert Comment

by:drichards
ID: 11938342
Check out the various overloads of Invalidate:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemwindowsformscontrolclassinvalidatetopic.asp

You can specify a region or rectangle to invalidate.  The PaintEventArgs contains a ClipRectangle member that indicates the invalidated rectangle that can be painted on.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemwindowsformspainteventargsclasscliprectangletopic.asp
0
 

Author Comment

by:judico
ID: 11940104
Thanks for the links. I looked at them but still can't figure out how to do this. Well, it appears that a function such as this has to be written:

public: void Invalidate(
   
       Rectangle rc
);

but how are the dimensions of the rectangle declared? I took a look at some solutions here in ee as well as some other web pages but cannot understand how this is done. The main idea is to avoid the flicker of the part of the screen (due to unnecessary redrawing)   where the x- and y-axes, tick-marks etc. are and have only the part where the curve builds up redrawn.
0
 
LVL 19

Expert Comment

by:drichards
ID: 11942245
You don't have to write an Invalidate function, you call Invalidate with a Reectangle or Region as a parameter rather than with no parameters as you are now.  If you inspect the PaintEventArgs parameter in the paint method now, the ClipRectangle will be the full size of the form.  The rectangle is specified as Rectangle(x, y, width, height) or Rectangle(Point, Size) where x,y or Point is the upper left corner and width, height or Size is the size of the rectangle.

The catch is that you need to be able to calculate the portion of the form that will need to be painted.  In your case, you can calculate the coord of the new point to be added and invalidate a small rectangle around that point.  Then when you are drawing, don't draw points that are outside the rectangle as they will not be cleared.  Check the ClipRectangle of the PaintEventArgs to see what region has been invalidated.
0
Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

 

Author Comment

by:judico
ID: 11943510
I need to invalidate the whole portion of the form where the curve bulds point by point and avoid the constant repainting of the area (where the x an y-axis values are) outside that portion. I don't understand how I should call Invalidate with a Rectangle as a parameter. Tried various ways but nothing helps.
0
 

Author Comment

by:judico
ID: 11948403
Can't figure out how to do that. As far as I understand from the help the rectangle should be created by something like this:

HDC hdc;
BOOL Rectangle(
hdc, // handle to DC
75, // x-coord of upper-left corner of rectangle
20, // y-coord of upper-left corner of rectangle
462, // x-coord of lower-right corner of rectangle
270 // y-coord of lower-right corner of rectangle
);

This, however, gives me

error C2078: too many initializers
error C2078: too many initializers

Also, how do you pass it as an argument to Invalidate -- is it something like:

Invalidate( Rectangle );

0
 
LVL 19

Expert Comment

by:drichards
ID: 11948559
You are looking at the Win32 Rectangle, not the .NET rectangle.  You want this one:

   http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemdrawingrectangleclasstopic.asp
0
 

Author Comment

by:judico
ID: 11949577
The only way it compiles is by writing:

public __value struct ClipRectangle
Invalidate( ClipRectangle );      

However, this doesn't do any good because ClipRectangle seems to encompass the entire form. I don't know how to declare ClipRectangle to be a specific portion of the form.

I tried many different ways also, say:

public __value struct updateRect
updateRect.X = 75;
updateRect.Y = 20;
updateRect.Width = 462;
updateRect.Height = 270;

this->Invalidate(updateRect);

or

public: void Invalidate(
Rectangle rc
);

etc.

Nothing seems to work.
0
 

Author Comment

by:judico
ID: 11951232
This also compiles well but with no apparent result:

System::Drawing::Rectangle *r = __nogc new System::Drawing::Rectangle(75,20,462,270);
public __value struct r;
this->Invalidate( r );
0
 
LVL 19

Accepted Solution

by:
drichards earned 50 total points
ID: 11952692
>> This also compiles well but with no apparent result:
First of all, the syntax doesn't seem quite right.  Secondly you are invalidating nearly the whole area, and third, did you remove the call to __super::OnPaint( paintEvent ) in the OnPaint method?  This last is what erases all the previous drawing.

So, suppose your most current point is going to be at the point (10,15).  If you are drawing circles 5 wide, you would only have to invalidate a rectangle (10,15,5,5).  You may have to adjust the number slightly as I don't know if the ellipse is measured the same way from the upper left corner.

You call Invalidate like this:

    Invalidate(System::Drawing::Rectangle(10,15,5,5);

In your pain method, only things you draw in this area will appear.  As a test, leave the __super::OnPaint( paintEvent ); in there and invalidate a region:

   Invalidate(System::Drawing::Rectangle(5, 0, 10,200);

You should see points only in a narrow vertical band close to the beginning.

0
 

Author Comment

by:judico
ID: 11953890
Now, this works perfectly. I need the first screen painted in full so I write:

if ( evtCounter < 2 )
{
      Invalidate();
}
else
{
         Invalidate(System::Drawing::Rectangle(75, 20, 1000, 250));
}

In this way I have the numbers of the axes steady (not flickering) and only the curve that builds is being repainted.

Thank you very much for your indispensable help.
0
 
LVL 19

Expert Comment

by:drichards
ID: 11954836
If you wantr to get really fancy, you can inalidate only the small area around the newest point and only that small area gets repainted.
0
 

Author Comment

by:judico
ID: 11956674
This is a very cool suggestion, indeed. I'm not sure it will work in my present case, though. Remember that I need to have the trace of the curve on the screen. I understand that according to you last idea every new point appearing on the graph after repaint will leave the previous point unaffected and in this way constant replotting of the ever growing array of points will become unnecessary. I wonder, however, if it will be worth the effort since as it is now it appears to work very well. Thanks anyway.
0
 
LVL 19

Expert Comment

by:drichards
ID: 11959390
>> I wonder, however, if it will be worth the effort since as it is now it appears to work very well
Nope, not worth the effort if it is working to your satisfaction.  Just remember you can do it - you never know what you might need for future work.
0
 

Author Comment

by:judico
ID: 11959901
Thanks and all the best.
0

Featured Post

Networking for the Cloud Era

Join Microsoft and Riverbed for a discussion and demonstration of enhancements to SteelConnect:
-One-click orchestration and cloud connectivity in Azure environments
-Tight integration of SD-WAN and WAN optimization capabilities
-Scalability and resiliency equal to a data center

Question has a verified solution.

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

Suggested Solutions

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…

860 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