Solved

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

Posted on 2004-08-28
14
510 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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
USPS intelligent mail barcode font 11 133
Problem with Frankling Gothic Book font 5 85
c++ syntax question 9 43
Embarcadero C++ Builder XE10.1 Berlin red arrow Indicator 2 13
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

914 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

17 Experts available now in Live!

Get 1:1 Help Now