signature=66ee059bbdb9aa026cf4962f2fe679a7,a00896.html

Win32k: update.c 文件参考
Win32k

/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */

var searchBox = new SearchBox("searchBox", "search",false,'搜索');

/* @license-end */

/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */

$(function() {

initMenu('',true,false,'search.php','搜索');

$(document).ready(function() { init_search(); });

});

/* @license-end */

class="ui-resizable-handle">

/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */

$(document).ready(function(){initNavTree('a00896.html',''); initResizable(); });

/* @license-end */

οnmοuseοver="return searchBox.OnSearchSelectShow()"

οnmοuseοut="return searchBox.OnSearchSelectHide()"

οnkeydοwn="return searchBox.OnSearchSelectKey(event)">

name="MSearchResults" id="MSearchResults">

update.c 文件参考
#include "precomp.h"

浏览源代码.

宏定义

#define UW_ENUMCHILDREN   0x0001
 
#define UW_RECURSED   0x0004
 
#define RIR_OUTSIDE   0
 
#define RIR_INTERSECT   1
 
#define RIR_INSIDE   2
 
#define RDW_IGNOREUPDATEDIRTY   0x8000
 
#define RECTINREGION_BUG
 

函数

BOOL xxxInvalidateRect (PWND pwnd, LPRECT lprcInvalid, BOOL fErase)
 
BOOL xxxValidateRect (PWND pwnd, LPRECT lprcValid)
 
BOOL xxxInvalidateRgn (PWND pwnd, HRGN hrgnInvalid, BOOL fErase)
 
BOOL xxxValidateRgn (PWND pwnd, HRGN hrgnValid)
 
UINT SmartRectInRegion (HRGN hrgn, LPRECT lprc)
 
VOID PixieHack (PWND pwnd, LPRECT prcBounds)
 
BOOL xxxRedrawWindow (PWND pwnd, LPRECT lprcUpdate, HRGN hrgnUpdate, DWORD flags)
 
BOOL InternalInvalidate2 (PWND pwnd, HRGN hrgn, HRGN hrgnSubtract, LPRECT prcParents, DWORD flags)
 
VOID InternalInvalidate3 (PWND pwnd, HRGN hrgn, DWORD flags)
 
BOOL ValidateParents (PWND pwnd, BOOL fRecurse)
 
BOOL xxxUpdateWindow2 (PWND pwnd, DWORD flags)
 
BOOL xxxInternalUpdateWindow (PWND pwnd, DWORD flags)
 
VOID xxxInternalInvalidate (PWND pwnd, HRGN hrgnUpdate, DWORD flags)
 
BOOL xxxUpdateWindow (PWND pwnd)
 
int _ExcludeUpdateRgn (HDC hdc, PWND pwnd)
 
BOOL xxxGetUpdateRect (PWND pwnd, LPRECT lprc, BOOL fErase)
 
int xxxGetUpdateRgn (PWND pwnd, HRGN hrgn, BOOL fErase)
 
BOOL IntersectWithParents (PWND pwnd, LPRECT lprc)
 

宏定义说明

◆ RDW_IGNOREUPDATEDIRTY

#define RDW_IGNOREUPDATEDIRTY   0x8000

在文件 update.c28 行定义.

◆ RECTINREGION_BUG

#define RECTINREGION_BUG

◆ RIR_INSIDE

#define RIR_INSIDE   2

在文件 update.c26 行定义.

◆ RIR_INTERSECT

#define RIR_INTERSECT   1

在文件 update.c25 行定义.

◆ RIR_OUTSIDE

#define RIR_OUTSIDE   0

在文件 update.c24 行定义.

◆ UW_ENUMCHILDREN

#define UW_ENUMCHILDREN   0x0001

在文件 update.c21 行定义.

◆ UW_RECURSED

#define UW_RECURSED   0x0004

在文件 update.c22 行定义.

函数说明

◆ _ExcludeUpdateRgn()

int _ExcludeUpdateRgn (HDC hdc,
PWND pwnd 
)

在文件 update.c1398 行定义.

1401 {
1402  POINT pt;
1403 
1404  if (pwnd-> hrgnUpdate == NULL) {
1405 
1406  RECT rc;
1407 
1408  /*
1409  * Pass FALSE for fXForm since &rc isn't used.
1410  */
1411  return GreGetClipBox(hdc, &rc, FALSE);
1412 
1413  } else if (pwnd-> hrgnUpdate == MAXREGION) {
1414 
1415  return GreIntersectClipRect(hdc, 0, 0, 0, 0);
1416 
1417  } else {
1418 
1419  /*
1420  * If no clip rgn exists, then subtract from a device-sized clip rgn.
1421  * (GetClipRgn returns clip rgn in screen coordinates).
1422  */
1423  GreGetDCOrg(hdc, &pt);
1424  if (GreGetRandomRgn(hdc, hrgnInv1, 1) != 1) {
1425 
1426  GreSetRectRgn( hrgnInv1,
1427  0,
1428  0,
1429  gpDispInfo-> rcScreen.right - gpDispInfo-> rcScreen.left,
1430  gpDispInfo-> rcScreen.bottom - gpDispInfo-> rcScreen.top);
1431 
1432  } else {
1433 
1434  /*
1435  * Gets returned in dc coords - translate to screen.
1436  */
1437  GreOffsetRgn( hrgnInv1, pt.x, pt.y);
1438  }
1439 
1440  SubtractRgn( hrgnInv1, hrgnInv1, pwnd-> hrgnUpdate);
1441 
1442  /*
1443  * Map to dc coords before select
1444  */
1445  GreOffsetRgn( hrgnInv1, -pt.x, -pt.y);
1446 
1447  return GreExtSelectClipRgn(hdc, hrgnInv1, RGN_COPY);
1448  }
1449 }

引用了 gpDispInfo, hrgnInv1, tagWND::hrgnUpdate , 以及 tagDISPLAYINFO::rcScreen.

被这些函数引用 NtUserExcludeUpdateRgn() , 以及 UT_InvertCaret().

◆ InternalInvalidate2()

BOOL InternalInvalidate2 (PWND pwnd,
HRGN hrgn,
HRGN hrgnSubtract,
LPRECT prcParents,
DWORD flags 
)

在文件 update.c369 行定义.

