By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,413 Members | 1,023 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,413 IT Pros & Developers. It's quick & easy.

invalidate rectangle

P: 1
hi,

In my Doc/view appication I want to user invalidate rectangle value in ondraw()
function.


can any one help me.

Thanks in advance.

Regards
Rushiraj.
Feb 20 '07 #1
Share this Question
Share on Google+
5 Replies


AdrianH
Expert 100+
P: 1,251
hi,

In my Doc/view appication I want to user invalidate rectangle value in ondraw()
function.


can any one help me.

Thanks in advance.

Regards
Rushiraj.
Hi, I'm not positive, but I don't think you can or should invalidate in the OnDraw() function as this is the function that is called when a portion of the screen is invalidated which would cause infinite recursion, resulting in blowing your stack.

Try doing it from somewhere else that is not called by OnDraw().


Adrian
Feb 20 '07 #2

Banfa
Expert Mod 5K+
P: 8,916
Hi as I read it you do not want to call InvalidateRect in OnDraw but you want access to the rectangle that InvalidateRect was called with.

If this is the case then it is possible, but first you need to understand how the underlying windows messages work a bit (MFC is just a wrapper for the standard way windows works).

When a WM_PAINT message is received you have to call BeginPaint which returns you an HDC (handle to a device context) and populates a PAINTSTRUCTURE object. Then you have to call EndPaint when you have finished. The PAINTSTRUCTURE contains a member rcPaint which is the region of the screen that it is being redrawn.

In MFC this is enbodied in the OnPaint handler (internal to CView) which instantiates a CPaintDC object, this subclasses CDC and automatically calls BeginPaint and EndPaint. A pointer to this class is passed to OnDraw (the handler in you code probably) via a CDC pointer (CDC *).

Now here is the tricky bit because OnDraw is not only used for redrawwing the screen, it is also used for printing and when OnDraw is called for a printer the CDC pointer points to a CDC object not a CPaintDC object.

So what you need to do is in OnDraw verify that you have a pointer to a CPaintDC, you can do this using the member function IsKindOf which is inherited from CObject. If it is a CPaintDC then you can access the PAINTSTRUCTURE via the member m_ps and then access the area being redrawn through rcPaint.

However the complications do not stop there, unfortuneately. If there has only been 1 call to InvalidateRect since the last OnDraw then the rcPaint rectangle will be the same as the data passed to InvalidateRect. However WM_PAINT messages are low priority and are only handled if there are no other messages in the applications input queue of a higher priority (which is just about all other messages) so it is possible that there has been 2 calls to InvalidateRect since the last call to OnDraw.

If there have been 2 or more calls to InvalidateRect (or any other Invalidate... function) since the last call to OnDraw then rcPaint is not the rectangle that was passed to InvalidateRect but smallest rectangle containing the union of all areas invalidated. It is however the area of the screen being redrawn which is I suspect what you want.
Feb 20 '07 #3

AdrianH
Expert 100+
P: 1,251
If there have been 2 or more calls to InvalidateRect (or any other Invalidate... function) since the last call to OnDraw then rcPaint is not the rectangle that was passed to InvalidateRect but smallest rectangle containing the union of all areas invalidated. It is however the area of the screen being redrawn which is I suspect what you want.
Hi Banfa,

I got everything you said except the last sentence. What do you mean by "It is however the area of the screen being redrawn"?


Adrian
Feb 20 '07 #4

Banfa
Expert Mod 5K+
P: 8,916
Sorry should have said window not screen.

The CPaintDC::m_ps.rcPaint structure (which is of type RECT) defines the area on the window that is being redrawn. In fact Windows sets the clipping region for the window so that areas out side this rectangle can not be redrawn. This may be the entire client area of the screen, for instance if Invalidate() is called in which case

CPaintDC::m_ps.rcPaint.left = 0
CPaintDC::m_ps.rcPaint.top = 0
CPaintDC::m_ps.rcPaint.right = client area width
CPaintDC::m_ps.rcPaint.bottom = client area height

However if you called InvalidateRect with RECT(10, 20, 300, 400) it would be

CPaintDC::m_ps.rcPaint.left = 10
CPaintDC::m_ps.rcPaint.top = 20
CPaintDC::m_ps.rcPaint.right = 300
CPaintDC::m_ps.rcPaint.bottom = 400

and if you called InvalidateRect twice with RECT(10, 20, 300, 400) and RECT(340, 200, 600, 500) it would be the smallest rectangle that contains the union of these 2 areas or

CPaintDC::m_ps.rcPaint.left = 10
CPaintDC::m_ps.rcPaint.top = 20
CPaintDC::m_ps.rcPaint.right = 600
CPaintDC::m_ps.rcPaint.bottom = 500

The point is that drawing to the screen is rather slow compared to everything else, Windows compensates for this by

1. Making most messages take priority over screen redraw messages so that redrawing only tends to take place if the program is idle (which most programs are most of the time).

2. Only redrawing the area of the window that is actually required rather than redrawning the whole window.

Imagine you have a programme that displays a circle that is a lot smaller than the window traveling from left to right on the window with a complex bitmap in the background. At each step the previous image must be erased and the circle displayed in a new location.

If you have to erase the entire screen and redraw the entire screen it will take a lot longer than if you just erase the current location and new location and redraw the image in the new location.


So Windows only redraws those parts of the window that are marked as needing redrawing and it passes that information via the PAINTSTRUCTURE so the OnDraw function can be written efficiently and not redraw those bits of the screen that are not being updated.

Does that make it clearer?
Feb 20 '07 #5

AdrianH
Expert 100+
P: 1,251
Sorry should have said window not screen.
Ahh, that makes more sense.
Does that make it clearer?
Hey, I've programmed in MFC before so it is clear to me. Question is, is it clear to rushiraj?

Well rushiraj, what do you think?


Adrian
Feb 21 '07 #6

Post your reply

Sign in to post your reply or Sign up for a free account.