00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
#include "precomp.h"
00015
#pragma hdrstop
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 BOOL xxxFlashWindow(
00028
PWND pwnd,
00029 DWORD dwFlags,
00030 DWORD dwTimeout)
00031 {
00032
00033
BOOL fStatePrev =
FALSE;
00034
BOOL fFlashOn;
00035
DWORD dwState;
00036
00037
CheckLock(pwnd);
00038
00039
00040
00041
00042 dwState =
GetFlashWindowState(pwnd);
00043
if (dwState == FLASHW_DONE) {
00044
00045
00046
00047 dwState |= FLASHW_KILLTIMER;
00048
dwFlags = FLASHW_STOP;
00049
goto flash;
00050 }
00051
if (dwState == FLASHW_STOP) {
00052
#if defined(_X86_)
00053
00054
00055
00056
00057
if (
gbFullScreen == FULLSCREEN) {
00058
_PostMessage(
gspwndFullScreen, WM_USER + 6, (WPARAM)WINDOWED, (LPARAM)0);
00059 }
00060
#endif // _X86_
00061
if (
TestWF(pwnd,
WFFRAMEON)) {
00062 dwState = FLASHW_ON | FLASHW_STARTON;
00063 }
00064 }
else if (
dwFlags == FLASHW_TIMERCALL) {
00065
dwFlags = dwState;
00066 }
00067
dwFlags &= FLASHW_CALLERBITS;
00068 fStatePrev = (dwState & FLASHW_ON);
00069
00070
00071
00072
00073
if (pwnd ==
gspwndAltTab) {
00074
return fStatePrev;
00075 }
00076
00077
00078
00079
if (dwState & FLASHW_FLASHNOFG) {
00080
if (
gpqForeground ==
GETPTI(pwnd)->pq)
00081
dwFlags = FLASHW_STOP;
00082 }
00083
00084 flash:
00085
00086
00087
00088
if (
dwFlags != FLASHW_STOP) {
00089 fFlashOn = !fStatePrev;
00090 }
else {
00091 fFlashOn = (
gpqForeground !=
NULL) && (
gpqForeground->
spwndActive == pwnd);
00092 }
00093
00094
00095
00096
if ((
dwFlags == FLASHW_STOP) || (
dwFlags & FLASHW_CAPTION)) {
00097
xxxSendMessage(pwnd, WM_NCACTIVATE, fFlashOn, 0
L);
00098 }
00099
if ((
dwFlags == FLASHW_STOP) || (
dwFlags & FLASHW_TRAY)) {
00100
if (
IsTrayWindow(pwnd)) {
00101 HWND hw =
HWq(pwnd);
00102
BOOL fShellFlash;
00103
if (dwState & FLASHW_DONE) {
00104
00105
00106
00107
00108
00109 fShellFlash = !fFlashOn;
00110 }
else {
00111 fShellFlash = (
dwFlags == FLASHW_STOP ?
FALSE : fFlashOn);
00112 }
00113
xxxCallHook(HSHELL_REDRAW, (WPARAM) hw, (LPARAM) fShellFlash, WH_SHELL);
00114
PostShellHookMessages(fShellFlash? HSHELL_FLASH:HSHELL_REDRAW, (LPARAM)hw);
00115 }
00116 }
00117
00118
00119
00120
00121
00122
if (
dwFlags != FLASHW_STOP) {
00123
00124
00125
00126
if (HIWORD(
dwFlags) != 0) {
00127 dwState |= FLASHW_COUNTING;
00128
if (!(fFlashOn ^ !!(dwState & FLASHW_STARTON))) {
00129
dwFlags -= MAKELONG(0,1);
00130 }
00131
00132
00133
00134
if (!(dwState & FLASHW_KILLTIMER)) {
00135
dwFlags |= FLASHW_TIMER;
00136 }
00137 }
00138
00139
00140
00141
if (
dwFlags & FLASHW_TIMER) {
00142 dwState |= FLASHW_KILLTIMER;
00143
InternalSetTimer(pwnd,
00144
IDSYS_FLASHWND,
00145 dwTimeout ? dwTimeout :
gpsi->dtCaretBlink,
00146
xxxSystemTimerProc,
00147 TMRF_SYSTEM);
00148 }
00149
00150
00151
00152
00153
if (dwState & FLASHW_COUNTING &&
00154 HIWORD(
dwFlags) == 0) {
00155 dwState = FLASHW_DONE;
00156 }
00157
else {
00158
SET_OR_CLEAR_FLAG(dwState, FLASHW_ON, fFlashOn);
00159
COPY_FLAG(dwState,
dwFlags, FLASHW_CALLERBITS & ~FLASHW_TIMER);
00160 }
00161
SetFlashWindowState(pwnd, dwState);
00162
00163 }
else {
00164
00165
00166
00167
if (dwState & FLASHW_KILLTIMER) {
00168
_KillSystemTimer(pwnd,
IDSYS_FLASHWND);
00169 }
00170
RemoveFlashWindowState(pwnd);
00171 }
00172
00173
return fStatePrev;
00174 }
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184 BOOL xxxEnableWindow(
00185
PWND pwnd,
00186 BOOL fEnable)
00187 {
00188
BOOL fOldState, fChange;
00189
00190
CheckLock(pwnd);
00191 UserAssert(
IsWinEventNotifyDeferredOK());
00192
00193 fOldState =
TestWF(pwnd,
WFDISABLED);
00194
00195
if (!fEnable) {
00196 fChange = !
TestWF(pwnd,
WFDISABLED);
00197
00198
xxxSendMessage(pwnd, WM_CANCELMODE, 0, 0);
00199
00200
if (pwnd ==
PtiCurrent()->pq->spwndFocus) {
00201
xxxSetFocus(
NULL);
00202 }
00203
SetWF(pwnd,
WFDISABLED);
00204
00205 }
else {
00206 fChange =
TestWF(pwnd,
WFDISABLED);
00207
ClrWF(pwnd,
WFDISABLED);
00208 }
00209
00210
if (fChange) {
00211
if (
FWINABLE()) {
00212
xxxWindowEvent(EVENT_OBJECT_STATECHANGE, pwnd, OBJID_WINDOW,
00213 INDEXID_CONTAINER, 0);
00214 }
00215
xxxSendMessage(pwnd, WM_ENABLE, fEnable, 0
L);
00216 }
00217
00218
return fOldState;
00219 }
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232 LRESULT
xxxDoSend(
00233
PWND pwnd,
00234 UINT message,
00235 WPARAM wParam,
00236 LPARAM lParam)
00237 {
00238
00239
00240
00241
00242
if (
GETPTI(pwnd)->ppi ==
PtiCurrent()->ppi) {
00243
return xxxSendMessage(pwnd, message, wParam, lParam);
00244 }
else {
00245
return xxxDefWindowProc(pwnd, message, wParam, lParam);
00246 }
00247 }
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257 int xxxGetWindowText(
00258
PWND pwnd,
00259 LPTSTR psz,
00260
int cchMax)
00261 {
00262
LARGE_UNICODE_STRING str;
00263
UINT nRet, nLen;
00264
00265
CheckLock(pwnd);
00266
00267
if (cchMax) {
00268
00269
00270
00271
00272 str.
bAnsi =
FALSE;
00273 str.
MaximumLength = cchMax *
sizeof(WCHAR);
00274 str.
Buffer = psz;
00275 str.
Length = 0;
00276
00277 *psz = TEXT(
'\0');
00278
00279 nRet = (
UINT)
xxxDoSend(pwnd, WM_GETTEXT, cchMax, (LPARAM)&str);
00280 nLen = str.Length /
sizeof(WCHAR);
00281
return (nRet > nLen) ? nLen : nRet;
00282 }
00283
00284
return 0;
00285 }
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311 PWND xxxSetParent(
00312
PWND pwnd,
00313
PWND pwndNewParent)
00314 {
00315 POINT pt;
00316
BOOL fVisible;
00317
PWND pwndOldParent;
00318
TL tlpwndOldParent;
00319
TL tlpwndNewParent;
00320 PVOID pvRet;
00321
PWND pwndDesktop;
00322
PWND pwndT;
00323
int flags = SWP_NOZORDER | SWP_NOSIZE;
00324
00325
CheckLock(pwnd);
00326
CheckLock(pwndNewParent);
00327
00328
if (!
ValidateParentDepth(pwnd, pwndNewParent)) {
00329 RIPERR0(ERROR_INVALID_PARAMETER, RIP_WARNING,
"Exceeded nested children limit");
00330
return NULL;
00331 }
00332
00333 pwndDesktop =
PWNDDESKTOP(pwnd);
00334
00335
00336
00337
00338
00339
00340
if (pwndNewParent ==
NULL)
00341 pwndNewParent = pwndDesktop;
00342
00343
00344
00345
00346
if ((pwnd == pwndDesktop) || (pwnd ==
PWNDMESSAGE(pwnd))) {
00347 RIPERR0(ERROR_ACCESS_DENIED,
00348 RIP_WARNING,
00349
"Access denied: can't change parent of the desktop");
00350
00351
return NULL;
00352 }
00353
00354
00355
00356
00357
for (pwndT = pwndNewParent; pwndT !=
NULL; pwndT = pwndT->
spwndParent) {
00358
00359
if (pwnd == pwndT) {
00360 RIPERR0(ERROR_INVALID_PARAMETER, RIP_WARNING,
00361
"Attempting to creating a parent-child relationship loop");
00362
return NULL;
00363 }
00364 }
00365
00366
00367
00368
00369
00370
ThreadLock(pwndNewParent, &tlpwndNewParent);
00371
00372
00373
00374
00375 fVisible =
xxxShowWindow(pwnd, MAKELONG(SW_HIDE,
TEST_PUDF(
PUDF_ANIMATE)));
00376
00377
00378
00379
00380
00381
00382
00383
00384
if (
TestWF(pwnd,
WFDESTROYED) ||
TestWF(pwndNewParent,
WFDESTROYED)) {
00385
ThreadUnlock(&tlpwndNewParent);
00386
return NULL;
00387 }
00388
00389 pwndOldParent = pwnd->
spwndParent;
00390
ThreadLock(pwndOldParent, &tlpwndOldParent);
00391
00392
#ifdef USE_MIRRORING
00393
if (
TestWF(pwndOldParent, WEFLAYOUTRTL)) {
00394 pt.x = pwnd->
rcWindow.right;
00395 }
else
00396
#endif
00397
{
00398 pt.x = pwnd->
rcWindow.left;
00399 }
00400 pt.y = pwnd->
rcWindow.top;
00401
_ScreenToClient(pwndOldParent, &pt);
00402
00403
UnlinkWindow(pwnd, pwndOldParent);
00404
Lock(&pwnd->
spwndParent, pwndNewParent);
00405
00406
if (pwndNewParent ==
PWNDDESKTOP(pwnd) && !
TestWF(pwnd,
WEFTOPMOST)) {
00407
00408
00409
00410
00411
00412
if (
TestWF(pwnd,
WFCHILD) &&
00413 (pwnd->
spwndOwner) &&
00414
TestWF(pwnd->
spwndOwner,
WEFTOPMOST)) {
00415
00416
SetWF(pwnd,
WEFTOPMOST);
00417 }
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
if ((pwndNewParent ==
_GetDesktopWindow()) &&
00432 !
TestWF(pwnd,
WFCLIPSIBLINGS)) {
00433
00434
SetWF(pwnd,
WFCLIPSIBLINGS);
00435
zzzInvalidateDCCache(pwnd,
IDC_DEFAULT);
00436 }
00437
00438
00439
00440
00441
00442
LinkWindow(pwnd,
00443
CalcForegroundInsertAfter(pwnd),
00444 pwndNewParent);
00445 }
else {
00446
00447
00448
00449
00450
00451
LinkWindow(pwnd,
NULL, pwndNewParent);
00452 }
00453
00454
00455
00456
00457
00458
if (
TestwndChild(pwnd)) {
00459
00460
00461
00462
00463
00464
if ((pwnd->
spwndParent !=
PWNDDESKTOP(pwnd)) &&
00465
GETPTI(pwnd) !=
GETPTI(pwndOldParent)) {
00466
00467
zzzAttachThreadInput(
GETPTI(pwnd),
GETPTI(pwndOldParent),
FALSE);
00468 }
00469
00470
00471
00472
00473
00474
if (pwndNewParent !=
PWNDDESKTOP(pwnd) &&
00475
GETPTI(pwnd) !=
GETPTI(pwndNewParent)) {
00476
00477
zzzAttachThreadInput(
GETPTI(pwnd),
GETPTI(pwndNewParent),
TRUE);
00478 }
00479 }
00480
00481
if (pwndNewParent ==
PWNDMESSAGE(pwnd) || pwndOldParent ==
PWNDMESSAGE(pwnd))
00482 flags |= SWP_NOACTIVATE;
00483
00484
if (
FWINABLE()) {
00485
xxxWindowEvent(EVENT_OBJECT_PARENTCHANGE, pwnd, OBJID_WINDOW,
00486 INDEXID_CONTAINER,
WEF_USEPWNDTHREAD);
00487 }
00488
00489
00490
00491
00492
xxxSetWindowPos(pwnd,
NULL, pt.x, pt.y, 0, 0, flags);
00493
00494
if (fVisible) {
00495
xxxShowWindow(pwnd, MAKELONG(SW_SHOWNORMAL,
TEST_PUDF(
PUDF_ANIMATE)));
00496 }
00497
00498
00499
00500
00501 pvRet =
ThreadUnlock(&tlpwndOldParent);
00502
ThreadUnlock(&tlpwndNewParent);
00503
00504
return pvRet;
00505 }
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522 #define CCHMAXNAME 80
00523
00524 PWND _FindWindowEx(
00525
PWND pwndParent,
00526
PWND pwndChild,
00527 LPCWSTR ccxlpszClass,
00528 LPCWSTR ccxlpszName,
00529 DWORD dwType)
00530 {
00531
00532
00533
00534
00535
PBWL pbwl;
00536 HWND *phwnd;
00537
PWND pwnd;
00538 WORD atomClass = 0;
00539 LPCWSTR lpName;
00540
BOOL fTryMessage =
FALSE;
00541
00542
if (ccxlpszClass !=
NULL) {
00543
00544 atomClass =
FindClassAtom(ccxlpszClass);
00545
00546
if (atomClass == 0) {
00547
return NULL;
00548 }
00549 }
00550
00551
00552
00553
00554
if (!pwndParent) {
00555 pwndParent =
_GetDesktopWindow();
00556
00557
00558
00559
00560
00561
00562
if (!pwndChild)
00563 fTryMessage =
TRUE;
00564 }
00565
00566 TryAgain:
00567
00568
00569
00570
if (!pwndChild) {
00571 pwndChild = pwndParent->
spwndChild;
00572 }
else {
00573
if (pwndChild->
spwndParent != pwndParent) {
00574 RIPMSG0(RIP_WARNING,
00575
"FindWindowEx: Child window doesn't have proper parent");
00576
return NULL;
00577 }
00578
00579 pwndChild = pwndChild->
spwndNext;
00580 }
00581
00582
00583
00584
00585
if ((pbwl =
BuildHwndList(pwndChild,
BWL_ENUMLIST,
NULL)) ==
NULL) {
00586
return NULL;
00587 }
00588
00589
00590
00591
00592 pwnd =
NULL;
00593
00594
try {
00595
for (phwnd = pbwl->
rghwnd; *phwnd != (HWND)1; phwnd++) {
00596
00597
00598
00599
00600
00601
if ((pwnd =
RevalidateHwnd(*phwnd)) ==
NULL)
00602
continue;
00603
00604
00605
00606
00607
if (dwType !=
FW_BOTH) {
00608
if (((dwType ==
FW_16BIT) && !(
GETPTI(pwnd)->TIF_flags &
TIF_16BIT)) ||
00609 ((dwType ==
FW_32BIT) && (
GETPTI(pwnd)->TIF_flags &
TIF_16BIT)))
00610
continue;
00611 }
00612
00613
00614
00615
00616
if (!atomClass || (atomClass == pwnd->
pcls->
atomClassName)) {
00617
if (!ccxlpszName)
00618
break;
00619
00620
if (pwnd->
strName.
Length) {
00621 lpName = pwnd->
strName.
Buffer;
00622 }
else {
00623 lpName =
szNull;
00624 }
00625
00626
00627
00628
00629
if (_wcsicmp(ccxlpszName, lpName) == 0)
00630
break;
00631 }
00632
00633
00634
00635
00636 pwnd =
NULL;
00637 }
00638 } except (W32ExceptionHandler(
FALSE, RIP_WARNING)) {
00639 pwnd =
NULL;
00640 }
00641
00642
FreeHwndList(pbwl);
00643
00644
if (!pwnd && fTryMessage) {
00645 fTryMessage =
FALSE;
00646 pwndParent =
_GetMessageWindow();
00647 pwndChild =
NULL;
00648
goto TryAgain;
00649 }
00650
00651
return ((*phwnd == (HWND)1) ?
NULL : pwnd);
00652 }
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663 PCHECKPOINT UpdateCheckpoint(
00664
PWND pwnd)
00665 {
00666 RECT rc;
00667
00668
GetRect(pwnd, &rc,
GRECT_WINDOW |
GRECT_PARENTCOORDS);
00669
return CkptRestore(pwnd, &rc);
00670 }
00671
00672
00673
00674
00675
00676
00677
00678
00679 BOOL _GetWindowPlacement(
00680
PWND pwnd,
00681 PWINDOWPLACEMENT pwp)
00682 {
00683
CHECKPOINT * pcp;
00684
00685
00686
00687
00688
00689 pcp =
UpdateCheckpoint(pwnd);
00690
00691
if (!pcp)
00692
return FALSE;
00693
00694
if (
TestWF(pwnd,
WFMINIMIZED)) {
00695 pwp->showCmd = SW_SHOWMINIMIZED;
00696 }
else if (
TestWF(pwnd,
WFMAXIMIZED)) {
00697 pwp->showCmd = SW_SHOWMAXIMIZED;
00698 }
else {
00699 pwp->showCmd = SW_SHOWNORMAL;
00700 }
00701
00702
CopyRect(&pwp->rcNormalPosition, &pcp->
rcNormal);
00703
00704
if (pcp->
fMinInitialized) {
00705 pwp->ptMinPosition = pcp->
ptMin;
00706 }
else {
00707 pwp->ptMinPosition.x = pwp->ptMinPosition.y = -1;
00708 }
00709
00710
00711
00712
00713
00714
00715
if (pcp->
fMaxInitialized && !
TestWF(pwnd,
WFREALLYMAXIMIZABLE)) {
00716 pwp->ptMaxPosition = pcp->
ptMax;
00717 }
else {
00718 pwp->ptMaxPosition.x = pwp->ptMaxPosition.y = -1;
00719 }
00720
00721
if ((pwnd->
spwndParent ==
PWNDDESKTOP(pwnd)) &&
00722 !
TestWF(pwnd,
WEFTOOLWINDOW)) {
00723
00724
PMONITOR pMonitor;
00725
00726 pMonitor =
_MonitorFromRect(&pwp->rcNormalPosition, MONITOR_DEFAULTTOPRIMARY);
00727
00728
00729
00730
00731
00732
00733
00734
00735
if (pcp->
fMinInitialized) {
00736 pwp->ptMinPosition.x -= (pMonitor->
rcWork.left - pMonitor->
rcMonitor.left);
00737 pwp->ptMinPosition.y -= (pMonitor->
rcWork.top - pMonitor->
rcMonitor.top);
00738 }
00739
00740
OffsetRect(&pwp->rcNormalPosition,
00741 pMonitor->
rcMonitor.left - pMonitor->
rcWork.left,
00742 pMonitor->
rcMonitor.top - pMonitor->
rcWork.top);
00743 }
00744
00745 pwp->flags = 0;
00746
00747
00748
00749
00750
00751
if (
TestwndChild(pwnd) && pcp->
fDragged)
00752 pwp->flags |= WPF_SETMINPOSITION;
00753
00754
if (pcp->
fWasMaximizedBeforeMinimized ||
TestWF(pwnd,
WFMAXIMIZED))
00755 pwp->flags |= WPF_RESTORETOMAXIMIZED;
00756
00757 pwp->length =
sizeof(WINDOWPLACEMENT);
00758
00759
return TRUE;
00760 }
00761
00762
00763
00764
00765
00766
00767
00768
00769 VOID CheckPlacementBounds(
00770 LPRECT lprc,
00771 LPPOINT ptMin,
00772 LPPOINT ptMax,
00773
PMONITOR pMonitor)
00774 {
00775
int xIcon;
00776
int yIcon;
00777
int sTop;
00778
int sBottom;
00779
int sLeft;
00780
int sRight;
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792 sTop = (lprc->top < pMonitor->
rcWork.top) ? -1 :
00793 ((lprc->top > pMonitor->
rcWork.bottom) ? 1 : 0);
00794
00795 sBottom = (lprc->bottom < pMonitor->
rcWork.top) ? -1 :
00796 ((lprc->bottom > pMonitor->
rcWork.bottom) ? 1 : 0);
00797
00798 sLeft = (lprc->left < pMonitor->
rcWork.left) ? -1 :
00799 ((lprc->left > pMonitor->
rcWork.right) ? 1 : 0);
00800
00801 sRight = (lprc->right < pMonitor->
rcWork.left) ? -1 :
00802 ((lprc->right > pMonitor->
rcWork.right) ? 1 : 0);
00803
00804
if ((sTop * sBottom > 0) || (sLeft * sRight > 0)) {
00805
00806
00807
00808
00809
00810
00811
00812
00813
int size;
00814
00815
if (sTop < 0) {
00816 lprc->bottom -= lprc->top;
00817 lprc->top = pMonitor->
rcWork.top;
00818 }
else if (sBottom > 0) {
00819 size = lprc->bottom - lprc->top;
00820 lprc->top =
max(pMonitor->
rcWork.bottom - size, pMonitor->
rcWork.top);
00821 lprc->bottom = lprc->top + size;
00822 }
00823
00824
if (sLeft < 0) {
00825 lprc->right -= lprc->left;
00826 lprc->left = pMonitor->
rcWork.left;
00827 }
else if (sRight > 0) {
00828 size = lprc->right - lprc->left;
00829 lprc->left =
max(pMonitor->
rcWork.right - size, pMonitor->
rcWork.left);
00830 lprc->right = lprc->left + size;
00831 }
00832 }
00833
00834
00835
00836
00837
if (ptMin->x != -1) {
00838
00839 xIcon =
SYSMET(CXMINSPACING);
00840 yIcon =
SYSMET(CYMINSPACING);
00841
00842 sTop = (ptMin->y < pMonitor->
rcWork.top) ? -1 :
00843 ((ptMin->y > pMonitor->
rcWork.bottom) ? 1 : 0);
00844
00845 sBottom = (ptMin->y + yIcon < pMonitor->
rcWork.top) ? -1 :
00846 ((ptMin->y + yIcon > pMonitor->
rcWork.bottom) ? 1 : 0);
00847
00848 sLeft = (ptMin->x < pMonitor->
rcWork.left) ? -1 :
00849 ((ptMin->x > pMonitor->
rcWork.right) ? 1 : 0);
00850
00851 sRight = (ptMin->x + xIcon < pMonitor->
rcWork.left) ? -1 :
00852 ((ptMin->x + xIcon > pMonitor->
rcWork.right) ? 1 : 0);
00853
00854
00855
00856
00857
if ((sTop * sBottom > 0) || (sLeft * sRight > 0))
00858 ptMin->x = ptMin->y = -1;
00859 }
00860
00861
00862
00863
00864
if (ptMax->x != -1 &&
00865 (ptMax->x + pMonitor->
rcWork.left >= pMonitor->
rcWork.right ||
00866 ptMax->y + pMonitor->
rcWork.top >= pMonitor->
rcWork.bottom)) {
00867
00868
00869
00870
00871
00872
00873 ptMax->x = 0;
00874 ptMax->y = 0;
00875 }
00876 }
00877
00878
00879
00880
00881
00882
00883
00884 void WPUpdateCheckPointSettings (
PWND pwnd, UINT uWPFlags)
00885 {
00886
CHECKPOINT * pcp;
00887
00888 UserAssert(
TestWF(pwnd,
WFMINIMIZED));
00889
if (pcp =
UpdateCheckpoint(pwnd)) {
00890
00891
00892
00893
00894
if (uWPFlags & WPF_SETMINPOSITION)
00895 pcp->
fDragged =
TRUE;
00896
00897
if (uWPFlags & WPF_RESTORETOMAXIMIZED) {
00898 pcp->
fWasMaximizedBeforeMinimized =
TRUE;
00899 }
else {
00900 pcp->
fWasMaximizedBeforeMinimized =
FALSE;
00901 }
00902 }
00903 }
00904
00905
00906
00907
00908
00909
00910
00911 BOOL xxxSetWindowPlacement(
00912
PWND pwnd,
00913 PWINDOWPLACEMENT pwp)
00914 {
00915
CHECKPOINT * pcp;
00916
PMONITOR pMonitor;
00917 RECT rc;
00918 POINT ptMin;
00919 POINT ptMax;
00920
BOOL fMin;
00921
BOOL fMax;
00922
UINT uSWPFlags;
00923
BOOL fRealAsync;
00924
00925
CheckLock(pwnd);
00926
00927
CopyRect(&rc, &pwp->rcNormalPosition);
00928
if (pwnd->
spwndParent ==
PWNDDESKTOP(pwnd)) {
00929 pMonitor =
_MonitorFromRect(&rc, MONITOR_DEFAULTTOPRIMARY);
00930 }
00931
00932 ptMin = pwp->ptMinPosition;
00933 fMin = ((ptMin.x != -1) && (ptMin.y != -1));
00934
00935 ptMax = pwp->ptMaxPosition;
00936 fMax = ((ptMax.x != -1) && (ptMax.y != -1));
00937
00938
00939
00940
00941
if ( pwnd->
spwndParent ==
PWNDDESKTOP(pwnd) &&
00942 !
TestWF(pwnd,
WEFTOOLWINDOW)) {
00943
00944
OffsetRect(
00945 &rc,
00946 pMonitor->
rcWork.left - pMonitor->
rcMonitor.left,
00947 pMonitor->
rcWork.top - pMonitor->
rcMonitor.top);
00948
00949
if (fMin) {
00950 ptMin.x += pMonitor->
rcWork.left - pMonitor->
rcMonitor.left;
00951 ptMin.y += pMonitor->
rcWork.top - pMonitor->
rcMonitor.top;
00952 }
00953
00954
CheckPlacementBounds(&rc, &ptMin, &ptMax, pMonitor);
00955 }
00956
00957
if (pcp =
UpdateCheckpoint(pwnd)) {
00958
00959
00960
00961
00962
CopyRect(&pcp->
rcNormal, &rc);
00963
00964 pcp->
ptMin = ptMin;
00965 pcp->
fMinInitialized = fMin;
00966 pcp->
fDragged = (pwp->flags & WPF_SETMINPOSITION) ?
00967
TRUE :
FALSE;
00968 pcp->
ptMax = ptMax;
00969 pcp->
fMaxInitialized = fMax;
00970 pcp->
fWasMaximizedBeforeMinimized =
FALSE;
00971 }
00972
00973
00974
00975
00976 uSWPFlags = SWP_NOZORDER | SWP_NOACTIVATE
00977 | ((pwp->flags & WPF_ASYNCWINDOWPLACEMENT) ? SWP_ASYNCWINDOWPOS : 0);
00978
00979
if (
TestWF(pwnd,
WFMINIMIZED)) {
00980
00981
if ((!pcp || pcp->
fDragged) && fMin) {
00982
xxxSetWindowPos(pwnd,
00983
PWND_TOP,
00984 ptMin.x,
00985 ptMin.y,
00986 0,
00987 0,
00988 SWP_NOSIZE | uSWPFlags);
00989 }
00990
00991 }
else if (
TestWF(pwnd,
WFMAXIMIZED)) {
00992
00993
if (pcp !=
NULL) {
00994
if (
TestWF(pwnd,
WFREALLYMAXIMIZABLE))
00995 pcp->
fMaxInitialized =
FALSE;
00996
00997
if (pcp->
fMaxInitialized) {
00998
if (pwnd->
spwndParent ==
PWNDDESKTOP(pwnd)) {
00999 ptMax.x += pMonitor->
rcWork.left;
01000 ptMax.y += pMonitor->
rcWork.top;
01001 }
01002
01003
xxxSetWindowPos(pwnd,
01004
PWND_TOP,
01005 ptMax.x,
01006 ptMax.y,
01007 0,
01008 0,
01009 SWP_NOSIZE | uSWPFlags);
01010 }
01011 }
01012
01013
01014 }
else {
01015
01016
xxxSetWindowPos(pwnd,
01017
PWND_TOP,
01018 rc.left,
01019 rc.top,
01020 rc.right - rc.left,
01021 rc.bottom - rc.top,
01022 uSWPFlags);
01023 }
01024
01025
01026
01027
01028 fRealAsync = (pwp->flags & WPF_ASYNCWINDOWPLACEMENT)
01029 && (
GETPTI(pwnd)->pq !=
PtiCurrent()->pq);
01030
01031
if (fRealAsync) {
01032
_ShowWindowAsync(pwnd, pwp->showCmd, pwp->flags);
01033 }
else {
01034
xxxShowWindow(pwnd, MAKELONG(pwp->showCmd,
TEST_PUDF(
PUDF_ANIMATE)));
01035 }
01036
01037
if (
TestWF(pwnd,
WFMINIMIZED) && !fRealAsync) {
01038
WPUpdateCheckPointSettings(pwnd, pwp->flags);
01039 }
01040
01041
return TRUE;
01042 }
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054 BOOL xxxSetInternalWindowPos(
01055
PWND pwnd,
01056 UINT cmdShow,
01057 LPRECT lprcWin,
01058 LPPOINT lpptMin)
01059 {
01060
CHECKPOINT * pcp;
01061
PMONITOR pMonitor;
01062
01063
CheckLock(pwnd);
01064
01065
if ((pcp =
UpdateCheckpoint(pwnd)) ==
NULL) {
01066
return FALSE;
01067 }
01068
01069
if (lprcWin) {
01070
01071 pcp->
rcNormal = *lprcWin;
01072
if (pwnd->
spwndParent ==
PWNDDESKTOP(pwnd)) {
01073 pMonitor =
_MonitorFromRect(lprcWin, MONITOR_DEFAULTTOPRIMARY);
01074
OffsetRect(
01075 &pcp->
rcNormal,
01076 pMonitor->
rcWork.left - pMonitor->
rcMonitor.left,
01077 pMonitor->
rcWork.top - pMonitor->
rcMonitor.top);
01078 }
01079 }
01080
01081
if (lpptMin && (lpptMin->x != -1)) {
01082
01083 pcp->
ptMin = *lpptMin;
01084
if (pwnd->
spwndParent ==
PWNDDESKTOP(pwnd)) {
01085 pMonitor =
_MonitorFromRect(&pcp->
rcNormal, MONITOR_DEFAULTTOPRIMARY);
01086 pcp->
ptMin.x += pMonitor->
rcWork.left - pMonitor->
rcMonitor.left;
01087 pcp->
ptMin.y += pMonitor->
rcWork.top - pMonitor->
rcMonitor.top;
01088 }
01089
01090 pcp->
fDragged =
TRUE;
01091 pcp->
fMinInitialized =
TRUE;
01092
01093 }
else {
01094 pcp->
fMinInitialized =
FALSE;
01095 pcp->
fDragged =
FALSE;
01096 }
01097
01098
if (
TestWF(pwnd,
WFMINIMIZED)) {
01099
01100
01101
01102
01103
if (pcp->
fMinInitialized) {
01104
xxxSetWindowPos(pwnd,
01105
PWND_TOP,
01106 pcp->
ptMin.x,
01107 pcp->
ptMin.y,
01108 0,
01109 0,
01110 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
01111 }
01112
01113 }
else if (!
TestWF(pwnd,
WFMAXIMIZED) && lprcWin) {
01114
01115
01116
01117
xxxSetWindowPos(pwnd,
01118
NULL,
01119 lprcWin->left,
01120 lprcWin->top,
01121 lprcWin->right - lprcWin->left,
01122 lprcWin->bottom - lprcWin->top,
01123 SWP_NOZORDER);
01124 }
01125
01126
xxxShowWindow(pwnd, MAKELONG(cmdShow,
TEST_PUDF(
PUDF_ANIMATE)));
01127
01128
return TRUE;
01129 }
01130
01131
01132
01133
01134
01135
01136
01137
01138 PWND _GetDesktopWindow(VOID)
01139 {
01140
PTHREADINFO pti =
PtiCurrent();
01141
PDESKTOPINFO pdi;
01142
01143
if (pti ==
NULL)
01144
return NULL;
01145
01146 pdi = pti->
pDeskInfo;
01147
01148
return pdi ==
NULL ?
NULL : pdi->
spwnd;
01149 }
01150
01151
01152
01153
01154
01155
01156
01157
01158 PWND _GetMessageWindow(VOID)
01159 {
01160
PTHREADINFO pti =
PtiCurrent();
01161
PDESKTOP pdi;
01162
01163
if (pti ==
NULL)
01164
return NULL;
01165
01166 pdi = pti->
rpdesk;
01167
01168
return pdi ==
NULL ?
NULL : pdi->
spwndMessage;
01169 }
01170
01171
01172
01173
01174
01175
01176
01177
01178 BOOL TestWindowProcess(
01179
PWND pwnd)
01180 {
01181
return (
PpiCurrent() ==
GETPTI(pwnd)->ppi);
01182 }
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195 #define NESTED_WINDOW_LIMIT 100
01196
01197 BOOL ValidateParentDepth(
PWND pwnd,
PWND pwndParent)
01198 {
01199
UINT cDepth = 1, cDepthMax;
01200
PWND pwndStop;
01201
01202
01203
01204
01205
while (pwndParent !=
NULL) {
01206 pwndParent = pwndParent->
spwndParent;
01207 cDepth++;
01208 }
01209
01210 cDepthMax = cDepth;
01211
01212
01213
01214
01215
01216
if (pwnd ==
NULL || pwnd->
spwndChild ==
NULL) {
01217
goto Exit;
01218 }
else {
01219 pwndStop = pwnd->
spwndParent;
01220 }
01221
01222 Restart:
01223
if (pwnd->
spwndChild !=
NULL) {
01224 pwnd = pwnd->
spwndChild;
01225 cDepth++;
01226 }
else if (pwnd->
spwndNext !=
NULL) {
01227 pwnd = pwnd->
spwndNext;
01228 }
else {
01229
if (cDepth > cDepthMax) {
01230 cDepthMax = cDepth;
01231 }
01232
01233
01234
01235
01236
01237
do {
01238 pwnd = pwnd->
spwndParent;
01239 cDepth--;
01240
01241
if (pwnd == pwndStop)
01242
goto Exit;
01243
01244 }
while (pwnd->
spwndNext ==
NULL);
01245
01246 pwnd = pwnd->
spwndNext;
01247 }
01248
goto Restart;
01249
01250 Exit:
01251
return (cDepthMax <=
NESTED_WINDOW_LIMIT);
01252 }
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265 BOOL ValidateOwnerDepth(
PWND pwnd,
PWND pwndOwner)
01266 {
01267
UINT cDepth = 1;
01268
01269
while (pwndOwner !=
NULL) {
01270
01271
01272
01273
01274
if (pwndOwner == pwnd) {
01275
return FALSE;
01276 }
01277
01278 pwndOwner = pwndOwner->
spwndOwner;
01279 cDepth++;
01280 }
01281
01282
return (cDepth <=
NESTED_WINDOW_LIMIT);
01283 }