From: Andrew G. <ag...@em...> - 2001-10-18 18:15:30
|
On 12 Oct 2001 14:31:33 -0700, Mark Wrenn wrote: > +----------------+ > | Back Win | > | | > | | > | | > | +----------------+ > | | A | | > | | | | > +----------|-----+ | > | | > | | > | Front Win | > +----------------+ > > When clicking to Back Win I only want to repaint the A area. > > Is this a problem with the way I am using SetClip()? Who maintains the > coordinates of the A area? > > Sample code anyone? Short answer ------------ Somewhere (hopefully not everywhere) you're probably doing something like this: MyPane::DoDraw(const ZDC& inDC, const ZDCRgn& inBoundsRgn) { ZDC localDC(inDC); localDC.SetClip(ZRect(0, 0, 100, 200)); ... } When the SetClip call should be: localDC.SetClip(localDC.GetClip() & ZRect(0, 0, 100, 200)); which will tighten the clip down to include only those pixels already in the clip *and* in the rectangle (0, 0, 100, 200). Who owns the A area? -------------------- In short, the invalid region for a window is owned by ZOSWindow. This is an implementation detail of ZooLib as it stands, all panes requiring only that they are ultimately owned by a ZFakeWindow derivative, and the only released implementation of the ZFakeWindow protocol is ZWindow, which wraps a ZOSWindow. So for most purposes you should think in terms of the invalid region being owned by ZWindow. The invalid region is modified in four ways, two that augment it and two that clear it. Augmenting the invalid region: 1) OS-level notifications (WM_PAINT messages, updateEvt events, and Expose/GraphicsExpose events) add pixels to the invalid region. These events are received by the ZOSApp_XXX event loop and are passed to the affected ZOSWindow_XXX, which unions them into the invalid region, invalidates the effective clip region of an extant ZDCCanvas_XXX_Window and posts a message to itself if the region was previously empty. 2) Explicit calls to ZFakeWindow::InvalidateRegion, usually invoked by ZWindow::InvalidateWindowRegion which is in turn usually invoked by ZSubPane::Invalidate. Clearing the invalid region: 1) When the ZOSWindow_Std::DispatchMessageImp receives a "zoolib:Invalid" message it checks its invalid region and if not empty copies it into a temp variable, empties it, sets up a ZDC with the invalid region as the clip and calls its owner's OwnerUpdate method passing the ZDC. As the owner of a ZOSWindow is usually a ZWindow you should look at ZWindow::OwnerUpdate to see how things work. Note that we clear the invalid region *before* calling OwnerUpdate, so if in the process of drawing we end up calling Invalidate we won't lose that invalidation (not that you should do so, but it does work). 2) A call to ZOSWindow::UpdateNow, usually invoked by ZWindow::UpdateWindowNow, itself usually invoked by ZSubPane::Update, will do all the work that the receipt of a "zoolib:Invalid" message does, including calling any affected panes' DoDraw methods. It should be noted that there is _no_ way to query the invalid region for a window. Each window has a dedicated thread which handles its messages, so a window can be quite lax about taking up CPU time without making other windows in the same application unresponsive. The OS itself may also multi-process preemptively, so other applications can be showing, hiding and resizing windows whilst the code for a ZooLib application's window is executing. Those other window operations in the same app or in the machine as a whole can cause changes to the invalid region for a window _at any time_, so querying and then acting on an invalid region will have problems that show up from time to time which would be difficult or impossible to manage. The behavior of a ZDC attached to a ZooLib window takes all this into account. As pixels are added to a window's invalid region they are removed from the window's effective clip region, so your code can't draw to them. Even if those pixels are removed whilst you're in the middle of drawing operations they will be cleanly locked out on your behalf, and an update message will be delivered to your window at the next opportunity. Blitting pixels from place to place within a window also takes account of the invalid region -- blitting which tries to copy invalid pixels will not copy them but will instead augment the invalid region. The ideal model --------------- ZooLib is most supportive of a model where the pixels in a window are considered to be a cached version of a rendering of an application's internal state. That is, they reflect a subset of the application's state at some time, potentially in the distant past. For the window to accurately reflect a fairly current state it needs to be managed as any other cache is managed -- changes to the state should determine which pixels are affected by those changes and should invalidate them. If you have code that makes changes that must be reflected in the window immediately, say because you have a sequence of images to show that should not be interrupted by user actions, simply change the state, invalidate the relevant pixels then call ZSubPane::Update (or ZWindow::UpdateWindowNow), change the state, invalidate, update etc... Andrew Green |