Improve company productivity with a Business Account.Sign Up

x
?
Solved

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

Posted on 2004-08-28
14
Medium Priority
?
561 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
Get 10% Off Your First Squarespace Website

Ready to showcase your work, publish content or promote your business online? With Squarespace’s award-winning templates and 24/7 customer service, getting started is simple. Head to Squarespace.com and use offer code ‘EXPERTS’ to get 10% off your first purchase.

 

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 200 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

Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

607 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