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
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 int GetTrueClipRgn(
00031 HDC hdc,
00032 HRGN hrgnClip)
00033 {
00034 POINT pt;
00035
int code;
00036
00037 code = GreCopyVisRgn(hdc, hrgnClip);
00038
00039
00040
00041
00042 GreGetDCOrg(hdc, &pt);
00043
00044
if (GreGetRandomRgn(hdc,
ghrgnScrl2, 1)) {
00045 GreOffsetRgn(
ghrgnScrl2, pt.x, pt.y);
00046 code =
IntersectRgn(hrgnClip, hrgnClip,
ghrgnScrl2);
00047 }
00048
00049
00050
00051
00052 GreOffsetRgn(hrgnClip, -pt.x, -pt.y);
00053
00054
return code;
00055 }
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 int InternalScrollDC(
00068 HDC hdc,
00069
int dx,
00070
int dy,
00071 RECT *prcSrc,
00072 RECT *prcClip,
00073 HRGN hrgnInvalid,
00074 HRGN hrgnUpdate,
00075 LPRECT prcUpdate,
00076 BOOL fLogUnits)
00077 {
00078 RECT rcVis;
00079 RECT rcSrc;
00080 RECT rcClip;
00081 RECT rcUnclippedSrc;
00082 RECT rcDst;
00083 RECT rcUpdate;
00084 RECT rcValid;
00085
BOOL fSrcNotEmpty;
00086
BOOL fHaveVisRgn;
00087 POINT rgpt[2];
00088
int dxLog;
00089
int dyLog;
00090
int wClip;
00091
int wClipValid;
00092
#if defined(USE_MIRRORING)
00093
BOOL bMirroredDC=
FALSE;
00094
#endif
00095
00096 fHaveVisRgn =
FALSE;
00097
00098
00099
00100
00101
00102 GreLockDisplay(
gpDispInfo->
hDev);
00103
00104
if ((wClip = GreGetClipBox(hdc, &rcVis,
TRUE)) == ERROR) {
00105
00106
ErrorExit:
00107
00108 GreUnlockDisplay(
gpDispInfo->
hDev);
00109
return ERROR;
00110 }
00111
00112
CopyRect(&rcSrc, (prcSrc) ? prcSrc : &rcVis);
00113
if (prcClip) {
00114
CopyRect(&rcClip, prcClip);
00115 }
00116
00117 dxLog = dx;
00118 dyLog = dy;
00119
00120
if (fLogUnits) {
00121
00122
00123
00124
00125 GreLPtoDP(hdc, (LPPOINT)&rcVis, 2);
00126 GreLPtoDP(hdc, (LPPOINT)&rcSrc, 2);
00127
00128
#if defined(USE_MIRRORING)
00129
00130
00131
00132
00133
00134
00135
if (GreGetLayout(hdc) & LAYOUT_RTL) {
00136
int iTemp = rcVis.left;
00137 rcVis.left = rcVis.right;
00138 rcVis.right = iTemp;
00139
00140 iTemp = rcSrc.left;
00141 rcSrc.left = rcSrc.right;
00142 rcSrc.right = iTemp;
00143
00144 bMirroredDC =
TRUE;
00145 }
00146
#endif
00147
00148
if (prcClip) {
00149 GreLPtoDP(hdc, (LPPOINT)&rcClip, 2);
00150
00151
#if defined(USE_MIRRORING)
00152
00153
00154
00155
00156
00157
00158
if (bMirroredDC) {
00159
int iTemp = rcClip.left;
00160 rcClip.left = rcClip.right;
00161 rcClip.right = iTemp;
00162 }
00163
#endif
00164
}
00165
00166
00167
00168
00169
00170
00171 rgpt[0].x = rgpt[0].y = 0;
00172 rgpt[1].x = dx;
00173 rgpt[1].y = dy;
00174
00175 GreLPtoDP(hdc, rgpt, 2);
00176
00177 dx = rgpt[1].x - rgpt[0].x;
00178 dy = rgpt[1].y - rgpt[0].y;
00179 }
00180
00181
switch (wClip) {
00182
case NULLREGION:
00183
00184 NullExit:
00185
00186
if (hrgnUpdate && !
SetEmptyRgn(hrgnUpdate))
00187
goto ErrorExit;
00188
00189
if (prcUpdate) {
00190
SetRectEmpty(prcUpdate);
00191 }
00192
00193 GreUnlockDisplay(
gpDispInfo->
hDev);
00194
return NULLREGION;
00195
00196
case COMPLEXREGION:
00197
GetTrueClipRgn(hdc,
ghrgnScrlVis);
00198 fHaveVisRgn =
TRUE;
00199
break;
00200 }
00201
00202
00203
00204
00205
00206
00207 rcDst.left = rcSrc.left + dx;
00208 rcDst.right = rcSrc.right + dx;
00209 rcDst.top = rcSrc.top + dy;
00210 rcDst.bottom = rcSrc.bottom + dy;
00211
00212
00213
00214
00215
if (prcClip) {
00216
00217
if ((wClip == SIMPLEREGION) &&
00218 ((hrgnInvalid ==
NULL) || (hrgnInvalid ==
HRGN_FULL))) {
00219
00220
00221
00222
00223
if (!
IntersectRect(&rcVis, &rcVis, &rcClip))
00224
goto NullExit;
00225
00226 }
else {
00227
00228
if (!fHaveVisRgn) {
00229
00230
if (
GetTrueClipRgn(hdc,
ghrgnScrlVis) == ERROR)
00231
goto ErrorExit;
00232
00233 fHaveVisRgn =
TRUE;
00234 }
00235
00236
SetRectRgnIndirect(
ghrgnScrl1, &rcClip);
00237 wClip =
IntersectRgn(
ghrgnScrlVis,
ghrgnScrl1,
ghrgnScrlVis);
00238
switch (wClip) {
00239
case ERROR:
00240
goto ErrorExit;
00241
00242
case NULLREGION:
00243
goto NullExit;
00244
00245
case SIMPLEREGION:
00246
00247
00248
00249
00250
00251 GreGetRgnBox(
ghrgnScrlVis, &rcVis);
00252
break;
00253
00254
case COMPLEXREGION:
00255
break;
00256 }
00257 }
00258 }
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
if ((wClip == SIMPLEREGION) &&
00276 ((hrgnInvalid ==
NULL) || (hrgnInvalid ==
HRGN_FULL))) {
00277
00278
00279
00280
00281
CopyRect(&rcUnclippedSrc, &rcSrc);
00282
00283
00284
00285
00286
IntersectRect(&rcDst, &rcDst, &rcVis);
00287
00288
00289
00290
00291 fSrcNotEmpty =
IntersectRect(&rcSrc, &rcSrc, &rcVis);
00292
00293
00294
00295
00296
if (hrgnInvalid ==
HRGN_FULL) {
00297
SetRectEmpty(&rcValid);
00298 }
else {
00299
00300 rcValid.left = rcSrc.left + dx;
00301 rcValid.right = rcSrc.right + dx;
00302 rcValid.top = rcSrc.top + dy;
00303 rcValid.bottom = rcSrc.bottom + dy;
00304
00305
IntersectRect(&rcValid, &rcValid, &rcDst);
00306 }
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
if (!fSrcNotEmpty) {
00325
00326
00327
00328
00329
CopyRect(&rcUpdate, &rcDst);
00330
goto RectUpdate;
00331
00332 }
else if (
IntersectRect(&rcUpdate, &rcSrc, &rcDst)) {
00333
00334
00335
00336
00337
00338
if (dx == 0 || dy == 0) {
00339
00340
UnionRect(&rcUpdate, &rcSrc, &rcDst);
00341
SubtractRect(&rcUpdate, &rcUpdate, &rcValid);
00342
goto RectUpdate;
00343 }
00344
00345 }
else if (
EqualRect(&rcSrc, &rcUnclippedSrc)) {
00346
00347
00348
00349
00350
00351
CopyRect(&rcUpdate, &rcSrc);
00352 RectUpdate:
00353
if (prcUpdate) {
00354
CopyRect(prcUpdate, &rcUpdate);
00355 }
00356
00357
if (hrgnUpdate && !
SetRectRgnIndirect(hrgnUpdate, &rcUpdate)) {
00358
goto ErrorExit;
00359 }
00360
00361 wClip = SIMPLEREGION;
00362
if (rcUpdate.left >= rcUpdate.right ||
00363 rcUpdate.top >= rcUpdate.bottom)
00364
00365 wClip = NULLREGION;
00366
00367
goto DoRectBlt;
00368 }
00369
00370
00371
00372
00373
00374
00375
00376
00377
if (hrgnUpdate ==
NULL && prcUpdate) {
00378 hrgnUpdate =
ghrgnScrl2;
00379 }
00380
00381
if (hrgnUpdate !=
NULL) {
00382
00383
00384
00385
00386
SetRectRgnIndirect(
ghrgnScrl1, &rcSrc);
00387
SetRectRgnIndirect(hrgnUpdate, &rcDst);
00388
if (
UnionRgn(hrgnUpdate, hrgnUpdate,
ghrgnScrl1) == ERROR)
00389
goto ErrorExit;
00390
00391
SetRectRgnIndirect(
ghrgnScrl1, &rcValid);
00392 wClip =
SubtractRgn(hrgnUpdate, hrgnUpdate,
ghrgnScrl1);
00393
if (wClip == ERROR)
00394
goto ErrorExit;
00395
00396
if (prcUpdate) {
00397 GreGetRgnBox(hrgnUpdate, prcUpdate);
00398 }
00399 }
00400
00401 DoRectBlt:
00402
00403
00404
00405
00406
if (rcValid.left < rcValid.right && rcValid.top < rcValid.bottom) {
00407
00408
00409
00410
00411
00412
if (fLogUnits)
00413 GreDPtoLP(hdc, (LPPOINT)&rcValid, 2);
00414
00415 GreBitBlt(hdc,
00416 rcValid.left,
00417 rcValid.top,
00418 rcValid.right - rcValid.left,
00419 rcValid.bottom - rcValid.top,
00420 hdc,
00421 rcValid.left - dxLog,
00422 rcValid.top - dyLog,
00423 SRCCOPY,
00424 0);
00425 }
00426
00427 }
else {
00428
00429
00430
00431
00432
if (!fHaveVisRgn) {
00433
00434
if (
GetTrueClipRgn(hdc,
ghrgnScrlVis) == ERROR)
00435
goto ErrorExit;
00436
00437 fHaveVisRgn =
TRUE;
00438 }
00439
00440
00441
00442
00443
00444
00445
00446
SetRectRgnIndirect(
ghrgnScrlSrc, &rcSrc);
00447
if (
IntersectRgn(
ghrgnScrlSrc,
ghrgnScrlSrc,
ghrgnScrlVis) == ERROR)
00448
goto ErrorExit;
00449
00450
00451
00452
00453
SetRectRgnIndirect(
ghrgnScrlDst, &rcDst);
00454
if (
IntersectRgn(
ghrgnScrlDst,
ghrgnScrlDst,
ghrgnScrlVis) == ERROR)
00455
goto ErrorExit;
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465 wClipValid = NULLREGION;
00466
if (hrgnInvalid !=
HRGN_FULL) {
00467
00468
00469
00470
00471
if (
CopyRgn(
ghrgnScrlValid,
ghrgnScrlSrc) == ERROR)
00472
goto ErrorExit;
00473
00474 GreOffsetRgn(
ghrgnScrlValid, dx, dy);
00475 wClipValid =
IntersectRgn(
ghrgnScrlValid,
00476
ghrgnScrlValid,
00477
ghrgnScrlDst);
00478
00479
00480
00481
00482
00483
if (hrgnInvalid >
HRGN_FULL) {
00484
00485
if (wClipValid != ERROR && wClipValid != NULLREGION) {
00486 POINT pt;
00487
00488
GetDCOrgOnScreen(hdc, &pt);
00489
00490
00491
00492
00493
CopyRgn(
ghrgnScrl2, hrgnInvalid);
00494 GreOffsetRgn(
ghrgnScrl2, -pt.x, -pt.y);
00495
00496 wClipValid =
SubtractRgn(
ghrgnScrlValid,
00497
ghrgnScrlValid,
00498
ghrgnScrl2);
00499 }
00500
00501
if (wClipValid != ERROR && wClipValid != NULLREGION) {
00502 GreOffsetRgn(
ghrgnScrl2, dx, dy);
00503
00504 wClipValid =
SubtractRgn(
ghrgnScrlValid,
00505
ghrgnScrlValid,
00506
ghrgnScrl2);
00507 }
00508 }
00509
00510
if (wClipValid == ERROR)
00511
goto ErrorExit;
00512 }
00513
00514
00515
00516
00517
if (hrgnUpdate ==
NULL && prcUpdate) {
00518 hrgnUpdate =
ghrgnScrl2;
00519 }
00520
00521
if (hrgnUpdate !=
NULL) {
00522
00523
00524
00525
00526 wClip =
UnionRgn(hrgnUpdate,
ghrgnScrlDst,
ghrgnScrlSrc);
00527
if (wClip == ERROR)
00528
goto ErrorExit;
00529
00530
if (wClipValid != NULLREGION) {
00531 wClip =
SubtractRgn(hrgnUpdate, hrgnUpdate,
ghrgnScrlValid);
00532 }
00533
00534
if (prcUpdate) {
00535 GreGetRgnBox(hrgnUpdate, prcUpdate);
00536 }
00537 }
00538
00539
if (wClipValid != NULLREGION) {
00540
00541
#ifdef LATER
00542
00543
00544
00545
00546 HRGN hrgnSaveVis =
CreateEmptyRgn();
00547
if (hrgnSaveVis !=
NULL) {
00548
00549
BOOL fClipped;
00550
00551 fClipped = (GreGetRandomRgn(hdc, hrgnSaveVis, 1) == 1);
00552 GreExtSelectClipRgn(hdc,
ghrgnScrlValid, RGN_COPY);
00553
00554
00555
00556
00557
00558
if (fLogUnits)
00559 GreDPtoLP(hdc, (LPPOINT)&rcDst, 2);
00560
00561
00562
00563
00564
00565 GreBitBlt(hdc,
00566 rcDst.left,
00567 rcDst.top,
00568 rcDst.right - rcDst.left,
00569 rcDst.bottom - rcDst.top,
00570 hdc,
00571 rcDst.left - dxLog,
00572 rcDst.top - dyLog,
00573 SRCCOPY,
00574 0);
00575
00576 GreExtSelectClipRgn(hdc,
00577 (fClipped ? hrgnSaveVis :
NULL),
00578 RGN_COPY);
00579
00580 GreDeleteObject(hrgnSaveVis);
00581 }
00582
00583
#else
00584
00585
00586
00587
00588
00589 POINT pt;
00590 GreGetDCOrg(hdc, &pt);
00591
00592 GreOffsetRgn(
ghrgnScrlValid, pt.x, pt.y);
00593
00594
00595
00596
00597
00598 GreSelectVisRgn(hdc,
ghrgnScrlValid, SVR_SWAP);
00599
00600
00601
00602
00603
00604
if (fLogUnits)
00605 GreDPtoLP(hdc, (LPPOINT)&rcDst, 2);
00606
00607
00608
00609
00610
00611 GreBitBlt(hdc,
00612 rcDst.left,
00613 rcDst.top,
00614 rcDst.right - rcDst.left,
00615 rcDst.bottom - rcDst.top,
00616 hdc,
00617 rcDst.left - dxLog,
00618 rcDst.top - dyLog,
00619 SRCCOPY,
00620 0);
00621
00622
00623
00624
00625
00626 GreSelectVisRgn(hdc,
ghrgnScrlValid, SVR_SWAP);
00627
00628
#endif
00629
}
00630 }
00631
00632
00633
00634
00635
00636
if (fLogUnits && prcUpdate) {
00637 GreDPtoLP(hdc, (LPPOINT)prcUpdate, 2);
00638 }
00639
00640 GreUnlockDisplay(
gpDispInfo->
hDev);
00641
00642
return wClip;
00643 }
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653 BOOL _ScrollDC(
00654 HDC hdc,
00655
int dx,
00656
int dy,
00657 LPRECT prcSrc,
00658 LPRECT prcClip,
00659 HRGN hrgnUpdate,
00660 LPRECT prcUpdate)
00661 {
00662 RECT rcSrc;
00663 RECT rcSpb;
00664
PWND pwnd;
00665 HRGN hrgnInvalid;
00666
BOOL fRet;
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676 hrgnInvalid =
NULL;
00677
if ((pwnd =
FastWindowFromDC(hdc)) !=
NULL) {
00678
00679 hrgnInvalid = pwnd->
hrgnUpdate;
00680
00681
if (hrgnInvalid ==
HRGN_FULL) {
00682
00683
00684
00685
00686
00687
00688
00689
00690 hrgnInvalid =
NULL;
00691 }
00692 }
00693
00694 fRet =
InternalScrollDC(hdc,
00695 dx,
00696 dy,
00697 prcSrc,
00698 prcClip,
00699 hrgnInvalid,
00700 hrgnUpdate,
00701 prcUpdate,
00702
TRUE) != ERROR;
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
if (pwnd !=
NULL &&
AnySpbs()) {
00714
00715
if (prcSrc) {
00716
00717 rcSrc = *prcSrc;
00718
OffsetRect(&rcSrc, pwnd->
rcClient.left, pwnd->
rcClient.top);
00719
00720 rcSpb = rcSrc;
00721
OffsetRect(&rcSpb, dx, dy);
00722
UnionRect(&rcSpb, &rcSpb, &rcSrc);
00723
00724 }
else {
00725 rcSpb = pwnd->
rcClient;
00726 }
00727
00728
SpbCheckRect(pwnd, &rcSpb, 0);
00729 }
00730
00731
return fRet;
00732 }
00733
00734
00735
00736
00737
00738
00739
00740
00741 int xxxScrollWindowEx(
00742
PWND pwnd,
00743
int dx,
00744
int dy,
00745 RECT *prcScroll,
00746 RECT *prcClip,
00747 HRGN hrgnUpdate,
00748 LPRECT prcUpdate,
00749 DWORD flags)
00750 {
00751
INT code;
00752 HDC hdc;
00753
int dxDev;
00754
int dyDev;
00755 RECT rcSrcDev;
00756 RECT rcSpb, rcSrc;
00757
DWORD flagsDCX;
00758
BOOL fHideCaret;
00759
BOOL fRcScroll = (prcScroll !=
NULL);
00760
BOOL fInvisible =
FALSE;
00761
PCARET pcaret;
00762 POINT pt;
00763
TL tlpwndChild;
00764 HRGN hrgnInvalid;
00765
PTHREADINFO ptiCurrent =
PtiCurrent();
00766
00767
CheckLock(pwnd);
00768 UserAssert(
IsWinEventNotifyDeferredOK());
00769
00770
00771
if (pwnd ==
NULL)
00772 pwnd = ptiCurrent->
rpdesk->
pDeskInfo->
spwnd;
00773
00774
#ifdef USE_MIRRORING
00775
if (
TestWF(pwnd, WEFLAYOUTRTL)) {
00776 dx = -dx;
00777
00778 MirrorRegion(pwnd, hrgnUpdate,
TRUE);
00779
00780
if(prcScroll) {
00781 MirrorRect(pwnd, prcScroll);
00782 }
00783
00784
if (prcClip) {
00785 MirrorRect(pwnd, prcClip);
00786 }
00787 }
00788
#endif
00789
00790
00791
00792
00793
if ((dx | dy) == 0 ) {
00794
00795
goto DoNothing;
00796
00797 }
else if (!
IsVisible(pwnd)) {
00798
00799
00800
00801
00802
00803
if (!
TestWF(pwnd,
WFMINIMIZED) &&
00804 (flags & SW_SCROLLCHILDREN) &&
00805 !fRcScroll) {
00806
00807 fInvisible =
TRUE;
00808 flags &= ~SW_INVALIDATE;
00809 }
00810
00811 DoNothing:
00812
00813
if (hrgnUpdate) {
00814
SetEmptyRgn(hrgnUpdate);
00815 }
00816
00817
if (prcUpdate) {
00818
SetRectEmpty(prcUpdate);
00819 }
00820
00821
if (!fInvisible)
00822
return NULLREGION;
00823 }
00824
00825
00826
00827
00828 fHideCaret =
FALSE;
00829
00830
if (!fInvisible) {
00831 pcaret = &ptiCurrent->
pq->
caret;
00832
if (pcaret->
spwnd !=
NULL &&
_IsDescendant(pcaret->
spwnd, pwnd)) {
00833 fHideCaret =
TRUE;
00834
zzzInternalHideCaret();
00835 }
00836 }
00837
00838
00839
00840
00841
00842
00843
00844
00845
if (flags & SW_SCROLLWINDOW) {
00846
00847
00848
00849
00850 flagsDCX = DCX_USESTYLE;
00851
if (!
TestCF(pwnd,
CFOWNDC) && !
TestCF(pwnd,
CFCLASSDC))
00852 flagsDCX |= DCX_CACHE;
00853
00854
00855
00856
00857
00858
00859
if ((flags & SW_SCROLLCHILDREN) &&
TestWF(pwnd,
WFCLIPCHILDREN))
00860 flagsDCX |= DCX_NOCLIPCHILDREN | DCX_CACHE;
00861
00862 }
else {
00863
00864
00865
00866
00867 flagsDCX = DCX_USESTYLE | DCX_CACHE;
00868
00869
00870
00871
00872
if (flags & SW_SCROLLCHILDREN)
00873 flagsDCX |= DCX_NOCLIPCHILDREN;
00874 }
00875
00876
#ifdef USE_MIRRORING
00877
flagsDCX |= DCX_NOMIRROR;
00878
#endif
00879
00880 hdc =
_GetDCEx(pwnd,
NULL, flagsDCX);
00881
00882
if (flags & SW_INVALIDATE) {
00883
00884
00885
00886
00887
GetDCOrgOnScreen(hdc, &pt);
00888
00889
00890
00891
00892
if (hrgnUpdate ==
NULL)
00893 hrgnUpdate =
ghrgnSW;
00894 }
00895
00896
00897
00898
00899
if (!fRcScroll) {
00900 prcScroll = &rcSrc;
00901
00902
00903
00904
00905
00906
00907
00908
GetRect(pwnd, &rcSrc,
GRECT_CLIENT |
GRECT_CLIENTCOORDS);
00909
00910
00911
00912
00913
00914
if (!(flagsDCX & DCX_CACHE))
00915 GreDPtoLP(hdc, (LPPOINT)&rcSrc, 2);
00916 }
00917
00918
00919
00920
00921
00922 dxDev = dx;
00923 dyDev = dy;
00924 rcSrcDev = *prcScroll;
00925
00926
if (!(flagsDCX & DCX_CACHE)) {
00927
00928 POINT rgpt[2];
00929
00930 GreLPtoDP(hdc, (POINT
FAR*)&rcSrcDev, 2);
00931
00932
00933
00934
00935
00936
00937 rgpt[0].x = rgpt[0].y = 0;
00938 rgpt[1].x = dx;
00939 rgpt[1].y = dy;
00940
00941 GreLPtoDP(hdc, rgpt, 2);
00942
00943 dxDev = rgpt[1].x - rgpt[0].x;
00944 dyDev = rgpt[1].y - rgpt[0].y;
00945 }
00946
00947
if (fInvisible)
00948 code = NULLREGION;
00949
else {
00950 hrgnInvalid = pwnd->
hrgnUpdate;
00951
if ((flags & SW_SCROLLWINDOW) && !
TestWF(pwnd,
WFWIN31COMPAT)) {
00952
00953
00954
00955
00956
00957
00958
if (pwnd->
hrgnUpdate >
HRGN_FULL) {
00959 RECT rc;
00960
00961 GreGetRgnBox(pwnd->
hrgnUpdate, &rc);
00962
OffsetRect(&rc,
00963 dxDev - pwnd->
rcClient.left,
00964 dyDev - pwnd->
rcClient.top);
00965
00966
xxxRedrawWindow(pwnd,
00967 &rc,
NULL,
00968 RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN);
00969 }
00970 hrgnInvalid =
NULL;
00971 }
00972
00973 code =
InternalScrollDC(hdc,
00974 dx,
00975 dy,
00976 prcScroll,
00977 prcClip,
00978 hrgnInvalid,
00979 hrgnUpdate,
00980 prcUpdate,
00981 !(flagsDCX & DCX_CACHE));
00982
#ifdef USE_MIRRORING
00983
if (prcUpdate &&
TestWF(pwnd, WEFLAYOUTRTL)) {
00984 MirrorRect(pwnd, prcUpdate);
00985 }
00986
#endif
00987
}
00988
00989
00990
00991
00992
_ReleaseDC(hdc);
00993
00994
00995
00996
00997
00998
00999
01000
01001
if (!fInvisible &&
AnySpbs()) {
01002
01003
if (fRcScroll) {
01004
if (pwnd ==
PWNDDESKTOP(pwnd)) {
01005 rcSrc = rcSrcDev;
01006 }
else {
01007
CopyOffsetRect(
01008 &rcSrc,
01009 &rcSrcDev,
01010 pwnd->
rcClient.left,
01011 pwnd->
rcClient.top);
01012 }
01013
01014 rcSpb = rcSrc;
01015
OffsetRect(&rcSpb, dxDev, dyDev);
01016
UnionRect(&rcSpb, &rcSpb, &rcSrc);
01017
01018 }
else {
01019
01020
01021
01022
01023 rcSpb = pwnd->
rcClient;
01024 }
01025
01026
SpbCheckRect(pwnd, &rcSpb, 0);
01027 }
01028
01029
01030
01031
01032
01033
01034
if (flags & SW_SCROLLCHILDREN) {
01035
01036 RECT rc;
01037
01038
01039
01040
01041
01042
01043
if (!fInvisible && (pwnd == pcaret->
spwnd)) {
01044
01045
if (fRcScroll)
01046
SetRect(&rc,
01047 pcaret->
x,
01048 pcaret->
y,
01049 pcaret->
x + pcaret->
cx,
01050 pcaret->
y + pcaret->
cy);
01051
01052
if (!fRcScroll ||
IntersectRect(&rc, &rc, &rcSrcDev)) {
01053 pcaret->
x += dxDev;
01054 pcaret->
y += dyDev;
01055 }
01056 }
01057
01058
if (fRcScroll) {
01059
01060
01061
01062
01063
if (pwnd ==
PWNDDESKTOP(pwnd)) {
01064
CopyRect(&rc, &rcSrcDev);
01065 }
else {
01066
CopyOffsetRect(
01067 &rc,
01068 &rcSrcDev,
01069 pwnd->rcClient.left,
01070 pwnd->rcClient.top);
01071 }
01072 }
01073
01074
if (pwnd->spwndChild) {
01075
01076
OffsetChildren(pwnd,
01077 dxDev,
01078 dyDev,
01079 (fRcScroll ? (LPRECT)&rc :
NULL));
01080
01081
01082
01083
01084
01085
01086
01087
01088
zzzInvalidateDCCache(pwnd,
01089
TestWF(pwnd,
WFCLIPCHILDREN) ?
01090
IDC_CLIENTONLY :
IDC_CHILDRENONLY);
01091
01092 }
01093 }
01094
01095
if (flags & SW_INVALIDATE) {
01096
01097
01098
01099
01100
01101
if (hrgnUpdate !=
ghrgnSW)
01102
CopyRgn(
ghrgnSW, hrgnUpdate);
01103
01104
01105
01106
01107 GreOffsetRgn(
ghrgnSW, pt.x, pt.y);
01108
01109
xxxInternalInvalidate(
01110 pwnd,
01111
ghrgnSW,
01112 (flags & SW_ERASE) ?
01113 (RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE) :
01114 (RDW_INVALIDATE | RDW_ALLCHILDREN));
01115 }
01116
01117
01118
01119
01120
if (flags & SW_SCROLLCHILDREN) {
01121
01122
PWND pwndChild;
01123 RECT rc;
01124 RECT rcScrolledChildren;
01125
01126
01127
01128
01129
01130
01131
if (fRcScroll) {
01132
if (pwnd->
spwndParent ==
PWNDDESKTOP(pwnd)) {
01133
CopyOffsetRect(&rcScrolledChildren, &rcSrcDev, dxDev, dyDev);
01134 }
else {
01135
CopyOffsetRect(
01136 &rcScrolledChildren,
01137 &rcSrcDev,
01138 dxDev + pwnd->
spwndParent->
rcClient.left,
01139 dyDev + pwnd->
spwndParent->
rcClient.top);
01140 }
01141 }
01142
01143
ThreadLockNever(&tlpwndChild);
01144 pwndChild = pwnd->
spwndChild;
01145
while (pwndChild !=
NULL) {
01146
01147
if ( !fRcScroll ||
01148
IntersectRect(&rc, &rcScrolledChildren, &pwndChild->
rcWindow)) {
01149
01150
01151
01152
01153
01154
01155
ThreadLockExchangeAlways(pwndChild, &tlpwndChild);
01156
xxxSendMessage(
01157 pwndChild,
01158 WM_MOVE,
01159 0,
01160 (pwnd ==
PWNDDESKTOP(pwnd)) ?
01161 MAKELONG(pwndChild->
rcClient.left, pwndChild->
rcClient.top) :
01162 MAKELONG(pwndChild->
rcClient.left - pwnd->rcClient.left,
01163 pwndChild->
rcClient.top - pwnd->rcClient.top));
01164 }
01165
01166 pwndChild = pwndChild->
spwndNext;
01167 }
01168
01169
ThreadUnlock(&tlpwndChild);
01170 }
01171
01172
if (fHideCaret) {
01173
01174
01175
01176
01177
zzzInternalShowCaret();
01178 }
01179
01180
01181
01182
01183
return code;
01184 }
01185