375 {
376  /*
377  * NOTE: Uses hrgnInv2
378  */
379  RECT rcOurShare;
380  DWORD flagsChildren;
381  PWND pwndT;
382 
383  /*
384  * This routine is called recursively down the parent/child chain.
385  * Remember if on the way one of the windows has a clipping region.
386  * This info is used later on to optimize out a loop in the common
387  * case.
388  */
389  if (pwnd-> hrgnClip != NULL)
390  flags |= RDW_HASWINDOWRGN;
391 
392  /*
393  * If we're invalidating, we only want to deal with the part of
394  * our window rectangle that intersects our parents.
395  * This way, we don't end up validating or invalidating more than our
396  * fair share. If we're completely obscured by our parents, then there is
397  * nothing to do.
398  *
399  * We don't perform this intersection if we're validating, because there
400  * are cases where a child and its update region may exist but be obscured
401  * by parents, and we want to make sure validation will work in these
402  * cases. ScrollWindow() can cause this when children are offset, as can
403  * various 3.0 compatibility hacks.
404  *
405  * If we recurse, make sure our children subtract themselves off.
406  */
407  flagsChildren = flags | RDW_SUBTRACTSELF;
408  rcOurShare = pwnd-> rcWindow;
409 
410  if (flags & RDW_INVALIDATE) {
411 
412  if (! IntersectRect(&rcOurShare, &rcOurShare, prcParents)) {
413 
414  /*
415  * BACKWARD COMPATIBILITY HACK: If hrgn is (HRGN)1, we need to
416  * invalidate ALL child windows, even if they're not visible. This
417  * is a bummer, because it'll result in all sorts of repaints that
418  * aren't necessary.
419  *
420  * Various apps, including WordStar for Windows and WaveEdit,
421  * depend on this behavior. Here's how WaveEdit relies on this: it
422  * has a CS_HDREDRAW | CS_VREDRAW window, that moves its children
423  * around with MoveWindow( ..., fRedraw = FALSE). The windows
424  * not part of the new client area didn't get invalidated.
425  */
426  if (!TestWF(pwnd, WFWIN31COMPAT) && (hrgn == MAXREGION)) {
427 
428  /*
429  * For purposes of hit-testing, our share is our window
430  * rectangle. However, we don't want to diddle the region
431  * passed to us, because by rights we're really clipped out!
432  */
433  flags &= ~RDW_SUBTRACTSELF;
434  flagsChildren &= ~RDW_SUBTRACTSELF;
435 
436  } else {
437  return TRUE;
438  }
439  }
440 
441  /*
442  * If our window rect doesn't intersect the valid/invalid region,
443  * nothing further to do.
444  */
445  if (hrgn > MAXREGION) {
446 
447  switch ( SmartRectInRegion(hrgn, &rcOurShare)) {
448  case RIR_OUTSIDE:
449  return TRUE;
450 
451  case RIR_INTERSECT:
452 
453  /*
454  * The update region can be within the window rect but not
455  * touch the window region; in this case we don't want this
456  * update region to be distributed to this window. If this
457  * is the case, return TRUE as if RIR_OUTSIDE.
458  *
459  * If RDW_HASWINDOWRGN is set, either this window or
460  * one of its parents has a window clipping region. This
461  * flag is just an optimization so that this loop isn't
462  * executed all the time.
463  *
464  * A future optimization may be to calculate this parent
465  * clipped region as part of recursion like prcParents is
466  * calculated. It is not super important though because this
467  * case rarely happens (a window with a region), and even
468  * more rare, a regional window that is a child of a regional
469  * window parent.
470  */
471  if (flags & RDW_HASWINDOWRGN) {
472 
473  /*
474  * Clip to the window's clipping region and parents!
475  * If we don't clip to parents, we may get a case where
476  * a child clips out some update region that was meant to
477  * go to a sibling of the parent.
478  */
479  GreSetRectRgn( hrgnInv2,
480  rcOurShare.left,
481  rcOurShare.top,
482  rcOurShare.right,
483  rcOurShare.bottom);
484 
485  for (pwndT = pwnd; pwndT != NULL; pwndT = pwndT-> spwndParent) {
486 
487  if (pwndT-> hrgnClip != NULL) {
488 
489  /*
490  * An error at this stage would possibly result
491  * in more being subtracted out of the clipping
492  * region that we'd like.
493  */
494  IntersectRgn( hrgnInv2, hrgnInv2, pwndT-> hrgnClip);
495  }
496  }
497 
498  if (IntersectRgn( hrgnInv2, hrgnInv2, hrgn) == NULLREGION)
499  return TRUE;
500  }
501  break;
502 
503  case RIR_INSIDE:
504  /*
505  * If the rectangle is completely within hrgn, then we can use
506  * MAXREGION, which is much faster and easier to deal with.
507  *
508  * COMPAT HACK: There are some apps (PP, MSDRAW) that depend
509  * on some weirdities of the 3.0 GetUpdateRect in order to
510  * paint properly. Since this stuff hinges on whether the
511  * update region is 1 or a real region, we need to simulate
512  * when 3.0 would generate a HRGN(1) update region. The
513  * following optimization was not made in 3.0, so we yank it
514  * in 3.1 for these apps. (win31 bugs 8235,10380)
515  */
516  if (!( GetAppCompatFlags(GETPTI(pwnd)) & GACF_NOHRGN1))
517  hrgn = MAXREGION;
518  break;
519  }
520  }
521  }
522 
523  /*
524  * Go diddle the update region (BEFORE our clipped children have
525  * done their thing to hrgnSubtract)
526  */
527  if (!TestWF(pwnd, WFCLIPCHILDREN))
528  InternalInvalidate3(pwnd, hrgn, flags);
529 
530  /*
531  * If this is a GACF_ALWAYSSENDNCPAINT app, take care of it...
532  */
533  if (TestWF(pwnd, WFALWAYSSENDNCPAINT))
534  PixieHack(pwnd, &rcOurShare);
535 
536  /*
537  * Recurse on our children if necessary.
538  *
539  * By default, our children are enumerated if we are not CLIPCHILDREN.
540  * Don't bother with children if we're minimized.
541  */
542  if ((pwnd-> spwndChild != NULL) &&
543  !TestWF(pwnd, WFMINIMIZED) &&
544  !(flags & RDW_NOCHILDREN) &&
545  ((flags & RDW_ALLCHILDREN) || !TestWF(pwnd, WFCLIPCHILDREN))) {
546 
547  RECT rcChildrenShare;
548  PWND pwndChild;
549 
550  /*
551  * If we're invalidating, framing, or erasing,
552  * make sure our children erase and frame themselves.
553  * Also, tell children to subtract themselves from hrgnSubtract.
554  */
555  if (flags & (RDW_INVALIDATE))
556  flagsChildren |= RDW_ERASE | RDW_FRAME;
557 
558  /*
559  * Our children are clipped to our client rect, so reflect
560  * that in the rectangle we give them.
561  */
562  if ( IntersectRect(&rcChildrenShare, &rcOurShare, &pwnd-> rcClient) ||
563  (!TestWF(pwnd, WFWIN31COMPAT) && (hrgn == MAXREGION))) {
564 
565  for (pwndChild = pwnd-> spwndChild; pwndChild != NULL;
566  pwndChild = pwndChild-> spwndNext) {
567 
568  if (!TestWF(pwndChild, WFVISIBLE))
569  continue;
570 
571  if (! InternalInvalidate2(pwndChild,
572  hrgn,
573  hrgnSubtract,
574  &rcChildrenShare,
575  flagsChildren)) {
576 
577  /*
578  * The children swallowed the region:
579  * If there are no update region related things
580  * to do then we can just return with FALSE
581  */
582  if (!(flags & (RDW_INTERNALPAINT | RDW_NOINTERNALPAINT)))
583  return FALSE;
584 
585  /*
586  * We have to enumerate the rest of the children because
587  * one of the RDW_NO/INTERNALPAINT bits is set. Since
588  * there's no longer any update region to worry about,
589  * strip out the update region bits from the parent
590  * and child fiags. Also, tell the children not to
591  * bother subtracting themselves from the region.
592  */
593  flags &= ~(RDW_INVALIDATE |
594  RDW_ERASE |
595  RDW_FRAME |
596  RDW_VALIDATE |
597  RDW_NOERASE |
598  RDW_NOFRAME);
599 
600  flagsChildren &= ~(RDW_INVALIDATE |
601  RDW_ERASE |
602  RDW_FRAME |
603  RDW_VALIDATE |
604  RDW_NOERASE |
605  RDW_NOFRAME |
606  RDW_SUBTRACTSELF);
607  }
608  }
609  }
610  }
611 
612  /*
613  * Go diddle the update region (AFTER our clipped children have
614  * done their thing to hrgnSubtract)
615  */
616  if (TestWF(pwnd, WFCLIPCHILDREN))
617  InternalInvalidate3(pwnd, hrgn, flags);
618 
619  /*
620  * If we're invalidating and we're supposed to,
621  * try to subtract off our window area from the region.
622  *
623  * This way our parent and our siblings below us will not
624  * get any update region for areas that don't need one.
625  */
626  if (flags & RDW_SUBTRACTSELF) {
627 
628  /*
629  * Subtract our visible region from the update rgn only if:
630  * a) we're not a transparent window
631  * b) we are clipsiblings
632  * c) we're validating OR our parent is clipchildren.
633  *
634  * The check for validation is a backward-compatibility hack: this
635  * is what 3.0 did, so this is what we do here.
636  *
637  * BACKWARD COMPATIBILITY HACK
638  *
639  * In 3.0, we subtracted this window from the update rgn if it
640  * was clipsiblings, even if the parent was not clipchildren.
641  * This causes a compatibility problem for Lotus Notes 3.1: it
642  * has a combobox dropdown in a dialog that is a WS_CLIPSIBLING
643  * sibling of the other dialog controls, which are not WS_CLIPSIBLINGs.
644  * The dialog is not WS_CLIPCHILDREN. What happens is that a listbox
645  * underneath the dropdown also gets a paint msg (since we didn't
646  * do this subtraction), and, since it's not CLIPSIBLINGS, it
647  * obliterates the dropdown.
648  *
649  * This is a very obscure difference, and it's too late in the
650  * project to make this change now, so we're leaving the code as is
651  * and using a compatibility hack to enable the 3.0-compatible
652  * behavior. It's quite likely that this code works the way it does
653  * for other compatibility reasons. Sigh (neilk).
654  */
655  if (!TestWF(pwnd, WEFTRANSPARENT) &&
656  TestWF(pwnd, WFCLIPSIBLINGS) &&
657  ((flags & RDW_VALIDATE) ||
658  ((pwnd-> spwndParent != NULL) &&
659  (TestWF(pwnd-> spwndParent, WFCLIPCHILDREN) ||
660  ( GetAppCompatFlags(GETPTI(pwnd)) & GACF_SUBTRACTCLIPSIBS))))) {
661 
662  /*
663  * Intersect with our visible area.
664  *
665  * Don't worry about errors: an error will result in more, not less
666  * area being invalidated, which is okay.
667  */
668  GreSetRectRgn( hrgnInv2,
669  rcOurShare.left,
670  rcOurShare.top,
671  rcOurShare.right,
672  rcOurShare.bottom);
673 
674  /*
675  * If RDW_HASWINDOWRGN is set, either this window or
676  * one of its parents has a window clipping region. This
677  * flag is just an optimization so that this loop isn't
678  * executed all the time.
679  */
680  if (flags & RDW_HASWINDOWRGN) {
681 
682  /*
683  * Clip to the window's clipping region and parents!
684  * If we don't clip to parents, we may get a case where
685  * a child clips out some update region that was meant to
686  * go to a sibling of the parent.
687  */
688  for (pwndT = pwnd; pwndT != NULL; pwndT = pwndT-> spwndParent) {
689 
690  if (pwndT-> hrgnClip != NULL) {
691 
692  /*
693  * An error at this stage would possibly result in more
694  * being subtracted out of the clipping region that
695  * we'd like.
696  */
697  IntersectRgn( hrgnInv2, hrgnInv2, pwndT-> hrgnClip);
698  }
699  }
700  }
701 
702 
703  #if 1
704  /*
705  * TEMP HACK!!! RE-ENABLE this code when regions work again
706  */
707  if (SubtractRgn(hrgnSubtract, hrgnSubtract, hrgnInv2) == NULLREGION)
708  return FALSE;
709  #else
710  {
711  DWORD iRet;
712 
713  iRet = SubtractRgn(hrgnSubtract, hrgnSubtract, hrgnInv2);
714 
715  if (iRet == NULLREGION)
716  return FALSE;
717 
718  if (iRet == SIMPLEREGION) {
719  RECT rcSub;
720  GreGetRgnBox(hrgnSubtract, &rcSub);
721  if (rcSub.left > rcSub.right)
722  return FALSE;
723  }
724  }
725  #endif
726 
727 
728 
729  }
730  }
731 
732  return TRUE;
733 }

