00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
#include "precomp.h"
00015
#pragma hdrstop
00016
00017 #define CTM_NOCHANGE 0
00018 #define CTM_TOPMOST 1
00019 #define CTM_NOTOPMOST 2
00020
00021
void
00022
FixBogusSWP(
PWND pwnd,
int * px,
int * py,
int cx,
int cy, UINT flags);
00023
void PreventInterMonitorBlts(
PCVR pcvr);
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
#if DBG
00034
void DBGCheskSMWP (
PSMWP psmwp)
00035 {
00036
if (psmwp->
bHandle) {
00037 UserAssert(psmwp->
head.
h != NULL);
00038 UserAssert(psmwp ==
HtoPqCat(
PtoHq(psmwp)));
00039 UserAssert(psmwp != &gSMWP);
00040 }
else {
00041 UserAssert((psmwp->
head.
h == NULL) && (psmwp->
head.
cLockObj == 0));
00042
if (psmwp == &
gSMWP) {
00043 UserAssert(
TEST_PUDF(PUDF_GSMWPINUSE));
00044 }
00045 }
00046
00047 UserAssert(psmwp->
ccvr <= psmwp->
ccvrAlloc);
00048 UserAssert(psmwp->
acvr != NULL);
00049
00050 }
00051
#else
00052 #define DBGCheskSMWP(psmwp)
00053
#endif
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
void
00064 DestroySMWP(
PSMWP psmwp)
00065 {
00066
BOOL fFree;
00067
00068
CheckCritIn();
00069
00070
DBGCheskSMWP(psmwp);
00071
00072
00073
00074
00075
00076
if (psmwp->
bHandle) {
00077
if (!
HMMarkObjectDestroy(psmwp)) {
00078
return;
00079 }
00080 fFree =
TRUE;
00081 }
else {
00082
00083
00084
00085 fFree = (psmwp != &
gSMWP);
00086 }
00087
00088
if (psmwp->
acvr) {
00089
00090
00091
00092
00093
PCVR pcvr;
00094
int ccvr;
00095
00096
for (pcvr = psmwp->
acvr, ccvr = psmwp->
ccvr; --ccvr >= 0; pcvr++) {
00097
if (pcvr->
hrgnInterMonitor !=
NULL) {
00098 GreDeleteObject(pcvr->
hrgnInterMonitor);
00099 }
00100 }
00101
00102
if (fFree) {
00103 UserFreePool(psmwp->
acvr);
00104 }
00105 }
00106
00107
00108
00109
00110
00111
if (psmwp->
bHandle) {
00112
HMFreeObject(psmwp);
00113 }
else if (fFree) {
00114 UserFreePool(psmwp);
00115 }
else {
00116 UserAssert(
TEST_PUDF(
PUDF_GSMWPINUSE));
00117
CLEAR_PUDF(
PUDF_GSMWPINUSE);
00118
00119
00120
00121
00122
if (psmwp->
ccvrAlloc > 8) {
00123
PCVR pcvr = UserAllocPool(4 *
sizeof(
CVR), TAG_SWP);
00124
if (pcvr !=
NULL) {
00125 UserFreePool(psmwp->
acvr);
00126 psmwp->
acvr = pcvr;
00127 psmwp->
ccvrAlloc = 4;
00128 }
00129 }
00130 }
00131 }
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141 #define MW_FLAGS_REDRAW (SWP_NOZORDER | SWP_NOACTIVATE)
00142 #define MW_FLAGS_NOREDRAW (SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW)
00143
00144 BOOL xxxMoveWindow(
00145
PWND pwnd,
00146
int x,
00147
int y,
00148
int cx,
00149
int cy,
00150 BOOL fRedraw)
00151 {
00152
CheckLock(pwnd);
00153
00154
if ((pwnd ==
PWNDDESKTOP(pwnd)) ||
00155
TestWF(pwnd,
WFWIN31COMPAT) ||
00156 (pwnd->
spwndParent !=
PWNDDESKTOP(pwnd))) {
00157
00158
return xxxSetWindowPos(
00159 pwnd,
00160
NULL,
00161 x,
00162 y,
00163 cx,
00164
cy,
00165 (fRedraw ?
MW_FLAGS_REDRAW :
MW_FLAGS_NOREDRAW));
00166 }
else {
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
BOOL fResult =
xxxSetWindowPos(pwnd,
00183
NULL,
00184 x,
00185 y,
00186 cx,
00187
cy,
00188
MW_FLAGS_REDRAW);
00189
00190
if (!fRedraw)
00191
xxxValidateRect(pwnd,
NULL);
00192
00193
return fResult;
00194 }
00195 }
00196
00197
00198
00199
00200
00201
00202
00203 BOOL AllocateCvr (
PSMWP psmwp,
int cwndHint)
00204 {
00205
PCVR acvr;
00206
00207 UserAssert(cwndHint != 0);
00208 acvr = (
PCVR)UserAllocPoolWithQuota(
sizeof(
CVR) * cwndHint, TAG_SWP);
00209
00210
if (acvr ==
NULL) {
00211
return FALSE;
00212 }
00213
00214
00215
00216
00217
00218
00219 psmwp->
acvr = acvr;
00220 psmwp->
ccvrAlloc = cwndHint;
00221 psmwp->
ccvr = 0;
00222
return TRUE;
00223 }
00224
00225
00226
00227
00228
00229
00230
00231 PSMWP InternalBeginDeferWindowPos(
int cwndHint)
00232 {
00233
PSMWP psmwp;
00234
00235
CheckCritIn();
00236
00237
00238
00239
00240
00241
if (
TEST_PUDF(
PUDF_GSMWPINUSE) || (cwndHint >
gSMWP.
ccvrAlloc)) {
00242 psmwp = (
PSMWP)UserAllocPoolWithQuotaZInit(
sizeof(
SMWP), TAG_SWP);
00243
if (psmwp ==
NULL) {
00244
return NULL;
00245 }
00246
if (!
AllocateCvr(psmwp, cwndHint)) {
00247 UserFreePool(psmwp);
00248
return NULL;
00249 }
00250 }
else {
00251
SET_PUDF(
PUDF_GSMWPINUSE);
00252 psmwp = &
gSMWP;
00253 RtlZeroMemory(&
gSMWP, FIELD_OFFSET(
SMWP, ccvrAlloc));
00254 UserAssert(
gSMWP.
ccvr == 0);
00255 UserAssert(
gSMWP.
acvr !=
NULL);
00256 }
00257
00258
DBGCheskSMWP(psmwp);
00259
return psmwp;
00260 }
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272 PSMWP _BeginDeferWindowPos(
int cwndHint)
00273 {
00274
PSMWP psmwp;
00275
00276 psmwp = (
PSMWP)
HMAllocObject(
PtiCurrent(),
NULL,
TYPE_SETWINDOWPOS,
sizeof(
SMWP));
00277
if (psmwp ==
NULL) {
00278
return NULL;
00279 }
00280
00281
if (cwndHint == 0) {
00282 cwndHint = 8;
00283 }
00284
00285
if (!
AllocateCvr(psmwp, cwndHint)) {
00286
HMFreeObject(psmwp);
00287
return NULL;
00288 }
00289
00290 psmwp->
bHandle =
TRUE;
00291
DBGCheskSMWP(psmwp);
00292
return psmwp;
00293 }
00294
00295
00296
00297
00298
00299
00300
00301 PWND PWInsertAfter(
00302 HWND hwnd)
00303 {
00304
PWND pwnd;
00305
00306
00307
00308
00309
switch ((ULONG_PTR)hwnd) {
00310
case (ULONG_PTR)HWND_TOP:
00311
case (ULONG_PTR)HWND_BOTTOM:
00312
case (ULONG_PTR)HWND_TOPMOST:
00313
case (ULONG_PTR)HWND_NOTOPMOST:
00314
return (
PWND)hwnd;
00315
00316
default:
00317
00318
00319
00320
00321
00322
if (pwnd =
RevalidateHwnd(hwnd)) {
00323
00324
00325
00326
00327
00328
if (
TestWF(pwnd,
WFDESTROYED) || pwnd->
spwndParent ==
NULL)
00329
return NULL;
00330
00331 UserAssert(
_IsDescendant(pwnd->
spwndParent, pwnd));
00332
return pwnd;
00333 }
00334
00335
return NULL;
00336 }
00337 }
00338
00339 HWND
HWInsertAfter(
00340
PWND pwnd)
00341 {
00342
00343
00344
00345
switch ((ULONG_PTR)pwnd) {
00346
case (ULONG_PTR)HWND_TOP:
00347
case (ULONG_PTR)HWND_BOTTOM:
00348
case (ULONG_PTR)HWND_TOPMOST:
00349
case (ULONG_PTR)HWND_NOTOPMOST:
00350
return (HWND)pwnd;
00351
00352
default:
00353
return HW(pwnd);
00354 }
00355 }
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365 PSMWP _DeferWindowPos(
00366
PSMWP psmwp,
00367
PWND pwnd,
00368
PWND pwndInsertAfter,
00369
int x,
00370
int y,
00371
int cx,
00372
int cy,
00373 UINT flags)
00374 {
00375 PWINDOWPOS
ppos;
00376
PCVR pcvr;
00377
00378
DBGCheskSMWP(psmwp);
00379
if (psmwp->
ccvr + 1 > psmwp->
ccvrAlloc) {
00380
00381
00382
00383
00384
DWORD dwNewAlloc = psmwp->
ccvrAlloc + 4;
00385
00386 pcvr = (
PCVR)UserReAllocPoolWithQuota(psmwp->
acvr,
00387 psmwp->
ccvrAlloc *
sizeof(
CVR),
00388
sizeof(
CVR) * dwNewAlloc,
00389 TAG_SWP);
00390
00391
if (pcvr ==
NULL) {
00392
DestroySMWP(psmwp);
00393
return NULL;
00394 }
00395
00396 psmwp->
acvr = pcvr;
00397 psmwp->
ccvrAlloc = dwNewAlloc;
00398 }
00399
00400 pcvr = &psmwp->
acvr[psmwp->
ccvr++];
00401
ppos = &pcvr->
pos;
00402
00403
ppos->hwnd =
HWq(pwnd);
00404
ppos->hwndInsertAfter = (
TestWF(pwnd,
WFBOTTOMMOST)) ?
00405 HWND_BOTTOM :
HWInsertAfter(pwndInsertAfter);
00406
ppos->x = x;
00407
ppos->y = y;
00408
ppos->cx = cx;
00409
ppos->cy =
cy;
00410
ppos->flags = flags;
00411
00412 pcvr->
hrgnClip =
NULL;
00413 pcvr->
hrgnInterMonitor =
NULL;
00414
00415
return psmwp;
00416 }
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429 BOOL ValidateWindowPos(
PCVR pcvr,
PWND pwndParent)
00430 {
00431
PWND pwnd;
00432
PWND pwndInsertAfter;
00433 HWND hwndInsertAfter;
00434
00435
if ((pwnd =
RevalidateHwnd(pcvr->
pos.hwnd)) ==
NULL)
00436
return FALSE;
00437
00438
00439
00440
00441 pcvr->
pti =
GETPTI(pwnd);
00442
00443
00444
00445
00446
00447
if (!(pcvr->
pos.flags & SWP_NOZORDER)) {
00448
BOOL fTopLevel = (pwnd->
spwndParent ==
PWNDDESKTOP(pwnd));
00449
00450
00451
00452
if (
TestWF(pwnd,
WFDESTROYED))
00453
return FALSE;
00454
00455 hwndInsertAfter = pcvr->
pos.hwndInsertAfter;
00456
00457
00458
00459
00460
00461
00462
if ((hwndInsertAfter == HWND_TOPMOST) ||
00463 (hwndInsertAfter == HWND_NOTOPMOST)) {
00464
00465
if (!fTopLevel) {
00466
return FALSE;
00467 }
00468 }
else if (hwndInsertAfter == HWND_TOP) {
00469
00470
00471
00472
if ((pwndParent !=
NULL) && fTopLevel
00473 && !
FSwpTopmost(pwnd)
00474 && (pwndParent->
spwndChild !=
NULL)
00475 &&
FSwpTopmost(pwndParent->
spwndChild)) {
00476
00477 RIPMSG2(RIP_WARNING,
"ValidateWindowPos: pwnd is not SWPTopMost."
00478
" pwnd:%#p. hwndInsertAfter:%#p",
00479 pwnd, hwndInsertAfter);
00480
return FALSE;
00481 }
00482 }
else if (hwndInsertAfter != HWND_BOTTOM) {
00483
00484
00485
00486
00487
if (((pwndInsertAfter =
RevalidateHwnd(hwndInsertAfter)) ==
NULL) ||
00488
TestWF(pwndInsertAfter,
WFDESTROYED)) {
00489
00490 RIPERR1(ERROR_INVALID_HANDLE, RIP_WARNING,
"Invalid hwndInsertAfter (%#p)", hwndInsertAfter);
00491
00492
return FALSE;
00493 }
00494
00495
00496
00497
00498
if (pwnd == pwndInsertAfter ||
00499 pwnd->
spwndParent != pwndInsertAfter->
spwndParent) {
00500 RIPMSG2(RIP_WARNING,
"hwndInsertAfter (%#p) is not a sibling "
00501
"of hwnd (%#p)", hwndInsertAfter, pcvr->
pos.hwnd);
00502
return FALSE;
00503 }
00504
00505
00506
00507
if ((pwndParent !=
NULL) && fTopLevel) {
00508
if (
FSwpTopmost(pwnd)) {
00509
00510
00511
00512
if (!
FSwpTopmost(pwndInsertAfter)) {
00513 RIPMSG2(RIP_WARNING,
"ValidateWindowPos: pwndInsertAfter is not SWPTopMost."
00514
" pwnd:%#p. pwndInsertAfter:%#p",
00515 pwnd, pwndInsertAfter);
00516
return FALSE;
00517 }
00518 }
else {
00519
00520
00521
00522
00523
if ((pwndInsertAfter->
spwndNext !=
NULL)
00524 &&
FSwpTopmost(pwndInsertAfter->
spwndNext)) {
00525
00526 RIPMSG2(RIP_WARNING,
"ValidateWindowPos: pwndInsertAfter->spwndNext is SWPTopMost."
00527
" pwnd:%#p. pwndInsertAfter:%#p",
00528 pwnd, pwndInsertAfter);
00529
return FALSE;
00530 }
00531 }
00532
00533 }
00534
00535 }
00536
00537
00538
00539
00540
if (pwndParent !=
NULL) {
00541
if (pwndParent != pwnd->
spwndParent) {
00542 RIPMSG3(RIP_WARNING,
"ValidateWindowPos: parent has changed."
00543
" pwnd:%#p. Old Parent:%#p. Current Parent:%#p",
00544 pwnd, pwndParent, pwnd->
spwndParent);
00545
return FALSE;
00546 }
00547 }
00548
00549 }
00550
00551
return TRUE;
00552 }
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562 BOOL IsStillWindowC(
00563 HWND hwndc)
00564 {
00565
switch ((ULONG_PTR)hwndc) {
00566
case (ULONG_PTR)HWND_TOP:
00567
case (ULONG_PTR)HWND_BOTTOM:
00568
case (ULONG_PTR)HWND_TOPMOST:
00569
case (ULONG_PTR)HWND_NOTOPMOST:
00570
return TRUE;
00571
00572
default:
00573
00574
00575
00576
00577
00578
return (
RevalidateHwnd(hwndc) != 0);
00579 }
00580 }
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591 BOOL ValidateSmwp(
00592
PSMWP psmwp,
00593 BOOL *pfSyncPaint)
00594 {
00595
PCVR pcvr;
00596
PWND pwndParent;
00597
PWND pwndT;
00598
int ccvr;
00599
00600 *pfSyncPaint =
TRUE;
00601
00602 pwndT =
RevalidateHwnd(psmwp->
acvr[0].
pos.hwnd);
00603
00604
if (pwndT ==
NULL)
00605
return FALSE;
00606
00607 pwndParent = pwndT->
spwndParent;
00608
00609
00610
00611
00612
for (pcvr = psmwp->
acvr, ccvr = psmwp->
ccvr; --ccvr >= 0; pcvr++) {
00613
00614
if (!
ValidateWindowPos(pcvr,
NULL)) {
00615 pcvr->
pos.hwnd =
NULL;
00616
continue;
00617 }
00618
00619
00620
00621
00622
00623 UserAssert(
IsStillWindowC(pcvr->
pos.hwnd));
00624
00625 UserAssert(
PW(pcvr->
pos.hwnd));
00626
if (
PW(pcvr->
pos.hwnd)->spwndParent != pwndParent) {
00627 RIPERR0(ERROR_HWNDS_HAVE_DIFF_PARENT, RIP_VERBOSE,
"");
00628
return FALSE;
00629 }
00630
00631
00632
00633
00634
00635
if (pcvr->
pos.flags & SWP_DEFERDRAWING)
00636 *pfSyncPaint =
FALSE;
00637 }
00638
00639
return TRUE;
00640 }
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653 PWINDOWPOS
FindValidWindowPos(
00654
PSMWP psmwp)
00655 {
00656
int i;
00657
00658
for (i = 0; i < psmwp->
ccvr; i++) {
00659
00660
if (psmwp->
acvr[i].
pos.hwnd !=
NULL)
00661
return &psmwp->
acvr[i].
pos;
00662 }
00663
00664
return NULL;
00665 }
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679 PWND GetLastNonBottomMostWindow(
00680
PWND pwnd,
00681 BOOL fSkipSelf)
00682 {
00683
PWND pwndT;
00684
PWND pwndLast =
NULL;
00685
00686
for (pwndT = pwnd->
spwndParent->
spwndChild;
00687 pwndT && !
TestWF(pwndT,
WFBOTTOMMOST);
00688 pwndT = pwndT->
spwndNext) {
00689
00690
if (!fSkipSelf || (pwnd != pwndT))
00691 pwndLast = pwndT;
00692 }
00693
00694
return pwndLast;
00695 }
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708 BOOL ValidateZorder(
00709
PCVR pcvr)
00710 {
00711
PWND pwnd;
00712
PWND pwndPrev;
00713
PWND pwndInsertAfter;
00714
BYTE bTopmost;
00715
00716
00717
00718
00719
00720 UserAssert(
RevalidateCatHwnd(pcvr->
pos.hwnd));
00721 pwnd =
PWCat(pcvr->
pos.hwnd);
00722
00723
00724
00725
00726
if (
TestWF(pwnd,
WFDESTROYED))
00727
return TRUE;
00728
00729 UserAssert((
HMPheFromObject(pwnd)->bFlags &
HANDLEF_DESTROY) == 0);
00730
00731 pwndInsertAfter =
PWInsertAfter(pcvr->
pos.hwndInsertAfter);
00732
if (pcvr->
pos.hwndInsertAfter !=
NULL && pwndInsertAfter ==
NULL)
00733
return TRUE;
00734
00735
if (pwndInsertAfter ==
PWND_BOTTOM) {
00736
00737
if (
TestWF(pwnd,
WFBOTTOMMOST))
00738
return(pwnd->
spwndNext ==
NULL);
00739
else
00740
return(pwnd ==
GetLastNonBottomMostWindow(pwnd,
FALSE));
00741 }
00742
00743 pwndPrev = pwnd->
spwndParent->
spwndChild;
00744
if (pwndInsertAfter ==
PWND_TOP)
00745
return pwndPrev == pwnd;
00746
00747
if (
TestWF(pwndInsertAfter,
WFDESTROYED))
00748
return TRUE;
00749
00750
00751
00752
00753
00754
00755
00756
00757
if (
TestWF(pwndInsertAfter,
WFBOTTOMMOST)) {
00758 pcvr->
pos.hwndInsertAfter =
HWInsertAfter(
GetLastNonBottomMostWindow(pwnd,
TRUE));
00759
return FALSE;
00760 }
00761
00762
00763
00764
00765
00766
00767
00768 bTopmost =
TestWF(pwnd,
WEFTOPMOST);
00769
00770
if (
TestWF(pwnd,
WFTOGGLETOPMOST))
00771 bTopmost ^=
LOBYTE(
WEFTOPMOST);
00772
00773
if (bTopmost != (
BYTE)
TestWF(pwndInsertAfter,
WEFTOPMOST)) {
00774
00775 pwndInsertAfter =
GetLastTopMostWindow();
00776
00777
00778
00779
00780
if (pwndInsertAfter == pwnd)
00781
return TRUE;
00782
00783 pcvr->
pos.hwndInsertAfter =
HW(pwndInsertAfter);
00784 }
00785
00786
00787
00788
00789
if (pwndPrev != pwnd) {
00790
00791
for ( ; pwndPrev !=
NULL; pwndPrev = pwndPrev->
spwndNext) {
00792
00793
if (pwndPrev->
spwndNext == pwnd)
00794
return pwndInsertAfter == pwndPrev;
00795 }
00796
00797
00798
00799
00800
00801 UserAssert(
FALSE);
00802
return TRUE;
00803 }
00804
00805
return FALSE;
00806 }
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821 BOOL xxxCalcValidRects(
00822
PSMWP psmwp,
00823 HWND *phwndNewActive)
00824 {
00825
PCVR pcvr;
00826
PWND pwnd;
00827
PWND pwndParent;
00828 HWND hwnd;
00829 HWND hwndNewActive =
NULL;
00830 PWINDOWPOS
ppos;
00831
BOOL fNoZorder;
00832
BOOL fForceNCCalcSize;
00833 NCCALCSIZE_PARAMS params;
00834
int cxSrc;
00835
int cySrc;
00836
int cxDst;
00837
int cyDst;
00838
int cmd;
00839
int ccvr;
00840
int xClientOld;
00841
int yClientOld;
00842
int cxClientOld;
00843
int cyClientOld;
00844
int xWindowOld;
00845
int yWindowOld;
00846
int cxWindowOld;
00847
int cyWindowOld;
00848
TL tlpwndParent;
00849
TL tlpwnd;
00850
00851
00852
00853
00854
00855
00856
00857
00858
if ((
ppos =
FindValidWindowPos(psmwp)) ==
NULL)
00859
return FALSE;
00860
00861 UserAssert(
PW(
ppos->hwnd));
00862 pwndParent =
PW(
ppos->hwnd)->spwndParent;
00863
00864 UserAssert(
HMRevalidateCatHandle(
PtoH(pwndParent)));
00865
00866
ThreadLock(pwndParent, &tlpwndParent);
00867
00868 fNoZorder =
TRUE;
00869
00870
00871
00872
00873
00874
for (pcvr = psmwp->
acvr, ccvr = psmwp->
ccvr; --ccvr >= 0; pcvr++) {
00875
00876
00877
00878
00879
00880
if ((hwnd = pcvr->
pos.hwnd) ==
NULL)
00881
continue;
00882
00883 pwnd =
RevalidateHwnd(hwnd);
00884
00885
if ((pwnd ==
NULL) || !
IsStillWindowC(pcvr->
pos.hwndInsertAfter)) {
00886 pcvr->
pos.hwnd =
NULL;
00887 pcvr->
pos.flags = SWP_NOREDRAW | SWP_NOCHANGE;
00888
continue;
00889 }
00890
00891
ThreadLockAlways(pwnd, &tlpwnd);
00892
00893
00894
00895
00896
00897 fForceNCCalcSize =
FALSE;
00898
00899
if (!hwndNewActive && !(pcvr->
pos.flags & SWP_NOACTIVATE))
00900 hwndNewActive =
HWq(pwnd);
00901
00902
if (!(pcvr->
pos.flags & SWP_NOSENDCHANGING)) {
00903
00904
PWND pwndT;
00905
00906
xxxSendMessage(pwnd, WM_WINDOWPOSCHANGING, 0, (LPARAM)&pcvr->
pos);
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
#if DBG
00918
if (LOWORD(pcvr->
pos.hwnd) != LOWORD(hwnd)) {
00919 RIPMSG0(RIP_ERROR,
00920
"xxxCalcValidRects: Ignoring pcvr->pos.hwnd change by WM_WINDOWPOSCHANGING");
00921 }
00922
#endif
00923
pcvr->
pos.hwnd = hwnd;
00924
00925
00926
00927
00928
00929
00930
if (pcvr->
pos.hwndInsertAfter == HWND_NOTOPMOST) {
00931
if (
TestWF(pwnd,
WEFTOPMOST)) {
00932
00933 pwndT =
GetLastTopMostWindow();
00934 pcvr->
pos.hwndInsertAfter =
HW(pwndT);
00935
00936
if (pcvr->
pos.hwndInsertAfter == pcvr->
pos.hwnd) {
00937 pwndT =
_GetWindow(pwnd, GW_HWNDPREV);
00938 pcvr->
pos.hwndInsertAfter =
HW(pwndT);
00939 }
00940 }
else {
00941 pwndT =
_GetWindow(pwnd, GW_HWNDPREV);
00942 pcvr->
pos.hwndInsertAfter =
HW(pwndT);
00943 }
00944 }
else if (pcvr->
pos.hwndInsertAfter == HWND_TOPMOST) {
00945 pcvr->
pos.hwndInsertAfter = HWND_TOP;
00946 }
00947 }
00948
00949
00950
00951
00952
00953 xWindowOld = pwnd->
rcWindow.left;
00954 yWindowOld = pwnd->
rcWindow.top;
00955
if (pwndParent !=
PWNDDESKTOP(pwnd)) {
00956 xWindowOld -= pwndParent->
rcClient.left;
00957 yWindowOld -= pwndParent->
rcClient.top;
00958 }
00959
00960
00961 cxWindowOld = pwnd->
rcWindow.right - pwnd->
rcWindow.left;
00962 cyWindowOld = pwnd->
rcWindow.bottom - pwnd->
rcWindow.top;
00963
00964
00965
00966
00967 pcvr->
pos.flags |= SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE;
00968
00969
if (!(pcvr->
pos.flags & SWP_NOMOVE)) {
00970
00971
if (pcvr->
pos.x == xWindowOld && pcvr->
pos.y == yWindowOld)
00972 pcvr->
pos.flags |= SWP_NOMOVE;
00973
00974
00975
#ifdef USE_MIRRORING
00976
00977
00978
00979
00980
00981
00982
00983
00984
if (
TestWF(pwndParent, WEFLAYOUTRTL) &&
TestwndChild(pwnd) &&
00985 (pwndParent->
rcClient.right - pwnd->
rcWindow.right + 1) != pcvr->
pos.x)
00986 pcvr->
pos.flags &= ~SWP_NOMOVE;
00987
#endif
00988
00989
if (
TestWF(pwnd,
WFMINIMIZED) &&
IsTrayWindow(pwnd)) {
00990 pcvr->
pos.x =
WHERE_NOONE_CAN_SEE_ME;
00991 pcvr->
pos.y =
WHERE_NOONE_CAN_SEE_ME;
00992 }
00993
00994 }
else {
00995 pcvr->
pos.x = xWindowOld;
00996 pcvr->
pos.y = yWindowOld;
00997 }
00998
00999
if (!(pcvr->
pos.flags & SWP_NOSIZE)) {
01000
01001
01002
01003
01004
01005
01006
01007
01008
if (
TestWF(pwnd,
WFMINIMIZED) &&
01009
_GetProp(pwnd,
PROP_CHECKPOINT,
PROPF_INTERNAL)) {
01010
01011 pcvr->
pos.cx =
SYSMET(CXMINIMIZED);
01012 pcvr->
pos.cy =
SYSMET(CYMINIMIZED);
01013
01014 }
else {
01015
if (pcvr->
pos.cx < 0)
01016 pcvr->
pos.cx = 0;
01017
01018
if (pcvr->
pos.cy < 0)
01019 pcvr->
pos.cy = 0;
01020 }
01021
01022
if (pcvr->
pos.cx == cxWindowOld && pcvr->
pos.cy == cyWindowOld) {
01023 pcvr->
pos.flags |= SWP_NOSIZE;
01024
if (!
TestWF(pwnd,
WFWIN31COMPAT))
01025 fForceNCCalcSize =
TRUE;
01026 }
01027 }
else {
01028 pcvr->
pos.cx = cxWindowOld;
01029 pcvr->
pos.cy = cyWindowOld;
01030 }
01031
01032
#ifdef USE_MIRRORING
01033
if (
TestWF(pwndParent, WEFLAYOUTRTL) &&
TestwndChild(pwnd) && (pwndParent !=
PWNDDESKTOP(pwnd))) {
01034
if (!(pcvr->
pos.flags & SWP_NOMOVE)) {
01035 pcvr->
pos.x = (pwndParent->
rcClient.right - pwndParent->
rcClient.left) - (pcvr->
pos.x + pcvr->
pos.cx);
01036 }
else {
01037
if (!(pcvr->
pos.flags & SWP_NOSIZE)) {
01038 pcvr->
pos.x -= (pcvr->
pos.cx - cxWindowOld);
01039 }
01040 }
01041 }
01042
#endif
01043
01044
01045
01046
01047
01048
if (
TestWF(pwnd,
WFVISIBLE)) {
01049 pcvr->
pos.flags &= ~SWP_SHOWWINDOW;
01050 }
else {
01051 pcvr->
pos.flags &= ~SWP_HIDEWINDOW;
01052
01053
01054
01055
01056
01057
if (!(pcvr->
pos.flags & SWP_SHOWWINDOW))
01058 pcvr->
pos.flags |= SWP_NOREDRAW;
01059 }
01060
01061
01062
01063
01064
01065
if (
TestWF(pwnd,
WFBOTTOMMOST)) {
01066 pcvr->
pos.flags &= ~SWP_NOZORDER;
01067 pcvr->
pos.hwndInsertAfter = HWND_BOTTOM;
01068 }
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
if (fNoZorder && !(pcvr->
pos.flags & SWP_NOZORDER)) {
01082
01083
01084
01085
01086
01087
01088 fNoZorder =
FALSE;
01089
if (!
TestWF(pwnd,
WFTOGGLETOPMOST) &&
ValidateZorder(pcvr)) {
01090 fNoZorder =
TRUE;
01091 pcvr->
pos.flags |= SWP_NOZORDER;
01092 }
01093 }
01094
01095
01096
01097
01098
01099
if (!(pcvr->
pos.flags & SWP_NOREDRAW)) {
01100
if ((pcvr->
pos.flags & SWP_CHANGEMASK) == SWP_NOCHANGE ||
01101 !
_FChildVisible(pwnd)) {
01102 pcvr->
pos.flags |= SWP_NOREDRAW;
01103 }
01104 }
01105
01106
01107
01108
01109
01110
01111
01112
01113
if (!(pcvr->
pos.flags & SWP_NOMOVE) &&
01114 !
TestWF(pwnd,
WFWIN31COMPAT) &&
01115 (
GetAppCompatFlags(
NULL) & GACF_NCCALCSIZEONMOVE)) {
01116
01117 fForceNCCalcSize =
TRUE;
01118 }
01119
01120
01121
01122
01123
01124
if (((pcvr->
pos.flags & (SWP_NOSIZE | SWP_FRAMECHANGED)) != SWP_NOSIZE) ||
01125 fForceNCCalcSize) {
01126
01127 WINDOWPOS pos;
01128
01129
01130
01131
01132
if (!
TestWF(pwnd,
WFCHILD) && !
TestWF(pwnd,
WEFTOOLWINDOW)) {
01133
xxxCheckFullScreen(pwnd, (
PSIZERECT)&pcvr->
pos.x);
01134 }
01135
01136
01137
01138
01139
01140
01141 pos = pcvr->
pos;
01142 params.lppos = &pos;
01143
01144
01145
01146
01147
01148
01149
#define rcWindowNew params.rgrc[0]
01150
#define rcWindowOld params.rgrc[1]
01151
#define rcClientOld params.rgrc[2]
01152
01153
01154
01155
01156
rcWindowNew.left = pcvr->
pos.x;
01157
rcWindowNew.right =
rcWindowNew.left + pcvr->
pos.cx;
01158
rcWindowNew.top = pcvr->
pos.y;
01159
rcWindowNew.bottom =
rcWindowNew.top + pcvr->
pos.cy;
01160
01161
01162
01163
01164
GetRect(pwnd, &
rcWindowOld,
GRECT_WINDOW |
GRECT_PARENTCOORDS);
01165
01166
01167
01168
01169
GetRect(pwnd, &
rcClientOld,
GRECT_CLIENT |
GRECT_PARENTCOORDS);
01170
01171
01172
01173
01174 xClientOld =
rcClientOld.left;
01175 cxClientOld =
rcClientOld.right -
rcClientOld.left;
01176 yClientOld =
rcClientOld.top;
01177 cyClientOld =
rcClientOld.bottom -
rcClientOld.top;
01178
01179 cmd = (
UINT)
xxxSendMessage(pwnd, WM_NCCALCSIZE,
TRUE, (LPARAM)¶ms);
01180
01181
if (!
IsStillWindowC(pcvr->
pos.hwndInsertAfter)) {
01182
ThreadUnlock(&tlpwnd);
01183
ThreadUnlock(&tlpwndParent);
01184
return FALSE;
01185 }
01186
01187
01188
01189
01190
01191
01192
01193
01194
#undef rcWindowNew
01195
#undef rcWindowOld
01196
#undef rcClientOld
01197
01198
#define rcClientNew params.rgrc[0]
01199
#define rcValidDst params.rgrc[1]
01200
#define rcValidSrc params.rgrc[2]
01201
01202
01203
01204
01205
01206
01207
01208
if (cmd < WVR_MINVALID || cmd > WVR_MAXVALID) {
01209
01210
01211
01212
01213
01214
01215
01216
rcValidDst =
rcClientNew;
01217
01218 cmd = WVR_ALIGNTOP | WVR_ALIGNLEFT;
01219 }
01220
01221
01222
01223
01224
#ifdef USE_MIRRORING
01225
if (
TestWF(pwnd, WEFLAYOUTRTL)) {
01226 pcvr->
dxBlt =
rcValidDst.right -
rcValidSrc.right;
01227 }
else
01228
#endif
01229
{
01230 pcvr->
dxBlt =
rcValidDst.left -
rcValidSrc.left;
01231 }
01232 pcvr->
dyBlt =
rcValidDst.top -
rcValidSrc.top;
01233
01234
01235
01236
01237 pcvr->
xClientNew =
rcClientNew.left;
01238 pcvr->
yClientNew =
rcClientNew.top;
01239
01240 pcvr->
cxClientNew =
rcClientNew.right -
rcClientNew.left;
01241 pcvr->
cyClientNew =
rcClientNew.bottom -
rcClientNew.top;
01242
01243
01244
01245
01246
01247
if (xClientOld !=
rcClientNew.left || yClientOld !=
rcClientNew.top)
01248 pcvr->
pos.flags &= ~SWP_NOCLIENTMOVE;
01249
01250
if (cxClientOld != pcvr->
cxClientNew || cyClientOld != pcvr->
cyClientNew) {
01251 pcvr->
pos.flags &= ~SWP_NOCLIENTSIZE;
01252 }
01253
01254
01255
01256
01257
if (pcvr->
pos.flags & SWP_NOCOPYBITS) {
01258 AllInvalid:
01259
01260
01261
01262
01263
01264
SetRectEmpty(&pcvr->
rcBlt);
01265
ThreadUnlock(&tlpwnd);
01266
continue;
01267 }
01268
01269
01270
01271
01272
01273
01274
if (
TestWF(pwnd,
WEFTRANSPARENT))
01275
goto AllInvalid;
01276
01277
01278
01279
01280
01281
01282
01283
if (
GetLayeredWindow(pwnd) !=
NULL)
01284
goto AllInvalid;
01285
01286
01287
01288
01289
01290
01291
if (((pcvr->
pos.flags &
01292 (SWP_NOSIZE | SWP_NOCLIENTSIZE | SWP_FRAMECHANGED))
01293 == (SWP_NOSIZE | SWP_NOCLIENTSIZE)) &&
01294 pcvr->
dxBlt == (pcvr->
pos.x - xWindowOld) &&
01295 pcvr->
dyBlt == (pcvr->
pos.y - yWindowOld)) {
01296
01297
goto AllValid;
01298 }
01299
01300
01301
01302
01303
01304
01305
01306
01307
if (cxClientOld != pcvr->
cxClientNew) {
01308
01309
if ((cmd & WVR_HREDRAW) ||
TestCF(pwnd,
CFHREDRAW))
01310
goto AllInvalid;
01311 }
01312
01313
if (cyClientOld != pcvr->
cyClientNew) {
01314
01315
if ((cmd & WVR_VREDRAW) ||
TestCF(pwnd,
CFVREDRAW))
01316
goto AllInvalid;
01317 }
01318
01319 cxSrc =
rcValidSrc.right -
rcValidSrc.left;
01320 cySrc =
rcValidSrc.bottom -
rcValidSrc.top;
01321
01322 cxDst =
rcValidDst.right -
rcValidDst.left;
01323 cyDst =
rcValidDst.bottom -
rcValidDst.top;
01324
01325
#ifdef USE_MIRRORING
01326
if ((!!(cmd & WVR_ALIGNRIGHT)) ^ (!!
TestWF(pwnd, WEFLAYOUTRTL)))
01327
rcValidDst.left += ((
TestWF(pwnd, WEFLAYOUTRTL) && (cxSrc > cxDst)) ? (cxSrc-cxDst) : (cxDst - cxSrc));
01328
#else
01329
if (cmd & WVR_ALIGNRIGHT)
01330
rcValidDst.left += (cxDst - cxSrc);
01331
#endif
01332
01333
if (cmd & WVR_ALIGNBOTTOM)
01334
rcValidDst.top += (cyDst - cySrc);
01335
01336
01337
01338
01339
01340
01341
01342
if (cxSrc < cxDst)
01343
rcValidDst.right =
rcValidDst.left + cxSrc;
01344
01345
if (cySrc < cyDst)
01346
rcValidDst.bottom =
rcValidDst.top + cySrc;
01347
01348
01349
01350
01351 pcvr->
rcBlt =
rcValidDst;
01352
if (pwndParent !=
PWNDDESKTOP(pwnd)) {
01353
01354
OffsetRect(
01355 &pcvr->
rcBlt,
01356 pwndParent->
rcClient.left,
01357 pwndParent->
rcClient.top);
01358 }
01359 }
else {
01360
01361 AllValid:
01362
01363
01364
01365
01366
01367
01368
if (pcvr->
pos.flags & SWP_NOCOPYBITS) {
01369
SetRectEmpty(&pcvr->
rcBlt);
01370 }
else {
01371 pcvr->
rcBlt.left = pcvr->
pos.x;
01372 pcvr->
rcBlt.top = pcvr->
pos.y;
01373
01374
if (pwndParent !=
PWNDDESKTOP(pwnd)) {
01375 pcvr->
rcBlt.left += pwndParent->
rcClient.left;
01376 pcvr->
rcBlt.top += pwndParent->
rcClient.top;
01377 }
01378
01379 pcvr->
rcBlt.right = pcvr->
rcBlt.left + pcvr->
pos.cx;
01380 pcvr->
rcBlt.bottom = pcvr->
rcBlt.top + pcvr->
pos.cy;
01381 }
01382
01383
01384
01385
01386
#ifdef USE_MIRRORING
01387
if (
TestWF(pwnd, WEFLAYOUTRTL)) {
01388 pcvr->
dxBlt = (pcvr->
pos.x + pcvr->
pos.cx) - (xWindowOld + cxWindowOld);
01389 }
else
01390
#endif
01391
{
01392 pcvr->
dxBlt = pcvr->
pos.x - xWindowOld;
01393 }
01394
01395 pcvr->
dyBlt = pcvr->
pos.y - yWindowOld;
01396
01397
01398
01399
01400
if (!(pcvr->
pos.flags & SWP_NOMOVE)) {
01401 pcvr->
pos.flags &= ~SWP_NOCLIENTMOVE;
01402
01403 pcvr->
xClientNew = pwnd->
rcClient.left + pcvr->
dxBlt;
01404 pcvr->
yClientNew = pwnd->
rcClient.top + pcvr->
dyBlt;
01405
if (pwndParent !=
PWNDDESKTOP(pwnd)) {
01406 pcvr->
xClientNew -= pwndParent->
rcClient.left;
01407 pcvr->
yClientNew -= pwndParent->
rcClient.top;
01408 }
01409
01410 pcvr->
cxClientNew = pwnd->
rcClient.right - pwnd->
rcClient.left;
01411 pcvr->
cyClientNew = pwnd->
rcClient.bottom - pwnd->
rcClient.top;
01412 }
01413 }
01414
01415
ThreadUnlock(&tlpwnd);
01416
01417 }
01418
01419
ThreadUnlock(&tlpwndParent);
01420 *phwndNewActive = hwndNewActive;
01421
01422
return TRUE;
01423 }
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436 PWND GetLastTopMostWindow(VOID)
01437 {
01438
PWND pwndT;
01439
PDESKTOP pdesk =
PtiCurrent()->rpdesk;
01440
01441
if (pdesk ==
NULL)
01442
return NULL;
01443
01444 pwndT = pdesk->
pDeskInfo->
spwnd->
spwndChild;
01445
01446
if (!pwndT || !
TestWF(pwndT,
WEFTOPMOST))
01447
return NULL;
01448
01449
while (pwndT->
spwndNext) {
01450
01451
if (!
TestWF(pwndT->
spwndNext,
WEFTOPMOST))
01452
break;
01453
01454 pwndT = pwndT->
spwndNext;
01455 }
01456
01457
return pwndT;
01458 }
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468 BOOL xxxSetWindowPos(
01469
PWND pwnd,
01470
PWND pwndInsertAfter,
01471
int x,
01472
int y,
01473
int cx,
01474
int cy,
01475 UINT flags)
01476 {
01477
PSMWP psmwp;
01478
BOOL fInval =
FALSE;
01479
01480
#if DBG
01481
CheckLock(pwnd);
01482
01483
switch((ULONG_PTR)pwndInsertAfter) {
01484
case 0x0000FFFF:
01485
case (ULONG_PTR)HWND_TOPMOST:
01486
case (ULONG_PTR)HWND_NOTOPMOST:
01487
case (ULONG_PTR)HWND_TOP:
01488
case (ULONG_PTR)HWND_BOTTOM:
01489
break;
01490
01491
default:
01492
CheckLock(pwndInsertAfter);
01493
break;
01494 }
01495
#endif
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
if (flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW)) {
01516
01517
if (!
TestWF(pwnd,
WFWIN31COMPAT)) {
01518
01519 flags |= SWP_NOMOVE | SWP_NOSIZE;
01520
if ((flags & SWP_SHOWWINDOW) &&
TestWF(pwnd,
WFVISIBLE))
01521 fInval =
TRUE;
01522 }
01523 }
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
if ( !
TestWF(pwnd,
WFWIN50COMPAT) &&
01535
gpDispInfo->
cMonitors > 1 &&
01536 !(flags & SWP_NOMOVE) &&
01537 !
TestWF(pwnd,
WFCHILD) &&
01538 !
TestWF(pwnd,
WFVISIBLE) &&
01539 (
TestWF(pwnd,
WFBORDERMASK) ==
LOBYTE(
WFCAPTION)) &&
01540 pwnd->
spwndOwner &&
01541
TestWF(pwnd->
spwndOwner,
WFVISIBLE) &&
01542 !
IsRectEmpty(&pwnd->
spwndOwner->
rcWindow)) {
01543
01544
FixBogusSWP(pwnd, &x, &y, cx,
cy, flags);
01545
01546 }
01547
01548
if (!(psmwp =
InternalBeginDeferWindowPos(1)) ||
01549 !(psmwp =
_DeferWindowPos(psmwp,
01550 pwnd,
01551 pwndInsertAfter,
01552 x,
01553 y,
01554 cx,
01555
cy,
01556 flags))) {
01557
01558
return FALSE;
01559 }
01560
01561
01562
if (
xxxEndDeferWindowPosEx(psmwp, flags & SWP_ASYNCWINDOWPOS)) {
01563
01564
if (fInval) {
01565
xxxRedrawWindow(
01566 pwnd,
01567
NULL,
01568
NULL,
01569 RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN);
01570 }
01571
01572
return TRUE;
01573 }
01574
01575
return FALSE;
01576 }
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586 BOOL xxxSwpActivate(
01587
PWND pwndNewActive)
01588 {
01589
PTHREADINFO pti;
01590
01591
CheckLock(pwndNewActive);
01592
01593
if (pwndNewActive ==
NULL)
01594
return FALSE;
01595
01596 pti =
PtiCurrent();
01597
01598
if (
TestwndChild(pwndNewActive)) {
01599
01600
xxxSendMessage(pwndNewActive, WM_CHILDACTIVATE, 0, 0
L);
01601
01602 }
else if (pti->
pq->
spwndActive != pwndNewActive) {
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
#ifdef DONTDOTHISANYMORE
01627
if ((pti->
pq ==
gpqForeground) && (pti !=
GETPTI(pwndNewActive))) {
01628
01629
01630
01631 pti->
TIF_flags |=
TIF_ALLOWFOREGROUNDACTIVATE;
01632 TAGMSG1(DBGTAG_FOREGROUND,
"xxxSwpActivate set TIF %#p", pti);
01633
GETPTI(pwndNewActive)->TIF_flags |=
TIF_ALLOWFOREGROUNDACTIVATE;
01634 TAGMSG1(DBGTAG_FOREGROUND,
"xxxSwpActivate set TIF %#p",
GETPTI(pwndNewActive));
01635 }
01636
#endif
01637
01638
if (!
xxxActivateWindow(pwndNewActive,
AW_USE))
01639
return FALSE;
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
if (pti->
pq->
spwndActive !=
NULL)
01650
SetWF(pti->
pq->
spwndActive,
WFNONCPAINT);
01651
01652
if (pti->
pq->
spwndActivePrev !=
NULL)
01653
SetWF(pti->
pq->
spwndActivePrev,
WFNONCPAINT);
01654
01655
return TRUE;
01656 }
01657
01658
return FALSE;
01659 }
01660
01661
01662
01663
01664
01665
01666
01667
01668
01669 VOID xxxSendChangedMsgs(
01670
PSMWP psmwp)
01671 {
01672
PWND pwnd;
01673
PCVR pcvr;
01674
int ccvr;
01675
TL tlpwnd;
01676
01677
01678
01679
01680
for (pcvr = psmwp->
acvr, ccvr = psmwp->
ccvr; --ccvr >= 0; pcvr++) {
01681
01682
if (pcvr->
pos.hwnd ==
NULL)
01683
continue;
01684
01685
01686
01687
01688
if ((pcvr->
pos.flags & SWP_CHANGEMASK) == SWP_NOCHANGE)
01689
continue;
01690
01691
if ((pwnd =
RevalidateHwnd(pcvr->
pos.hwnd)) ==
NULL) {
01692 RIPMSG0(RIP_WARNING,
"xxxSendChangedMsgs: window went away in middle");
01693 pcvr->
pos.flags = SWP_NOREDRAW | SWP_NOCHANGE;
01694 pcvr->
pos.hwnd =
NULL;
01695
continue;
01696 }
01697
01698
if (!
IsStillWindowC(pcvr->
pos.hwndInsertAfter)) {
01699 pcvr->
pos.hwnd =
NULL;
01700
continue;
01701 }
01702
01703
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719
ThreadLockAlways(pwnd, &tlpwnd);
01720
xxxSendMessage(pwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)&pcvr->
pos);
01721
01722
01723
01724
01725
01726
if (
FWINABLE() &&
01727 (!(pcvr->
pos.flags & SWP_NOCLIENTMOVE) ||
01728 !(pcvr->
pos.flags & SWP_NOCLIENTSIZE) ||
01729 (pcvr->
pos.flags & SWP_STATECHANGE) ||
01730 (pcvr->
pos.flags & SWP_FRAMECHANGED))) {
01731
xxxWindowEvent(EVENT_OBJECT_LOCATIONCHANGE, pwnd, OBJID_WINDOW, INDEXID_CONTAINER,
WEF_USEPWNDTHREAD);
01732 }
01733
ThreadUnlock(&tlpwnd);
01734 }
01735
01736
01737 }
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753 void AsyncWindowPos(
01754
PSMWP psmwp)
01755 {
01756
BOOL fFinished;
01757
PCVR pcvrFirst;
01758
PCVR pcvr;
01759
PCVR pcvrT;
01760
int ccvrRemaining;
01761
int ccvr;
01762
int chwnd;
01763
PTHREADINFO ptiT;
01764
PTHREADINFO ptiCurrent;
01765
PSMWP psmwpNew;
01766
01767 pcvrFirst = psmwp->
acvr;
01768 ccvrRemaining = psmwp->
ccvr;
01769
01770 ptiCurrent =
PtiCurrent();
01771
01772
while (
TRUE) {
01773
01774 fFinished =
TRUE;
01775
01776
01777
01778
01779
01780
for (; ccvrRemaining != 0; pcvrFirst++, ccvrRemaining--) {
01781
01782
if (pcvrFirst->
pos.hwnd ==
NULL)
01783
continue;
01784
01785 ptiT = pcvrFirst->
pti;
01786
if (ptiT->
pq != ptiCurrent->
pq) {
01787 fFinished =
FALSE;
01788
break;
01789 }
01790 }
01791
01792
if (fFinished) {
01793
return;
01794 }
01795
01796
01797
01798
01799
01800
01801 chwnd = 0;
01802
01803
for (pcvr = pcvrFirst, ccvr = ccvrRemaining; --ccvr >= 0; pcvr++) {
01804
01805
if (pcvr->
pos.hwnd ==
NULL)
01806
continue;
01807
01808
if (pcvr->
pti->
pq == ptiT->
pq)
01809 chwnd++;
01810 }
01811
01812
01813
01814
01815 psmwpNew = (
PSMWP)UserAllocPool(
sizeof(
SMWP) + (
sizeof(
CVR) * chwnd),
01816 TAG_SWP);
01817
01818
01819
01820
01821
01822
if (psmwpNew ==
NULL) {
01823
01824
for (pcvr = pcvrFirst; chwnd != 0; pcvr++) {
01825
01826
if (pcvr->
pti->
pq == ptiT->
pq) {
01827 pcvr->
pos.hwnd =
NULL;
01828 chwnd--;
01829 }
01830 }
01831
01832
continue;
01833 }
01834
01835 psmwpNew->
ccvr = chwnd;
01836 psmwpNew->
acvr = (
PCVR)((
PBYTE)psmwpNew +
sizeof(
SMWP));
01837
01838
for (pcvr = pcvrFirst, pcvrT = psmwpNew->
acvr; chwnd != 0; pcvr++) {
01839
01840
if (pcvr->
pos.hwnd ==
NULL)
01841
continue;
01842
01843
01844
01845
01846
if (pcvr->
pti->
pq == ptiT->
pq) {
01847
01848 *pcvrT++ = *pcvr;
01849 chwnd--;
01850
01851
01852
01853
01854
01855 pcvr->
pos.hwnd =
NULL;
01856 }
01857 }
01858
01859
01860
01861
01862
01863
if (!
PostEventMessage(ptiT, ptiT->
pq,
QEVENT_SETWINDOWPOS,
NULL, 0,
01864 (WPARAM)psmwpNew, (LPARAM)ptiT)) {
01865
01866 RIPMSG1(RIP_WARNING,
"PostEventMessage swp to pti %#p failed", ptiT);
01867 UserFreePool(psmwpNew);
01868 }
01869 }
01870
01871 }
01872
01873
01874
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884 VOID xxxProcessSetWindowPosEvent(
01885
PSMWP psmwpT)
01886 {
01887
PSMWP psmwp;
01888
01889
01890
01891
01892
01893
if ((psmwp =
InternalBeginDeferWindowPos(psmwpT->
ccvr)) ==
NULL) {
01894 UserFreePool(psmwpT);
01895
return;
01896 }
01897
01898
01899
01900
01901 RtlCopyMemory(psmwp->
acvr, psmwpT->
acvr,
sizeof(
CVR) * psmwpT->
ccvr);
01902 psmwp->
ccvr = psmwpT->
ccvr;
01903
01904
01905
01906
01907
01908
xxxEndDeferWindowPosEx(psmwp,
FALSE);
01909
01910
01911
01912
01913 UserFreePool(psmwpT);
01914 }
01915
01916 #define SWP_BOZO ( SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOREDRAW | SWP_NOACTIVATE )
01917
01918
01919
01920
01921
01922
01923
01924
#if DBG
01925
void DBGValidateSibblingZOrder(
PWND pwndParent)
01926 {
01927
PWND pwndT = pwndParent->
spwndChild;
01928
01929
01930
01931
01932
if ((pwndT !=
NULL) && (pwndParent !=
PWNDMESSAGE(pwndParent))) {
01933
BOOL fFoundNonTopMost = !
TestWF(pwndT,
WEFTOPMOST);
01934
while (pwndT !=
NULL) {
01935
if (
TestWF(pwndT,
WEFTOPMOST)) {
01936 UserAssert(!fFoundNonTopMost);
01937 }
else {
01938 fFoundNonTopMost =
TRUE;
01939 }
01940 pwndT = pwndT->
spwndNext;
01941 }
01942 }
01943 }
01944
#else
01945 #define DBGValidateSibblingZOrder(pwndParent)
01946
#endif
01947
01948
01949
01950
01951
01952
01953
01954
01955 VOID zzzChangeStates(
01956
PWND pwndParent,
01957
PSMWP psmwp)
01958 {
01959
int ccvr;
01960
PCVR pcvr;
01961
PWND pwnd;
01962
TL tlpwnd;
01963
TL tlpwndParent;
01964
int czorder = 0;
01965
01966
BEGINATOMICCHECK();
01967
ThreadLockAlways(pwndParent, &tlpwndParent);
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
for (pcvr = psmwp->
acvr, ccvr = psmwp->
ccvr; --ccvr >= 0; pcvr++) {
01989
01990
if (pcvr->
pos.hwnd ==
NULL)
01991
continue;
01992
01993 UserAssert(0 == (pcvr->
pos.flags & SWP_NOTIFYALL));
01994
01995 pwnd =
RevalidateHwnd(pcvr->
pos.hwnd);
01996
01997
if ((pwnd ==
NULL) || !
IsStillWindowC(pcvr->
pos.hwndInsertAfter)) {
01998 RIPMSG0(RIP_WARNING,
"zzzChangeStates: Window went away in middle");
01999 pcvr->
pos.flags = SWP_NOREDRAW | SWP_NOCHANGE;
02000 pcvr->
pos.hwnd =
NULL;
02001 }
02002
02003
#if DBG
02004
02005
02006
02007
02008
02009
02010
if (
TestWF(pwnd,
WFTOGGLETOPMOST) && (pcvr->
pos.flags & SWP_NOZORDER))
02011 RIPMSG0(RIP_WARNING,
"zzzChangeState: WFTOGGLETOPMOST should not be set");
02012
02013
02014
#endif
02015
02016
02017
02018
02019
02020
if ((pcvr->
pos.flags & SWP_CHANGEMASK) == SWP_NOCHANGE) {
02021
02022 pcvr->
pos.flags |= SWP_NOREDRAW;
02023
continue;
02024 }
02025
02026
02027
02028
02029
02030
02031
02032
02033
02034
02035
02036
02037
02038
02039
02040
02041
02042
if (((pcvr->
pos.flags & SWP_CHANGEMASK) ==
02043 (SWP_NOCHANGE & ~SWP_NOZORDER))) {
02044
02045
02046
02047
02048
02049
if ((!
TestWF(pwnd,
WFTOGGLETOPMOST)) &&
ValidateZorder(pcvr)) {
02050
02051
02052
02053
02054
02055
02056 pcvr->
pos.flags |= SWP_NOZORDER | SWP_NOREDRAW;
02057
02058
if (pcvr->
hrgnVisOld) {
02059 GreDeleteObject(pcvr->
hrgnVisOld);
02060 pcvr->
hrgnVisOld =
NULL;
02061 }
02062
continue;
02063 }
02064 }
02065
02066
02067
02068
02069
if ((pcvr->
pos.flags &
02070 (SWP_NOMOVE | SWP_NOSIZE | SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE)) !=
02071 (SWP_NOMOVE | SWP_NOSIZE | SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE)) {
02072
02073
PCARET pcaret = &
PtiCurrent()->pq->caret;
02074
BOOL fRecreateRedirectionBitmap =
FALSE;
02075
02076
if (
FLayeredOrRedirected(pwnd)) {
02077
int cx = pwnd->
rcWindow.right - pwnd->
rcWindow.left;
02078
int cy = pwnd->
rcWindow.bottom - pwnd->
rcWindow.top;
02079
02080
if (cx != pcvr->
pos.cx ||
cy != pcvr->
pos.cy) {
02081 fRecreateRedirectionBitmap =
TRUE;
02082 }
02083 }
02084
02085
02086
02087
02088 pwnd->
rcWindow.left = pcvr->
pos.x;
02089 pwnd->
rcWindow.top = pcvr->
pos.y;
02090
if (pwndParent !=
PWNDDESKTOP(pwnd)) {
02091 pwnd->
rcWindow.left += pwndParent->
rcClient.left;
02092 pwnd->
rcWindow.top += pwndParent->
rcClient.top;
02093 }
02094
02095 pwnd->
rcWindow.right = pwnd->
rcWindow.left + pcvr->
pos.cx;
02096 pwnd->
rcWindow.bottom = pwnd->
rcWindow.top + pcvr->
pos.cy;
02097
02098
if (pwnd->
rcWindow.right < pwnd->
rcWindow.left) {
02099 RIPMSG1(RIP_WARNING,
"SWP: cx changed for pwnd %#p", pwnd);
02100 pwnd->
rcWindow.right = pwnd->
rcWindow.left;
02101 }
02102
02103
if (pwnd->
rcWindow.bottom < pwnd->
rcWindow.top) {
02104 RIPMSG1(RIP_WARNING,
"SWP: cy changed for pwnd %#p", pwnd);
02105 pwnd->
rcWindow.bottom = pwnd->
rcWindow.top;
02106 }
02107
02108
02109
02110
02111
02112
02113
if (pwnd == pcaret->
spwnd) {
02114
02115
02116
02117
02118
02119
02120
02121
int dx = pcvr->
dxBlt + pwnd->
rcClient.left - pcvr->
xClientNew;
02122
int dy = pcvr->
dyBlt + pwnd->
rcClient.top - pcvr->
yClientNew;
02123
02124
if (pwndParent !=
PWNDDESKTOP(pwnd))
02125 {
02126 dx -= pwndParent->
rcClient.left;
02127 dy -= pwndParent->
rcClient.top;
02128 }
02129
02130
if ((dx | dy) != 0) {
02131 pcaret->
x += dx;
02132 pcaret->
y += dy;
02133 }
02134 }
02135
02136
02137
02138
02139
02140 pwnd->
rcClient.left = pcvr->
xClientNew;
02141 pwnd->
rcClient.top = pcvr->
yClientNew;
02142
if (pwndParent !=
PWNDDESKTOP(pwnd))
02143 {
02144 pwnd->
rcClient.left += pwndParent->
rcClient.left;
02145 pwnd->
rcClient.top += pwndParent->
rcClient.top;
02146 }
02147
02148 pwnd->
rcClient.right = pwnd->
rcClient.left + pcvr->
cxClientNew;
02149 pwnd->
rcClient.bottom = pwnd->
rcClient.top + pcvr->
cyClientNew;
02150
02151
02152
02153
02154
02155
02156
if (
TestWF(pwnd,
WFMAXFAKEREGIONAL) &&
IsSmallerThanScreen(pwnd)) {
02157
SelectWindowRgn(pwnd,
NULL);
02158 }
02159
02160
02161
02162
02163
02164
if (fRecreateRedirectionBitmap) {
02165
RecreateRedirectionBitmap(pwnd);
02166 }
02167
02168
02169
02170
02171
02172
if ((pcvr->
dxBlt | pcvr->
dyBlt) != 0) {
02173
02174
02175
02176
02177
if ( pwnd->
hrgnClip >
HRGN_FULL &&
02178 !
TestWF(pwnd,
WFMAXFAKEREGIONAL)) {
02179 GreOffsetRgn(pwnd->
hrgnClip, pcvr->
dxBlt, pcvr->
dyBlt);
02180 }
02181
02182
if (pwnd->
hrgnUpdate >
HRGN_FULL) {
02183 GreOffsetRgn(pwnd->
hrgnUpdate, pcvr->
dxBlt, pcvr->
dyBlt);
02184 }
02185
OffsetChildren(pwnd, pcvr->
dxBlt, pcvr->
dyBlt,
NULL);
02186
02187
02188
02189
02190
02191
if (
TestWF(pwnd,
WEFLAYERED)) {
02192 POINT ptPos = {pcvr->
pos.x, pcvr->
pos.y};
02193
02194 GreUpdateSprite(
gpDispInfo->
hDev,
PtoHq(pwnd),
NULL,
NULL,
02195 &ptPos,
NULL,
NULL,
NULL, 0,
NULL, 0,
NULL);
02196 }
02197 }
02198 }
02199
02200
02201
02202
02203
02204
if (!(pcvr->
pos.flags & SWP_NOZORDER)) {
02205
02206
if (
ValidateWindowPos(pcvr, pwndParent)) {
02207
02208
UnlinkWindow(pwnd, pwndParent);
02209
02210
LinkWindow(pwnd,
02211
PWInsertAfter(pcvr->
pos.hwndInsertAfter),
02212 pwndParent);
02213 czorder++;
02214
02215
02216
02217
02218
02219
02220
02221
02222
02223
02224
02225
02226
02227
if (
TestWF(pwnd,
WFTOGGLETOPMOST)) {
02228
PBYTE pb;
02229
02230
ClrWF(pwnd,
WFTOGGLETOPMOST);
02231 pb = ((
BYTE *)&pwnd->state);
02232 pb[
HIBYTE(
WEFTOPMOST)] ^=
LOBYTE(
WEFTOPMOST);
02233 }
02234 }
else {
02235 pcvr->
pos.flags |= SWP_NOZORDER;
02236
ClrWF(pwnd,
WFTOGGLETOPMOST);
02237 }
02238 }
02239
02240
02241
02242
02243
02244
02245 UserAssert(pwndParent !=
NULL);
02246
ThreadLockAlways(pwnd, &tlpwnd);
02247
if (pcvr->
pos.flags & SWP_SHOWWINDOW) {
02248
02249
02250
02251
02252
02253
02254
if (
GETPTI(pwnd)->ppi->W32PF_Flags & W32PF_APPSTARTING)
02255
zzzCalcStartCursorHide((PW32PROCESS)
GETPTI(pwnd)->ppi, 5000);
02256
02257
02258
02259
02260
SetVisible(pwnd,
SV_SET);
02261
02262
if (
FWINABLE())
02263
zzzWindowEvent(EVENT_OBJECT_SHOW, pwnd, OBJID_WINDOW, INDEXID_CONTAINER,
WEF_USEPWNDTHREAD);
02264
02265
if (
IsTrayWindow(pwnd)) {
02266 psmwp->
bShellNotify =
TRUE;
02267 pcvr->
pos.flags |=
TestWF(pwnd,
WFFRAMEON) ? SWP_NOTIFYACTIVATE|SWP_NOTIFYCREATE: SWP_NOTIFYCREATE;
02268
02269
02270
02271
02272
02273
02274
02275
02276
02277
02278
02279
02280
02281
02282
02283
02284
02285
02286 }
else if (
TestWF(pwnd,
WFFULLSCREEN)) {
02287
02288
02289
02290
02291
02292 psmwp->
bShellNotify =
TRUE;
02293 pcvr->
pos.flags |= SWP_NOTIFYFS;
02294 }
02295
02296
02297
02298
02299
02300
if (!(pcvr->
pos.flags & SWP_NOREDRAW) ||
02301 (pcvr->
pos.flags & SWP_CREATESPB)) {
02302
02303
02304
02305
02306
02307
02308
02309
02310
02311
02312
02313
if (
TestCF(pwnd,
CFSAVEBITS) &&
02314 pwnd->head.rpdesk ==
grpdeskRitInput) {
02315
02316
02317
02318
02319
02320
PWND pwndT;
02321 RECT rcT;
02322
02323
for (pwndT = pwnd->
spwndParent->
spwndChild ;
02324 pwndT;
02325 pwndT = pwndT->
spwndNext) {
02326
02327
if (pwndT == pwnd) {
02328
CreateSpb(pwnd,
FALSE,
gpDispInfo->
hdcScreen);
02329
break;
02330 }
02331
02332
if (
TestWF(pwndT,
WFVISIBLE)) {
02333
02334
02335
02336
02337
02338
if (
IntersectRect(&rcT,
02339 &pwnd->rcWindow,
02340 &pwndT->
rcWindow)) {
02341
break;
02342 }
02343 }
02344 }
02345 }
02346 }
02347
02348 }
else if (pcvr->
pos.flags & SWP_HIDEWINDOW) {
02349
02350
02351
02352
02353
02354
02355
if (((pcvr->
pos.flags &
SWP_BOZO ) !=
SWP_BOZO) &&
02356
IsTrayWindow(pwnd)) {
02357
02358 psmwp->
bShellNotify =
TRUE;
02359 pcvr->
pos.flags |= SWP_NOTIFYDESTROY;
02360
02361
02362
02363
02364
02365
02366
02367
02368
02369
02370
02371
02372
02373 }
02374
02375
02376
02377
02378
SetVisible(pwnd,
SV_UNSET |
SV_CLRFTRUEVIS);
02379
02380
if (
FWINABLE())
02381
zzzWindowEvent(EVENT_OBJECT_HIDE, pwnd, OBJID_WINDOW, INDEXID_CONTAINER,
WEF_USEPWNDTHREAD);
02382 }
02383
02384
02385
02386
02387
02388
02389
02390
02391
02392
02393
02394
02395
02396
if (
TestWF(pwnd,
WFVISIBLE)) {
02397
if ((pcvr->
pos.flags & SWP_STATECHANGE) ||
02398 (!
TestWF(pwnd,
WFWIN31COMPAT) && (pcvr->
pos.flags & SWP_NOREDRAW))) {
02399
02400
SetWF(pwnd,
WFSENDNCPAINT);
02401 }
02402 }
02403
02404
02405
02406
02407
if (pcvr->
hrgnClip !=
NULL) {
02408
SelectWindowRgn(pwnd, pcvr->
hrgnClip);
02409 }
02410
ThreadUnlock(&tlpwnd);
02411 }
02412
02413
02414
02415
02416
02417
02418
if (
FWINABLE() && czorder)
02419
zzzWindowEvent(EVENT_OBJECT_REORDER, pwndParent, OBJID_CLIENT, INDEXID_CONTAINER, 0);
02420
ThreadUnlock(&tlpwndParent);
02421
02422
ENDATOMICCHECK();
02423 }
02424
02425
02426
02427
02428
02429
02430
02431
02432
02433
02434 BOOL SwpCalcVisRgn(
02435
PWND pwnd,
02436 HRGN hrgn)
02437 {
02438
02439
02440
02441
02442
if (!
TestWF(pwnd,
WFVISIBLE))
02443
return FALSE;
02444
02445
02446
02447
02448
return CalcVisRgn(&hrgn,
02449 pwnd,
02450 pwnd,
02451 (
TestWF(pwnd,
WFCLIPSIBLINGS) ?
02452 (DCX_CLIPSIBLINGS | DCX_WINDOW) : (DCX_WINDOW)));
02453 }
02454
02455
02456
02457
02458
02459
02460
02461
02462
02463
02464
02465
02466
02467 BOOL CombineOldNewVis(
02468 HRGN hrgn,
02469 HRGN hrgnVisOld,
02470 HRGN hrgnVisNew,
02471 UINT crgn,
02472 UINT fsRgnEmpty)
02473 {
02474
switch (fsRgnEmpty & (
RE_VISOLD |
RE_VISNEW)) {
02475
case RE_VISOLD:
02476
02477
02478
02479
02480
02481
if (crgn == RGN_DIFF)
02482
return FALSE;
02483
02484
CopyRgn(hrgn, hrgnVisNew);
02485
break;
02486
02487
case RE_VISNEW:
02488
02489
02490
02491
02492
CopyRgn(hrgn, hrgnVisOld);
02493
break;
02494
02495
case RE_VISNEW |
RE_VISOLD:
02496
02497
02498
02499
02500
return FALSE;
02501
02502
case 0:
02503
02504
02505
02506
02507
switch (GreCombineRgn(hrgn, hrgnVisOld, hrgnVisNew, crgn)) {
02508
case NULLREGION:
02509
case ERROR:
02510
return FALSE;
02511
02512
default:
02513
break;
02514 }
02515
break;
02516 }
02517
02518
return TRUE;
02519 }
02520
02521
02522
02523
02524
02525
02526
02527
02528
02529 int BltValidInit(
02530
PSMWP psmwp)
02531 {
02532
int ccvr;
02533
int cIter = 0;
02534
PCVR pcvr;
02535
PWND pwnd;
02536
BOOL fChangeState =
FALSE;
02537
02538
02539
02540
02541
for (pcvr = psmwp->
acvr, ccvr = psmwp->
ccvr; --ccvr >= 0; pcvr++) {
02542
02543
UINT flags = pcvr->
pos.flags;
02544
02545
02546
02547
02548
02549 pcvr->
hrgnVisOld =
NULL;
02550
02551
if (pcvr->
pos.hwnd ==
NULL)
02552
continue;
02553
02554 pwnd =
RevalidateHwnd(pcvr->
pos.hwnd);
02555
02556
if ((pwnd ==
NULL) || !
IsStillWindowC(pcvr->
pos.hwndInsertAfter)) {
02557 pcvr->
pos.hwnd =
NULL;
02558 pcvr->
pos.flags = SWP_NOREDRAW | SWP_NOCHANGE;
02559
continue;
02560 }
02561
02562
02563
02564
02565
02566
02567
02568
02569
if (
AnySpbs() && !(flags & SWP_NOREDRAW))
02570
SpbCheckRect(pwnd, &pwnd->
rcWindow, DCX_WINDOW);
02571
02572
02573
02574
02575 cIter++;
02576
02577
02578
02579
02580
if ((flags & SWP_CHANGEMASK) != SWP_NOCHANGE)
02581 fChangeState =
TRUE;
02582
02583
02584
02585
02586
if (pcvr->
pos.flags & SWP_NOREDRAW)
02587
continue;
02588
02589
if (!
SYSMET(SAMEDISPLAYFORMAT))
02590
PreventInterMonitorBlts(pcvr);
02591
02592 pcvr->
fsRE = 0;
02593 pcvr->
hrgnVisOld =
CreateEmptyRgn();
02594
02595
if (pcvr->
hrgnVisOld ==
NULL ||
02596 !
SwpCalcVisRgn(pwnd, pcvr->
hrgnVisOld)) {
02597
02598 pcvr->
fsRE =
RE_VISOLD;
02599 }
02600 }
02601
02602
return (fChangeState ? cIter : 0);
02603 }
02604
02605
02606
02607
02608
02609
02610
02611
02612
02613
02614
02615
02616
02617
02618
02619
02620
02621
02622
02623
02624
02625
02626
02627
02628
02629
02630
02631
02632
02633
02634
02635
02636
02637
02638
02639
02640
02641
02642
02643
02644
02645
02646
02647
02648
02649
02650
02651
02652
02653
02654
02655
02656
02657
02658
02659
02660
02661
02662
02663
02664
02665
02666
02667
02668
02669
02670
02671
02672
02673
02674
02675
02676
02677
02678
02679
02680
02681 BOOL zzzBltValidBits(
02682
PSMWP psmwp)
02683 {
02684
int ccvr;
02685
int cIter;
02686
PCVR pcvr;
02687
PWND pwnd;
02688
PWND pwndParent;
02689
PWND pwndT;
02690 PWINDOWPOS
ppos;
02691 HRGN hrgnInvalidate;
02692
UINT fsRgnEmpty;
02693
UINT fsSumEmpty;
02694
int cwndShowing;
02695
BOOL fSyncPaint =
FALSE;
02696
BOOL fInvalidateLayers =
FALSE;
02697 HDC hdcScreen =
NULL;
02698
02699
DeferWinEventNotify();
02700 GreLockDisplay(
gpDispInfo->
hDev);
02701
02702
02703
02704
02705
02706
02707
02708
if ((cIter =
BltValidInit(psmwp)) == 0) {
02709
02710 CleanupAndExit:
02711
02712
02713
02714
02715
02716
for (pcvr = psmwp->
acvr, ccvr = psmwp->
ccvr; --ccvr >= 0; pcvr++) {
02717
02718
if (pcvr->
hrgnVisOld) {
02719 GreDeleteObject(pcvr->
hrgnVisOld);
02720 pcvr->
hrgnVisOld =
NULL;
02721 }
02722 }
02723
02724
goto UnlockAndExit;
02725 }
02726
02727
02728
02729
02730
02731
02732
ppos =
NULL;
02733
for (pcvr = psmwp->
acvr, ccvr = psmwp->
ccvr; --ccvr >= 0; pcvr++) {
02734
02735
02736
02737
02738
02739 pwnd =
RevalidateHwnd(pcvr->
pos.hwnd);
02740
02741
if ((pwnd ==
NULL) ||
02742 (pwnd->
spwndParent ==
NULL) ||
02743 !
IsStillWindowC(pcvr->
pos.hwndInsertAfter)) {
02744
02745 pcvr->
pos.hwnd =
NULL;
02746 pcvr->
pos.flags = SWP_NOREDRAW | SWP_NOCHANGE;
02747
continue;
02748 }
02749
02750
02751
02752
02753
02754
if (
ppos ==
NULL)
02755
ppos = &pcvr->
pos;
02756 }
02757
02758
if (
ppos ==
NULL)
02759
goto CleanupAndExit;
02760
02761 UserAssert(
PW(
ppos->hwnd));
02762 pwndParent =
PW(
ppos->hwnd)->spwndParent;
02763 UserAssert(pwndParent);
02764
02765
02766
02767
02768
02769
02770
02771
02772
02773
02774
if (
AnySpbs())
02775
SpbCheck();
02776
02777
02778
02779
02780
zzzChangeStates(pwndParent, psmwp);
02781
02782
02783
02784
02785
02786
02787
02788
02789
02790
02791
02792
02793
02794
02795
02796
zzzInvalidateDCCache(pwndParent,
02797
IDC_MOVEBLT |
02798 (
TestWF(pwndParent,
WFCLIPCHILDREN) ?
02799
IDC_CLIENTONLY :
IDC_CHILDRENONLY));
02800
02801
02802
02803
02804 fsSumEmpty =
RE_VALIDSUM |
RE_INVALIDSUM;
02805 hrgnInvalidate =
ghrgnInvalidSum;
02806
02807
02808
02809
02810
02811 cwndShowing = 0;
02812
02813
for (pcvr = psmwp->
acvr, ccvr = psmwp->
ccvr; --ccvr >= 0; pcvr++) {
02814
02815
02816
02817
02818
02819 cIter--;
02820
02821
if (pcvr->
pos.hwnd ==
NULL)
02822
continue;
02823
02824
02825
02826
02827
if (pcvr->
pos.flags & SWP_NOREDRAW)
02828
continue;
02829
02830
02831
02832
02833 fSyncPaint =
TRUE;
02834
02835 pwnd =
PW(pcvr->
pos.hwnd);
02836
02837 fsRgnEmpty = pcvr->
fsRE;
02838
02839
02840
02841
02842
if (
FLayeredOrRedirected(pwnd)) {
02843
if (
_GetProp(pwnd,
PROP_LAYER,
TRUE) ==
NULL)
02844
goto InvalidEmpty;
02845
02846
02847
02848
02849
02850
02851
02852
02853
02854
02855
if ((pcvr->
pos.flags & SWP_NOSIZE) &&
02856 !(pcvr->
pos.flags & SWP_SHOWWINDOW)) {
02857
goto InvalidEmpty;
02858 }
else {
02859 fInvalidateLayers =
TRUE;
02860 }
02861 }
02862
02863
02864
02865
02866
if (!
SwpCalcVisRgn(pwnd,
ghrgnVisNew))
02867 fsRgnEmpty |=
RE_VISNEW;
02868
02869
02870
02871
02872
02873
02874
02875
if (
AnySpbs())
02876
SpbCheckRect(pwnd, &pwnd->
rcWindow, DCX_WINDOW);
02877
02878
02879
02880
02881
02882
02883
02884
02885
02886
02887
02888
02889
02890
if (fsRgnEmpty & (
RE_VISOLD |
RE_VISNEW))
02891
goto ValidEmpty;
02892
02893
02894
02895
02896
if (pwnd->
hrgnUpdate ==
HRGN_FULL)
02897
goto ValidEmpty;
02898
02899
02900
02901
02902
if ((pcvr->
rcBlt.right <= pcvr->
rcBlt.left) ||
02903 (pcvr->
rcBlt.bottom <= pcvr->
rcBlt.top)) {
02904
02905
goto ValidEmpty;
02906 }
02907
02908 GreSetRectRgn(
ghrgnSWP1,
02909 pcvr->
rcBlt.left - pcvr->
dxBlt,
02910 pcvr->
rcBlt.top - pcvr->
dyBlt,
02911 pcvr->
rcBlt.right - pcvr->
dxBlt,
02912 pcvr->
rcBlt.bottom - pcvr->
dyBlt);
02913
02914
switch (
IntersectRgn(
ghrgnValid,
ghrgnSWP1, pcvr->
hrgnVisOld)) {
02915
case NULLREGION:
02916
case ERROR:
02917
goto ValidEmpty;
02918
break;
02919 }
02920
02921
if (!(fsSumEmpty &
RE_VALIDSUM)) {
02922
switch (
SubtractRgn(
ghrgnValid,
ghrgnValid,
ghrgnValidSum)) {
02923
case NULLREGION:
02924
case ERROR:
02925
goto ValidEmpty;
02926
break;
02927 }
02928 }
02929
02930
if ((pcvr->
dxBlt | pcvr->
dyBlt) != 0)
02931 GreOffsetRgn(
ghrgnValid, pcvr->
dxBlt, pcvr->
dyBlt);
02932
02933
02934
02935
02936
02937 pwndT = pwnd;
02938
02939
do {
02940
02941
if (pwndT->
hrgnUpdate ==
HRGN_FULL)
02942
goto ValidEmpty;
02943
02944
if (pwndT->
hrgnUpdate !=
NULL) {
02945
switch (
SubtractRgn(
ghrgnValid,
ghrgnValid, pwndT->
hrgnUpdate)) {
02946
case NULLREGION:
02947
case ERROR:
02948
goto ValidEmpty;
02949
break;
02950 }
02951 }
02952
02953 pwndT = pwndT->
spwndParent;
02954
02955 }
while (pwndT && !
TestWF(pwndT,
WFCLIPCHILDREN));
02956
02957
02958
02959
02960
if (pcvr->
hrgnInterMonitor !=
NULL) {
02961
switch (
SubtractRgn(
ghrgnValid,
ghrgnValid, pcvr->
hrgnInterMonitor)) {
02962
case NULLREGION:
02963
case ERROR:
02964
goto ValidEmpty;
02965 }
02966 }
02967
02968
switch (
IntersectRgn(
ghrgnValid,
ghrgnValid,
ghrgnVisNew)) {
02969
case NULLREGION:
02970
case ERROR:
02971
02972 ValidEmpty:
02973
02974 fsRgnEmpty |=
RE_VALID;
02975
break;
02976 }
02977
02978
02979
02980
02981
02982
02983
if (!(fsRgnEmpty &
RE_VALID) && ((pcvr->
dxBlt | pcvr->
dyBlt) != 0)) {
02984
02985
if (hdcScreen ==
NULL)
02986 hdcScreen =
gpDispInfo->
hdcScreen;
02987
02988 GreSelectVisRgn(hdcScreen,
ghrgnValid, SVR_COPYNEW);
02989
02990
#ifdef _WINDOWBLT_NOTIFICATION_
02991
02992
02993
02994
02995
02996
02997
02998
02999 NtGdiBitBlt(hdcScreen,
03000 pcvr->
rcBlt.left,
03001 pcvr->
rcBlt.top,
03002 pcvr->
rcBlt.right - pcvr->
rcBlt.left,
03003 pcvr->
rcBlt.bottom - pcvr->
rcBlt.top,
03004 hdcScreen,
03005 pcvr->
rcBlt.left - pcvr->
dxBlt,
03006 pcvr->
rcBlt.top - pcvr->
dyBlt,
03007 SRCCOPY,
03008 0,
03009 GBB_WINDOWBLT);
03010
#else
03011
GreBitBlt(hdcScreen,
03012 pcvr->
rcBlt.left,
03013 pcvr->
rcBlt.top,
03014 pcvr->
rcBlt.right - pcvr->
rcBlt.left,
03015 pcvr->
rcBlt.bottom - pcvr->
rcBlt.top,
03016 hdcScreen,
03017 pcvr->
rcBlt.left - pcvr->
dxBlt,
03018 pcvr->
rcBlt.top - pcvr->
dyBlt,
03019 SRCCOPY,
03020 0);
03021
#endif
03022
}
03023
03024
03025
03026
03027
03028
03029
03030
03031
if (
TestWF(pwnd,
WFHASSPB) &&
03032 !(fsRgnEmpty &
RE_VISOLD) &&
03033
CombineOldNewVis(
ghrgnInvalid, pcvr->
hrgnVisOld,
ghrgnVisNew, RGN_DIFF, fsRgnEmpty)) {
03034
03035
UINT retRSPB;
03036
03037
03038
03039
03040
03041
03042
03043
03044
03045
03046
03047
03048
03049
03050
03051
03052
if ((retRSPB =
RestoreSpb(pwnd,
ghrgnInvalid, &hdcScreen)) ==
RSPB_NO_INVALIDATE) {
03053
03054
03055
03056
03057
03058
if (fsRgnEmpty &
RE_VISNEW)
03059
goto InvalidEmpty;
03060
03061 }
else if (retRSPB ==
RSPB_INVALIDATE_SSB) {
03062
03063
03064
03065
03066
03067
03068
03069
03070
if (!(fsSumEmpty &
RE_VALIDSUM))
03071
SubtractRgn(
ghrgnValidSum,
ghrgnValidSum,
ghrgnInvalid);
03072 }
03073
03074
03075
03076
03077
if (!(fsRgnEmpty &
RE_VISNEW))
03078
UnionRgn(
ghrgnInvalid,
ghrgnInvalid,
ghrgnVisNew);
03079
03080
03081
03082
03083
03084
03085
03086
if (!(fsRgnEmpty &
RE_VALIDSUM)) {
03087
switch (
SubtractRgn(
ghrgnValid,
ghrgnValid,
ghrgnInvalid)) {
03088
case NULLREGION:
03089
case ERROR:
03090 fsRgnEmpty |=
RE_VALIDSUM;
03091
break;
03092 }
03093 }
03094
03095 }
else {
03096
03097
03098
03099
03100
03101
03102
if (pcvr->
hrgnVisOld ==
NULL) {
03103
03104
03105
03106
03107
03108
SetRectRgnIndirect(
ghrgnInvalid, &pwndParent->rcWindow);
03109 }
else {
03110
03111
if (!
CombineOldNewVis(
ghrgnInvalid,
03112 pcvr->
hrgnVisOld,
03113
ghrgnVisNew,
03114 RGN_OR,
03115 fsRgnEmpty)) {
03116
03117
goto InvalidEmpty;
03118 }
03119 }
03120 }
03121
03122
03123
03124
03125
03126
03127
if (!(fsRgnEmpty &
RE_VALID)) {
03128
03129
03130
03131
03132
if (fsSumEmpty &
RE_VALIDSUM)
03133
CopyRgn(
ghrgnValidSum,
ghrgnValid);
03134
else
03135
UnionRgn(
ghrgnValidSum,
ghrgnValid,
ghrgnValidSum);
03136 fsSumEmpty &= ~
RE_VALIDSUM;
03137 }
03138
03139
03140
03141
03142
03143
03144
if (!(fsSumEmpty &
RE_VALIDSUM) || !(fsRgnEmpty &
RE_VALID)) {
03145
switch (
SubtractRgn(
ghrgnInvalid,
ghrgnInvalid,
03146 !(fsSumEmpty &
RE_VALIDSUM) ?
ghrgnValidSum :
ghrgnValid)) {
03147
case NULLREGION:
03148
case ERROR:
03149 InvalidEmpty:
03150 fsRgnEmpty |=
RE_INVALID;
03151
break;
03152 }
03153 }
03154
03155
03156
03157
03158
03159
03160
03161
03162
03163
if (
TestWF(pwnd,
WFHASSPB) && !(pcvr->
pos.flags & SWP_SHOWWINDOW) &&
03164 (pcvr->
pos.flags &
03165 (SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_HIDEWINDOW))
03166 != (SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER)) {
03167
03168
FreeSpb(
FindSpb(pwnd));
03169 }
03170
03171
03172
03173
03174
if (pcvr->
hrgnVisOld) {
03175 GreDeleteObject(pcvr->
hrgnVisOld);
03176 pcvr->
hrgnVisOld =
NULL;
03177 }
03178
03179
03180
03181
03182
03183
03184
03185
03186
03187
03188
03189
03190
03191
if (!
TestWF(pwnd,
WFWIN31COMPAT) && (pcvr->
pos.flags & SWP_SHOWWINDOW))
03192 cwndShowing++;
03193
03194
03195
03196
03197
03198
03199
if (!(fsRgnEmpty &
RE_INVALID)) {
03200
03201
03202
03203
03204
03205
03206
03207
03208
03209
03210
03211
03212
03213
03214
03215
03216
03217
03218
if ((fsRgnEmpty &
RE_VALID) && !(fsRgnEmpty &
RE_VISNEW)) {
03219
03220
03221
03222
03223
03224
BEGINATOMICCHECK();
03225
xxxInternalInvalidate(pwnd,
03226
HRGN_FULL,
03227 RDW_INVALIDATE |
03228 RDW_FRAME |
03229 RDW_ERASE |
03230 RDW_ALLCHILDREN);
03231
ENDATOMICCHECK();
03232 }
03233
03234
03235
03236
03237
if (fsSumEmpty &
RE_INVALIDSUM) {
03238
03239
03240
03241
03242
03243
03244
03245
03246
03247
if (cIter == 0) {
03248 hrgnInvalidate =
ghrgnInvalid;
03249 }
else {
03250
CopyRgn(
ghrgnInvalidSum,
ghrgnInvalid);
03251 }
03252
03253 }
else {
03254
03255
UnionRgn(
ghrgnInvalidSum,
ghrgnInvalid,
ghrgnInvalidSum);
03256 }
03257
03258 fsSumEmpty &= ~
RE_INVALIDSUM;
03259 }
03260 }
03261
03262
03263
03264
03265
if (!(fsSumEmpty &
RE_INVALIDSUM)) {
03266
03267
03268
03269
03270
03271
03272
03273
03274
03275
03276
03277
03278
03279
03280
03281
03282
03283
03284
03285
03286
03287
03288
03289
03290
03291
03292
03293
03294
03295
03296
03297
03298
03299
03300
03301
03302
03303
03304
03305
03306
03307
03308
03309
03310
03311
03312
03313
DWORD dwFlags = RDW_INVALIDATE | RDW_ERASE;
03314
if (cwndShowing == psmwp->
ccvr &&
03315 pwndParent !=
PWNDDESKTOP(pwndParent)) {
03316
dwFlags |= RDW_NOCHILDREN;
03317 }
else {
03318
dwFlags |= RDW_ALLCHILDREN;
03319 }
03320
if (fInvalidateLayers) {
03321
dwFlags |= RDW_INVALIDATELAYERS;
03322 }
03323
03324
BEGINATOMICCHECK();
03325
xxxInternalInvalidate(pwndParent, hrgnInvalidate,
dwFlags);
03326
ENDATOMICCHECK();
03327 }
03328
03329
03330
03331
03332
03333
03334
03335
03336
03337
03338
03339
if (
gcountPWO != 0) {
03340 GreClientRgnDone(GCR_WNDOBJEXISTS);
03341 }
03342
03343 UnlockAndExit:
03344
03345
03346
03347
03348
if (hdcScreen !=
NULL) {
03349
03350
03351
03352
03353 GreSelectVisRgn(hdcScreen,
NULL, SVR_DELETEOLD);
03354
03355
03356
03357
03358
03359 GreGetBounds(hdcScreen,
NULL, 0);
03360 }
03361
03362
03363
03364
03365
03366 GreUnlockDisplay(
gpDispInfo->
hDev);
03367
zzzEndDeferWinEventNotify();
03368
03369
return fSyncPaint;
03370 }
03371
03372
03373
03374
03375
03376
03377
03378
03379
03380
03381 VOID xxxHandleWindowPosChanged(
03382
PWND pwnd,
03383 PWINDOWPOS ppos)
03384 {
03385
CheckLock(pwnd);
03386
03387
if (!(
ppos->flags & SWP_NOCLIENTMOVE)) {
03388 POINT pt;
03389
PWND pwndParent;
03390
03391 pt.x = pwnd->
rcClient.left;
03392 pt.y = pwnd->
rcClient.top;
03393
03394 pwndParent = pwnd->
spwndParent;
03395 UserAssert(pwndParent);
03396
03397
if (pwndParent !=
PWNDDESKTOP(pwnd)) {
03398 pt.x -= pwndParent->
rcClient.left;
03399 pt.y -= pwndParent->
rcClient.top;
03400 }
03401
03402
xxxSendMessage(
03403 pwnd,
03404 WM_MOVE,
03405
FALSE,
03406 MAKELONG(pt.x, pt.y));
03407 }
03408
03409
if ((
ppos->flags & SWP_STATECHANGE) || !(
ppos->flags & SWP_NOCLIENTSIZE)) {
03410
03411
if (
TestWF(pwnd,
WFMINIMIZED))
03412
xxxSendSizeMessage(pwnd, SIZEICONIC);
03413
else if (
TestWF(pwnd,
WFMAXIMIZED))
03414
xxxSendSizeMessage(pwnd, SIZEFULLSCREEN);
03415
else
03416
xxxSendSizeMessage(pwnd, SIZENORMAL);
03417 }
03418 }
03419
03420
03421
03422
03423
03424
03425
03426
03427
03428
03429
03430 PWND GetRealOwner(
03431
PWND pwnd)
03432 {
03433
PWND pwndParent = pwnd->
spwndParent;
03434
03435
03436
03437
03438
if (pwnd != pwnd->
spwndOwner && (pwnd = pwnd->
spwndOwner) !=
NULL) {
03439
03440
03441
03442
03443
03444
while (pwnd !=
NULL && pwnd->
spwndParent != pwndParent)
03445 pwnd = pwnd->
spwndParent;
03446 }
03447
03448
return pwnd;
03449 }
03450
03451
03452
03453
03454
03455
03456
03457
03458
03459
03460 PWND NextOwnedWindow(
03461
PWND pwnd,
03462
PWND pwndOwner,
03463
PWND pwndParent)
03464 {
03465
if (pwnd ==
NULL) {
03466 pwnd = pwndParent->
spwndChild;
03467
goto loop;
03468 }
03469
03470
while ((pwnd = pwnd->
spwndNext) !=
NULL) {
03471
03472 loop:
03473
03474
03475
03476
03477
if (pwndOwner ==
GetRealOwner(pwnd))
03478
break;
03479 }
03480
03481
return pwnd;
03482 }
03483
03484
03485
03486
03487
03488
03489
03490
03491
03492
03493
03494
03495
03496
03497
03498 VOID SetTopmost(
03499
PWND pwndRoot,
03500 BOOL fTopmost)
03501 {
03502
PWND pwnd;
03503
03504
03505
03506
03507
03508
03509 UserAssert((fTopmost ==
TRUE) || (fTopmost ==
FALSE));
03510
if (!!
TestWF(pwndRoot,
WEFTOPMOST) ^ fTopmost) {
03511
SetWF(pwndRoot,
WFTOGGLETOPMOST);
03512 }
else {
03513
ClrWF(pwndRoot,
WFTOGGLETOPMOST);
03514 }
03515
03516 pwnd =
NULL;
03517
while (pwnd =
NextOwnedWindow(pwnd, pwndRoot, pwndRoot->
spwndParent)) {
03518
SetTopmost(pwnd, fTopmost);
03519 }
03520
03521 }
03522
03523
03524
03525
03526
03527
03528
#ifdef LATER
03529
03530
03531
03532
03533
03534
03535
03536
BOOL IsBottomIMEWindow(
03537
PWND pwnd)
03538 {
03539
if (
TestCF(pwnd, CFIME) ||
03540 (pwnd->
pcls->
atomClassName ==
gpsi->
atomSysClass[
ICLS_IME])) {
03541
PWND pwndT2 = pwnd;
03542
PWND pwndTopOwner = pwnd;
03543
PWND pwndDesktop;
03544
03545
if (
grpdeskRitInput ==
NULL ||
grpdeskRitInput->
pDeskInfo ==
NULL) {
03546
03547 RIPMSG1(RIP_WARNING,
"IsBottomIMEWindow: Desktop is being created or not yet created. pwnd=%#p\n",
03548 pwnd);
03549
return FALSE;
03550 }
03551
03552 pwndDesktop =
grpdeskRitInput->
pDeskInfo->
spwnd;
03553
03554 UserAssert(pwndDesktop);
03555
03556
03557
03558
03559
while (pwndT2 && (pwndT2 != pwndDesktop)) {
03560 pwndTopOwner = pwndT2;
03561 pwndT2 = pwndT2->
spwndOwner;
03562 }
03563
03564
03565
03566
return (
BOOL)(
TestWF(pwndTopOwner, WFBOTTOMMOST));
03567 }
03568
return FALSE;
03569 }
03570
03571
03572
03573
03574
03575
03576
03577
03578
BOOL ImeCheckBottomIMEWindow(
03579
PWND pwndT)
03580 {
03581
03582
03583
03584
PWND pwndDesktop;
03585
PWND pwndT2 = pwndT->
spwndNext;
03586
PWND pwndTopOwner = pwndT2;
03587
03588 UserAssert(grpdeskRipInput != NULL &&
grpdeskRitInput->
pDeskInfo != NULL);
03589 pwndDesktop =
grpdeskRitInput->
pDeskInfo->
spwnd;
03590
03591
03592
03593
03594
while (pwndT2 && (pwndT2 != pwndDesktop)) {
03595 pwndTopOwner = pwndT2;
03596 pwndT2 = pwndT2->
spwndOwner;
03597 }
03598
03599
if (pwndTopOwner &&
TestWF(pwndTopOwner, WFBOTTOMMOST)) {
03600
03601
03602
03603
return TRUE;
03604 }
03605
03606
return FALSE;
03607 }
03608
#endif // LATER
03609
03610
03611
03612
03613
03614
03615
03616
03617
03618
03619
03620 PWND CalcForegroundInsertAfter(
03621
PWND pwnd)
03622 {
03623
PWND pwndInsertAfter, pwndInsertAfterSave;
03624
PWND pwndT;
03625
PTHREADINFO ptiTop;
03626
#ifdef LATER // see #88810
03627
BOOLEAN fImeOwnerIsBottom =
FALSE;
03628
#endif
03629
03630
03631
03632
03633
03634
03635
03636
03637
03638
03639
03640
03641
if (
TestWF(pwnd,
WFBOTTOMMOST)) {
03642 pwndInsertAfter =
GetLastNonBottomMostWindow(pwnd,
TRUE);
03643 }
else {
03644 pwndInsertAfter =
GetLastTopMostWindow();
03645
#ifdef LATER // see #88810
03646
if (
IS_IME_ENABLED()) {
03647 fImeOwnerIsBottom = IsBottomIMEWindow(pwnd);
03648
if (fImeOwnerIsBottom) {
03649
for (pwndT = pwndInsertAfter; pwndT; pwndT = pwndT->
spwndNext) {
03650
if (ImeCheckBottomIMEWindow(pwndT)) {
03651
03652
03653
03654
break;
03655 }
03656 pwndInsertAfter = pwndT;
03657 }
03658 }
03659 }
03660
#endif // LATER
03661
}
03662
03663
03664
if (!
TestwndChild(pwnd)) {
03665
03666
03667
if ((
GETPTI(pwnd)->TIF_flags &
TIF_ALLOWFOREGROUNDACTIVATE) ||
03668 (
GETPTI(pwnd)->ppi->W32PF_Flags & W32PF_ALLOWFOREGROUNDACTIVATE)) {
03669
03670
return pwndInsertAfter;
03671 }
03672 }
03673
03674
03675
03676
03677
03678
if (
gpqForeground ==
NULL)
03679
return pwndInsertAfter;
03680
03681
if (
GETPTI(pwnd)->pq ==
gpqForeground)
03682
return pwndInsertAfter;
03683
03684
03685
03686
03687
03688 pwndT = ((pwndInsertAfter ==
NULL) ?
03689 pwnd->
spwndParent->
spwndChild :
03690 pwndInsertAfter);
03691
03692
03693
03694
03695
03696 pwndInsertAfterSave = pwndInsertAfter;
03697
03698
for (; pwndT !=
NULL; pwndT = pwndT->
spwndNext) {
03699
03700
03701
03702
03703
03704
03705
03706
if ((pwndT == pwnd) ||
TestWF(pwndT,
WFBOTTOMMOST))
03707
break;
03708
03709
03710
03711
03712
if (
GETPTI(pwndT) !=
GETPTI(pwnd)) {
03713 pwndInsertAfter = pwndT;
03714
continue;
03715 }
03716
03717
03718
03719
03720
03721
if (
TestWF(pwndT,
WEFTOPMOST)) {
03722 pwndInsertAfter = pwndT;
03723
continue;
03724 }
03725
03726
#ifdef LATER // see #88810
03727
03728
if (fImeOwnerIsBottom && ImeCheckBottomIMEWindow(pwndT)) {
03729
03730
03731
03732
03733 pwndInsertAfter = pwndT;
03734
continue;
03735 }
03736
03737
#endif
03738
03739
03740
03741
03742
03743
03744
if (!
TestwndChild(pwndT)) {
03745
if (!
TestWF(pwndT,
WFVISIBLE)) {
03746 pwndInsertAfter = pwndT;
03747
continue;
03748 }
03749 }
03750
03751
break;
03752 }
03753
03754
03755
03756
03757
03758
03759
03760
03761
03762
if ((pwndT ==
NULL) ||
TestWF(pwndT,
WFBOTTOMMOST)) {
03763
03764
03765
03766 pwndInsertAfter = pwndInsertAfterSave;
03767
03768
03769
03770
03771
03772
if ((pwndT = pwndInsertAfter) ==
NULL)
03773 pwndT = pwnd->
spwndParent->
spwndChild;
03774
03775
03776
03777
03778 ptiTop =
NULL;
03779
if (
gpqForeground->
spwndActive !=
NULL)
03780 ptiTop =
GETPTI(
gpqForeground->
spwndActive);
03781
03782
for (; pwndT !=
NULL; pwndT = pwndT->
spwndNext) {
03783
03784
if (
TestWF(pwndT,
WFBOTTOMMOST))
03785
break;
03786
03787
03788
03789
03790
if (
GETPTI(pwndT) != ptiTop)
03791
continue;
03792
03793
03794
03795
03796
03797
03798
03799
03800
if (pwndT->
spwndOwner !=
NULL) {
03801 pwndInsertAfter = pwndT;
03802
continue;
03803 }
03804
03805
03806
03807
03808
03809
if (!
TestWF(pwndT,
WFVISIBLE))
03810
continue;
03811
#ifdef LATER // see #88810
03812
03813
if (fImeOwnerIsBottom && ImeCheckBottomIMEWindow(pwndT)) {
03814
continue;
03815 }
03816
03817
#endif
03818
03819
03820
03821
03822
03823 pwndInsertAfter = pwndT;
03824 }
03825 }
03826
03827 UserAssert(pwnd != pwndInsertAfter);
03828
03829
return pwndInsertAfter;
03830 }
03831
03832
03833
03834
03835
03836
03837
03838
03839
03840
03841
03842
03843 PWND GetTopMostInsertAfter (
PWND pwnd)
03844 {
03845
PWND pwndT;
03846
PTHREADINFO ptiCurrent;
03847
PDESKTOP pdesk;
03848 WORD wfnid;
03849
03850
03851
03852
03853
03854 UserAssert(
gHardErrorHandler.
pti !=
NULL);
03855
03856
03857
03858 wfnid =
GETFNID(pwnd);
03859
if ((wfnid ==
FNID_MENU) || (wfnid ==
FNID_SWITCH)) {
03860
return NULL;
03861 }
03862
03863
03864
03865
03866
03867 ptiCurrent =
PtiCurrent();
03868 UserAssert(ptiCurrent !=
NULL);
03869
03870
if (ptiCurrent ==
gHardErrorHandler.
pti || (ptiCurrent->
ppi->W32PF_Flags & W32PF_SCREENSAVER)) {
03871
return NULL;
03872 }
03873
03874
03875
03876
03877
03878 pdesk = ptiCurrent->
rpdesk;
03879 UserAssert(pdesk !=
NULL);
03880 UserAssert(pdesk->
rpwinstaParent);
03881 UserAssert(pdesk->
rpwinstaParent->
pTerm);
03882
03883
if ((pdesk ==
grpdeskLogon)
03884 || (pdesk !=
gHardErrorHandler.
pti->
rpdesk)) {
03885
return NULL;
03886 }
03887
03888
03889
03890
03891
03892
03893 UserAssert(pdesk->
pDeskInfo);
03894 UserAssert(pdesk->
pDeskInfo->
spwnd);
03895
03896
for (pwndT = pdesk->
pDeskInfo->
spwnd->
spwndChild;
03897 pwndT !=
NULL; pwndT = pwndT->
spwndNext) {
03898
03899
03900
03901
03902
if (!
TestWF(pwndT,
WEFTOPMOST)) {
03903
break;
03904 }
03905
03906
03907
03908
03909
03910
if (
gHardErrorHandler.
pti ==
GETPTI(pwndT)) {
03911
return pwndT;
03912 }
03913 }
03914
03915
return NULL;
03916 }
03917
03918
03919
03920
03921
03922
03923
03924
03925
03926
03927
03928
03929
03930
03931
03932
03933
03934
03935
03936
03937
03938
03939
03940
03941
03942
03943
03944
03945
03946
03947
03948
03949
03950
03951
03952
03953
03954
03955
03956
03957
03958
03959
03960
03961
03962
03963
03964
03965
03966
03967
03968
03969
03970 int CheckTopmost(
03971 PWINDOWPOS ppos)
03972 {
03973
PWND pwnd, pwndInsertAfter, pwndT;
03974
03975
03976
03977
03978
03979
03980
03981
03982
03983
03984
03985
03986
03987
03988
03989
03990
03991
03992
03993
03994
03995 pwnd =
PW(
ppos->hwnd);
03996
if (!(
ppos->flags & SWP_NOACTIVATE) &&
03997 !(
ppos->flags & SWP_NOZORDER) &&
03998 (
ppos->hwndInsertAfter != HWND_TOPMOST &&
03999
ppos->hwndInsertAfter != HWND_NOTOPMOST) &&
04000 (pwnd !=
GETPTI(pwnd)->pq->spwndActive)) {
04001
ppos->hwndInsertAfter = HWND_TOP;
04002 }
04003
04004
04005
04006
04007
if (
ppos->flags & SWP_NOZORDER)
04008
return CTM_NOCHANGE;
04009
04010
04011
if (
ppos->hwndInsertAfter == HWND_BOTTOM) {
04012
04013
return CTM_NOTOPMOST;
04014
04015 }
else if (
ppos->hwndInsertAfter == HWND_NOTOPMOST) {
04016
04017
04018
04019
04020
04021
04022
04023
04024
if (
TestWF(pwnd,
WEFTOPMOST)) {
04025
04026 pwndT =
GetLastTopMostWindow();
04027
ppos->hwndInsertAfter =
HW(pwndT);
04028
04029
if (
ppos->hwndInsertAfter ==
ppos->hwnd) {
04030 pwndT =
_GetWindow(pwnd, GW_HWNDPREV);
04031
ppos->hwndInsertAfter =
HW(pwndT);
04032 }
04033
04034 }
else {
04035
04036 pwndT =
_GetWindow(pwnd, GW_HWNDPREV);
04037
ppos->hwndInsertAfter =
HW(pwndT);
04038 }
04039
04040
return CTM_NOTOPMOST;
04041
04042 }
else if (
ppos->hwndInsertAfter == HWND_TOPMOST) {
04043 pwndT =
GETTOPMOSTINSERTAFTER(pwnd);
04044
if (pwndT !=
NULL) {
04045
ppos->hwndInsertAfter =
HW(pwndT);
04046 }
else {
04047
ppos->hwndInsertAfter = HWND_TOP;
04048 }
04049
04050
return CTM_TOPMOST;
04051
04052 }
else if (
ppos->hwndInsertAfter == HWND_TOP) {
04053
04054
04055
04056
04057
04058
04059
04060
if (
TestWF(pwnd,
WEFTOPMOST)) {
04061 pwndT =
GETTOPMOSTINSERTAFTER(pwnd);
04062
if (pwndT !=
NULL) {
04063
ppos->hwndInsertAfter =
HW(pwndT);
04064 }
04065
return CTM_NOCHANGE;
04066 }
04067
04068
04069
04070
04071
04072 pwndInsertAfter =
CalcForegroundInsertAfter(pwnd);
04073
ppos->hwndInsertAfter =
HW(pwndInsertAfter);
04074
04075
return CTM_NOCHANGE;
04076 }
04077
04078
04079
04080
04081
04082 pwndT =
GetLastTopMostWindow();
04083
if (
ppos->hwndInsertAfter ==
HW(pwndT))
04084
return CTM_NOCHANGE;
04085
04086
04087
04088
04089
04090
if (
TestWF(
PW(
ppos->hwndInsertAfter),
WEFTOPMOST)) {
04091
04092
if (!
TestWF(pwnd,
WEFTOPMOST)) {
04093
return CTM_TOPMOST;
04094 }
04095
04096 pwndT =
GETTOPMOSTINSERTAFTER(pwnd);
04097
if (pwndT !=
NULL) {
04098
ppos->hwndInsertAfter =
HW(pwndT);
04099 }
04100
04101 }
else {
04102
04103
if (
TestWF(pwnd,
WEFTOPMOST))
04104
return CTM_NOTOPMOST;
04105 }
04106
04107
return CTM_NOCHANGE;
04108 }
04109
04110
04111
04112
04113
04114
04115
04116
04117
04118
04119
04120 BOOL IsOwnee(
04121
PWND pwndOwnee,
04122
PWND pwndOwner)
04123 {
04124
PWND pwnd;
04125
04126
while (pwndOwnee !=
NULL) {
04127
04128
04129
04130
04131
for (pwnd = pwndOwnee; pwnd !=
NULL; pwnd = pwnd->
spwndParent) {
04132
if (pwnd == pwndOwner)
04133
return TRUE;
04134 }
04135
04136
04137
04138
04139
04140 pwndOwnee = (pwndOwnee->spwndOwner != pwndOwnee ?
04141 pwndOwnee->spwndOwner :
NULL);
04142 }
04143
04144
return FALSE;
04145 }
04146
04147
04148
04149
04150
04151
04152
04153 BOOL IsBehind(
04154
PWND pwnd,
04155
PWND pwndReference)
04156 {
04157
04158
04159
04160
04161
04162
04163
04164
if (pwndReference == (
PWND)HWND_TOP)
04165
return TRUE;
04166
04167
if (pwndReference == (
PWND)HWND_BOTTOM)
04168
return FALSE;
04169
04170
for ( ; pwnd !=
NULL; pwnd = pwnd->
spwndNext) {
04171
if (pwnd == pwndReference)
04172
return FALSE;
04173 }
04174
04175
return TRUE;
04176 }
04177
04178
04179
04180
04181
04182
04183
04184
04185
04186
04187
04188
04189
04190
04191 PSMWP AddSelfAndOwnees(
04192
PSMWP psmwp,
04193
PWND pwnd,
04194
PWND pwndChange,
04195
PWND pwndInsertAfter,
04196
int iTop)
04197 {
04198
PWND pwndChgOwnee;
04199
PWND pwndT;
04200
BOOL fChgOwneeInserted;
04201
CVR *pcvr;
04202
04203
04204
04205
04206
04207
04208
04209
04210
04211
04212
04213 pwndChgOwnee = pwndChange;
04214
while (pwndChgOwnee !=
NULL) {
04215
04216 pwndT =
GetRealOwner(pwndChgOwnee);
04217
04218
if (pwnd == pwndT)
04219
break;
04220
04221 pwndChgOwnee = pwndT;
04222 }
04223
04224
04225
04226
04227
04228 fChgOwneeInserted =
FALSE;
04229 pwndT =
NULL;
04230
while ((pwndT =
NextOwnedWindow(pwndT, pwnd, pwnd->
spwndParent)) !=
NULL) {
04231
04232
04233
04234
04235
04236
if (pwndChgOwnee ==
NULL) {
04237
04238
04239
04240
04241 psmwp =
AddSelfAndOwnees(psmwp, pwndT,
NULL,
NULL, iTop);
04242
04243 }
else {
04244
04245
04246
04247
04248
04249
04250
if (!fChgOwneeInserted &&
IsBehind(pwndT, pwndInsertAfter)) {
04251
04252 psmwp =
AddSelfAndOwnees(psmwp,
04253 pwndChgOwnee,
04254 pwndChange,
04255 pwndInsertAfter,
04256 iTop);
04257
04258
if (psmwp ==
NULL)
04259
return NULL;
04260
04261 fChgOwneeInserted =
TRUE;
04262 }
04263
04264
if (pwndT != pwndChgOwnee) {
04265
04266
04267
04268
04269 psmwp =
AddSelfAndOwnees(psmwp, pwndT,
NULL,
NULL, iTop);
04270 }
04271 }
04272
04273
if (psmwp ==
NULL)
04274
return NULL;
04275 }
04276
04277
04278
04279
04280
if ((pwndChgOwnee !=
NULL) && !fChgOwneeInserted) {
04281
04282 psmwp =
AddSelfAndOwnees(psmwp,
04283 pwndChgOwnee,
04284 pwndChange,
04285 pwndInsertAfter,
04286 iTop);
04287
04288
if (psmwp ==
NULL)
04289
return NULL;
04290 }
04291
04292
04293
04294
04295 psmwp =
_DeferWindowPos(psmwp, pwnd,
NULL,
04296 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
04297
04298
if (psmwp ==
NULL)
04299
return NULL;
04300
04301
04302
04303
04304
04305
04306
if (iTop != psmwp->
ccvr - 1) {
04307 pcvr = &psmwp->
acvr[psmwp->
ccvr - 1];
04308 pcvr->
pos.hwndInsertAfter = (pcvr - 1)->pos.hwnd;
04309 }
04310
return psmwp;
04311 }
04312
04313
04314
04315
04316
04317
04318
04319
04320
04321
04322
04323 PSMWP ZOrderByOwner2(
04324
PSMWP psmwp,
04325
int iTop)
04326 {
04327
PWND pwndT;
04328
PWND pwndOwnerRoot;
04329
PWND pwndTopInsert;
04330 PWINDOWPOS
ppos;
04331
PWND pwnd;
04332
PWND pwndInsertAfter;
04333
BOOL fHasOwnees;
04334
04335
ppos = &psmwp->
acvr[iTop].
pos;
04336
04337
04338
04339
04340
04341
04342
04343
if ((
ppos->flags & SWP_NOZORDER) ||
04344 (
ppos->flags & SWP_NOOWNERZORDER)) {
04345
04346
return psmwp;
04347 }
04348
04349 pwnd =
PW(
ppos->hwnd);
04350 pwndInsertAfter =
PWInsertAfter(
ppos->hwndInsertAfter);
04351
04352 fHasOwnees = (
NextOwnedWindow(
NULL, pwnd, pwnd->
spwndParent) !=
NULL);
04353
04354
04355
04356
04357
04358
if (!pwnd->
spwndOwner && !fHasOwnees)
04359
return psmwp;
04360
04361
04362
04363
04364
04365 pwndOwnerRoot = pwndT = pwnd;
04366
while ((pwndT =
GetRealOwner(pwndT)) !=
NULL)
04367 pwndOwnerRoot = pwndT;
04368
04369
04370
04371
04372
04373
04374
04375
04376
04377
04378
04379
04380
04381
04382
04383
04384
04385
04386
04387
04388
04389
04390
04391
04392 pwndTopInsert = pwndInsertAfter;
04393
if (pwndInsertAfter == (
PWND)HWND_TOP) {
04394
04395
04396
04397
04398
04399 }
else if (pwndInsertAfter == (
PWND)HWND_BOTTOM) {
04400
04401
04402
04403
04404
04405
for (pwndT = pwnd->spwndParent->spwndChild;
04406 (pwndT !=
NULL) && !
TestWF(pwndT,
WFBOTTOMMOST); pwndT = pwndT->spwndNext) {
04407
04408
04409
04410
04411
if (!
IsOwnee(pwndT, pwndOwnerRoot))
04412 pwndTopInsert = pwndT;
04413 }
04414
04415
04416
04417
04418
04419
if (pwndTopInsert == (
PWND)HWND_BOTTOM)
04420
ppos->flags |= SWP_NOZORDER;
04421
04422 }
else {
04423
04424
04425
04426
04427
if (
IsOwnee(pwndInsertAfter, pwndOwnerRoot)) {
04428
04429
04430
04431
04432
04433
04434
04435
04436
04437
04438
if (!fHasOwnees) {
04439
04440
04441
04442
04443
04444
04445
for (pwndT = pwndInsertAfter; pwndT !=
NULL;
04446 pwndT = pwndT->spwndNext) {
04447
04448
if (pwndT == pwnd->spwndOwner)
04449
return psmwp;
04450 }
04451 }
04452
04453
04454
04455
04456
04457 pwndTopInsert = (
PWND)HWND_TOP;
04458
for (pwndT = pwnd->spwndParent->spwndChild; pwndT !=
NULL;
04459 pwndT = pwndT->spwndNext) {
04460
04461
if (
IsOwnee(pwndT, pwndOwnerRoot))
04462
break;
04463
04464 pwndTopInsert = pwndT;
04465 }
04466 }
04467 }
04468
04469
04470
04471
04472
if (!(
ppos->flags & SWP_NOZORDER)) {
04473
04474
04475
04476
04477 psmwp->
ccvr--;
04478
04479 psmwp =
AddSelfAndOwnees(psmwp,
04480 pwndOwnerRoot,
04481 pwnd,
04482 pwndInsertAfter,
04483 iTop);
04484
04485
04486
04487
04488
if (psmwp !=
NULL)
04489 psmwp->
acvr[iTop].
pos.hwndInsertAfter =
HW(pwndTopInsert);
04490 }
04491
04492
return psmwp;
04493 }
04494
04495
04496
04497
04498
04499
04500
04501
04502
04503 BOOL TrackBackground(WINDOWPOS *ppos,
PWND pwndPrev,
PWND pwnd)
04504 {
04505
PWND pwndT;
04506
04507
if (pwndPrev ==
NULL)
04508
return FALSE;
04509
04510
04511
04512
04513
04514
if (
GETPTI(pwnd)->TIF_flags &
TIF_16BIT) {
04515
04516
if (
gptiForeground ==
NULL)
04517
return FALSE;
04518
04519
if (
GETPTI(pwnd)->ppi ==
gptiForeground->
ppi)
04520
return FALSE;
04521
04522 }
else {
04523
04524
if (
GETPTI(pwnd) ==
gptiForeground)
04525
return FALSE;
04526 }
04527
04528
04529
04530
04531
04532
if (!
FSwpTopmost(pwndPrev))
04533
return FALSE;
04534
04535
04536
04537
04538
04539
04540
04541
04542
if (
TestWF(pwnd,
WEFTOPMOST))
04543
return FALSE;
04544
04545
04546
04547
04548
04549 pwndT =
CalcForegroundInsertAfter(pwnd);
04550
ppos->hwndInsertAfter =
HW(pwndT);
04551
return TRUE;
04552 }
04553
04554
04555
04556
04557
04558
04559
04560
04561
04562
04563 void TrackZorderHelper(WINDOWPOS *ppos, HWND *phwnd)
04564 {
04565
04566
04567
04568
04569
04570
if (*phwnd !=
NULL) {
04571
04572
#if DBG
04573
if (
ppos->hwndInsertAfter != *phwnd) {
04574 RIPMSG0(RIP_WARNING,
"TrackZorder: modified hwndInsertAfter");
04575 }
04576
#endif
04577
04578
ppos->hwndInsertAfter = *phwnd;
04579 }
04580 *phwnd =
ppos->hwnd;
04581 }
04582
04583 PWND TrackZorder(WINDOWPOS* ppos,
PWND pwndPrev, HWND *phwndTop, HWND *phwndReg)
04584 {
04585
PWND pwnd =
PW(
ppos->hwnd);
04586
04587
if (pwnd ==
NULL)
04588
return NULL;
04589
04590
if (
TrackBackground(
ppos, pwndPrev, pwnd)) {
04591 *phwndReg =
ppos->hwnd;
04592 }
else if (
FSwpTopmost(pwnd)) {
04593
TrackZorderHelper(
ppos, phwndTop);
04594 }
else {
04595
TrackZorderHelper(
ppos, phwndReg);
04596 }
04597
04598
return pwnd;
04599 }
04600
04601
04602
04603
04604
04605
04606
04607
04608
04609
04610
04611
04612
04613 PSMWP ZOrderByOwner(
04614
PSMWP psmwp)
04615 {
04616
int i;
04617
PWND pwnd;
04618
PWND pwndT;
04619 WINDOWPOS pos;
04620
PTHREADINFO ptiT;
04621 HRGN hrgnClipSave;
04622
04623
04624
04625
04626
04627
04628
04629
04630
if (
FindValidWindowPos(psmwp) ==
NULL)
04631
return psmwp;
04632
04633
04634
04635
04636
04637
for (i = psmwp->
ccvr; i-- != 0; ) {
04638
04639
int iScan;
04640
int iTop;
04641
int code;
04642 WINDOWPOS *
ppos;
04643 HWND hwndTopmost;
04644 HWND hwndRegular;
04645
04646
if (psmwp->
acvr[0].
pos.hwnd ==
NULL)
04647
continue;
04648
04649 code =
CheckTopmost(&psmwp->
acvr[0].
pos);
04650
04651
04652
04653
04654
04655
04656
04657
04658 pos = psmwp->
acvr[0].
pos;
04659 ptiT = psmwp->
acvr[0].
pti;
04660 hrgnClipSave = psmwp->
acvr[0].
hrgnClip;
04661
04662
04663
04664
04665 iTop = psmwp->
ccvr - 1;
04666
04667
if (iTop != 0) {
04668
04669 RtlCopyMemory(&psmwp->
acvr[0],
04670 &psmwp->
acvr[1],
04671 iTop *
sizeof(
CVR));
04672
04673 psmwp->
acvr[iTop].
pos = pos;
04674 psmwp->
acvr[iTop].
pti = ptiT;
04675 psmwp->
acvr[iTop].
hrgnClip = hrgnClipSave;
04676 }
04677
04678
if ((psmwp =
ZOrderByOwner2(psmwp, iTop)) ==
NULL)
04679
break;
04680
04681
04682
04683
04684
04685
04686
04687
04688
04689
04690
04691
04692
04693
if (code !=
CTM_NOCHANGE) {
04694
PWND pwndRoot =
PW(pos.hwnd);
04695
#if DBG
04696
PWND pwndOriginal = pwndRoot;
04697
#endif
04698
04699
04700
04701
04702
04703 UserAssert(!(pos.flags & SWP_NOZORDER));
04704
04705
04706
04707
04708
04709
if (code ==
CTM_NOTOPMOST) {
04710
04711
while (pwnd =
GetRealOwner(pwndRoot))
04712 pwndRoot = pwnd;
04713 }
04714
04715
#if DBG
04716
if ((pos.flags & SWP_NOOWNERZORDER)
04717 && ((pwndOriginal != pwndRoot)
04718 || (
NextOwnedWindow(
NULL, pwndRoot, pwndRoot->
spwndParent) !=
NULL))) {
04719
04720
04721
04722
04723
04724
04725 RIPMSG2(RIP_WARNING,
"ZOrderByOwner: Topmost change while using SWP_NOOWNERZORDER."
04726
" pwndRoot:%p pwndOriginal:%p",
04727 pwndRoot, pwndOriginal);
04728 }
04729
#endif
04730
04731
SetTopmost(pwndRoot, code ==
CTM_TOPMOST);
04732 }
04733
04734
04735
04736
04737
04738
04739
04740
04741
04742
04743 pwnd =
NULL;
04744 hwndTopmost = hwndRegular =
NULL;
04745
for (iScan = iTop; iScan != psmwp->
ccvr; iScan++) {
04746
04747
ppos = &psmwp->
acvr[iScan].
pos;
04748
04749
if (
ppos->hwnd == pos.hwnd) {
04750
ppos->x = pos.x;
04751
ppos->y = pos.y;
04752
ppos->cx = pos.cx;
04753
ppos->cy = pos.cy;
04754
ppos->flags ^= ((
ppos->flags ^ pos.flags) & ~SWP_NOZORDER);
04755 psmwp->
acvr[iScan].
hrgnClip = hrgnClipSave;
04756 }
04757
04758 pwndT = pwnd;
04759 pwnd =
TrackZorder(
ppos, pwndT, &hwndTopmost, &hwndRegular);
04760 }
04761 }
04762
04763
return psmwp;
04764 }
04765
04766
04767
04768
04769
04770
04771
04772
04773 BOOL xxxEndDeferWindowPosEx(
04774
PSMWP psmwp,
04775 BOOL fAsync)
04776 {
04777
PWND pwndNewActive;
04778
PWND pwndParent;
04779
PWND pwndActive;
04780
PWND pwndActivePrev;
04781 HWND hwndNewActive;
04782 PWINDOWPOS pwp;
04783
BOOL fClearBits;
04784
BOOL fSyncPaint;
04785
UINT cVisWindowsPrev;
04786
PTHREADINFO ptiCurrent =
PtiCurrent();
04787
TL tlpwndNewActive;
04788
TL tlpwndParent;
04789
TL tlcuSMWP;
04790
BOOL fForegroundPrev;
04791
04792 UserAssert(
IsWinEventNotifyDeferredOK());
04793
04794
DBGCheskSMWP(psmwp);
04795
if (psmwp->
bHandle) {
04796
CheckLock(psmwp);
04797 }
04798
04799
04800
04801
04802
if ((psmwp->
ccvr != 0) &&
ValidateSmwp(psmwp, &fSyncPaint)) {
04803
04804
if ((pwp =
FindValidWindowPos(psmwp)) ==
NULL)
04805
goto lbFinished;
04806
04807
04808
04809
04810
04811
04812
04813 UserAssert(
PW(pwp->hwnd));
04814 pwndParent =
PW(pwp->hwnd)->spwndParent;
04815
if (pwndParent ==
NULL || pwndParent->
head.rpdesk ==
NULL)
04816
goto lbFinished;
04817
04818
04819
04820
04821
04822
04823
04824
04825
04826
04827
04828
04829
04830
04831
04832
04833
04834
04835
04836
04837
if (fAsync) {
04838
AsyncWindowPos(psmwp);
04839 }
04840
04841
04842
04843
04844
04845
if (pwndParent ==
PWNDDESKTOP(pwndParent)) {
04846
04847
if ((psmwp =
ZOrderByOwner(psmwp)) ==
NULL) {
04848
return FALSE;
04849 }
04850 }
04851
04852
ThreadLockAlwaysWithPti(ptiCurrent, pwndParent, &tlpwndParent);
04853
ThreadLockPoolCleanup(ptiCurrent, psmwp, &tlcuSMWP,
DestroySMWP);
04854
04855
04856
04857
04858
if (
xxxCalcValidRects(psmwp, &hwndNewActive)) {
04859
04860
int i;
04861
04862 pwndNewActive =
RevalidateHwnd(hwndNewActive);
04863
04864
ThreadLockWithPti(ptiCurrent, pwndNewActive, &tlpwndNewActive);
04865
04866 cVisWindowsPrev = ptiCurrent->
cVisWindows;
04867 fForegroundPrev = (ptiCurrent ==
gptiForeground);
04868
04869
04870
04871
04872
04873 UserAssert(
IsWinEventNotifyDeferredOK());
04874
if (!
zzzBltValidBits(psmwp))
04875 fSyncPaint =
FALSE;
04876 UserAssert(
IsWinEventNotifyDeferredOK());
04877
04878
if (psmwp->
bShellNotify) {
04879
for (i = psmwp->
ccvr; i-- != 0; ) {
04880
04881
04882
04883
04884
if (0 == (psmwp->
acvr[i].
pos.flags & SWP_NOTIFYALL))
04885
continue;
04886
04887
if (psmwp->
acvr[i].
pos.flags & SWP_NOTIFYCREATE) {
04888
PostShellHookMessages(HSHELL_WINDOWCREATED,
04889 (LPARAM)psmwp->
acvr[i].
pos.hwnd);
04890
04891
xxxCallHook(HSHELL_WINDOWCREATED,
04892 (WPARAM)psmwp->
acvr[i].
pos.hwnd,
04893 (LPARAM)0,
04894 WH_SHELL);
04895 }
04896
04897
if (psmwp->
acvr[i].
pos.flags & SWP_NOTIFYDESTROY) {
04898
PostShellHookMessages(HSHELL_WINDOWDESTROYED,
04899 (LPARAM)psmwp->
acvr[i].
pos.hwnd);
04900
04901
xxxCallHook(HSHELL_WINDOWDESTROYED,
04902 (WPARAM)psmwp->
acvr[i].
pos.hwnd,
04903 (LPARAM)0,
04904 WH_SHELL);
04905 }
04906
04907
if (psmwp->
acvr[i].
pos.flags & SWP_NOTIFYACTIVATE) {
04908
PWND pwnd =
RevalidateHwnd(psmwp->
acvr[i].
pos.hwnd);
04909
if (pwnd !=
NULL){
04910
TL tlpwnd;
04911
ThreadLockAlwaysWithPti(ptiCurrent, pwnd, &tlpwnd);
04912
xxxSetTrayWindow(pwnd->
head.rpdesk, pwnd,
NULL);
04913
ThreadUnlock(&tlpwnd);
04914 }
04915 }
04916
04917
if (psmwp->
acvr[i].
pos.flags & SWP_NOTIFYFS) {
04918
xxxSetTrayWindow(ptiCurrent->rpdesk,
STW_SAME,
NULL);
04919 }
04920 }
04921 }
04922
04923
04924
04925
04926
04927
04928
04929
if (fForegroundPrev && cVisWindowsPrev && !ptiCurrent->cVisWindows) {
04930
04931 ptiCurrent->TIF_flags |=
TIF_ALLOWFOREGROUNDACTIVATE;
04932 TAGMSG1(DBGTAG_FOREGROUND,
"xxxEndDeferWindowPosEx set TIF %#p", ptiCurrent);
04933
04934
04935
04936
04937
04938
RestoreForegroundActivate();
04939 }
04940
04941
04942
04943
04944 fClearBits =
FALSE;
04945
if (pwndNewActive !=
NULL)
04946 fClearBits =
xxxSwpActivate(pwndNewActive);
04947
04948
04949
04950
04951
04952 UserAssert(pwndParent);
04953
if (fSyncPaint)
04954
xxxDoSyncPaint(pwndParent,
DSP_ENUMCLIPPEDCHILDREN);
04955
04956
ThreadUnlock(&tlpwndNewActive);
04957
04958
04959
04960
04961
if (fClearBits) {
04962
04963
if (pwndActive = ptiCurrent->pq->spwndActive)
04964
ClrWF(pwndActive,
WFNONCPAINT);
04965
04966
if (pwndActivePrev = ptiCurrent->pq->spwndActivePrev)
04967
ClrWF(pwndActivePrev,
WFNONCPAINT);
04968 }
04969
04970
04971
04972
04973
xxxSendChangedMsgs(psmwp);
04974 }
04975
04976
ThreadUnlockPoolCleanup(ptiCurrent, &tlcuSMWP);
04977
ThreadUnlock(&tlpwndParent);
04978 }
04979
04980 lbFinished:
04981
04982
04983
04984
04985
DestroySMWP(psmwp);
04986
return TRUE;
04987 }
04988
04989
04990
04991
04992
04993
04994
04995
04996
04997
04998
#if DBG
04999
05000
BOOL gfVisVerify =
FALSE;
05001
05002
void VerifycVisWindows(
PWND pwnd)
05003 {
05004
BOOL fShowMeTheWindows =
FALSE;
05005
PTHREADINFO pti =
GETPTI(pwnd);
05006
PWND pwndNext;
05007
UINT uVisWindows = 0;
05008
05009
if (!gfVisVerify) {
05010
return;
05011 }
05012
05013
05014
05015
05016
if ((
int)pti->
cVisWindows < 0) {
05017 RIPMSG0(RIP_ERROR,
"VerifycVisWindows: pti->cVisWindows underflow!");
05018 fShowMeTheWindows =
TRUE;
05019 }
05020
05021
05022
05023
05024
if (pti->
rpdesk ==
NULL || (pti->
TIF_flags &
TIF_SYSTEMTHREAD)) {
05025
return;
05026 }
05027
05028
05029
05030
05031
if (!
FTopLevel(pwnd)) {
05032
return;
05033 }
05034
05035 ShowMeTheWindows:
05036
05037
05038
05039
05040 pwndNext = pti->
rpdesk->
pDeskInfo->
spwnd;
05041
05042
05043
05044
05045
if (pwndNext == pwnd->
spwndParent) {
05046 pwndNext = pwndNext->
spwndChild;
05047 }
else if (pwndNext->
spwndParent != pwnd->
spwndParent) {
05048 RIPMSG1(RIP_WARNING,
"VerifycVisWindows: Non top level window:%#p", pwnd);
05049
return;
05050 }
05051
05052
if (fShowMeTheWindows) {
05053 RIPMSG1(RIP_WARNING,
"VerifycVisWindows: Start window walk at:%#p", pwndNext);
05054 }
05055
05056
05057
05058
05059
while (pwndNext !=
NULL) {
05060
if (pti ==
GETPTI(pwndNext)) {
05061
if (fShowMeTheWindows) {
05062 RIPMSG1(RIP_WARNING,
"VerifycVisWindows: pwndNext:%#p", pwndNext);
05063 }
05064
if (!
TestWF(pwndNext, WFMINIMIZED)
05065 &&
TestWF(pwndNext, WFVISIBLE)) {
05066
05067 uVisWindows++;
05068
05069
if (fShowMeTheWindows) {
05070 RIPMSG1(RIP_WARNING,
"VerifycVisWindows: Counted:%#p", pwndNext);
05071 }
05072 }
05073 }
05074 pwndNext = pwndNext->
spwndNext;
05075 }
05076
05077
05078
05079
05080
if (pti->
cVisWindows != uVisWindows) {
05081 RIPMSG2(RIP_WARNING,
"VerifycVisWindows: pti->cVisWindows:%#lx. uVisWindows:%#lx",
05082 pti->
cVisWindows, uVisWindows);
05083
05084
05085
05086
05087
05088
05089 fShowMeTheWindows =
TRUE;
05090
05091
if (!fShowMeTheWindows) {
05092 fShowMeTheWindows =
TRUE;
05093 uVisWindows = 0;
05094
goto ShowMeTheWindows;
05095 }
05096 }
05097 }
05098
#endif
05099
05100
05101
05102
05103
05104
05105
05106
05107 BOOL FVisCountable(
PWND pwnd)
05108 {
05109
if (!
TestWF(pwnd,
WFDESTROYED)) {
05110
if ((
GETFNID(pwnd) ==
FNID_DESKTOP) ||
05111 (
FTopLevel(pwnd) && !
TestWF(pwnd,
WFMINIMIZED))) {
05112
return TRUE;
05113 }
05114 }
05115
return FALSE;
05116 }
05117
05118
05119
05120
05121
05122
05123 VOID IncVisWindows(
05124
PWND pwnd)
05125 {
05126
if (
FVisCountable(pwnd))
05127
GETPTI(pwnd)->cVisWindows++;
05128
05129
#if DBG
05130
if (!
ISTS())
05131 VerifycVisWindows(pwnd);
05132
#endif
05133
}
05134
05135
05136
05137
05138
05139
05140
05141
05142
05143 __inline
void cDecVis(
PWND pwnd)
05144 {
05145 UserAssert(pwnd !=
NULL);
05146
05147
if (
FVisCountable(pwnd))
05148
GETPTI(pwnd)->cVisWindows--;
05149 }
05150
05151
05152
05153
05154
05155
05156 VOID DecVisWindows(
05157
PWND pwnd)
05158 {
05159
cDecVis(pwnd);
05160
05161
#if DBG
05162
if (!
ISTS())
05163 VerifycVisWindows(pwnd);
05164
#endif
05165
}
05166
05167
05168
05169
05170
05171
05172
05173
05174
05175
05176 VOID SetMinimize(
05177
PWND pwnd,
05178 UINT uFlags)
05179 {
05180
05181
05182
05183
05184
05185
if (uFlags &
SMIN_SET) {
05186 UserAssert(!
TestWF(pwnd,
WFMINIMIZED));
05187
if (
TestWF(pwnd,
WFVISIBLE)) {
05188
05189
05190
05191
05192
05193
#if DBG
05194
cDecVis(pwnd);
05195
#else
05196
DecVisWindows(pwnd);
05197
#endif
05198
}
05199
SetWF(pwnd,
WFMINIMIZED);
05200
05201
#if DBG
05202
VerifycVisWindows(pwnd);
05203
#endif
05204
}
else {
05205
05206 UserAssert(
TestWF(pwnd,
WFMINIMIZED));
05207
ClrWF(pwnd,
WFMINIMIZED);
05208
if (
TestWF(pwnd,
WFVISIBLE)) {
05209
05210
05211
05212
05213
IncVisWindows(pwnd);
05214 }
05215 }
05216 }
05217
05218
05219
05220
05221
05222
05223
05224
05225
05226
05227
05228
05229
05230
05231
05232
05233
05234
05235
05236
05237 VOID SetVisible(
05238
PWND pwnd,
05239 UINT flags)
05240 {
05241
if (flags &
SV_SET) {
05242
05243
#if DBG
05244
if (
TestWF(pwnd,
WFINDESTROY)) {
05245 RIPMSG1(RIP_WARNING,
"SetVisible: show INDESTROY %#p", pwnd);
05246 }
05247
#endif
05248
05249
if (
TestWF(pwnd,
WFVISIBLE)) {
05250 RIPMSG1(RIP_WARNING,
"SetVisible: already visible %#p", pwnd);
05251 }
else {
05252
SetWF(pwnd,
WFVISIBLE);
05253
IncVisWindows(pwnd);
05254 }
05255 }
else {
05256
05257
if (flags &
SV_CLRFTRUEVIS)
05258
ClrFTrueVis(pwnd);
05259
05260
#if DBG
05261
if (
TestWF(pwnd,
WFDESTROYED)) {
05262 RIPMSG1(RIP_WARNING,
"SetVisible: hide DESTROYED %#p", pwnd);
05263 }
05264
#endif
05265
05266
if (
TestWF(pwnd,
WFVISIBLE)) {
05267
ClrWF(pwnd,
WFVISIBLE);
05268
DecVisWindows(pwnd);
05269 }
else {
05270 RIPMSG1(RIP_WARNING,
"SetVisible: already hidden %#p", pwnd);
05271 }
05272 }
05273 }
05274
05275
05276
05277
05278
05279
05280
05281
05282
05283 BOOL IsMaxedRect(
05284 LPRECT lprcWithin,
05285
PCSIZERECT psrcMaybe)
05286 {
05287
return(psrcMaybe->
x <= lprcWithin->left &&
05288 psrcMaybe->
y <= lprcWithin->top &&
05289 psrcMaybe->
cx >= lprcWithin->right - lprcWithin->left &&
05290 psrcMaybe->
cy >= lprcWithin->bottom - lprcWithin->top);
05291 }
05292
05293
05294
05295
05296
05297
05298
05299
05300
05301
05302
05303
05304
05305 BOOL xxxCheckFullScreen(
05306
PWND pwnd,
05307
PSIZERECT psrc)
05308 {
05309
BOOL fYielded =
FALSE;
05310
PMONITOR pMonitor;
05311
PMONITOR pMonitorPrimary;
05312
TL tlpMonitor;
05313 RECT rc;
05314
BOOL fIsPrimary;
05315
05316
05317
CheckLock(pwnd);
05318
05319
05320
05321
05322
05323
05324
05325
05326 UserAssert(!
TestWF(pwnd,
WFCHILD));
05327 UserAssert(!
TestWF(pwnd,
WEFTOOLWINDOW));
05328
05329 pMonitorPrimary =
GetPrimaryMonitor();
05330
if (
gpDispInfo->
cMonitors == 1) {
05331 pMonitor = pMonitorPrimary;
05332 }
else {
05333
05334
05335
05336
05337
05338
05339
05340
05341
05342
05343
05344
05345
05346
05347
05348
05349
05350
05351
if (
IsMaxedRect(&
gpDispInfo->
rcScreen, psrc))
05352
return fYielded;
05353
05354
RECTFromSIZERECT(&rc, psrc);
05355 pMonitor =
_MonitorFromRect(&rc, MONITOR_DEFAULTTOPRIMARY);
05356 }
05357
05358 fIsPrimary = (pMonitor == pMonitorPrimary);
05359
ThreadLockAlways(pMonitor, &tlpMonitor);
05360
05361
if (
IsMaxedRect(&pMonitor->rcWork, psrc)) {
05362
if (
TestWF(pwnd,
WFMAXIMIZED)) {
05363
SetWF(pwnd,
WFREALLYMAXIMIZABLE);
05364
05365
if (
gpDispInfo->
cMonitors > 1) {
05366
05367
05368
05369
05370
05371
05372
05373
05374
05375
05376
PMONITOR pMonitorReal;
05377
05378 pMonitorReal =
_MonitorFromWindow(pwnd, MONITOR_DEFAULTTOPRIMARY);
05379
if (pMonitorReal != pMonitor && fIsPrimary) {
05380
05381
05382
05383 psrc->
x += pMonitorReal->
rcMonitor.left;
05384 psrc->
y += pMonitorReal->
rcMonitor.top;
05385 psrc->
cx -= (pMonitor->rcMonitor.right - pMonitor->rcMonitor.left) +
05386 (pMonitorReal->
rcMonitor.right - pMonitorReal->
rcMonitor.left);
05387
05388 psrc->
cy -= (pMonitor->rcMonitor.bottom - pMonitor->rcMonitor.top) +
05389 (pMonitorReal->
rcMonitor.bottom - pMonitorReal->
rcMonitor.top);
05390
05391
ThreadUnlock(&tlpMonitor);
05392 pMonitor = pMonitorReal;
05393 fIsPrimary =
FALSE;
05394
ThreadLockAlways(pMonitor, &tlpMonitor);
05395 }
05396 }
05397 }
05398
05399
if (
TestWF(pwnd,
WFMAXIMIZED) &&
05400
TestWF(pwnd,
WFMAXBOX) &&
05401 (
TestWF(pwnd,
WFBORDERMASK) ==
LOBYTE(
WFCAPTION))) {
05402
05403
if ( psrc->
y +
SYSMET(CYCAPTION) <= pMonitor->rcMonitor.top &&
05404 psrc->
y + psrc->
cy >= pMonitor->rcMonitor.bottom) {
05405
05406
if (!
TestWF(pwnd,
WFFULLSCREEN)) {
05407
05408
05409
05410
05411 fYielded =
xxxAddFullScreen(pwnd, pMonitor);
05412 }
05413 }
else {
05414
int iRight;
05415
int iBottom;
05416
int dxy;
05417
05418
if (
TestWF(pwnd,
WFFULLSCREEN)) {
05419 fYielded =
xxxRemoveFullScreen(pwnd, pMonitor);
05420 }
05421
05422
05423
05424
05425
05426
05427
05428
05429
05430
05431
05432 dxy =
GetWindowBorders(pwnd->style, pwnd->ExStyle,
TRUE,
FALSE);
05433 dxy *=
SYSMET(CXBORDER);
05434
05435 psrc->
x = pMonitor->rcWork.left - dxy;
05436 psrc->
y = pMonitor->rcWork.top - dxy;
05437
05438 dxy *= 2;
05439 iRight =
05440 pMonitor->rcWork.right - pMonitor->rcWork.left + dxy;
05441 iBottom =
05442 pMonitor->rcWork.bottom - pMonitor->rcWork.top + dxy;
05443
05444
05445
05446
05447
if (pwnd->
pcls->
atomClassName ==
gatomConsoleClass) {
05448 psrc->
cx =
min(iRight, psrc->
cx);
05449 psrc->
cy =
min(iBottom, psrc->
cy);
05450 }
else {
05451 psrc->
cx = iRight;
05452
05453
05454
05455
05456
05457
05458
05459
05460
05461
if (fIsPrimary && !
TestWF(pwnd,
WFWIN40COMPAT)) {
05462 psrc->
cy =
min(iBottom, psrc->
cy);
05463 }
else {
05464 psrc->
cy = iBottom;
05465 }
05466 }
05467 }
05468
05469 }
else if (
IsMaxedRect(&pMonitor->rcMonitor, psrc)) {
05470 fYielded =
xxxAddFullScreen(pwnd, pMonitor);
05471 }
05472 }
else {
05473
if (
TestWF(pwnd,
WFMAXIMIZED)) {
05474
ClrWF(pwnd,
WFREALLYMAXIMIZABLE);
05475 }
05476
05477 fYielded =
xxxRemoveFullScreen(pwnd, pMonitor);
05478 }
05479
05480
ThreadUnlock(&tlpMonitor);
05481
return fYielded;
05482 }
05483
05484
05485
05486
05487
05488
05489
05490
05491
05492
05493
05494
05495 VOID ClrFTrueVis(
05496
PWND pwnd)
05497 {
05498
05499
05500
05501
05502
05503
05504
05505
05506
05507
05508
05509
05510
05511
05512
05513
if (
NEEDSPAINT(pwnd)) {
05514
05515
DeleteMaybeSpecialRgn(pwnd->
hrgnUpdate);
05516
05517
ClrWF(pwnd,
WFINTERNALPAINT);
05518
05519 pwnd->
hrgnUpdate =
NULL;
05520
DecPaintCount(pwnd);
05521 }
05522
05523
for (pwnd = pwnd->
spwndChild; pwnd !=
NULL; pwnd = pwnd->
spwndNext) {
05524
05525
05526
05527
05528
if (
TestWF(pwnd,
WFVISIBLE))
05529
ClrFTrueVis(pwnd);
05530 }
05531 }
05532
05533
05534
05535
05536
05537
05538
05539
05540
05541
05542
05543 VOID OffsetChildren(
05544
PWND pwnd,
05545
int dx,
05546
int dy,
05547 LPRECT prcHitTest)
05548 {
05549 RECT rc;
05550
PWND pwndStop;
05551
05552
if (!pwnd->
spwndChild)
05553
return;
05554
05555 pwndStop = pwnd;
05556 pwnd = pwndStop->
spwndChild;
05557
for (;;) {
05558
05559
05560
05561
if (prcHitTest && !
IntersectRect(&rc, prcHitTest, &pwnd->rcWindow))
05562
goto NextWindow;
05563
05564 pwnd->
rcWindow.left += dx;
05565 pwnd->rcWindow.right += dx;
05566 pwnd->rcWindow.top += dy;
05567 pwnd->rcWindow.bottom += dy;
05568
05569 pwnd->rcClient.left += dx;
05570 pwnd->rcClient.right += dx;
05571 pwnd->rcClient.top += dy;
05572 pwnd->rcClient.bottom += dy;
05573
05574
if (pwnd->hrgnUpdate >
HRGN_FULL && !
TestWF(pwnd,
WFMAXFAKEREGIONAL)) {
05575 GreOffsetRgn(pwnd->hrgnUpdate, dx, dy);
05576 }
05577
05578
05579
05580
05581
if (pwnd->hrgnClip !=
NULL)
05582 GreOffsetRgn(pwnd->hrgnClip, dx, dy);
05583
05584
if (
TestWF(pwnd,
WFHASSPB))
05585
OffsetRect(&(
FindSpb(pwnd))->rc, dx, dy);
05586
05587
#ifdef CHILD_LAYERING
05588
if (
TestWF(pwnd,
WEFLAYERED)) {
05589 POINT ptPos = {pwnd->rcWindow.left, pwnd->rcWindow.top};
05590
05591 GreUpdateSprite(
gpDispInfo->
hDev,
PtoHq(pwnd),
NULL,
NULL,
05592 &ptPos,
NULL,
NULL,
NULL, 0,
NULL, 0,
NULL);
05593 }
05594
#endif // CHILD_LAYERING
05595
05596
05597
05598
05599
if (pwnd->spwndChild) {
05600 pwnd = pwnd->spwndChild;
05601
continue;
05602 }
05603
05604 NextWindow:
05605
if (pwnd->spwndNext) {
05606
05607
05608
05609 pwnd = pwnd->spwndNext;
05610 }
else {
05611
for (;;) {
05612
05613
05614
05615
05616 pwnd = pwnd->spwndParent;
05617
if (pwnd == pwndStop)
05618
return;
05619
05620
if (pwnd->spwndNext) {
05621 pwnd = pwnd->spwndNext;
05622
break;
05623 }
05624 }
05625 }
05626 }
05627 }
05628
05629
05630
05631
05632
05633
05634
05635
05636
05637
05638
05639
05640
05641
05642
05643
05644
05645
05646
05647
05648
05649
05650
05651
05652
05653
05654
05655
05656
05657
05658 #define SWR_FLAGS_REDRAW (SWP_NOCHANGE | SWP_FRAMECHANGED | SWP_NOACTIVATE)
05659 #define SWR_FLAGS_NOREDRAW (SWP_NOCHANGE | SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOREDRAW)
05660
05661 BOOL xxxSetWindowRgn(
05662
PWND pwnd,
05663 HRGN hrgn,
05664 BOOL fRedraw)
05665 {
05666
PSMWP psmwp;
05667 HRGN hrgnClip =
NULL;
05668
BOOL bRet =
FALSE;
05669
05670
05671
05672
05673
05674
05675
05676
05677
05678
05679
05680
05681
05682
if (hrgn) {
05683
05684
if ((hrgnClip =
UserValidateCopyRgn(hrgn)) ==
NULL) {
05685
05686
#if DBG
05687
RIPMSG0(RIP_WARNING,
"xxxSetWindowRgn: Failed to create region!");
05688
#endif
05689
goto swrClean;
05690 }
05691
#ifdef USE_MIRRORING
05692
MirrorRegion(pwnd, hrgnClip,
FALSE);
05693
#endif
05694
}
else {
05695
05696 hrgnClip =
HRGN_FULL;
05697 }
05698
05699
05700
05701
05702
05703
05704
05705
if (psmwp =
InternalBeginDeferWindowPos(1)) {
05706
05707
05708
05709
05710
if (psmwp =
_DeferWindowPos(
05711 psmwp,
05712 pwnd,
05713
PWND_TOP,
05714 0,
05715 0,
05716 0,
05717 0,
05718 fRedraw ?
SWR_FLAGS_REDRAW :
SWR_FLAGS_NOREDRAW)) {
05719
05720
05721
05722
05723
05724
05725 psmwp->
acvr[0].
hrgnClip = hrgnClip;
05726 bRet =
xxxEndDeferWindowPosEx(psmwp,
FALSE);
05727 }
05728 }
05729
05730
05731
05732
05733
05734
05735
if (!bRet && (hrgnClip !=
HRGN_FULL)) {
05736
05737 swrClean:
05738
05739 GreDeleteObject(hrgnClip);
05740 }
05741
05742
return bRet;
05743 }
05744
05745
05746
05747
05748
05749
05750
05751
05752
05753 void SelectWindowRgn(
05754
PWND pwnd,
05755 HRGN hrgnClip)
05756 {
05757
05758
05759
05760
05761
05762
05763
05764
05765
if (pwnd->
hrgnClip !=
NULL) {
05766
if (
TestWF(pwnd,
WFMAXFAKEREGIONAL)) {
05767
ClrWF(pwnd,
WFMAXFAKEREGIONAL);
05768 }
else {
05769
05770
05771
05772
05773
05774
05775
if (hrgnClip ==
HRGN_MONITOR)
05776
return;
05777
05778 GreDeleteObject(pwnd->
hrgnClip);
05779 }
05780
05781 pwnd->
hrgnClip =
NULL;
05782 }
05783
05784
05785
05786
05787
05788
05789
if (hrgnClip >
HRGN_FULL) {
05790
05791
if (hrgnClip ==
HRGN_MONITOR) {
05792
PMONITOR pMonitor;
05793
05794
05795
05796
05797
05798
05799
05800
05801 UserAssert(pwnd->
spwndParent ==
PWNDDESKTOP(pwnd));
05802
05803
if (!
TestWF(pwnd,
WFMAXIMIZED) || !
TestWF(pwnd,
WFREALLYMAXIMIZABLE))
05804
return;
05805
05806
05807
05808
05809 pMonitor =
_MonitorFromWindow(pwnd, MONITOR_DEFAULTTONULL);
05810
if (!pMonitor)
05811
return;
05812
05813 hrgnClip = pMonitor->
hrgnMonitor;
05814
SetWF(pwnd,
WFMAXFAKEREGIONAL);
05815 }
else {
05816
if (pwnd !=
PWNDDESKTOP(pwnd)) {
05817 GreOffsetRgn(hrgnClip, pwnd->
rcWindow.left, pwnd->
rcWindow.top);
05818 }
05819
05820 GreSetRegionOwner(hrgnClip, OBJECT_OWNER_PUBLIC);
05821 }
05822
05823 pwnd->
hrgnClip = hrgnClip;
05824 }
05825 }
05826
05827
05828
05829
05830
05831
05832
05833
05834
05835
05836
05837
05838 #define SLOP_X 8
05839 #define SLOP_Y 8
05840
05841
BOOL
05842 TestRectBogus(RECT * prc,
int x,
int y,
int cx,
int cy)
05843 {
05844
05845
05846
05847
if ( x <= prc->left &&
05848 y <= prc->top &&
05849 cx >= (prc->right - prc->left) &&
05850
cy >= (prc->bottom - prc->top)) {
05851
05852
05853
return FALSE;
05854 }
05855
05856
05857
05858
05859
05860
05861
if (
abs(x - (prc->right + prc->left - cx) / 2) <=
SLOP_X &&
05862
abs(y - (prc->bottom + prc->top -
cy) / 2) <=
SLOP_Y ) {
05863
05864
05865
return TRUE;
05866 }
05867
05868
05869
05870
05871
if ( x == prc->left ||
05872 y == prc->top ||
05873 x == (prc->right - cx) ||
05874 y == (prc->bottom -
cy)) {
05875
05876
05877
return TRUE;
05878 }
05879
05880
return FALSE;
05881 }
05882
05883
05884
05885
05886
05887
05888
05889
05890
05891
05892
05893
05894
BOOL
05895 IsRectBogus(
int x,
int y,
int cx,
int cy)
05896 {
05897
PMONITOR pMonitorPrimary =
GetPrimaryMonitor();
05898
05899
return TestRectBogus(&pMonitorPrimary->
rcWork, x, y, cx,
cy) ||
05900
TestRectBogus(&pMonitorPrimary->
rcMonitor, x, y, cx,
cy);
05901 }
05902
05903
05904
05905
05906
05907
05908
05909
05910
05911
05912
05913
05914
05915
05916
05917
05918
void
05919 FixBogusSWP(
PWND pwnd,
int * px,
int * py,
int cx,
int cy, UINT flags)
05920 {
05921
PMONITOR pMonitor;
05922
05923 pMonitor =
_MonitorFromWindow(pwnd->
spwndOwner, MONITOR_DEFAULTTONEAREST);
05924
05925
05926
05927
05928
if (pMonitor !=
GetPrimaryMonitor()) {
05929
05930
05931
05932
05933
if (flags & SWP_NOSIZE) {
05934 cx = pwnd->
rcWindow.right - pwnd->
rcWindow.left;
05935
cy = pwnd->
rcWindow.bottom - pwnd->
rcWindow.top;
05936 }
05937
05938
05939
05940
05941
if (
IsRectBogus(*px, *py, cx,
cy))
05942 {
05943 RECT rc;
05944
05945
#if DBG
05946
int oldX = *px;
05947
int oldY = *py;
05948
#endif
05949
05950
05951
05952
05953
05954
05955
05956
05957
05958
05959
IntersectRect(&rc, &pMonitor->
rcWork, &pwnd->
spwndOwner->
rcWindow);
05960
05961
05962
05963
05964 *px = rc.left + (rc.right - rc.left - cx) / 2;
05965 *py = rc.top + (rc.bottom - rc.top -
cy) / 2;
05966
05967
05968
05969
05970
if (*px + cx > pMonitor->
rcWork.right) {
05971 *px = pMonitor->
rcWork.right - cx;
05972 }
05973
05974
if (*py +
cy > pMonitor->
rcWork.bottom) {
05975 *py = pMonitor->
rcWork.bottom -
cy;
05976 }
05977
05978
if (*px < pMonitor->
rcWork.left) {
05979 *px = pMonitor->
rcWork.left;
05980 }
05981
05982
if (*py < pMonitor->
rcWork.top) {
05983 *py = pMonitor->
rcWork.top;
05984 }
05985
05986 RIPMSG0(RIP_WARNING | RIP_THERESMORE,
"SetWindowPos detected that your app is centering or clipping");
05987 RIPMSG0(RIP_WARNING | RIP_THERESMORE | RIP_NONAME,
"a window to the primary monitor when its owner is on a different monitor.");
05988 RIPMSG0(RIP_WARNING | RIP_THERESMORE | RIP_NONAME,
"Consider fixing your app to use the Window Manager Multimonitor APIs.");
05989 RIPMSG4(RIP_WARNING | RIP_NONAME,
"SetWindowPos moved the window from (%d,%d) to (%d,%d).\n",
05990 oldX, oldY, *px, *py);
05991 }
05992 }
05993 }
05994
05995
05996
05997
05998
05999
06000
06001
06002
06003
06004
06005
06006
06007
06008
06009
06010
06011
06012
06013 void PreventInterMonitorBlts(
PCVR pcvr)
06014 {
06015 RECT rcSrc;
06016 RECT rcDst;
06017 RECT rcSrcT;
06018 RECT rcDstT;
06019
PMONITOR pMonitor;
06020
06021
06022
06023
if (
IsRectEmpty(&pcvr->
rcBlt))
06024
return;
06025
06026
06027
06028
06029
06030
CopyOffsetRect(&rcSrc, &pcvr->
rcBlt, -pcvr->
dxBlt, -pcvr->
dyBlt);
06031
06032
06033
06034
06035
06036
06037
06038
06039
06040
06041
06042
06043
for (pMonitor =
gpDispInfo->
pMonitorFirst;
06044 pMonitor !=
NULL;
06045 pMonitor = pMonitor->
pMonitorNext) {
06046
06047
06048
06049
06050
if (!(pMonitor->
dwMONFlags &
MONF_VISIBLE))
06051
continue;
06052
06053
06054
06055
06056
if (!
IntersectRect(&rcSrcT, &rcSrc, &pMonitor->
rcMonitor))
06057
continue;
06058
06059
06060
06061
06062
CopyOffsetRect(&rcDst, &rcSrcT, pcvr->
dxBlt, pcvr->
dyBlt);
06063
06064
06065
06066
06067
06068
IntersectRect(&rcDstT, &rcDst, &pMonitor->
rcMonitor);
06069
06070
06071
06072
06073
if (
EqualRect(&rcDstT, &rcDst)) {
06074
06075
06076
06077
06078
06079
if (
EqualRect(&rcSrcT, &rcSrc)) {
06080
06081
06082
06083
06084
06085 UserAssert(pcvr->
hrgnInterMonitor ==
NULL);
06086
return;
06087 }
else {
06088
continue;
06089 }
06090 }
06091
06092
06093
06094
06095
06096
06097
if (pcvr->
hrgnInterMonitor ==
NULL) {
06098 pcvr->
hrgnInterMonitor =
CreateEmptyRgn();
06099 }
06100
06101
06102
06103
06104
06105
06106
06107
06108
06109
06110 GreSetRectRgn(
ghrgnInv2, rcDst.left, rcDst.top, rcDst.right, rcDst.bottom);
06111 GreSetRectRgn(
ghrgnGDC, rcDstT.left, rcDstT.top, rcDstT.right, rcDstT.bottom);
06112
SubtractRgn(
ghrgnInv2,
ghrgnInv2,
ghrgnGDC);
06113
UnionRgn(pcvr->
hrgnInterMonitor, pcvr->
hrgnInterMonitor,
ghrgnInv2);
06114 }
06115
#if DBG
06116
VerifyVisibleMonitorCount();
06117
#endif
06118
}
06119