Solved

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

Posted on 2004-08-28
14
501 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
 

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
How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

 

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

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

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…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

744 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

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now