引用了 DWORD, GetAppCompatFlags(), tagWND::hrgnClip, hrgnInv2, InternalInvalidate3(), IntersectRect(), PixieHack(), tagWND::rcClient, tagWND::rcWindow, RIR_INSIDE, RIR_INTERSECT, RIR_OUTSIDE, SmartRectInRegion(), tagWND::spwndChild, tagWND::spwndNext , 以及 tagWND::spwndParent.

被这些函数引用 ValidateParents() , 以及 xxxInternalInvalidate().

◆ InternalInvalidate3()

VOID InternalInvalidate3 (PWND pwnd,
HRGN hrgn,
DWORD flags 
)

在文件 update.c743 行定义.

747 {
748  BOOL fNeededPaint;
749 
750  fNeededPaint = NEEDSPAINT(pwnd);
751 
752  if (flags & (RDW_INVALIDATE | RDW_INTERNALPAINT | RDW_ERASE | RDW_FRAME)) {
753 
754  if (flags & RDW_INTERNALPAINT)
755  SetWF(pwnd, WFINTERNALPAINT);
756 
757  if (flags & RDW_INVALIDATE) {
758 
759  /*
760  * Make sure that the NONCPAINT bit is cleared
761  * to ensure that the caption will redraw when we update.
762  */
763  ClrWF(pwnd, WFNONCPAINT);
764 
765  /*
766  * If another app is invalidating this window, then set the
767  * UPDATEDIRTY flag.
768  *
769  * Solves critical section where thread A draws, then validates,
770  * but thread B goes and invalidates before A validates.
771  * See comments later in RDW_VALIDATE code.
772  */
773  if (GETPTI(pwnd) != PtiCurrent()) {
774 
775  SetWF(pwnd, WFUPDATEDIRTY);
776 
777  /*
778  * Paint order problem, see paint.c
779  */
780  if (TestWF(pwnd, WFWMPAINTSENT)) {
781  SetWF(pwnd, WFDONTVALIDATE);
782  }
783  }
784 
785  /*
786  * BACKWARD COMPATIBILITY HACK
787  *
788  * In 3.0, InvalidateRect(pwnd, NULL, FALSE) would always
789  * clear the WFSENDERASEBKGND flag, even if it was previously
790  * set from an InvalidateRect(pwnd, NULL, TRUE). This is bogus,
791  * because it can cause you to "lose" WM_ERASEBKGND messages, but
792  * AttachMate Extra (and maybe other apps) depend on this behavior.
793  */
794  if ((hrgn == MAXREGION) && !TestWF(pwnd, WFWIN31COMPAT))
795  ClrWF(pwnd, WFSENDERASEBKGND);
796 
797  if (flags & RDW_ERASE)
798  SetWF(pwnd, WFSENDERASEBKGND);
799 
800  if ((flags & (RDW_FRAME | RDW_ERASE)) && !TestWF(pwnd, WEFTRANSPARENT))
801  SetHungFlag(pwnd, WFREDRAWIFHUNG);
802 
803  if (flags & RDW_FRAME)
804  SetWF(pwnd, WFSENDNCPAINT);
805 
806  /*
807  * If window is already completely invalidated,
808  * no need to do any further invalidation.
809  */
810  if (pwnd-> hrgnUpdate != MAXREGION) {
811 
812  if (hrgn == MAXREGION) {
813 InvalidateAll:
814  if (pwnd-> hrgnUpdate > MAXREGION)
815  GreDeleteObject(pwnd-> hrgnUpdate);
816 
817  pwnd-> hrgnUpdate = MAXREGION;
818 
819  } else {
820 
821  if (pwnd-> hrgnUpdate == NULL) {
822 
823  if (!(pwnd-> hrgnUpdate = GreCreateRectRgn(0, 0, 0, 0)))
824  goto InvalidateAll;
825 
826  if (CopyRgn(pwnd-> hrgnUpdate, hrgn) == ERROR)
827  goto InvalidateAll;
828 
829  } else { // pwnd->hrgnUpdate is a region
830 
831  if (UnionRgn(pwnd-> hrgnUpdate,
832  pwnd-> hrgnUpdate,
833  hrgn) == ERROR) {
834 
835  goto InvalidateAll;
836  }
837  }
838 
839  GreSetRegionOwner(pwnd-> hrgnUpdate, OBJECT_OWNER_PUBLIC);
840  }
841  }
842  }
843 
844  if (!fNeededPaint && NEEDSPAINT(pwnd))
845  IncPaintCount(pwnd);
846 
847  } else if (flags & (RDW_VALIDATE | RDW_NOINTERNALPAINT | RDW_NOERASE | RDW_NOFRAME)) {
848 
849  /*
850  * Validation:
851  *
852  * Do not allow validation if this window has been invalidated from
853  * another process - because this window may be validating just
854  * after another process invalidated, thereby validating invalid
855  * bits.
856  *
857  * Sometimes applications draw stuff, then validate what they drew.
858  * If another app invalidated some area during the drawing operation,
859  * then it will need another paint message.
860  *
861  * This wouldn't be necessary if people validated BEFORE they drew.
862  */
863  if (TestWF(pwnd, WFUPDATEDIRTY) && !(flags & RDW_IGNOREUPDATEDIRTY))
864  return;
865 
866  if (flags & RDW_NOINTERNALPAINT)
867  ClrWF(pwnd, WFINTERNALPAINT);
868 
869  if (flags & RDW_VALIDATE) {
870 
871  if (flags & RDW_NOERASE)
872  ClrWF(pwnd, WFSENDERASEBKGND);
873 
874  if (flags & RDW_NOFRAME) {
875  ClrWF(pwnd, WFSENDNCPAINT);
876  ClrWF(pwnd, WFPIXIEHACK);
877  }
878 
879  if (flags & (RDW_NOERASE | RDW_NOFRAME))
880  ClearHungFlag(pwnd, WFREDRAWIFHUNG);
881 
882  if (pwnd-> hrgnUpdate != NULL) {
883 
884  /*
885  * If WFSENDNCPAINT is set, then all or part of the
886  * window border still needs to be drawn. This means
887  * that we must subtract off the client rectangle only.
888  * Convert MAXREGION to the client region.
889  */
890  if (TestWF(pwnd, WFSENDNCPAINT) && (hrgn == MAXREGION)) {
891  hrgn = hrgnInv2;
892  CalcWindowRgn(pwnd, hrgn, TRUE);
893  }
894 
895  if (hrgn == MAXREGION) {
896 ValidateAll:
897 
898  /*
899  * We're validating the entire window. Just
900  * blow away the update region.
901  */
902  if (pwnd-> hrgnUpdate > MAXREGION)
903  GreDeleteObject(pwnd-> hrgnUpdate);
904 
905  pwnd-> hrgnUpdate = (HRGN)NULL;
906 
907  /*
908  * No need to erase the background...
909  */
910  ClrWF(pwnd, WFSENDERASEBKGND);
911  ClearHungFlag(pwnd, WFREDRAWIFHUNG);
912 
913  } else {
914 
915  /*
916  * Subtracting some region from pwnd->hrgnUpdate.
917  * Be sure pwnd->hrgnUpdate is a real region.
918  */
919  if (pwnd-> hrgnUpdate == MAXREGION) {
920 
921  /*
922  * If the WFSENDNCPAINT bit is set,
923  * the update region must include the entire window
924  * area. Otherwise it includes only the client.
925  */
926  pwnd-> hrgnUpdate = GreCreateRectRgn(0, 0, 0, 0);
927 
928  /*
929  * If the creation failed, punt by
930  * invalidating the entire window.
931  */
932  if (pwnd-> hrgnUpdate == NULL)
933  goto InvalidateAll;
934 
935  GreSetRegionOwner(pwnd-> hrgnUpdate, OBJECT_OWNER_PUBLIC);
936 
937  if ( CalcWindowRgn(pwnd,
938  pwnd-> hrgnUpdate,
939  !(TestWF(pwnd, WFSENDNCPAINT))) == ERROR) {
940 
941  goto InvalidateAll;
942  }
943  }
944 
945  /*
946  * Subtract off the region. If we get an error,
947  * punt by invalidating everything. If the
948  * region becomes empty, then validate everything.
949  */
950  switch (SubtractRgn(pwnd-> hrgnUpdate,
951  pwnd-> hrgnUpdate,
952  hrgn)) {
953  case ERROR:
954  goto InvalidateAll;
955 
956  case NULLREGION:
957  goto ValidateAll;
958  }
959  }
960  }
961  }
962 
963  if (fNeededPaint && !NEEDSPAINT(pwnd))
964  DecPaintCount(pwnd);
965  }
966 }

