Link to home
Start Free TrialLog in
Avatar of idlegravity
idlegravity

asked on

How to update one region of the view...

I've got a large, double-buffered, scrollable view in an SDI app.  When the user clicks in the view, the corresponding value in the document is toggled, and the the view needs to be updated to show the change.

Currently I just Invalidate() the view and cause it to be redrawn, but it's big enough that it's just too slow to redraw the whole thing every time the user interacts with it.  I am trying to figure out how to update just a small region of the view.  I would like to be able to update a region without going through all the nested loops of the OnDraw() function (I know that you can use clipping regions so that OnDraw() only updates a specific region, it would still take too long to go through everything I have in there).

Thanks for your help, experts!
ASKER CERTIFIED SOLUTION
Avatar of AndyAinscow
AndyAinscow
Flag of Switzerland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
If the information you present has a tabular format, then CListView in "Report mode" derived window will be more suitable for your needs, because it allows you to update row by row using owner draw feature, and of course has scrollbar.
GetUpdateRect only receives the enclosing update rectangle of the update region that is determined by one or more calls to InvalidateRect.

Therefore, use InvalidateRect as Nass98 told you and the next painting happens automatically ...

(from MSDN)

Windows sends a WM_PAINT message whenever the CWnd update region is not empty and there are no other messages in the application queue for that window.

Regards, Alex

? - without using GetUpdateRect how does idlegravity know what to repaint, as he says it is too big to repaint the complete view (as he presumable does at present) and since when does windows draw the contents of your view.
>>  without using GetUpdateRect how does idlegravity know what to repaint

Look to your post above:

   The update rectangle retrieved by the BeginPaint member function is identical to that retrieved
    by the GetUpdateRect member function.

   The BeginPaint member function automatically validates the update region, so any call to
   GetUpdateRect made immediately after a call to BeginPaint retrieves an empty update region.

So InvalidateRect is first (you have to say what regions became invalid) and BeginPaint gets the rectangle to update. You could call GetUpdateRect if you are actively drawing but not in OnDraw as you would get an empty rectangle. Furthermore, if you already have to know the update rectangle before calling InvalidateRect, there is no need to retrieve that rectangle again, except there are more than one regions to update.

Regards, Alex

void CMyView::OnPaint()
{
      GetUpdateRect(&m_rectUpdate);
      CPaintDC dc(this); // device context for painting
      OnDraw(&dc);
}


m_rectUpdate contains the rectangle to redraw
this is actually better

void CMyView::OnPaint()
{
     GetUpdateRect(&m_rectUpdate);
     CScrollView::OnPaint();  //or whatever your base class is
}


m_rectUpdate contains the rectangle to redraw