00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
#include "precomp.h"
00013
#pragma hdrstop
00014
00015
00016
00017
00018
00019
00020 VOID IncrementRedirectedCount(VOID)
00021 {
00022
gnRedirectedCount++;
00023
00024
if (
gnRedirectedCount == 1) {
00025
InternalSetTimer(
gTermIO.
spwndDesktopOwner,
IDSYS_LAYER, 100,
00026
xxxSystemTimerProc, TMRF_SYSTEM | TMRF_PTIWINDOW);
00027 }
00028
00029 UserAssert(
gnRedirectedCount >= 0);
00030 }
00031
00032
00033
00034
00035
00036
00037 VOID DecrementRedirectedCount(VOID)
00038 {
00039
gnRedirectedCount--;
00040
00041
if (
gnRedirectedCount == 0) {
00042
_KillSystemTimer(
gTermIO.
spwndDesktopOwner,
IDSYS_LAYER);
00043 }
00044
00045 UserAssert(
gnRedirectedCount >= 0);
00046 }
00047
00048
00049
00050
00051
00052
00053
00054 HBITMAP
CreateRedirectionBitmap(
PWND pwnd)
00055 {
00056 HBITMAP hbm;
00057
00058 UserAssert(pwnd->
rcWindow.right >= pwnd->
rcWindow.left);
00059 UserAssert(pwnd->
rcWindow.bottom >= pwnd->
rcWindow.top);
00060
00061
00062
00063
00064
00065
if ((hbm = GreCreateCompatibleBitmap(
gpDispInfo->
hdcScreen,
00066
max(pwnd->
rcWindow.right - pwnd->
rcWindow.left, 1),
00067
max(pwnd->
rcWindow.bottom - pwnd->
rcWindow.top, 1) |
00068 CCB_NOVIDEOMEMORY)) ==
NULL) {
00069 RIPMSG0(RIP_WARNING,
"CreateRedirectionBitmap: bitmap create failed");
00070
return NULL;
00071 }
00072
00073
if (!GreSetBitmapOwner(hbm, OBJECT_OWNER_PUBLIC) ||
00074 !GreMarkUndeletableBitmap(hbm) ||
00075 !
InternalSetProp(pwnd,
PROP_LAYER, hbm,
PROPF_INTERNAL |
00076
PROPF_NOPOOL)) {
00077 RIPMSG0(RIP_WARNING,
"CreateRedirectionBitmap: bitmap set failed");
00078 GreMarkDeletableBitmap(hbm);
00079 GreDeleteObject(hbm);
00080
return NULL;
00081 }
00082
00083
00084
00085
00086
00087
00088
BEGINATOMICCHECK();
00089
xxxInternalInvalidate(pwnd,
HRGN_FULL, RDW_INVALIDATE | RDW_ERASE |
00090 RDW_FRAME | RDW_ALLCHILDREN);
00091
ENDATOMICCHECK();
00092
00093
IncrementRedirectedCount();
00094
00095
return hbm;
00096 }
00097
00098
00099
00100
00101
00102
00103
00104 VOID ConvertRedirectionDCs(
PWND pwnd, HBITMAP hbm)
00105 {
00106
PDCE pdce;
00107
00108 GreLockDisplay(
gpDispInfo->
hDev);
00109
00110
for (pdce =
gpDispInfo->
pdceFirst; pdce !=
NULL; pdce = pdce->
pdceNext) {
00111
00112
if (!(pdce->
DCX_flags & DCX_INUSE))
00113
continue;
00114
00115
if (
GetTopLevelWindow(pdce->
pwndOrg) != pwnd)
00116
continue;
00117
00118
00119
00120
00121
00122
if (pdce->
pMonitor !=
NULL)
00123
continue;
00124
00125
SET_OR_CLEAR_FLAG(pdce->
DCX_flags, DCX_LAYERED, (hbm !=
NULL));
00126
00127 UserVerify(GreSelectRedirectionBitmap(pdce->
hdc, hbm));
00128
00129
InvalidateDce(pdce);
00130 }
00131
00132 GreUnlockDisplay(
gpDispInfo->
hDev);
00133 }
00134
00135
00136
00137
00138
00139
00140
00141 VOID UpdateLayeredSprite(
PDCE pdce)
00142 {
00143 RECT rcBounds;
00144
PWND pwnd;
00145 SIZE size;
00146 POINT pt;
00147 HBITMAP hbm, hbmOld;
00148
00149
00150
00151
00152
00153
if (!GreGetBounds(pdce->
hdc, &rcBounds, 0))
00154
return;
00155
00156 pwnd =
GetLayeredWindow(pdce->
pwndOrg);
00157
00158 UserAssert(
FLayeredOrRedirected(pwnd));
00159
00160
if (
TestWF(pwnd,
WEFLAYERED)) {
00161 hbm = (HBITMAP)
_GetProp(pwnd,
PROP_LAYER,
TRUE);
00162
00163 UserAssert(hbm !=
NULL);
00164
00165 hbmOld = GreSelectBitmap(
ghdcMem, hbm);
00166
00167 size.cx = pwnd->
rcWindow.right - pwnd->
rcWindow.left;
00168 size.cy = pwnd->
rcWindow.bottom - pwnd->
rcWindow.top;
00169
00170 pt.x = pt.y = 0;
00171 GreUpdateSprite(
gpDispInfo->
hDev,
PtoHq(pwnd),
NULL,
NULL,
NULL,
00172 &size,
ghdcMem, &pt, 0,
NULL, ULW_DEFAULT_ATTRIBUTES, &rcBounds);
00173
00174 GreSelectBitmap(
ghdcMem, hbmOld);
00175 }
00176
00177
#ifdef REDIRECTION
00178
if (
FWINABLE()) {
00179
BEGINATOMICCHECK();
00180
xxxWindowEvent(EVENT_SYSTEM_REDIRECTEDPAINT, pwnd,
00181 MAKELONG(rcBounds.left, rcBounds.top),
00182 MAKELONG(rcBounds.right, rcBounds.bottom),
00183
WEF_ASYNC);
00184
ENDATOMICCHECK();
00185 }
00186
#endif // REDIRECTION
00187
}
00188
00189
00190
00191
00192
00193
00194 VOID DeleteRedirectionBitmap(HBITMAP hbm)
00195 {
00196 GreMarkDeletableBitmap(hbm);
00197 GreDeleteObject(hbm);
00198
DecrementRedirectedCount();
00199 }
00200
00201
00202
00203
00204
00205
00206
00207 VOID RemoveRedirectionBitmap(
PWND pwnd)
00208 {
00209 HBITMAP hbm;
00210
00211 UserAssert(
FLayeredOrRedirected(pwnd));
00212
00213
00214
00215
00216
if ((hbm = (HBITMAP)
_GetProp(pwnd,
PROP_LAYER,
TRUE)) ==
NULL)
00217
return;
00218
00219
ConvertRedirectionDCs(pwnd,
NULL);
00220 UserVerify(
InternalRemoveProp(pwnd,
PROP_LAYER,
TRUE));
00221
DeleteRedirectionBitmap(hbm);
00222 }
00223
00224
00225
00226
00227
00228
00229
00230 BOOL _SetLayeredWindowAttributes(
PWND pwnd, COLORREF crKey, BYTE bAlpha,
00231 DWORD dwFlags)
00232 {
00233
BOOL bRet;
00234 BLENDFUNCTION blend;
00235 HBITMAP hbm;
00236
00237
if (!
TestWF(pwnd,
WEFLAYERED)) {
00238 RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING,
00239
"SetLayeredWindowAttributes: not a sprite %X", pwnd);
00240
return FALSE;
00241 }
00242
00243
if ((hbm =
_GetProp(pwnd,
PROP_LAYER,
TRUE)) ==
NULL) {
00244 HBITMAP hbmNew;
00245
00246
if ((hbmNew =
CreateRedirectionBitmap(pwnd)) ==
NULL) {
00247
return FALSE;
00248 }
00249
00250
ConvertRedirectionDCs(pwnd, hbmNew);
00251 }
00252
00253 blend.BlendOp = AC_SRC_OVER;
00254 blend.BlendFlags = 0;
00255 blend.AlphaFormat = 0;
00256 blend.SourceConstantAlpha = bAlpha;
00257
00258
dwFlags |= ULW_NEW_ATTRIBUTES;
00259
00260
if (hbm !=
NULL) {
00261 HBITMAP hbmOld;
00262 SIZE size;
00263 POINT ptSrc = {0,0};
00264
00265 hbmOld = GreSelectBitmap(
ghdcMem, hbm);
00266
00267 size.cx = pwnd->
rcWindow.right - pwnd->
rcWindow.left;
00268 size.cy = pwnd->
rcWindow.bottom - pwnd->
rcWindow.top;
00269
00270 bRet = GreUpdateSprite(
gpDispInfo->
hDev,
PtoHq(pwnd),
NULL,
NULL,
00271
NULL, &size,
ghdcMem, &ptSrc, crKey, &blend,
dwFlags,
NULL);
00272
00273 GreSelectBitmap(
ghdcMem, hbmOld);
00274 }
else {
00275 bRet = GreUpdateSprite(
gpDispInfo->
hDev,
PtoHq(pwnd),
NULL,
NULL,
00276
NULL,
NULL,
NULL,
NULL, crKey, &blend,
dwFlags,
NULL);
00277 }
00278
00279
return bRet;
00280 }
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290 BOOL UserRecreateRedirectionBitmap(HWND hwnd)
00291 {
00292
PWND pwnd;
00293
00294
if ((pwnd =
RevalidateHwnd(hwnd)) ==
NULL) {
00295 RIPMSG0(RIP_WARNING,
"UserRecreateRedirectionBitmap: invalid hwnd");
00296
return FALSE;
00297 }
00298
00299
return RecreateRedirectionBitmap(pwnd);
00300 }
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310 VOID UserRemoveRedirectionBitmap(HWND hwnd)
00311 {
00312
PWND pwnd;
00313
00314
if ((pwnd =
RevalidateHwnd(hwnd)) ==
NULL) {
00315 RIPMSG0(RIP_WARNING,
"UserRemoveRedirectionBitmap: invalid hwnd");
00316
return;
00317 }
00318
00319
RemoveRedirectionBitmap(pwnd);
00320
00321
00322
00323
00324
00325
00326
00327
00328
ClrWF(pwnd,
WEFLAYERED);
00329 }
00330
00331
00332
00333
00334
00335
00336
00337 BOOL RecreateRedirectionBitmap(
PWND pwnd)
00338 {
00339 HBITMAP hbm, hbmNew, hbmMem, hbmMem2;
00340 BITMAP bm, bmNew;
00341
int cx,
cy;
00342
PDCE pdce;
00343
00344 UserAssert(
FLayeredOrRedirected(pwnd));
00345
00346
00347
00348
00349
00350
if ((hbm = (HBITMAP)
_GetProp(pwnd,
PROP_LAYER,
TRUE)) ==
NULL)
00351
return FALSE;
00352
00353
00354
00355
00356
00357
if ((hbmNew =
CreateRedirectionBitmap(pwnd)) ==
NULL) {
00358
RemoveRedirectionBitmap(pwnd);
00359
return FALSE;
00360 }
00361
00362
00363
00364
00365
00366 UserAssert(GreIsDisplayLocked(
gpDispInfo->
hDev));
00367
00368
00369
00370
00371 GreExtGetObjectW(hbm,
sizeof(bm), (LPSTR)&bm);
00372 GreExtGetObjectW(hbmNew,
sizeof(bmNew), (LPSTR)&bmNew);
00373
00374
00375
00376
00377 hbmMem = GreSelectBitmap(
ghdcMem, hbm);
00378 hbmMem2 = GreSelectBitmap(
ghdcMem2, hbmNew);
00379
00380 cx =
min(bm.bmWidth, bmNew.bmWidth);
00381
cy =
min(bm.bmHeight, bmNew.bmHeight);
00382
00383 GreBitBlt(
ghdcMem2, 0, 0, cx,
cy,
ghdcMem, 0, 0, SRCCOPY | NOMIRRORBITMAP, 0);
00384
00385
00386
00387
00388
00389
for (pdce =
gpDispInfo->
pdceFirst; pdce !=
NULL; pdce = pdce->
pdceNext) {
00390
00391
if (!(pdce->
DCX_flags & DCX_LAYERED) || !(pdce->
DCX_flags & DCX_INUSE))
00392
continue;
00393
00394
if (
GetTopLevelWindow(pdce->
pwndOrg) != pwnd)
00395
continue;
00396
00397 UserVerify(GreSelectRedirectionBitmap(pdce->
hdc, hbmNew));
00398 }
00399
00400 GreSelectBitmap(
ghdcMem, hbmMem);
00401 GreSelectBitmap(
ghdcMem2, hbmMem2);
00402
00403
00404
00405
00406
DeleteRedirectionBitmap(hbm);
00407
00408
return TRUE;
00409 }
00410
00411
00412
00413
00414
00415
00416
00417 BOOL UnsetLayeredWindow(
PWND pwnd)
00418 {
00419 HWND hwnd =
PtoHq(pwnd);
00420
00421
00422
00423
00424
RemoveRedirectionBitmap(pwnd);
00425
00426
00427
00428
00429
if (
TestWF(pwnd,
WFVISIBLE)) {
00430 GreUpdateSprite(
gpDispInfo->
hDev, hwnd,
NULL,
NULL,
NULL,
NULL,
00431
NULL,
NULL, 0,
NULL, ULW_NOREPAINT,
NULL);
00432 }
00433
00434
00435
00436
00437
if (!GreDeleteSprite(
gpDispInfo->
hDev,
PtoHq(pwnd),
NULL)) {
00438 RIPMSG1(RIP_WARNING,
"xxxSetLayeredWindow failed %X", pwnd);
00439
return FALSE;
00440 }
00441
ClrWF(pwnd,
WEFLAYERED);
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
if (
TestWF(pwnd,
WFVISIBLE)) {
00454
BEGINATOMICCHECK();
00455
zzzInvalidateDCCache(pwnd,
IDC_DEFAULT |
IDC_NOMOUSE);
00456
ENDATOMICCHECK();
00457 }
00458
return TRUE;
00459 }
00460
00461
00462
00463
00464
00465
00466
00467 HANDLE
xxxSetLayeredWindow(
PWND pwnd, BOOL fRepaintBehind)
00468 {
00469 HANDLE hsprite;
00470 SIZE size;
00471
00472
CheckLock(pwnd);
00473
00474
#ifndef CHILD_LAYERING
00475
if (!
FTopLevel(pwnd)) {
00476 RIPMSG1(RIP_WARNING,
"xxxSetLayeredWindow: not top-level %X", pwnd);
00477
return NULL;
00478 }
00479
#endif // CHILD_LAYERING
00480
00481
#ifdef REDIRECTION
00482
00483
00484
00485
00486
00487
00488
00489
00490
if (
TestWF(pwnd, WEFREDIRECTED))
00491
return NULL;
00492
#endif // REDIRECTION
00493
00494
#if DBG
00495
if (
TestWF(pwnd,
WEFLAYERED)) {
00496 RIPMSG1(RIP_ERROR,
"xxxSetLayeredWindow: already layered %X", pwnd);
00497 }
00498
#endif
00499
00500 size.cx = pwnd->
rcWindow.right - pwnd->
rcWindow.left;
00501 size.cy = pwnd->
rcWindow.bottom - pwnd->
rcWindow.top;
00502
00503 hsprite = GreCreateSprite(
gpDispInfo->
hDev,
PtoHq(pwnd), &pwnd->
rcWindow);
00504
if (hsprite ==
NULL) {
00505 RIPMSG1(RIP_WARNING,
"xxxSetLayeredWindow failed %X", pwnd);
00506
return NULL;
00507 }
00508
00509
SetWF(pwnd,
WEFLAYERED);
00510
TrackLayeredZorder(pwnd);
00511
00512
00513
00514
00515
00516
00517
00518
00519
BEGINATOMICCHECK();
00520
zzzInvalidateDCCache(pwnd,
IDC_DEFAULT |
IDC_NOMOUSE);
00521
ENDATOMICCHECK();
00522
00523
00524
00525
00526
00527
00528
00529
00530
if (
TestWF(pwnd,
WFVISIBLE)) {
00531
if (fRepaintBehind) {
00532 POINT pt;
00533
00534 pt.x = pwnd->
rcWindow.left;
00535 pt.y = pwnd->
rcWindow.top;
00536
00537
_UpdateLayeredWindow(pwnd,
gpDispInfo->
hdcScreen, &pt, &size,
00538
gpDispInfo->
hdcScreen, &pt, 0,
NULL, ULW_OPAQUE);
00539 }
00540 }
else {
00541
00542
00543
00544 fRepaintBehind =
FALSE;
00545 }
00546
00547
00548
00549
00550
00551
if (fRepaintBehind) {
00552 HRGN hrgn = GreCreateRectRgnIndirect(&pwnd->
rcWindow);
00553
xxxRedrawWindow(
NULL,
NULL, hrgn, RDW_INVALIDATE | RDW_FRAME |
00554 RDW_ERASE | RDW_ALLCHILDREN);
00555
xxxUpdateWindows(pwnd, hrgn);
00556 GreDeleteObject(hrgn);
00557 }
00558
return hsprite;
00559 }
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570 BOOL UserVisrgnFromHwnd(HRGN *phrgn, HWND hwnd)
00571 {
00572
PWND pwnd;
00573
DWORD dwFlags;
00574 RECT rcWindow;
00575
BOOL fRet;
00576
00577
CheckCritIn();
00578
00579
if ((pwnd =
RevalidateHwnd(hwnd)) ==
NULL) {
00580 RIPMSG0(RIP_WARNING,
"VisrgnFromHwnd: invalid hwnd");
00581
return FALSE;
00582 }
00583
00584
00585
00586
00587
00588
00589
00590 rcWindow = pwnd->
rcWindow;
00591 pwnd->
rcWindow =
gpDispInfo->
rcScreen;
00592
00593
00594
00595
00596
dwFlags = DCX_WINDOW;
00597
if (
TestWF(pwnd,
WFCLIPSIBLINGS))
00598
dwFlags |= DCX_CLIPSIBLINGS;
00599
00600 fRet =
CalcVisRgn(phrgn, pwnd, pwnd,
dwFlags);
00601
00602 pwnd->
rcWindow = rcWindow;
00603
00604
return fRet;
00605 }
00606
00607
00608
00609
00610
00611 void SetRectRelative(PRECT prc,
int dx,
int dy,
int dcx,
int dcy)
00612 {
00613 prc->left += dx;
00614 prc->top += dy;
00615 prc->right += (dx + dcx);
00616 prc->bottom += (dy + dcy);
00617 }
00618
00619
00620
00621
00622
00623
00624
00625 BOOL _UpdateLayeredWindow(
00626
PWND pwnd,
00627 HDC hdcDst,
00628 POINT *pptDst,
00629 SIZE *psize,
00630 HDC hdcSrc,
00631 POINT *pptSrc,
00632 COLORREF crKey,
00633 BLENDFUNCTION *pblend,
00634 DWORD dwFlags)
00635 {
00636
int dx, dy, dcx, dcy;
00637
BOOL fMove =
FALSE, fSize =
FALSE;
00638
00639
00640
00641
00642
if (!
TestWF(pwnd,
WEFLAYERED) ||
00643
_GetProp(pwnd,
PROP_LAYER,
TRUE) !=
NULL) {
00644 RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING,
00645
"_UpdateLayeredWindow: can't call on window %X", pwnd);
00646
return FALSE;
00647 }
00648
00649
if (!GreUpdateSprite(
gpDispInfo->
hDev,
PtoHq(pwnd),
NULL, hdcDst, pptDst,
00650 psize, hdcSrc, pptSrc, crKey, pblend,
dwFlags,
NULL)) {
00651 RIPMSG1(RIP_WARNING,
"_UpdateLayeredWindow: !UpdateSprite %X", pwnd);
00652
return FALSE;
00653 }
00654
00655
00656
00657
00658
if (pptDst !=
NULL) {
00659 dx = pptDst->x - pwnd->
rcWindow.left;
00660 dy = pptDst->y - pwnd->
rcWindow.top;
00661
if (dx != 0 || dy != 0) {
00662 fMove =
TRUE;
00663 }
00664 }
else {
00665 dx = 0;
00666 dy = 0;
00667 }
00668
if (psize !=
NULL) {
00669 dcx = psize->cx - (pwnd->
rcWindow.right - pwnd->
rcWindow.left);
00670 dcy = psize->cy - (pwnd->
rcWindow.bottom - pwnd->
rcWindow.top);
00671
if (dcx != 0 || dcy != 0) {
00672 fSize =
TRUE;
00673 }
00674 }
else {
00675 dcx = 0;
00676 dcy = 0;
00677 }
00678
00679
if (fMove || fSize) {
00680
00681
00682
00683
00684
SetRectRelative(&pwnd->
rcWindow, dx, dy, dcx, dcy);
00685
SetRectRelative(&pwnd->
rcClient, dx, dy, dcx, dcy);
00686
00687
00688
00689
00690
00691
if ((dcx < 0) && (pwnd->
rcClient.left < pwnd->
rcWindow.left)) {
00692 pwnd->
rcClient.left = pwnd->
rcWindow.left;
00693 pwnd->
rcClient.right = pwnd->
rcWindow.left;
00694 }
00695
if ((dcy < 0) && (pwnd->
rcClient.top < pwnd->
rcWindow.top)) {
00696 pwnd->
rcClient.top = pwnd->
rcWindow.top;
00697 pwnd->
rcClient.bottom = pwnd->
rcWindow.top;
00698 }
00699
00700
00701
00702
00703
00704
00705 }
00706
00707
return TRUE;
00708 }
00709
00710
00711
00712
00713
00714 PWND DeleteFadeSprite(
void)
00715 {
00716
PWND pwnd =
NULL;
00717
00718
if (
gfade.
dwFlags &
FADE_WINDOW) {
00719
if ((pwnd =
RevalidateHwnd(
gfade.
hsprite)) !=
NULL) {
00720
if (
TestWF(pwnd,
WEFLAYERED)) {
00721
UnsetLayeredWindow(pwnd);
00722 }
00723 }
else {
00724 RIPMSG0(RIP_WARNING,
"DeleteFadeSprite: hwnd no longer valid");
00725 }
00726 }
else {
00727 GreDeleteSprite(
gpDispInfo->
hDev,
NULL,
gfade.
hsprite);
00728 }
00729
gfade.
hsprite =
NULL;
00730
return pwnd;
00731 }
00732
00733
00734
00735
00736
00737
00738
00739 void UpdateFade(POINT *pptDst, SIZE *psize, HDC hdcSrc, POINT *pptSrc,
00740 BLENDFUNCTION *pblend)
00741 {
00742
PWND pwnd;
00743
00744
if (
gfade.
dwFlags &
FADE_WINDOW) {
00745
if ((pwnd =
RevalidateHwnd(
gfade.
hsprite)) !=
NULL) {
00746
_UpdateLayeredWindow(pwnd,
NULL, pptDst, psize, hdcSrc,
00747 pptSrc, 0, pblend, ULW_ALPHA);
00748 }
00749 }
else {
00750 GreUpdateSprite(
gpDispInfo->
hDev,
NULL,
gfade.
hsprite,
NULL,
00751 pptDst, psize, hdcSrc, pptSrc, 0, pblend, ULW_ALPHA,
NULL);
00752 }
00753 }
00754
00755
00756
00757
00758
00759
00760
00761 HDC
CreateFade(
PWND pwnd, RECT *prc, DWORD dwTime, DWORD dwFlags)
00762 {
00763 SIZE size;
00764
00765
00766
00767
00768
if (
gfade.
hbm !=
NULL) {
00769 RIPMSG0(RIP_WARNING,
"CreateFade: failed, fade not available");
00770
return NULL;
00771 }
00772
00773
00774
00775
00776
if (
gfade.
hdc ==
NULL) {
00777
gfade.
hdc = GreCreateCompatibleDC(
gpDispInfo->
hdcScreen);
00778
if (
gfade.
hdc ==
NULL) {
00779
return NULL;
00780 }
00781 }
00782
00783
00784
00785
00786
00787 UserAssert((pwnd ==
NULL) || (prc ==
NULL));
00788
00789
if (pwnd !=
NULL) {
00790 prc = &pwnd->
rcWindow;
00791 }
00792
00793 size.cx = prc->right - prc->left;
00794 size.cy = prc->bottom - prc->top;
00795
00796
if (pwnd ==
NULL) {
00797
gfade.
hsprite = GreCreateSprite(
gpDispInfo->
hDev,
NULL, prc);
00798 }
else {
00799
gfade.
dwFlags |=
FADE_WINDOW;
00800
gfade.
hsprite =
HWq(pwnd);
00801
00802
BEGINATOMICCHECK();
00803
xxxSetLayeredWindow(pwnd,
FALSE);
00804
ENDATOMICCHECK();
00805 }
00806
00807
if (
gfade.
hsprite ==
NULL)
00808
return FALSE;
00809
00810
00811
00812
00813
gfade.
hbm = GreCreateCompatibleBitmap(
gpDispInfo->
hdcScreen, size.cx, size.cy);
00814
if (
gfade.
hbm ==
NULL) {
00815
DeleteFadeSprite();
00816
return NULL;
00817 }
00818
00819 GreSelectBitmap(
gfade.
hdc,
gfade.
hbm);
00820
00821
00822
00823
00824
00825
00826 GreSetDCOwner(
gfade.
hdc, OBJECT_OWNER_CURRENT);
00827
00828
00829
00830
00831
gfade.
ptDst.x = prc->left;
00832
gfade.
ptDst.y = prc->top;
00833
gfade.
size.cx = size.cx;
00834
gfade.
size.cy = size.cy;
00835
gfade.
dwTime = dwTime;
00836
gfade.
dwFlags |=
dwFlags;
00837
00838
return gfade.
hdc;
00839 }
00840
00841
00842
00843
00844
00845
00846
00847
00848 #define ALPHASTART 40
00849
00850 void ShowFade(
void)
00851 {
00852 BLENDFUNCTION blend;
00853 POINT ptSrc;
00854
BOOL fShow;
00855
00856 UserAssert(
gfade.
hdc !=
NULL);
00857 UserAssert(
gfade.
hbm !=
NULL);
00858
00859
if (
gfade.
dwFlags &
FADE_SHOWN)
00860
return;
00861
00862 fShow = (
gfade.
dwFlags &
FADE_SHOW);
00863 ptSrc.x = ptSrc.y = 0;
00864 blend.BlendOp = AC_SRC_OVER;
00865 blend.BlendFlags = 0;
00866 blend.AlphaFormat = 0;
00867 blend.SourceConstantAlpha = fShow ?
ALPHASTART : (255 -
ALPHASTART);
00868
UpdateFade(&
gfade.
ptDst, &
gfade.
size,
gfade.
hdc, &ptSrc, &blend);
00869
00870
gfade.
dwFlags |=
FADE_SHOWN;
00871 }
00872
00873
00874
00875
00876
00877
00878
00879 void StartFade(
void)
00880 {
00881
DWORD dwElapsed;
00882
00883 UserAssert(
gfade.
hdc !=
NULL);
00884 UserAssert(
gfade.
hbm !=
NULL);
00885
00886
00887
00888
00889 GreSetDCOwner(
gfade.
hdc, OBJECT_OWNER_PUBLIC);
00890 GreSetBitmapOwner(
gfade.
hbm, OBJECT_OWNER_PUBLIC);
00891
00892
00893
00894
00895
00896
ShowFade();
00897
00898
00899
00900
00901 dwElapsed = (
gfade.
dwTime *
ALPHASTART + 255) / 255;
00902
gfade.
dwStart =
NtGetTickCount() - dwElapsed;
00903
00904
00905
00906
00907
00908
InternalSetTimer(
gTermIO.
spwndDesktopOwner,
IDSYS_FADE, 10,
00909
xxxSystemTimerProc, TMRF_SYSTEM | TMRF_PTIWINDOW);
00910 }
00911
00912
00913
00914
00915
00916
00917
00918 void StopFade(
void)
00919 {
00920
DWORD dwRop=SRCCOPY;
00921
PWND pwnd;
00922
00923 UserAssert(
gfade.
hdc !=
NULL);
00924 UserAssert(
gfade.
hbm !=
NULL);
00925
00926
00927
00928
00929
_KillSystemTimer(
gTermIO.
spwndDesktopOwner,
IDSYS_FADE);
00930
00931 pwnd =
DeleteFadeSprite();
00932
00933
00934
00935
00936
if (!(
gfade.
dwFlags &
FADE_COMPLETED) && (
gfade.
dwFlags &
FADE_SHOW)) {
00937
int x, y;
00938 HDC hdc;
00939
00940
00941
00942
00943
if (pwnd !=
NULL) {
00944 hdc =
_GetDCEx(pwnd,
NULL, DCX_WINDOW | DCX_CACHE);
00945 x = 0;
00946 y = 0;
00947 }
else {
00948 hdc =
gpDispInfo->
hdcScreen;
00949 x =
gfade.
ptDst.x;
00950 y =
gfade.
ptDst.y;
00951 }
00952
00953
#ifdef USE_MIRRORING
00954
00955
00956
00957
00958
00959
if (GreGetLayout(hdc) & LAYOUT_RTL) {
00960 dwRop |= NOMIRRORBITMAP;
00961 }
00962
#endif
00963
00964 GreBitBlt(hdc, x, y,
gfade.
size.cx,
gfade.
size.cy,
gfade.
hdc, 0, 0, dwRop, 0);
00965
_ReleaseDC(hdc);
00966 }
00967
00968
00969
00970
00971 GreSelectBitmap(
gfade.
hdc, GreGetStockObject(PRIV_STOCK_BITMAP));
00972 GreDeleteObject(
gfade.
hbm);
00973
00974
gfade.
hbm =
NULL;
00975
gfade.
dwFlags = 0;
00976 }
00977
00978
00979
00980
00981
00982
00983
00984 void AnimateFade(
void)
00985 {
00986
DWORD dwTimeElapsed;
00987 BLENDFUNCTION blend;
00988
BYTE bAlpha;
00989
BOOL fShow;
00990
00991 UserAssert(
gfade.
hdc !=
NULL);
00992 UserAssert(
gfade.
hbm !=
NULL);
00993
00994 dwTimeElapsed =
NtGetTickCount() -
gfade.
dwStart;
00995
00996
00997
00998
00999
if (dwTimeElapsed >
gfade.
dwTime) {
01000
StopFade();
01001
return;
01002 }
01003
01004 fShow = (
gfade.
dwFlags &
FADE_SHOW);
01005
01006
01007
01008
01009
if (fShow) {
01010 bAlpha = (
BYTE)((255 * dwTimeElapsed) /
gfade.
dwTime);
01011 }
else {
01012 bAlpha = (
BYTE)(255 * (
gfade.
dwTime - dwTimeElapsed) /
gfade.
dwTime);
01013 }
01014
01015 blend.BlendOp = AC_SRC_OVER;
01016 blend.BlendFlags = 0;
01017 blend.AlphaFormat = 0;
01018 blend.SourceConstantAlpha = bAlpha;
01019
UpdateFade(
NULL,
NULL,
NULL,
NULL, &blend);
01020
01021
01022
01023
01024
if ((fShow && bAlpha == 255) || (!fShow && bAlpha == 0)) {
01025
gfade.
dwFlags |=
FADE_COMPLETED;
01026
StopFade();
01027 }
01028 }
01029
01030
#ifdef REDIRECTION
01031
#ifndef CHILD_LAYERING
01032
#error You must enable CHILD_LAYERING to use REDIRECTION
01033
#endif // CHILD_LAYERING
01034
01035
01036
01037
01038
01039
01040
01041
BOOL SetRedirectedWindow(
PWND pwnd)
01042 {
01043 HBITMAP hbmNew =
NULL;
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
if (
TestWF(pwnd, WEFLAYERED))
01054
return FALSE;
01055
01056
if (
_GetProp(pwnd, PROP_LAYER, TRUE) ==
NULL) {
01057
if ((hbmNew =
CreateRedirectionBitmap(pwnd)) ==
NULL) {
01058
return FALSE;
01059 }
01060 }
01061
01062
SetWF(pwnd, WEFREDIRECTED);
01063
01064
if (hbmNew !=
NULL) {
01065
ConvertRedirectionDCs(pwnd, hbmNew);
01066 }
01067
01068
01069
01070
01071
01072
BEGINATOMICCHECK();
01073
zzzInvalidateDCCache(pwnd, IDC_DEFAULT | IDC_NOMOUSE);
01074
ENDATOMICCHECK();
01075
01076
return TRUE;
01077 }
01078
01079
01080
01081
01082
01083
01084
01085
BOOL UnsetRedirectedWindow(
PWND pwnd)
01086 {
01087
RemoveRedirectionBitmap(pwnd);
01088
01089
ClrWF(pwnd, WEFREDIRECTED);
01090
01091
01092
01093
01094
01095
BEGINATOMICCHECK();
01096
zzzInvalidateDCCache(pwnd, IDC_DEFAULT | IDC_NOMOUSE);
01097
ENDATOMICCHECK();
01098
01099
return TRUE;
01100 }
01101
01102
#endif // REDIRECTION
01103
01104
#ifdef CHILD_LAYERING
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
PWND GetNextLayeredWindow(
PWND pwnd)
01115 {
01116
PWND pwndStop =
PWNDDESKTOP(pwnd);
01117
01118
while (
TRUE) {
01119
if (pwnd->
spwndChild !=
NULL) {
01120 pwnd = pwnd->
spwndChild;
01121 }
else if (pwnd->
spwndNext !=
NULL) {
01122 pwnd = pwnd->
spwndNext;
01123 }
else {
01124
01125
do {
01126 pwnd = pwnd->
spwndParent;
01127
01128
if (pwnd == pwndStop) {
01129
return NULL;
01130 }
01131
01132 }
while (pwnd->
spwndNext ==
NULL);
01133
01134 pwnd = pwnd->
spwndNext;
01135 }
01136
01137
if (
TestWF(pwnd, WEFLAYERED)) {
01138
return pwnd;
01139 }
01140 }
01141 }
01142
01143
01144
01145
01146
01147
01148
PWND GetLayeredWindow(
PWND pwnd)
01149 {
01150
while (pwnd !=
NULL) {
01151
if (
FLayeredOrRedirected(pwnd))
01152
break;
01153
01154 pwnd = pwnd->
spwndParent;
01155 }
01156
return pwnd;
01157 }
01158
01159
#else // CHILD_LAYERING
01160
01161
01162
01163
01164
01165
01166 PWND GetLayeredWindow(
PWND pwnd)
01167 {
01168 pwnd =
GetTopLevelWindow(pwnd);
01169
01170
if (
TestWF(pwnd,
WEFLAYERED))
01171
return pwnd;
01172
01173
return NULL;
01174 }
01175
01176
#endif // CHILD_LAYERING
01177
01178
01179
01180
01181
01182
01183
01184 void TrackLayeredZorder(
PWND pwnd)
01185 {
01186
#ifdef CHILD_LAYERING
01187
01188
PWND pwndT = GetNextLayeredWindow(pwnd);
01189
01190
#else // CHILD_LAYERING
01191
01192
PWND pwndT = pwnd->
spwndNext;
01193
01194
while (pwndT !=
NULL) {
01195
01196
if (
TestWF(pwndT,
WEFLAYERED))
01197
break;
01198
01199 pwndT = pwndT->
spwndNext;
01200 }
01201
01202
#endif // CHILD_LAYERING
01203
01204 GreZorderSprite(
gpDispInfo->
hDev,
PtoHq(pwnd),
PtoH(pwndT));
01205 }
01206