引用了 CalcWindowRgn(), ClearHungFlag(), DecPaintCount(), hrgnInv2, tagWND::hrgnUpdate, IncPaintCount(), PtiCurrent(), RDW_IGNOREUPDATEDIRTY , 以及 SetHungFlag().

被这些函数引用 _EndPaint() , 以及 InternalInvalidate2().

◆ IntersectWithParents()

BOOL IntersectWithParents (PWND pwnd,
LPRECT lprc 
)

在文件 update.c1700 行定义.

1703 {
1704  while ((pwnd = pwnd-> spwndParent) != NULL) {
1705 
1706  if (!TestWF(pwnd, WFVISIBLE) || TestWF(pwnd, WFMINIMIZED))
1707  return FALSE;
1708 
1709  if (! IntersectRect(lprc, lprc, &pwnd-> rcClient))
1710  return FALSE;
1711  }
1712 
1713  return TRUE;
1714 }

引用了 IntersectRect(), tagWND::rcClient , 以及 tagWND::spwndParent.

被这些函数引用 SpbTransfer(), ValidateParents(), xxxGetUpdateRect(), xxxGetUpdateRgn() , 以及 xxxInternalInvalidate().

◆ PixieHack()

VOID PixieHack (PWND pwnd,
LPRECT prcBounds 
)

在文件 update.c243 行定义.

246 {
247  /*
248  * If a child intersects the update region, and it isn't already
249  * getting an NCPAINT, then make sure it gets one later.
250  *
251  * Don't apply this hack to top level windows.
252  */
253  if ((pwnd != _GetDesktopWindow()) &&
254  TestWF(pwnd, WFCLIPCHILDREN) &&
255  !TestWF(pwnd, WFMINIMIZED)) {
256 
257  RECT rc;
258 
259  for (pwnd = pwnd-> spwndChild; pwnd; pwnd = pwnd-> spwndNext) {
260 
261  /*
262  * If the window isn't already getting an NCPAINT message,
263  * and it has a caption, and it's inside the bounding rect,
264  * make sure it gets a WM_NCPAINT with wParam == MAXREGION.
265  */
266  if (!TestWF(pwnd, WFSENDNCPAINT) &&
267  (TestWF(pwnd, WFBORDERMASK) == LOBYTE(WFCAPTION)) &&
268  IntersectRect(&rc, prcBounds, &pwnd-> rcWindow)) {
269 
270  /*
271  * Sync paint count is incremented when
272  * (senderasebkgnd | sendncpaint) goes from 0 to != 0.
273  * (should make a routine out of this!)
274  */
275  SetWF(pwnd, WFSENDNCPAINT);
276 
277  /*
278  * Force MAXREGION clip rgn.
279  */
280  SetWF(pwnd, WFPIXIEHACK);
281  }
282  }
283  }
284 }

引用了 _GetDesktopWindow(), IntersectRect(), tagWND::rcWindow, tagWND::spwndChild , 以及 tagWND::spwndNext.

被这些函数引用 InternalInvalidate2().

◆ SmartRectInRegion()

UINT SmartRectInRegion (HRGN hrgn,
LPRECT lprc 
)

在文件 update.c159 行定义.

162 {
163  RECT rc;
164 
165  if (!GreRectInRegion(hrgn, lprc))
166  return RIR_OUTSIDE;
167 
168  /*
169  * Algorithm: if the intersection of hrgn and *lprc is the
170  * same as *lprc, then *lprc is completely within hrgn.
171  *
172  * If the region is a rectangular one, then do it the easy way.
173  */
174  if (GreGetRgnBox(hrgn, &rc) == SIMPLEREGION) {
175 
176  if (! IntersectRect(&rc, &rc, lprc))
177  return RIR_OUTSIDE;
178 
179  if ( EqualRect(lprc, &rc))
180  return RIR_INSIDE;
181 
182  } else {
183 
184  GreSetRectRgn( hrgnInv2,
185  lprc->left,
186  lprc->top,
187  lprc->right,
188  lprc->bottom);
189 
190  switch (IntersectRgn( hrgnInv2, hrgnInv2, hrgn)) {
191 
192  case SIMPLEREGION:
193  GreGetRgnBox( hrgnInv2, &rc);
194  if ( EqualRect(lprc, &rc))
195  return RIR_INSIDE;
196  break;
197 
198  #define RECTINREGION_BUG
199  #ifdef RECTINREGION_BUG
200 
201  /*
202  * NOTE: RectInRegion has a BUG, where it sometimes returns TRUE
203  * even if the rectangles of a region touch only on the edges
204  * with no overlap. This will result in an empty region after
205  * the combination above.
206  */
207  case NULLREGION:
208  return RIR_OUTSIDE;
209  break;
210  #endif
211 
212  default:
213  break;
214  }
215  }
216 
217  return RIR_INTERSECT;
218 }

引用了 EqualRect(), hrgnInv2, IntersectRect(), RIR_INSIDE, RIR_INTERSECT , 以及 RIR_OUTSIDE.

被这些函数引用 InternalInvalidate2().

◆ ValidateParents()

BOOL ValidateParents (PWND pwnd,
BOOL fRecurse 
)

在文件 update.c984 行定义.

