Solved

How to update one region of the view...

Posted on 2004-08-16
10
355 Views
Last Modified: 2013-11-20
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!
0
Comment
Question by:idlegravity
10 Comments
 
LVL 44

Accepted Solution

by:
AndyAinscow earned 63 total points
ID: 11817866
This function should be what you require.
Find out what needs to be repainted AND what part of that is visible.  Then redraw that part.


CWnd::GetUpdateRect
BOOL GetUpdateRect( LPRECT lpRect, BOOL bErase = FALSE );

Return Value

Specifies the status of the update region. The value is nonzero if the update region is not empty; otherwise 0.

If the lpRect parameter is set to NULL, the return value is nonzero if an update region exists; otherwise 0.

Parameters

lpRect

Points to a CRect object or RECT structure that is to receive the client coordinates of the update that encloses the update region.

Set this parameter to NULL to determine whether an update region exists within the CWnd. If lpRect is NULL, the GetUpdateRect member function returns nonzero if an update region exists and 0 if one does not. This provides a way to determine whether a WM_PAINT message resulted from an invalid area. Do not set this parameter to NULL in Windows version 3.0 and earlier.

bErase

Specifies whether the background in the update region is to be erased.

Remarks

Retrieves the coordinates of the smallest rectangle that completely encloses the update region. If CWnd was created with the CS_OWNDC style and the mapping mode is not MM_TEXT, the GetUpdateRect member function gives the rectangle in logical coordinates. Otherwise, GetUpdateRect gives the rectangle in client coordinates. If there is no update region, GetUpdateRect sets the rectangle to be empty (sets all coordinates to 0).

The bErase parameter specifies whether GetUpdateRect should erase the background of the update region. If bErase is TRUE and the update region is not empty, the background is erased. To erase the background, GetUpdateRect sends the WM_ERASEBKGND message.

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.

0
 
LVL 5

Assisted Solution

by:Nass89
Nass89 earned 62 total points
ID: 11827495
Hi,
Have a look at:

from MSDN:

CWindow::InvalidateRect
BOOL InvalidateRect( LPCRECT lpRect, BOOL bErase = TRUE );

SeeInvalidateRect in the Win32 SDK.

Remarks

Invalidates the client area within the specified rectangle.


Good Luck!
0
 
LVL 55

Expert Comment

by:Jaime Olivares
ID: 11828355
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.
0
Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 11833339
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

0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 11833899
? - 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.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 11838419
>>  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

0
 
LVL 44

Expert Comment

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


m_rectUpdate contains the rectangle to redraw
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 11838868
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
0

Featured Post

Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

Introduction: Dialogs (2) modeless dialog and a worker thread.  Handling data shared between threads.  Recursive functions. Continuing from the tenth article about sudoku.   Last article we worked with a modal dialog to help maintain informat…
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…

808 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