987 {
988  RECT rcParents;
989  RECT rc;
990  PWND pwndParent = pwnd;
991  BOOL fInit = FALSE;
992 
993  /*
994  * This is checking whether we are in an in-between state, just before
995  * a WM_SYNCPAINT is about to arrive. If not, then ValidateParents()
996  * needs to work like it did in Win 3.1.
997  */
998  while (TestWF(pwndParent, WFCHILD))
999  pwndParent = pwndParent-> spwndParent;
1000 
1001  if (!TestWF(pwndParent, WFSYNCPAINTPENDING))
1002  fRecurse = FALSE;
1003 
1004  pwndParent = pwnd;
1005 
1006  while ((pwndParent = pwndParent-> spwndParent) != NULL) {
1007 
1008  /*
1009  * Stop when we find a clipchildren parent
1010  */
1011  if (TestWF(pwndParent, WFCLIPCHILDREN))
1012  break;
1013 
1014  /*
1015  * Subtract the region from this parent's update region,
1016  * if it has one.
1017  */
1018  if (pwndParent-> hrgnUpdate != NULL) {
1019  if (fRecurse) {
1020  return FALSE;
1021  }
1022  if (!fInit) {
1023  fInit = TRUE;
1024 
1025  /*
1026  * Do initial setup. If our window rectangle is
1027  * completely obscured, get out.
1028  */
1029  rc = pwnd-> rcWindow;
1030  if (! IntersectWithParents(pwnd, &rc))
1031  break;
1032 
1033  GreSetRectRgn( hrgnInv1, rc.left, rc.top, rc.right, rc.bottom);
1034 
1035  /*
1036  * If this window has a region, make sure the piece being validated
1037  * is within this region.
1038  */
1039  if (pwnd-> hrgnClip != NULL) {
1040 
1041  /*
1042  * If we get NULLREGION back, there is nothing to validate
1043  * against parents, so break out. If ERROR gets returned,
1044  * there is not much we can do: the best "wrong" thing
1045  * to do is just continue and validate a little more
1046  * from the parent.
1047  */
1048  if (!IntersectRgn( hrgnInv1, hrgnInv1, pwnd-> hrgnClip))
1049  break;
1050  }
1051  }
1052 
1053  /*
1054  * Calculate the rcParents parameter to
1055  * pass up to InternalInvalidate2.
1056  */
1057  rcParents = pwndParent-> rcWindow;
1058 
1059  if (! IntersectWithParents(pwndParent, &rcParents))
1060  break;
1061 
1063  pwndParent,
1064  hrgnInv1,
1065  hrgnInv1,
1066  &rcParents,
1067  RDW_VALIDATE | RDW_NOCHILDREN | RDW_IGNOREUPDATEDIRTY);
1068  }
1069  }
1070 
1071  return TRUE;
1072 }

引用了 tagWND::hrgnClip, hrgnInv1, tagWND::hrgnUpdate, InternalInvalidate2(), IntersectWithParents(), tagWND::rcWindow, RDW_IGNOREUPDATEDIRTY , 以及 tagWND::spwndParent.

被这些函数引用 xxxUpdateWindow2().

◆ xxxGetUpdateRect()

BOOL xxxGetUpdateRect (PWND pwnd,
LPRECT lprc,
BOOL fErase 
)

在文件 update.c1467 行定义.

1471 {
1472  RECT rc;
1473 
1474  CheckLock(pwnd);
1475 
1476  if (fErase)
1477  xxxSimpleDoSyncPaint(pwnd);
1478 
1479  /*
1480  * The app is looking at the update region: okay to allow window
1481  * validation.
1482  */
1483  ClrWF(pwnd, WFUPDATEDIRTY);
1484 
1485  if (pwnd-> hrgnUpdate == NULL) {
1486 
1487  if (HIWORD(lprc) != 0)
1488  SetRectEmpty(lprc);
1489 
1490  return FALSE;
1491 
1492  } else {
1493 
1494  /*
1495  * We must handle the case where a window has an update region,
1496  * but it is completely obscured by its parents. In this case, we
1497  * must validate the window and all its children, and return FALSE.
1498  *
1499  * An OffsetChildren() call resulting from SetWindowPos() or
1500  * ScrollWindowEx() will cause this to happen. Update regions are
1501  * just offset without checking their new positions to see if they
1502  * are obscured by the parent(s). This is too painful to check in
1503  * those cases, so we instead handle it here.
1504  *
1505  * BeginPaint() handles this case correctly by returning an empty
1506  * rectangle, so nothing special need be done there.
1507  */
1508  if (pwnd-> hrgnUpdate == MAXREGION) {
1509 
1510  rc = pwnd-> rcClient;
1511 
1512  } else {
1513 
1514  switch (GreGetRgnBox(pwnd-> hrgnUpdate, &rc)) {
1515  case ERROR:
1516  case NULLREGION:
1517  SetRectEmpty(&rc);
1518  break;
1519 
1520  case SIMPLEREGION:
1521  case COMPLEXREGION:
1522  break;
1523  }
1524 
1525  IntersectRect(&rc, &rc, &pwnd-> rcClient);
1526  }
1527 
1528  if ( IntersectWithParents(pwnd, &rc)) {
1529 
1530  OffsetRect(&rc, -pwnd-> rcClient.left, -pwnd-> rcClient.top);
1531 
1532  /*
1533  * If the window is CS_OWNDC, then we must map the returned
1534  * rectangle with DPtoLP, to ensure that the rectangle is
1535  * in the same coordinate system as the rectangle returned
1536  * by BeginPaint().
1537  *
1538  * BUT ONLY IF hwnd->hrgnUpdate != MAXREGION! For true
1539  * compatibility with 3.0.
1540  */
1541  if (TestCF(pwnd, CFOWNDC) &&
1542  (TestWF(pwnd, WFWIN31COMPAT) || pwnd-> hrgnUpdate != MAXREGION)) {
1543 
1544  PDCE pdce;
1545 
1546  /*
1547  * Look up this window's DC in the cache, and use it to
1548  * map the returned rectangle.
1549  */
1550  for (pdce = gpDispInfo-> pdceFirst; pdce; pdce = pdce-> pdceNext) {
1551 
1552  if (pdce-> pwndOrg == pwnd && !(pdce-> flags & DCX_CACHE)) {
1553  GreDPtoLP(pdce-> hdc, (LPPOINT)&rc, 2);
1554  break;
1555  }
1556  }
1557  }
1558 
1559  } else {
1560  SetRectEmpty(&rc);
1561  }
1562  }
1563 
1564  if (HIWORD(lprc) != 0)
1565  *lprc = rc;
1566 
1567  #if 0
1568  /*
1569  * If we're in the process a dragging a full window, mark the start
1570  * of the application painting. This is to make sure that if the
1571  * application calls DefWindowProc on the WM_PAINT after painting, we
1572  * won't erase the newly painted areas. Visual Slick calls GetUpdateRect
1573  * and then DefWindowProc.
1574  * See other comments for xxxBeginPaint and xxxDWP_Paint.
1575  * 8/3/94 johannec
1576  *
1577  * NOTE: This causes other problems in vslick where some controls
1578  * won't paint. Since the app doesn't call BeginPaint/EndPaint
1579  * to truly set/clear the STARTPAINT flag, we do not clear this
1580  * bit. (6-27-1996 : ChrisWil).
1581  */
1582  if ( gfDraggingFullWindow) {
1583  SetWF(pwnd, WFSTARTPAINT);
1584  }
1585  #endif
1586 
1587  return TRUE;
1588 }

引用了 CheckLock(), tagDCE::flags, gfDraggingFullWindow, gpDispInfo, tagDCE::hdc, tagWND::hrgnUpdate, IntersectRect(), IntersectWithParents(), OffsetRect(), tagDISPLAYINFO::pdceFirst, tagDCE::pdceNext, tagDCE::pwndOrg, tagWND::rcClient, SetRectEmpty() , 以及 xxxSimpleDoSyncPaint().

被这些函数引用 NtUserGetUpdateRect().

◆ xxxGetUpdateRgn()

int xxxGetUpdateRgn (PWND pwnd,
HRGN hrgn,
BOOL fErase 
)

在文件 update.c1598 行定义.

1602 {
1603  RECT rc;
1604  int code;
1605 
1606  CheckLock(pwnd);
1607 
1608  if (fErase)
1609  xxxSimpleDoSyncPaint(pwnd);
1610 
1611  /*
1612  * The application is looking at the update region: okay to
1613  * allow validation
1614  */
1615  ClrWF(pwnd, WFUPDATEDIRTY);
1616 
1617  if (pwnd-> hrgnUpdate == NULL) {
1618 
1619 ReturnEmpty:
1620 
1621  code = NULLREGION;
1622  GreSetRectRgn(hrgn, 0, 0, 0, 0);
1623 
1624  } else {
1625 
1626  BOOL fNotEmpty;
1627 
1628  rc = pwnd-> rcClient;
1629  fNotEmpty = IntersectWithParents(pwnd, &rc);
1630 
1631  if (pwnd-> hrgnUpdate == MAXREGION) {
1632 
1633  /*
1634  * Since the update region may be larger than the window
1635  * rectangle, intersect it with the window rectangle.
1636  */
1637  if (!fNotEmpty) {
1638  goto ReturnEmpty;
1639  }
1640 
1641  code = SIMPLEREGION;
1642 
1643  /*
1644  * Normalize the rectangle\region relative to the unclipped window
1645  */
1646  OffsetRect(&rc, -pwnd-> rcClient.left, -pwnd-> rcClient.top);
1647 
1648  GreSetRectRgn(hrgn, rc.left, rc.top, rc.right, rc.bottom);
1649 
1650  } else {
1651 
1652  GreSetRectRgn( hrgnInv2, rc.left, rc.top, rc.right, rc.bottom);
1653  code = IntersectRgn(hrgn, hrgnInv2, pwnd-> hrgnUpdate);
1654 
1655  switch (code) {
1656  case NULLREGION:
1657  case ERROR:
1658  goto ReturnEmpty;
1659 
1660  default:
1661  GreOffsetRgn(hrgn, -pwnd-> rcClient.left, -pwnd-> rcClient.top);
1662  break;
1663  }
1664  }
1665 
1666  #if 0
1667  /*
1668  * If we're in the process a dragging a full window, mark the start
1669  * of the application painting. This is to make sure that if the
1670  * application calls DefWindowProc on the WM_PAINT after painting, we
1671  * won't erase the newly painted areas.
1672  * See other comments for xxxBeginPaint and xxxDWP_Paint.
1673  * 8/3/94 johannec
1674  *
1675  * NOTE: This causes other problems in vslick where some controls
1676  * won't paint. Since the app doesn't call BeginPaint/EndPaint
1677  * to truly set/clear the STARTPAINT flag, we do not clear this
1678  * bit. (6-27-1996 : ChrisWil).
1679  */
1680  if ( gfDraggingFullWindow) {
1681  SetWF(pwnd, WFSTARTPAINT);
1682  }
1683  #endif
1684  }
1685 
1686  return code;
1687 }

引用了 CheckLock(), gfDraggingFullWindow, hrgnInv2, tagWND::hrgnUpdate, IntersectWithParents(), OffsetRect(), tagWND::rcClient , 以及 xxxSimpleDoSyncPaint().

被这些函数引用 NtUserGetUpdateRgn().

◆ xxxInternalInvalidate()

VOID xxxInternalInvalidate (PWND pwnd,
HRGN hrgnUpdate,
DWORD flags 
)

在文件 update.c1257 行定义.

1261 {
1262  RECT rcParents;
1263  HRGN hrgnSubtract;
1264 
1265  #ifdef DEBUG
1266  if (flags & (RDW_ERASENOW | RDW_UPDATENOW))
1267  CheckLock(pwnd);
1268  #endif
1269 
1270  /*
1271  * Ensure that hrgnSubtract is a valid region: if it's NULLREGION,
1272  * use the client region.
1273  */
1274  rcParents = (flags & RDW_FRAME ? pwnd-> rcWindow : pwnd-> rcClient);
1275 
1276  if (flags & (RDW_VALIDATE | RDW_INVALIDATE)) {
1277 
1278  hrgnSubtract = hrgnUpdate;
1279 
1280  if (hrgnSubtract == MAXREGION) {
1281 
1282  hrgnSubtract = hrgnInv1;
1283  CalcWindowRgn(pwnd,
1284  hrgnSubtract,
1285  (flags & RDW_FRAME) ? FALSE : TRUE);
1286  }
1287 
1288  /*
1289  * Calculate the bounding rectangle of our screen real estate,
1290  * by intersecting with our parent rectangles. While we're at
1291  * it, check the visibility of ourself and our parents.
1292  *
1293  * If we're validating we want to skip this, since there
1294  * are a number of cases where obscured windows may have
1295  * update regions to be validated -- in particular, after
1296  * a ScrollWindow() call where a child window was offset
1297  * by OffsetChildren() to a new, obscured position. Some of
1298  * the 3.0 compatibility hacks also can lead to this situation.
1299  */
1300  if ((flags & RDW_INVALIDATE) && ! IntersectWithParents(pwnd, &rcParents))
1301  return;
1302 
1303  } else {
1304  /*
1305  * hrgnsubtract needs to be a real region even if
1306  * we are not invalidating or validating. It really doesn't
1307  * matter what the region is, but we set it to null so the code
1308  * has less degrees of freedom.
1309  */
1310  hrgnSubtract = hrgnInv1;
1311  GreSetRectRgn(hrgnSubtract, 0, 0, 0, 0);
1312  }
1313 
1314  /*
1315  * If we're invalidating, and we're being called by the app,
1316  * we need to invalidate any SPBs that might be affected by
1317  * drawing in the client area of this window.
1318  * We have to do this because there is no guarantee that the
1319  * application will draw in an area that is invalidated
1320  * (e.g., if the window is completely obscured by another).
1321  */
1322  if ((flags & RDW_INVALIDATE) && (flags & RDW_REDRAWWINDOW) && AnySpbs()) {
1323 
1324  RECT rcInvalid;
1325 
1326  /*
1327  * Intersect the parent's rect with the region bounds...
1328  */
1329  GreGetRgnBox(hrgnSubtract, &rcInvalid);
1330  IntersectRect(&rcInvalid, &rcInvalid, &rcParents);
1331  SpbCheckRect(pwnd, &rcInvalid, 0);
1332  }
1333 
1334  /*
1335  * Now go do the recursive update region calculations...
1336  */
1337  InternalInvalidate2(pwnd, hrgnUpdate, hrgnSubtract, &rcParents, flags);
1338 
1339  /*
1340  * Finally handle any needed drawing.
1341  *
1342  * (NOTE: RDW_UPDATENOW implies RDW_ERASENOW)
1343  */
1344  if (flags & RDW_UPDATENOW) {
1345 
1347  flags & RDW_NOCHILDREN ? 0 : UW_ENUMCHILDREN);
1348 
1349  } else if (flags & RDW_ERASENOW) {
1350 
1351  UINT flagsDSP = DSP_ENUMCLIPPEDCHILDREN;
1352 
1353  if (flags & RDW_ALLCHILDREN)
1354  flagsDSP = DSP_ALLCHILDREN;
1355 
1356  if (flags & RDW_NOCHILDREN)
1357  flagsDSP = 0;
1358 
1359  xxxDoSyncPaint(pwnd, flagsDSP);
1360  }
1361 }

引用了 CalcWindowRgn(), CheckLock(), hrgnInv1, InternalInvalidate2(), IntersectRect(), IntersectWithParents(), tagWND::rcClient, tagWND::rcWindow, SpbCheckRect(), UINT(), UW_ENUMCHILDREN, xxxDoSyncPaint() , 以及 xxxInternalUpdateWindow().

被这些函数引用 BltValidBits(), SpbTransfer(), UserChangeDisplaySettings(), UserRedrawDesktop(), xxxRedrawWindow(), xxxScrollWindowEx() , 以及 xxxSystemParametersInfo().

◆ xxxInternalUpdateWindow()

BOOL xxxInternalUpdateWindow (PWND pwnd,
DWORD flags 
)

在文件 update.c1215 行定义.

1218 {
1219  CheckLock(pwnd);
1220 
1221  /*
1222  * If the passed-in window is transparent and a sibling below
1223  * needs repainting, don't do anything.
1224  */
1225  if (TestWF(pwnd, WEFTRANSPARENT)) {
1226 
1227  PWND pwndT = pwnd;
1228  PTHREADINFO ptiCurrent = GETPTI(pwnd);
1229 
1230  while ((pwndT = pwndT-> spwndNext) != NULL) {
1231 
1232  /*
1233  * Make sure sibling window belongs to same app.
1234  */
1235  if (GETPTI(pwndT) != ptiCurrent)
1236  continue;
1237 
1238  if (NEEDSPAINT(pwndT))
1239  return TRUE;
1240  }
1241  }
1242 
1243  /*
1244  * Enumerate pwnd and all its children, sending WM_PAINTs as needed.
1245  */
1246  return xxxUpdateWindow2(pwnd, flags);
1247 }

引用了 CheckLock(), tagWND::spwndNext , 以及 xxxUpdateWindow2().

被这些函数引用 xxxInternalInvalidate() , 以及 xxxUpdateWindow().

◆ xxxInvalidateRect()

BOOL xxxInvalidateRect (PWND pwnd,
LPRECT lprcInvalid,
BOOL fErase 
)

在文件 update.c39 行定义.

43 {
44  CheckLock(pwnd);
45 
46  /*
47  * BACKWARD COMPATIBILITY HACK
48  *
49  * In Windows 3.0 and less, ValidateRect/InvalidateRect() call with
50  * hwnd == NULL always INVALIDATED and ERASED the entire desktop, and
51  * synchronously sent WM_ERASEBKGND and WM_NCPAINT messages before
52  * returning. The Rgn() calls did not have this behavior.
53  */
54  if (pwnd == NULL) {
55  return xxxRedrawWindow(
56  pwnd,
57  NULL,
58  NULL,
59  RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE | RDW_ERASENOW);
60  } else {
61  return xxxRedrawWindow(
62  pwnd,
63  lprcInvalid,
64  NULL,
65  fErase ? RDW_INVALIDATE | RDW_ERASE : RDW_INVALIDATE);
66  }
67 }

引用了 CheckLock() , 以及 xxxRedrawWindow().

被这些函数引用 EnableSBCtlArrows() , 以及 NtUserInvalidateRect().

◆ xxxInvalidateRgn()

BOOL xxxInvalidateRgn (PWND pwnd,
HRGN hrgnInvalid,
BOOL fErase 
)

在文件 update.c110 行定义.

114 {
115  CheckLock(pwnd);
116 
117  return xxxRedrawWindow(
118  pwnd,
119  NULL,
120  hrgnInvalid,
121  fErase ? RDW_INVALIDATE | RDW_ERASE : RDW_INVALIDATE);
122 }

引用了 CheckLock(), hrgnInvalid , 以及 xxxRedrawWindow().

被这些函数引用 NtUserInvalidateRgn().

◆ xxxRedrawWindow()

BOOL xxxRedrawWindow (PWND pwnd,
LPRECT lprcUpdate,
HRGN hrgnUpdate,
DWORD flags 
)

在文件 update.c302 行定义.

307 {
308  CheckLock(pwnd);
309 
310  /*
311  * Always map NULL to the desktop.
312  */
313  if (pwnd == NULL)
314  pwnd = PtiCurrent()-> rpdesk-> pDeskInfo-> spwnd;
315 
316  if ( IsVisible(pwnd)) {
317 
318  TL tlpwnd;
319  HRGN hrgn = hrgnUpdate;
320 
321  if (flags & (RDW_VALIDATE | RDW_INVALIDATE)) {
322 
323  if (hrgn == NULL) {
324 
325  hrgn = MAXREGION;
326 
327  if (HIWORD(lprcUpdate) != 0) {
328 
329  hrgn = hrgnInv0;
330 
331  GreSetRectRgn(hrgn,
332  lprcUpdate->left + pwnd-> rcClient.left,
333  lprcUpdate->top + pwnd-> rcClient.top,
334  lprcUpdate->right + pwnd-> rcClient.left,
335  lprcUpdate->bottom + pwnd-> rcClient.top);
336  }
337 
338  } else {
339 
340  /*
341  * If necessary, make a copy of the passed-in region, because
342  * we'll be trashing it...
343  */
344  if (hrgn != MAXREGION) {
345  CopyRgn( hrgnInv0, hrgn);
346  hrgn = hrgnInv0;
347  }
348 
349  GreOffsetRgn(hrgn, pwnd-> rcClient.left, pwnd-> rcClient.top);
350  }
351  }
352 
353  ThreadLock(pwnd, &tlpwnd);
354  xxxInternalInvalidate(pwnd, hrgn, flags | RDW_REDRAWWINDOW);
355  ThreadUnlock(&tlpwnd);
356  }
357 
358  return TRUE;
359 }

引用了 CheckLock(), hrgnInv0, IsVisible(), tagDESKTOP::pDeskInfo, PtiCurrent(), tagWND::rcClient, tagTHREADINFO::rpdesk, tagDESKTOPINFO::spwnd, ThreadLock() , 以及 xxxInternalInvalidate().

被这些函数引用 NtUserRedrawWindow(), UserResetDisplayDevice(), xxxDesktopWndProc(), xxxDrawWallpaper(), xxxInvalidateIconicWindows(), xxxInvalidateRect(), xxxInvalidateRgn(), xxxMakeWindowForegroundWithState(), xxxScrollWindowEx(), xxxSetWindowPos(), xxxValidateRect() , 以及 xxxValidateRgn().

◆ xxxUpdateWindow()

BOOL xxxUpdateWindow (PWND pwnd)

在文件 update.c1371 行定义.

1373 {
1374  CheckLock(pwnd);
1375 
1376  return( xxxInternalUpdateWindow(pwnd, UW_ENUMCHILDREN));
1377 
1378 }

引用了 CheckLock(), UW_ENUMCHILDREN , 以及 xxxInternalUpdateWindow().

被这些函数引用 UserChangeDisplaySettings(), xxxDragObject(), xxxMNLoop(), xxxShowSwitchWindow() , 以及 xxxUpdateThreadsWindows().

◆ xxxUpdateWindow2()

BOOL xxxUpdateWindow2 (PWND pwnd,
DWORD flags 
)

在文件 update.c1082 行定义.

1085 {
1086  TL tlpwnd;
1087 
1088  CheckLock(pwnd);
1089 
1090  if (NEEDSPAINT(pwnd)) {
1091 
1092  /*
1093  * Punch a hole in our parent's update region, if we have one.
1094  */
1095  if (pwnd-> hrgnUpdate) {
1096  if ( ValidateParents(pwnd, flags & UW_RECURSED) == FALSE) {
1097  return TRUE;
1098  }
1099  }
1100 
1101  /*
1102  * Now that we're sending the message, clear the
1103  * internal paint bit if it was previously set.
1104  */
1105  if (TestWF(pwnd, WFINTERNALPAINT)) {
1106 
1107  ClrWF(pwnd, WFINTERNALPAINT);
1108 
1109  /*
1110  * If there is no update region, then no further paint messages
1111  * are pending, so we must dec the paint count.
1112  */
1113  if (pwnd-> hrgnUpdate == NULL)
1114  DecPaintCount(pwnd);
1115  }
1116 
1117  /*
1118  * Set a flag indicating that a paint message was not processed
1119  * (but should be).
1120  */
1121  SetWF(pwnd, WFPAINTNOTPROCESSED);
1122 
1123  /*
1124  * Clear this bit, for apps (like MicroLink) that don't call
1125  * BeginPaint or GetUpdateRect/Rgn (but DO call ValidateRect)
1126  * when handling their WM_PAINT message.
1127  */
1128  ClrWF(pwnd, WFUPDATEDIRTY);
1129 
1130  /*
1131  * BACKWARD COMPATIBILITY HACK
1132  *
1133  * Win 3.0 always sent WM_PAINTICON with wParam == TRUE for no good
1134  * reason, and Lotus Notes has come to depend on this.
1135  */
1136  if (!TestWF(pwnd, WFWIN40COMPAT) &&
1137  TestWF(pwnd, WFMINIMIZED) &&
1138  (pwnd-> pcls->spicn != NULL)) {
1139 
1140  xxxSendMessage(pwnd, WM_PAINTICON, TRUE, 0L);
1141 
1142  } else {
1143 
1144  xxxSendMessage(pwnd, WM_PAINT, 0, 0L);
1145  }
1146 
1147  /*
1148  * If the guy didn't call BeginPaint/EndPaint(), or GetUpdateRect/Rgn
1149  * with fErase == TRUE, then we have to clean up for him here.
1150  */
1151  if (TestWF(pwnd, WFPAINTNOTPROCESSED)) {
1152 
1153  RIPMSG0( RIP_VERBOSE,
1154  "App didn't call BeginPaint() or GetUpdateRect/Rgn(fErase == TRUE) in WM_PAINT");
1155 
1156  xxxSimpleDoSyncPaint(pwnd);
1157  }
1158  }
1159 
1160  /*
1161  * For desktop window, do not force the top level window repaint at this
1162  * this point. We are calling UpdateWindow() for the desktop before
1163  * size/move is sent for the top level windows.
1164  *
1165  * BUG: The comment above seems a bit random. Is there really a problem?
1166  * If nothing else this has to remain this way because it is
1167  * how Win 3.0 worked (neilk)
1168  */
1169  if ((flags & UW_ENUMCHILDREN) && (pwnd != PWNDDESKTOP(pwnd))) {
1170 
1171  /*
1172  * Update any children...
1173  */
1174  pwnd = pwnd-> spwndChild;
1175  while (pwnd != NULL) {
1176 
1177  /*
1178  * If there is a transparent window that needs painting,
1179  * ensure that no window below it needs to paint.
1180  */
1181  if (TestWF(pwnd, WEFTRANSPARENT) && NEEDSPAINT(pwnd)) {
1182 
1183  PWND pwndT = pwnd;
1184 
1185  while ((pwndT = pwndT-> spwndNext) != NULL) {
1186  if (NEEDSPAINT(pwndT))
1187  break;
1188  }
1189  if (pwndT != NULL) {
1190  pwnd = pwnd-> spwndNext;
1191  continue;
1192  }
1193  }
1194 
1195  ThreadLockAlways(pwnd, &tlpwnd);
1196 
1197  xxxUpdateWindow2(pwnd, flags | UW_RECURSED);
1198  pwnd = pwnd-> spwndNext;
1199 
1200  ThreadUnlock(&tlpwnd);
1201  }
1202  }
1203 
1204  return TRUE;
1205 }

引用了 CheckLock(), DecPaintCount(), tagWND::hrgnUpdate, tagWND::pcls, RIP_VERBOSE, RIPMSG0, tagWND::spwndChild, tagWND::spwndNext, UW_ENUMCHILDREN, UW_RECURSED, ValidateParents(), xxxSendMessage() , 以及 xxxSimpleDoSyncPaint().

被这些函数引用 xxxInternalUpdateWindow().

◆ xxxValidateRect()

BOOL xxxValidateRect (PWND pwnd,
LPRECT lprcValid 
)

在文件 update.c77 行定义.

80 {
81  CheckLock(pwnd);
82 
83  /*
84  * BACKWARD COMPATIBILITY HACK
85  *
86  * In Windows 3.0 and less, ValidateRect/InvalidateRect() call with
87  * hwnd == NULL always INVALIDATED and ERASED the entire desktop, and
88  * synchronously sent WM_ERASEBKGND and WM_NCPAINT messages before
89  * returning. The Rgn() calls did not have this behavior.
90  */
91  if (pwnd == NULL) {
92  return xxxRedrawWindow(
93  pwnd,
94  NULL,
95  NULL,
96  RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE | RDW_ERASENOW);
97  } else {
98  return xxxRedrawWindow(pwnd, lprcValid, NULL, RDW_VALIDATE);
99  }
100 }

引用了 CheckLock() , 以及 xxxRedrawWindow().

被这些函数引用 NtUserValidateRect(), xxxMenuWindowProc() , 以及 xxxMoveWindow().

◆ xxxValidateRgn()

BOOL xxxValidateRgn (PWND pwnd,
HRGN hrgnValid 
)

在文件 update.c132 行定义.

135 {
136  CheckLock(pwnd);
137 
138  return xxxRedrawWindow(pwnd, NULL, hrgnValid, RDW_VALIDATE);
139 }

引用了 CheckLock(), hrgnValid , 以及 xxxRedrawWindow().

#define RIPMSG0(flags, szFmt)
Definition: winerrp.h:131
BOOL xxxUpdateWindow2(PWND pwnd, DWORD flags)
Definition: update.c:1082
BOOL IntersectWithParents(PWND pwnd, LPRECT lprc)
Definition: update.c:1700
#define RDW_IGNOREUPDATEDIRTY
Definition: update.c:28
BOOL xxxRedrawWindow(PWND pwnd, LPRECT lprcUpdate, HRGN hrgnUpdate, DWORD flags)
Definition: update.c:302
PCLS pcls
Definition: user.h:1403
HDC hdc
Definition: userk.h:2460
UINT SmartRectInRegion(HRGN hrgn, LPRECT lprc)
Definition: update.c:159
#define RIP_VERBOSE
Definition: winerrp.h:30
int CalcWindowRgn(PWND pwnd, HRGN hrgn, BOOL fClient)
Definition: visrgn.c:490
PDESKTOPINFO pDeskInfo
Definition: userk.h:1706
#define RIR_INSIDE
Definition: update.c:26
DWORD flags
Definition: userk.h:2466
PDCE pdceFirst
Definition: user.h:1574
VOID DecPaintCount(PWND pwnd)
Definition: paint.c:1221
LONG xxxSendMessage(PWND pwnd, UINT message, DWORD wParam, LONG lParam)
Definition: sendmsg.c:613
PTHREADINFO PtiCurrent(VOID)
Definition: winmgrc.c:526
struct tagWND * spwndNext
Definition: user.h:1391
VOID ClearHungFlag(PWND pwnd, WORD wFlag)
Definition: hungapp.c:93
HRGN hrgnUpdate
Definition: user.h:1406
HRGN hrgnInv2
Definition: kernel/globals.c:455
BOOL APIENTRY OffsetRect(LPRECT prc, int cx, int cy)
Definition: rect.c:132
VOID ThreadLock(PVOID pobj, PTL ptl)
VOID xxxDoSyncPaint(PWND pwnd, DWORD flags)
Definition: paint.c:1028
BOOL APIENTRY IntersectRect(LPRECT prcDst, CONST RECT *prcSrc1, CONST RECT *prcSrc2)
Definition: rect.c:184
Definition: userk.h:2458
struct tagDCE * pdceNext
Definition: userk.h:2459
PDISPLAYINFO gpDispInfo
Definition: kernel/globals.c:125
#define RIR_INTERSECT
Definition: update.c:25
ddeml v[i< inst >][t< type >][hObj|pObj] Dump DDEML state information ddeml lists all ddeml instances for this process n ddeml t< type > lists all ddeml objects of the given type n n assumes link is first DWORD
Definition: exts.h:175
_TL
Definition: usercli.h:347
HRGN hrgnClip
Definition: user.h:1427
RECT rcWindow
Definition: user.h:1398
Definition: user.h:1388
struct tagWND * spwndParent
Definition: user.h:1392
BOOL xxxInternalUpdateWindow(PWND pwnd, DWORD flags)
Definition: update.c:1215
HRGN hrgnInvalid
Definition: kernel/globals.c:439
BOOL InternalInvalidate2(PWND pwnd, HRGN hrgn, HRGN hrgnSubtract, LPRECT prcParents, DWORD flags)
Definition: update.c:369
BOOL gfDraggingFullWindow
Definition: kernel/globals.c:37
VOID IncPaintCount(PWND pwnd)
Definition: paint.c:1197
struct tagWND * pwndOrg
Definition: userk.h:2461
RECT rcScreen
Definition: user.h:1570
HRGN hrgnValid
Definition: kernel/globals.c:437
BOOL APIENTRY EqualRect(CONST RECT *prc1, CONST RECT *prc2)
Definition: rect.c:285
VOID SpbCheckRect(PWND pwnd, LPRECT lprc, DWORD flags)
Definition: spb.c:1031
#define UW_RECURSED
Definition: update.c:22
VOID xxxInternalInvalidate(PWND pwnd, HRGN hrgnUpdate, DWORD flags)
Definition: update.c:1257
PDESKTOP rpdesk
Definition: userk.h:2288
VOID PixieHack(PWND pwnd, LPRECT prcBounds)
Definition: update.c:243
VOID xxxSimpleDoSyncPaint(PWND pwnd)
Definition: paint.c:704
typedef UINT(FAR WINAPI *MSGSOUNDPROC)()
HRGN hrgnInv0
Definition: kernel/globals.c:453
VOID CheckLock(PVOID pobj)
struct tagWND * spwnd
Definition: user.h:1603
struct tagWND * spwndChild
Definition: user.h:1393
BOOL ValidateParents(PWND pwnd, BOOL fRecurse)
Definition: update.c:984
BOOL APIENTRY SetRectEmpty(LPRECT prc)
Definition: rect.c:414
DWORD GetAppCompatFlags(PTHREADINFO pti)
Definition: winmgrc.c:457
PWND _GetDesktopWindow(void)
Definition: client/wow.c:229
#define RIR_OUTSIDE
Definition: update.c:24
RECT rcClient
Definition: user.h:1399
VOID InternalInvalidate3(PWND pwnd, HRGN hrgn, DWORD flags)
Definition: update.c:743
BOOL IsVisible(PWND pwnd)
Definition: rtl/winmgr.c:456
HRGN hrgnInv1
Definition: kernel/globals.c:454
#define UW_ENUMCHILDREN
Definition: update.c:21
VOID SetHungFlag(PWND pwnd, WORD wFlag)
Definition: hungapp.c:31

一键复制

编辑

Web IDE

原始数据

按行查看

历史

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值