00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
#include "precomp.h"
00015
#pragma hdrstop
00016
00017 #define TITLE_EXTRA 5
00018 #define MAX_TITLE_LEN 160
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 void xxxSetFrameTitle(
00033
PWND pwndFrame,
00034
PWND pwndMDI,
00035 LPWSTR lpch)
00036 {
00037
PWND pwnd;
00038
PMDI pmdi;
00039 WCHAR sz[
MAX_TITLE_LEN];
00040 HWND hwndFrame =
HW(pwndFrame);
00041
00042
CheckLock(pwndFrame);
00043
CheckLock(pwndMDI);
00044
00045
00046
00047
00048 pmdi = ((
PMDIWND)pwndMDI)->pmdi;
00049
00050
if (
IS_PTR(lpch) || lpch ==
NULL) {
00051
if (
HTITLE(pmdi)) {
00052
UserLocalFree(
HTITLE(pmdi));
00053 }
00054
HTITLE(pmdi) =
TextAlloc(lpch);
00055 }
00056
00057
if (
HTITLE(pmdi)) {
00058
LARGE_UNICODE_STRING str;
00059
int cch;
00060
00061
RtlInitLargeUnicodeString(&str,
HTITLE(pmdi), (
UINT)-1);
00062
TextCopy(&str, sz,
sizeof(sz)/
sizeof(WCHAR));
00063
00064
if (
MAXED(pmdi) && (pwnd =
ValidateHwnd(
MAXED(pmdi))) && pwnd->
strName.
Length) {
00065
00066 cch =
MAX_TITLE_LEN - ((str.
Length /
sizeof(WCHAR)) +
TITLE_EXTRA);
00067
if (cch > 0) {
00068 wcscat(sz, TEXT(
" - ["));
00069 wcsncat(sz,
REBASE(pwnd, strName.Buffer), cch - 1);
00070 wcscat(sz, TEXT(
"]"));
00071 }
00072 }
00073 }
else {
00074 sz[0] = 0;
00075 }
00076
00077
_DefSetText(hwndFrame, sz,
FALSE);
00078
00079
if (lpch == (LPWSTR)1
L)
00080
NtUserRedrawFrameAndHook(hwndFrame);
00081
00082
else if (lpch != (LPWSTR)2
L) {
00083
if (!
NtUserRedrawTitle(hwndFrame, DC_TEXT))
00084
NtUserRedrawFrame(hwndFrame);
00085 }
00086 }
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 BOOL TranslateMDISysAccel(
00097 HWND hwnd,
00098 LPMSG lpMsg)
00099 {
00100
PWND pwnd;
00101
PMDI pmdi;
00102
int event;
00103
00104
00105
00106
00107
if (lpMsg->message != WM_KEYDOWN && lpMsg->message != WM_SYSKEYDOWN) {
00108
return FALSE;
00109 }
00110
00111
00112
00113
00114
00115
00116
00117
00118
if ((pwnd =
ValidateHwndNoRip(hwnd)) ==
NULL) {
00119 RIPERR0(ERROR_INVALID_WINDOW_HANDLE, RIP_VERBOSE,
"");
00120
return FALSE;
00121 }
00122
00123
CheckLock(pwnd);
00124
00125
00126
00127
00128
00129
00130
if (
GETFNID(pwnd) !=
FNID_MDICLIENT) {
00131 RIPMSG0(RIP_WARNING,
"Window not of MDIClient class");
00132
return FALSE;
00133 }
00134
00135
00136
00137
00138 pmdi = ((
PMDIWND)pwnd)->pmdi;
00139
00140
if (!
ACTIVE(pmdi))
00141
return FALSE;
00142
00143
if (!
IsWindowEnabled(
ACTIVE(pmdi)))
00144
return FALSE;
00145
00146
switch (lpMsg->wParam) {
00147
case VK_F4:
00148 event = SC_CLOSE;
00149
break;
00150
case VK_F6:
00151
case VK_TAB:
00152
if (
GetKeyState(VK_SHIFT) < 0)
00153 event = SC_PREVWINDOW;
00154
else
00155 event = SC_NEXTWINDOW;
00156
break;
00157
default:
00158
return FALSE;
00159 }
00160
00161
00162
00163
00164
if (
GetKeyState(VK_CONTROL) >= 0)
00165
return FALSE;
00166
00167
if (
GetKeyState(VK_MENU) < 0)
00168
return FALSE;
00169
00170
SendMessage(
ACTIVE(pmdi), WM_SYSCOMMAND, event, MAKELONG(lpMsg->wParam, 0));
00171
00172
return TRUE;
00173 }
00174
00175
00176
00177
00178
00179
00180
00181 #define SBJ_HORZ HAS_SBHORZ
00182 #define SBJ_VERT HAS_SBVERT
00183 #define SBJ_BOTH (SBJ_HORZ | SBJ_VERT)
00184
00185 void ByteOutsetRect(LPRECT lprc)
00186 {
00187
int FAR *pi;
00188
int i;
00189
00190
for (i = 0, pi = (
int FAR *) lprc; i < 4; i++, pi++) {
00191
if (*pi > 0)
00192 *pi += 7;
00193
else if (*pi < 0)
00194 *pi -= 7;
00195
00196 *pi /= 8;
00197 }
00198 }
00199
00200 void CalcClientScrolling(HWND hwnd, UINT sbj, BOOL fIgnoreMin)
00201 {
00202
PWND pwnd;
00203 RECT rcScroll;
00204 RECT rcClient;
00205 RECT rcRange;
00206 RECT rcT;
00207
PWND pwndT;
00208
BOOL fVert;
00209
BOOL fHorz;
00210
BYTE fHadVert, fHadHorz;
00211
BOOL fCheckVert;
00212
BOOL fCheckHorz;
00213
BOOL fNeedScrolls;
00214 SCROLLINFO si;
00215
00216
if ((pwnd =
ValidateHwnd(hwnd)) ==
NULL) {
00217
return;
00218 }
00219
CheckLock(pwnd);
00220
00221 UserAssert(
GETFNID(pwnd) !=
FNID_DESKTOP);
00222
00223
00224
00225
if (
TestWF(pwnd,
WFMINIMIZED))
00226
return;
00227
00228 fVert =
FALSE;
00229 fHorz =
FALSE;
00230 fNeedScrolls=
FALSE;
00231
00232 fCheckHorz = (sbj &
SBJ_HORZ);
00233 fCheckVert = (sbj &
SBJ_VERT);
00234
00235
00236
CopyRect(&rcClient, &pwnd->
rcClient);
00237
00238 fHadVert =
TestWF(pwnd,
WFVSCROLL);
00239
if (fCheckVert && fHadVert)
00240 rcClient.right +=
SYSMET(CXVSCROLL);
00241
00242 fHadHorz =
TestWF(pwnd,
WFHSCROLL);
00243
if (fCheckHorz && fHadHorz)
00244 rcClient.bottom +=
SYSMET(CYHSCROLL);
00245
00246
00247
SetRectEmpty(&rcScroll);
00248
00249
for (pwndT =
REBASEPWND(pwnd, spwndChild); pwndT;
00250 pwndT =
REBASEPWND(pwndT, spwndNext)) {
00251
if (fIgnoreMin &&
TestWF(pwndT,
WFMINIMIZED))
00252
continue;
00253
00254
if (
TestWF(pwndT,
WFVISIBLE)) {
00255
if (
TestWF(pwndT,
WFMAXIMIZED)) {
00256 fNeedScrolls =
FALSE;
00257
break;
00258 }
00259
00260
00261
00262
00263
UnionRect(&rcScroll, &rcScroll, &pwndT->
rcWindow);
00264
00265
00266
00267
00268
00269
UnionRect(&rcT, &rcClient, &pwndT->
rcWindow);
00270
if (!
EqualRect(&rcClient, &rcT)) {
00271 fNeedScrolls =
TRUE;
00272 }
00273 }
00274 }
00275
00276
SetRectEmpty(&rcRange);
00277
00278
00279
00280
OffsetRect(&rcScroll, -rcClient.left, -rcClient.top);
00281
OffsetRect(&rcClient, -rcClient.left, -rcClient.top);
00282
00283
if (!fNeedScrolls)
00284 rcClient.bottom = rcClient.right = 0;
00285
else do
00286 {
00287
00288
00289
00290
00291
CopyRect(&rcT, &rcRange);
00292
UnionRect(&rcRange, &rcScroll, &rcClient);
00293
00294
if (fCheckVert) {
00295
00296
if (((rcRange.bottom - rcRange.top) > rcClient.bottom) && !fVert) {
00297 fVert =
TRUE;
00298 rcClient.right -=
SYSMET(CXVSCROLL);
00299 }
00300 }
00301
00302
if (fCheckHorz) {
00303
00304
if (((rcRange.right - rcRange.left) > rcClient.right) && !fHorz) {
00305 fHorz =
TRUE;
00306 rcClient.bottom -=
SYSMET(CYHSCROLL);
00307 }
00308 }
00309 }
00310
while (!
EqualRect(&rcRange, &rcT));
00311
00312
if (fNeedScrolls) {
00313
00314
if (rcRange.right == rcClient.right)
00315 rcRange.right -= 8;
00316
00317
if (rcRange.bottom == rcClient.bottom)
00318 rcRange.bottom -= 8;
00319
00320 }
00321
00322
if (fCheckVert) {
00323
00324
00325
00326
00327
00328
if ((rcRange.bottom - rcRange.top) <= rcClient.bottom) {
00329
ClearWindowState(pwnd,
WFVSCROLL);
00330 }
else {
00331
SetWindowState(pwnd,
WFVSCROLL);
00332 }
00333 }
00334
00335
if (fCheckHorz) {
00336
00337
00338
00339
00340
if ((rcRange.right - rcRange.left) <= rcClient.right) {
00341
ClearWindowState(pwnd,
WFHSCROLL);
00342 }
else {
00343
SetWindowState(pwnd,
WFHSCROLL);
00344 }
00345 }
00346
00347
if (fNeedScrolls) {
00348
ByteOutsetRect(&rcClient);
00349
ByteOutsetRect(&rcRange);
00350 }
00351
00352 si.cbSize =
sizeof(SCROLLINFO);
00353 si.fMask = SIF_ALL;
00354 si.nPos = 0;
00355
00356 si.nMin = rcRange.left;
00357 si.nMax = rcRange.right;
00358 si.nPage = rcClient.right;
00359
00360
NtUserSetScrollInfo(hwnd, SB_HORZ, &si,
FALSE);
00361
00362 si.nMin = rcRange.top;
00363 si.nMax = rcRange.bottom;
00364 si.nPage = rcClient.bottom;
00365
00366
NtUserSetScrollInfo(hwnd, SB_VERT, &si,
FALSE);
00367
00368
if ((fHadVert !=
TestWF(pwnd,
WFVSCROLL)) ||
00369 (fHadHorz !=
TestWF(pwnd,
WFHSCROLL)))
00370
NtUserRedrawFrame(hwnd);
00371 }
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383 void ScrollMDIChildren(
00384 HWND hwnd,
00385
int nCtl,
00386 UINT wCmd,
00387
int iThumbPos)
00388 {
00389 SCROLLINFO si;
00390
int wInc;
00391
int wNewPos;
00392
00393
int x, y;
00394
00395 wInc = (((nCtl == SB_VERT) ?
SYSMET(CYSIZE) :
SYSMET(CXSIZE)) + 7) / 8;
00396
00397 si.cbSize =
sizeof(SCROLLINFO);
00398 si.fMask = SIF_ALL;
00399
GetScrollInfo(hwnd, nCtl, &si);
00400
00401 si.nPage--;
00402 si.nMax -= si.nPage;
00403
00404
switch (wCmd) {
00405
case SB_BOTTOM:
00406 wNewPos = si.nMax;
00407
break;
00408
case SB_TOP:
00409 wNewPos = si.nMin;
00410
break;
00411
case SB_LINEDOWN:
00412 wNewPos = si.nPos + wInc;
00413
break;
00414
case SB_LINEUP:
00415 wNewPos = si.nPos - wInc;
00416
break;
00417
case SB_PAGEDOWN:
00418 wNewPos = si.nPos + si.nPage;
00419
break;
00420
case SB_PAGEUP:
00421 wNewPos = si.nPos - si.nPage;
00422
break;
00423
case SB_THUMBPOSITION:
00424
00425 wNewPos = iThumbPos;
00426
break;
00427
case SB_ENDSCROLL:
00428
CalcClientScrolling(hwnd, (nCtl == SB_VERT) ?
SBJ_VERT :
SBJ_HORZ,
FALSE);
00429
00430
00431
00432
00433
default:
00434
return;
00435 }
00436
00437
if (wNewPos < si.nMin)
00438 wNewPos = si.nMin;
00439
else if (wNewPos > si.nMax)
00440 wNewPos = si.nMax;
00441
00442
SetScrollPos(hwnd, nCtl, wNewPos,
TRUE);
00443
00444
00445
00446
00447
00448
00449 x = (si.nPos - wNewPos) * 8;
00450
00451
if (nCtl == SB_VERT) {
00452 y = x;
00453 x = 0;
00454 }
else
00455
00456 y = 0;
00457
00458
NtUserScrollWindowEx(hwnd, x, y,
NULL,
NULL,
NULL,
NULL,
00459 SW_SCROLLWINDOW | SW_INVALIDATE | SW_ERASE | SW_SCROLLCHILDREN);
00460 }
00461
00462
00463 VOID ScrollChildren(
00464 HWND hwnd,
00465 UINT wMsg,
00466 DWORD wParam)
00467 {
00468
ScrollMDIChildren(hwnd,
00469 wMsg == WM_VSCROLL ? SB_VERT : SB_HORZ,
00470 LOWORD(wParam),
00471 (
short)(HIWORD(wParam)));
00472 }
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483 void RecalculateScrollRanges(
00484
PWND pwndParent,
00485 BOOL fIgnoreMin)
00486 {
00487
PMDI pmdi = ((
PMDIWND)pwndParent)->pmdi;
00488
00489
if (!(
SCROLL(pmdi) & (
CALCSCROLL |
SCROLLCOUNT))) {
00490
if (
PostMessage(
HWq(pwndParent), MM_CALCSCROLL, fIgnoreMin, 0
L)) {
00491
SCROLL(pmdi) |=
CALCSCROLL;
00492 }
00493 }
00494 }
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505 void GetCascadeWindowPos(
00506 LPCRECT prcClient,
00507
int iWindow,
00508 LPRECT lprc)
00509 {
00510
int cStack;
00511
int xStep, yStep;
00512
int dxClient, dyClient;
00513
00514
00515
00516
00517 dxClient = prcClient->right - prcClient->left;
00518 UserAssert(dxClient >= 0);
00519 dyClient = prcClient->bottom - prcClient->top;
00520 UserAssert(dyClient >= 0);
00521
00522
00523
00524
00525 xStep =
SYSMET(CXSIZEFRAME) +
SYSMET(CXSIZE);
00526 yStep =
SYSMET(CYSIZEFRAME) +
SYSMET(CYSIZE);
00527
00528
00529
00530
00531 cStack = dyClient / (3 * yStep);
00532
00533 lprc->right = dxClient - (cStack * xStep);
00534 lprc->bottom = dyClient - (cStack * yStep);
00535
00536
00537
00538
00539
00540
if (++cStack <= 0) {
00541 cStack = 1;
00542 }
00543
00544 lprc->left = prcClient->left + (iWindow % cStack) * xStep;
00545 lprc->top = prcClient->top + (iWindow % cStack) * yStep;
00546 }
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557 void MDICheckCascadeRect(
00558
PWND pwndClient,
00559 LPRECT lprc)
00560 {
00561
PMDI pmdi;
00562 RECT rc, rcClient;
00563
int iWindow;
00564
00565
00566
00567
00568 pmdi = ((
PMDIWND)pwndClient)->pmdi;
00569
00570 iWindow =
ITILELEVEL(pmdi);
00571
00572
GetRect(pwndClient, &rcClient,
GRECT_CLIENT |
GRECT_CLIENTCOORDS);
00573
GetCascadeWindowPos(&rcClient, iWindow, &rc);
00574
00575
if ((lprc->right == CW_USEDEFAULT || lprc->right ==
CW2_USEDEFAULT) ||
00576 !(lprc->right)) {
00577 lprc->right = rc.right;
00578 }
00579
00580
if ((lprc->bottom == CW_USEDEFAULT || lprc->bottom ==
CW2_USEDEFAULT) ||
00581 !(lprc->bottom)) {
00582 lprc->bottom = rc.bottom;
00583 }
00584
00585
if (lprc->left == CW_USEDEFAULT || lprc->left ==
CW2_USEDEFAULT) {
00586 lprc->left = rc.left;
00587 lprc->top = rc.top;
00588 }
00589 }
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603 BOOL UnmaximizeChildWindows(
00604 HWND hwndParent)
00605 {
00606 HWND hwndMove;
00607
PWND pwndMove;
00608
BOOL fFoundOne =
FALSE;
00609
BOOL fAsync;
00610
UINT chwnd;
00611 HWND *phwndList;
00612 HWND *phwnd;
00613 HWND hwndChild =
GetWindow(hwndParent, GW_CHILD);
00614
00615
00616
00617
00618
00619
if (hwndChild ==
NULL ||
00620 (chwnd =
BuildHwndList(
NULL,
GetWindow(hwndParent, GW_CHILD),
00621
FALSE, 0, &phwndList)) == 0) {
00622
return FALSE;
00623 }
00624
00625 fAsync = (hwndParent ==
GetDesktopWindow());
00626
00627
for (phwnd = phwndList; chwnd > 0; chwnd--, phwnd++) {
00628
if ((hwndMove = *phwnd) ==
NULL)
00629
continue;
00630
00631
if ((pwndMove =
ValidateHwnd(hwndMove)) ==
NULL)
00632
continue;
00633
00634
00635
00636
00637
00638
if (
TestWF(pwndMove,
WFMAXIMIZED) &&
TestWF(pwndMove,
WFVISIBLE)) {
00639
00640
00641
00642
00643
if (!fFoundOne && fAsync)
00644
NtUserLockWindowUpdate(hwndParent);
00645
00646 fFoundOne =
TRUE;
00647
00648
if (fAsync)
00649
NtUserShowWindowAsync(hwndMove, SW_SHOWNOACTIVATE);
00650
else
00651
NtUserShowWindow(hwndMove, SW_SHOWNORMAL);
00652 }
00653 }
00654
00655
UserLocalFree(phwndList);
00656
00657
if (fFoundOne && fAsync) {
00658
00659 HWND hwndActive =
NtUserGetForegroundWindow();
00660
if (hwndActive !=
NULL) {
00661
00662
00663
00664
00665
00666
NtUserSetWindowPos(hwndActive, HWND_TOP, 0, 0, 0, 0,
00667 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_ASYNCWINDOWPOS);
00668
00669 }
00670
NtUserLockWindowUpdate(
NULL);
00671
RedrawWindow(hwndParent,
NULL,
NULL,
00672 RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE | RDW_FRAME);
00673 }
00674
00675
return fFoundOne;
00676 }
00677
00678
00679
00680
00681
00682
00683
00684
00685 typedef struct tagARRANGEWINDOWSDATA {
00686 PWND pwndParent;
00687 UINT flags;
00688 LPRECT
lprcParent;
00689 int chwnd;
00690 int chwndReal;
00691 HWND *
phwnd;
00692 PWND pwndDesktop;
00693 HDWP
hdwp;
00694 UINT uGRCFlags;
00695 int fVerifyParent;
00696 }
ARRANGEWINDOWSDATA, *
PARRANGEWINDOWSDATA;
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711 WORD
ArrangeWindows(
00712 HWND hwndParent,
00713 UINT flags,
00714 CONST RECT * lpRect,
00715 UINT chwnd,
00716 CONST HWND * ahwnd,
00717 MONITORENUMPROC lpfnEnum)
00718 {
00719
ARRANGEWINDOWSDATA awd;
00720 HWND * phwnd =
NULL;
00721
00722
00723
00724
00725 awd.
pwndDesktop =
_GetDesktopWindow();
00726
if (!hwndParent) {
00727 hwndParent =
HW(awd.
pwndDesktop);
00728 awd.
pwndParent = awd.
pwndDesktop;
00729 }
else {
00730 awd.
pwndParent =
ValidateHwnd(hwndParent);
00731
if (awd.
pwndParent ==
NULL) {
00732
return 0;
00733 }
00734 }
00735
00736
UnmaximizeChildWindows(hwndParent);
00737
00738
00739
00740
00741
00742
if ( lpRect &&
00743 awd.
pwndParent == awd.
pwndDesktop &&
00744 lpRect->left <= awd.
pwndDesktop->
rcClient.left &&
00745 lpRect->top <= awd.
pwndDesktop->
rcClient.top &&
00746 lpRect->right >= awd.
pwndDesktop->
rcClient.right &&
00747 lpRect->bottom >= awd.
pwndDesktop->
rcClient.bottom ) {
00748
00749 lpRect =
NULL;
00750 }
00751
00752
00753
00754
00755
00756
if (lpRect ==
NULL) {
00757
if ( ( awd.
pwndParent != awd.
pwndDesktop ||
00758 !(
SYSMET(ARRANGE) & ARW_HIDE)) &&
00759
NtUserArrangeIconicWindows(hwndParent) != 0) {
00760
00761 awd.
uGRCFlags =
GRC_SCROLLS |
GRC_MINWNDS;
00762 }
else {
00763 awd.
uGRCFlags =
GRC_SCROLLS;
00764 }
00765 }
00766
00767
00768
00769
00770
if (ahwnd ==
NULL) {
00771 HWND hwndChild;
00772
PWND pwndChild;
00773
00774 pwndChild =
REBASEPWND(awd.
pwndParent, spwndChild);
00775 hwndChild =
HW(pwndChild);
00776
if ( hwndChild ==
NULL ||
00777 (chwnd =
BuildHwndList(
NULL, hwndChild,
FALSE, 0, &phwnd)) == 0) {
00778
return 0;
00779 }
00780 }
00781
00782
00783
00784
00785 awd.
hdwp =
NtUserBeginDeferWindowPos(chwnd);
00786
if (awd.
hdwp ==
NULL)
00787
goto Done;
00788
00789 awd.
flags = flags;
00790 awd.
lprcParent = (LPRECT) lpRect;
00791 awd.
chwnd = chwnd;
00792 awd.
chwndReal = 0;
00793 awd.
phwnd = ahwnd ? (HWND *) ahwnd : phwnd;
00794 awd.
fVerifyParent = (ahwnd !=
NULL);
00795
00796
00797
00798
00799
00800
00801
if (awd.
pwndParent == awd.
pwndDesktop && lpRect ==
NULL) {
00802
NtUserEnumDisplayMonitors(
NULL,
NULL, lpfnEnum, (LPARAM) &awd);
00803 }
else {
00804 (*lpfnEnum)(
NULL,
NULL,
NULL, (LPARAM) &awd);
00805 }
00806
00807
00808
if (awd.
hdwp !=
NULL) {
00809
NtUserEndDeferWindowPosEx(awd.
hdwp,
TRUE);
00810 }
00811
00812 Done:
00813
if (phwnd) {
00814
UserLocalFree(phwnd);
00815 }
00816
00817
return (awd.
hdwp !=
NULL) ? awd.
chwndReal : 0;
00818 }
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
void
00833 GetParentArrangeRect(PARRANGEWINDOWSDATA pawd,
PMONITOR pMonitor, LPRECT lprc)
00834 {
00835
UINT uGRCFlags;
00836
00837
if (pawd->
lprcParent) {
00838 *lprc = *pawd->
lprcParent;
00839 }
else {
00840 uGRCFlags = pawd->
uGRCFlags;
00841
00842
00843
00844
00845
00846
00847
if (pMonitor && pMonitor !=
GetPrimaryMonitor()) {
00848 uGRCFlags &= ~
GRC_MINWNDS;
00849 }
00850
00851
GetRealClientRect(
00852 pawd->
pwndParent, lprc, uGRCFlags, pMonitor);
00853 }
00854 }
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
PWND
00869 ValidatePositionableWindow(
00870 HWND hwndChild,
00871
PWND pwndParent,
00872
PWND pwndDesktop,
00873 DWORD dwMDIFlags,
00874
PMONITOR pMonitor,
00875 DWORD * pdwSWPFlags)
00876 {
00877
PWND pwndChild;
00878
00879 pwndChild =
ValidateHwnd(hwndChild);
00880
if (pwndChild) {
00881
if (pwndParent &&
REBASEPWND(pwndChild, spwndParent) != pwndParent) {
00882 RIPMSG0(RIP_WARNING,
"Cascade/Tile Windows: Windows in list must have same parent");
00883 }
else if (
00884
00885
00886
00887
00888
00889
TestWF(pwndChild,
WFVISIBLE) &&
00890
TestWF(pwndChild,
WFCPRESENT) &&
00891 !
TestWF(pwndChild,
WFMINIMIZED) &&
00892 !
TestWF(pwndChild,
WEFTOPMOST) &&
00893 (!(dwMDIFlags & MDITILE_SKIPDISABLED) || !
TestWF(pwndChild,
WFDISABLED)) &&
00894 !
TestWF(pwndChild,
WEFTOOLWINDOW) &&
00895 ((pMonitor) ?
00896 (pMonitor ==
_MonitorFromWindow(pwndChild, MONITOR_DEFAULTTONULL)) :
00897 (pwndParent != pwndDesktop ||
_MonitorFromWindow(pwndChild, MONITOR_DEFAULTTONULL)))) {
00898
00899
if (pdwSWPFlags) {
00900 *pdwSWPFlags = SWP_NOACTIVATE | SWP_NOCOPYBITS;
00901
if (!
TestWF(pwndChild,
WFSIZEBOX)) {
00902 *pdwSWPFlags |= SWP_NOSIZE;
00903 }
00904
if (!(dwMDIFlags & MDITILE_ZORDER)) {
00905 *pdwSWPFlags |= SWP_NOZORDER;
00906 }
00907 }
00908
return pwndChild;
00909 }
00910 }
00911
00912
return NULL;
00913 }
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
BOOL CALLBACK
00927 CascadeWindowsEnum(
00928 HMONITOR hmonitor,
00929 HDC hdc,
00930 LPRECT lprc,
00931 LPARAM lparam)
00932 {
00933
PARRANGEWINDOWSDATA pawd = (
PARRANGEWINDOWSDATA)lparam;
00934
PMONITOR pMonitor = hmonitor ?
VALIDATEHMONITOR(hmonitor) :
NULL;
00935 RECT rcParent;
00936
int i;
00937
int chwndReal = 0;
00938 RECT rc;
00939 HWND * phwnd, * phwndCopy;
00940
BOOL fRet =
TRUE;
00941
00942 UNREFERENCED_PARAMETER(hdc);
00943 UNREFERENCED_PARAMETER(lprc);
00944
00945
00946
00947
00948
GetParentArrangeRect(pawd, pMonitor, &rcParent);
00949
00950
00951
00952
00953
00954
if (pawd->
flags & MDITILE_ZORDER) {
00955
PWND pwndChild;
00956 HWND * phwndFullList, * phwndNext, * phwndSort, * phwndSearch;
00957
int chwndFullList, chwndSort, chwndSearch;
00958
00959
00960
00961 phwndCopy =
UserLocalAlloc(0, pawd->
chwnd *
sizeof(HWND));
00962
if (phwndCopy ==
NULL) {
00963
return FALSE;
00964 }
00965 RtlCopyMemory(phwndCopy, pawd->
phwnd, pawd->
chwnd *
sizeof(HWND));
00966
00967
00968
00969 pwndChild =
REBASEPWND(pawd->
pwndParent, spwndChild);
00970
if (pwndChild ==
NULL) {
00971 fRet =
FALSE;
00972
goto CleanUp;
00973 }
00974 chwndFullList =
BuildHwndList(
NULL,
HWq(pwndChild),
FALSE, 0, &phwndFullList);
00975
if (chwndFullList == 0) {
00976 fRet =
FALSE;
00977
goto CleanUp;
00978 }
00979
00980
00981
00982
for (phwndNext = phwndFullList, chwndSort = pawd->
chwnd, phwndSort = phwndCopy;
00983 (chwndFullList > 0) && (chwndSort > 1);
00984 chwndFullList--, phwndNext++) {
00985
00986
for (chwndSearch = chwndSort, phwndSearch = phwndSort;
00987 chwndSearch > 0;
00988 chwndSearch--, phwndSearch++) {
00989
00990
00991
00992
if (*phwndNext == *phwndSearch) {
00993 HWND hwndFirst = *phwndSort;
00994 *phwndSort = *phwndSearch;
00995 *phwndSearch = hwndFirst;
00996 phwndSort++;
00997 chwndSort--;
00998
break;
00999 }
01000 }
01001 }
01002
UserLocalFree(phwndFullList);
01003 }
else {
01004 phwndCopy = pawd->
phwnd;
01005 }
01006
01007
01008
01009
01010
for (i = pawd->
chwnd, phwnd = phwndCopy + i - 1; --i >= 0; phwnd--) {
01011 HWND hwndChild;
01012
PWND pwndChild =
NULL;
01013
DWORD dwSWPFlags;
01014
01015 hwndChild = *phwnd;
01016 pwndChild =
ValidatePositionableWindow(
01017 hwndChild,
01018 pawd->
fVerifyParent ? pawd->
pwndParent :
NULL,
01019 pawd->
pwndDesktop,
01020 pawd->
flags,
01021 pMonitor,
01022 &dwSWPFlags);
01023
01024
if (!pwndChild)
01025
continue;
01026
01027
GetCascadeWindowPos(&rcParent, chwndReal, &rc);
01028
01029 pawd->
hdwp =
NtUserDeferWindowPos(
01030 pawd->
hdwp,
01031 hwndChild,
01032 HWND_TOP,
01033 rc.left,
01034 rc.top,
01035 rc.right,
01036 rc.bottom,
01037 dwSWPFlags);
01038
01039 chwndReal++;
01040 pawd->
chwndReal++;
01041 }
01042
01043 CleanUp:
01044
if (pawd->
flags & MDITILE_ZORDER) {
01045
UserLocalFree(phwndCopy);
01046 }
01047
01048
return fRet && (pawd->
hdwp !=
NULL);
01049 }
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061 WORD
CascadeWindows(
01062 HWND hwndParent,
01063 UINT flags,
01064 CONST RECT *lpRect,
01065 UINT chwnd,
01066 CONST HWND *ahwnd)
01067 {
01068
return ArrangeWindows(hwndParent, flags, lpRect, chwnd, ahwnd,
CascadeWindowsEnum);
01069 }
01070
01071
BOOL CALLBACK
01072 TileWindowsEnum(
01073 HMONITOR hmonitor,
01074 HDC hdc,
01075 LPRECT lprc,
01076 LPARAM lparam)
01077 {
01078
PARRANGEWINDOWSDATA pawd = (
PARRANGEWINDOWSDATA)lparam;
01079
PMONITOR pMonitor = hmonitor ?
VALIDATEHMONITOR(hmonitor) :
NULL;
01080 RECT rcParent;
01081
int ihwnd;
01082
int chwndReal;
01083
int square;
01084
int iCol, iRow;
01085
int cCol, cRow;
01086
int cRem;
01087
int dx, dy;
01088
int xRes, yRes;
01089
01090 UNREFERENCED_PARAMETER(hdc);
01091 UNREFERENCED_PARAMETER(lprc);
01092
01093
01094
01095
01096
GetParentArrangeRect(pawd, pMonitor, &rcParent);
01097
01098
01099
01100
01101 chwndReal = 0;
01102
for (ihwnd = pawd->
chwnd; --ihwnd >= 0;) {
01103
if (
ValidatePositionableWindow(
01104 pawd->
phwnd[ihwnd],
01105 pawd->
fVerifyParent ? pawd->
pwndParent :
NULL,
01106 pawd->
pwndDesktop,
01107 pawd->
flags,
01108 pMonitor,
01109
NULL)) {
01110
01111 chwndReal++;
01112 }
01113 }
01114
01115
if (chwndReal == 0)
01116
return TRUE;
01117
01118 xRes = rcParent.right - rcParent.left;
01119 yRes = rcParent.bottom - rcParent.top;
01120
if (xRes <= 0 || yRes <= 0)
01121
return TRUE;
01122
01123
01124
01125
01126
for (square = 2; square * square <= chwndReal; square++) {
01127 ;
01128 }
01129
01130
if (pawd->
flags & MDITILE_HORIZONTAL) {
01131 cCol = square - 1;
01132 cRow = chwndReal / cCol;
01133 cRem = chwndReal % cCol;
01134 }
else {
01135 cRow = square - 1;
01136 cCol = chwndReal / cRow;
01137 cRem = chwndReal % cRow;
01138 }
01139
01140 chwndReal = 0;
01141 ihwnd = -1;
01142
for (iCol = 0; iCol < cCol; iCol++) {
01143
01144
01145
01146
if (cCol - iCol <= cRem) {
01147 cRow++;
01148 }
01149
01150
for (iRow = 0; iRow < cRow; iRow++) {
01151 HWND hwndChild;
01152
PWND pwndChild;
01153
DWORD dwSWPFlags;
01154
01155 dx = xRes / cCol;
01156 dy = yRes / cRow;
01157
01158 NextWindow:
01159
01160
01161
01162 ihwnd++;
01163
if (ihwnd >= pawd->
chwnd)
01164
return TRUE;
01165
01166 hwndChild = pawd->
phwnd[ihwnd];
01167 pwndChild =
ValidatePositionableWindow(
01168 hwndChild,
01169 pawd->
fVerifyParent ? pawd->
pwndParent :
NULL,
01170 pawd->
pwndDesktop,
01171 pawd->
flags,
01172 pMonitor,
01173 &dwSWPFlags);
01174
01175
if (!pwndChild)
01176
goto NextWindow;
01177
01178
01179
01180
01181 pawd->
hdwp =
NtUserDeferWindowPos(
01182 pawd->
hdwp,
01183 hwndChild,
01184 HWND_TOP,
01185 rcParent.left + iCol*dx,
01186 rcParent.top + iRow*dy,
01187 dx,
01188 dy,
01189 dwSWPFlags);
01190
01191
if (pawd->
hdwp ==
NULL)
01192
return FALSE;
01193
01194 chwndReal++;
01195 pawd->
chwndReal++;
01196 }
01197
01198
if (cCol - iCol <= cRem) {
01199 cRow--;
01200 cRem--;
01201 }
01202 }
01203
01204
return TRUE;
01205 }
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217 WORD
TileWindows(
01218 HWND hwndParent,
01219 UINT flags,
01220 CONST RECT *lpRect,
01221 UINT chwnd,
01222 CONST HWND *ahwnd)
01223 {
01224
return ArrangeWindows(hwndParent, flags, lpRect, chwnd, ahwnd,
TileWindowsEnum);
01225 }
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237 void xxxMDIActivate(
01238
PWND pwnd,
01239
PWND pwndActivate)
01240 {
01241 HWND hwndOld;
01242
PWND pwndOld;
01243
01244
PMDI pmdi;
01245
BOOL fShowActivate;
01246
UINT nID;
01247
TL tlpwnd;
01248
TL tlpwndOld;
01249
PWND pwndT;
01250 HWND hwnd =
HWq(pwnd);
01251 HWND hwndActivate =
HW(pwndActivate);
01252
01253
CheckLock(pwnd);
01254
CheckLock(pwndActivate);
01255
01256
01257
01258
01259 pmdi = ((
PMDIWND)pwnd)->pmdi;
01260
01261
if (
ACTIVE(pmdi) == hwndActivate)
01262
return;
01263
01264
if ((pwndActivate !=
NULL) && (
TestWF(pwndActivate,
WFDISABLED))) {
01265
01266
01267
01268
return;
01269 }
01270
01271 pwndT =
REBASEPWND(pwnd, spwndParent);
01272 fShowActivate = (
HW(pwndT) ==
01273
NtUserQueryWindow(hwnd, WindowActiveWindow));
01274
01275 hwndOld =
ACTIVE(pmdi);
01276
if (hwndOld && (pwndOld =
ValidateHwnd(hwndOld)) ==
NULL) {
01277 hwndOld =
NULL;
01278 }
01279
ThreadLock(pwndOld, &tlpwndOld);
01280
01281
if (hwndOld) {
01282
01283
01284
01285
01286
01287
01288
01289
if (!
SendMessage(hwndOld, WM_NCACTIVATE,
FALSE, 0
L) && fShowActivate) {
01290
if (
TestWF(pwndOld,
WFWIN31COMPAT))
01291
goto UnlockOld;
01292 }
01293
01294
if (!
TestWF(pwndOld,
WFWIN31COMPAT) &&
TestWF(pwndOld,
WFFRAMEON)) {
01295
01296
01297
01298
01299
01300
01301
01302
01303
goto UnlockOld;
01304 }
01305
01306
SendMessage(hwndOld, WM_MDIACTIVATE, (WPARAM)hwndOld, (LPARAM)hwndActivate);
01307
01308
01309
01310
01311
if (
WINDOW(pmdi))
01312
CheckMenuItem(
WINDOW(pmdi), PtrToUlong(pwndOld->spmenu),
01313 MF_BYCOMMAND | MF_UNCHECKED);
01314 }
01315
01316
01317
01318
01319
01320
01321
01322
if (
MAXED(pmdi) &&
MAXED(pmdi) != hwndActivate) {
01323 HWND hwndMax;
01324
int iShowCode;
01325
01326
01327
01328
01329
if (pwndActivate && (
TestWF(pwndActivate,
WFMAXBOX) || !
TestWF(pwndActivate,
WFWIN40COMPAT))) {
01330 hwndMax = hwndActivate;
01331 iShowCode = SW_SHOWMAXIMIZED;
01332
Lock(&
ACTIVE(pmdi), hwndMax);
01333 }
else {
01334 hwndMax =
MAXED(pmdi);
01335 iShowCode = SW_SHOWNORMAL;
01336 }
01337
01338
01339
01340
01341
01342
NtUserCallHwndParam(hwndMax,
WFNOANIMATE, SFI_SETWINDOWSTATE);
01343
NtUserShowWindow(hwndMax, iShowCode);
01344
NtUserCallHwndParam(hwndMax,
WFNOANIMATE, SFI_CLEARWINDOWSTATE);
01345 }
01346
01347
Lock(&
ACTIVE(pmdi), hwndActivate);
01348
01349
01350
01351
01352
if (!pwndActivate) {
01353
if (fShowActivate)
01354
NtUserSetFocus(hwnd);
01355
goto UnlockOld;
01356 }
01357
01358
if (
WINDOW(pmdi)) {
01359
01360
01361
01362
01363 nID = GetWindowID(
ACTIVE(pmdi));
01364
if (nID -
FIRST(pmdi) < (
MAXITEMS - 1)) {
01365
CheckMenuItem(
WINDOW(pmdi), nID, MF_BYCOMMAND | MFS_CHECKED);
01366 }
else {
01367
01368
01369
01370
PWND pwndOther =
FindPwndChild(pwnd, (
UINT)(
FIRST(pmdi) +
MAXITEMS - 2));
01371
01372
SetWindowLongPtr(
HW(pwndOther), GWLP_ID, PtrToLong(pwndActivate->
spmenu));
01373
SetWindowLongPtr(hwndActivate, GWLP_ID,
FIRST(pmdi) +
MAXITEMS - 2);
01374
01375
ModifyMenuItem(pwndActivate);
01376 }
01377 }
01378
01379
01380
01381
01382
NtUserSetWindowPos(
ACTIVE(pmdi),
NULL, 0, 0, 0, 0,
01383 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
01384
01385
01386
01387
01388
if (fShowActivate) {
01389
SendMessage(
ACTIVE(pmdi), WM_NCACTIVATE,
TRUE, 0
L);
01390
01391
ThreadLock(pwnd, &tlpwnd);
01392
01393
if (hwnd ==
NtUserQueryWindow(hwnd, WindowFocusWindow))
01394
SendMessage(hwnd, WM_SETFOCUS, (WPARAM)hwnd, 0);
01395
else
01396
NtUserSetFocus(hwnd);
01397
01398
ThreadUnlock(&tlpwnd);
01399 }
01400
01401
01402
01403
01404
SendMessage(
ACTIVE(pmdi), WM_MDIACTIVATE, (WPARAM)hwndOld,
01405 (LPARAM)hwndActivate);
01406
01407 UnlockOld:
01408
ThreadUnlock(&tlpwndOld);
01409 }
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420 void xxxMDINext(
01421
PWND pwndMDI,
01422
PWND pwnd,
01423 BOOL fPrevWindow)
01424 {
01425
PMDI pmdi;
01426
PWND pwndNextGuy;
01427 HDWP hdwp;
01428
BOOL fHack =
FALSE;
01429
01430
CheckLock(pwndMDI);
01431
CheckLock(pwnd);
01432
01433
01434
01435
01436 pmdi = ((
PMDIWND)pwndMDI)->pmdi;
01437
01438 pwndNextGuy = pwnd;
01439
01440
while (
TRUE) {
01441
if (fPrevWindow)
01442 pwndNextGuy =
_GetWindow(pwndNextGuy, GW_HWNDPREV);
01443
else
01444 pwndNextGuy =
REBASEPWND(pwndNextGuy, spwndNext);
01445
01446
if (!pwndNextGuy) {
01447
if (fPrevWindow) {
01448 pwndNextGuy =
_GetWindow(pwnd, GW_HWNDLAST);
01449 }
else {
01450 pwndNextGuy =
REBASEPWND(pwndMDI, spwndChild);
01451 }
01452 }
01453
01454
if (pwndNextGuy == pwnd)
01455
return;
01456
01457
01458
01459
01460
01461
if (
TestWF(pwndNextGuy,
WFVISIBLE) && !
TestWF(pwndNextGuy,
WFDISABLED))
01462
break;
01463 }
01464
01465
if (
MAXED(pmdi)) {
01466
NtUserSetVisible(
HWq(pwndMDI),
SV_UNSET |
SV_CLRFTRUEVIS);
01467 fHack =
TRUE;
01468 }
01469
01470 hdwp =
NtUserBeginDeferWindowPos(2);
01471
01472
01473
01474
01475 hdwp =
NtUserDeferWindowPos(hdwp,
HW(pwndNextGuy), HWND_TOP, 0, 0, 0, 0,
01476 SWP_NOMOVE | SWP_NOSIZE);
01477
01478
01479
01480
01481
if (hdwp && !fPrevWindow && (pwnd != pwndNextGuy))
01482 hdwp =
NtUserDeferWindowPos(hdwp,
HW(pwnd),
01483 HWND_BOTTOM, 0, 0, 0, 0,
01484 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE );
01485
01486
NtUserEndDeferWindowPosEx(hdwp,
FALSE);
01487
01488
if (fHack) {
01489
NtUserShowWindow(
HWq(pwndMDI), SW_SHOW);
01490 }
01491 }
01492
01493
01494 HWND
01495 CreateMDIWindowA(
01496 LPCSTR pClassName,
01497 LPCSTR pWindowName,
01498 DWORD dwStyle,
01499
int x,
01500
int y,
01501
int nWidth,
01502
int nHeight,
01503 HWND hwndParent,
01504 HINSTANCE hModule,
01505 LPARAM lParam)
01506 {
01507
return CreateWindowExA(
WS_EX_MDICHILD, pClassName, pWindowName,
01508 dwStyle, x, y, nWidth, nHeight,
01509 hwndParent,
NULL, hModule, (
LPVOID)lParam);
01510 }
01511
01512
01513 HWND
01514 CreateMDIWindowW(
01515 LPCWSTR pClassName,
01516 LPCWSTR pWindowName,
01517 DWORD dwStyle,
01518
int x,
01519
int y,
01520
int nWidth,
01521
int nHeight,
01522 HWND hwndParent,
01523 HINSTANCE hModule,
01524 LPARAM lParam)
01525 {
01526
return CreateWindowExW(
WS_EX_MDICHILD, pClassName, pWindowName,
01527 dwStyle, x, y, nWidth, nHeight,
01528 hwndParent,
NULL, hModule, (
LPVOID)lParam);
01529 }
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540 void xxxMDIDestroy(
01541
PWND pwnd,
01542 HWND hwndVictim)
01543 {
01544
PWND pwndVictim;
01545
TL tlpwndParent;
01546
PMDI pmdi;
01547
PWND pwndParent;
01548 HWND hwnd;
01549
01550
CheckLock(pwnd);
01551
01552
if ((pwndVictim =
ValidateHwnd(hwndVictim)) ==
NULL) {
01553
return;
01554 }
01555
CheckLock(pwndVictim);
01556
01557
01558
01559
01560 pmdi = ((
PMDIWND)pwnd)->pmdi;
01561
01562
#ifdef NEVER
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
if (((
UINT)pwndVictim->
spmenu) <
FIRST(pmdi) ||
01577 ((
UINT)pwndVictim->
spmenu) >= (
UINT)(
FIRST(pmdi) +
CKIDS(pmdi)) ||
01578 pwndVictim->
spwndOwner !=
NULL) {
01579 RIPERR0(ERROR_NON_MDICHILD_WINDOW, RIP_VERBOSE,
"");
01580
return;
01581 }
01582
#endif
01583
01584
ShiftMenuIDs(pwnd, pwndVictim);
01585
01586
01587
01588
01589
if (
SAMEWOWHANDLE(hwndVictim,
ACTIVE(pmdi))) {
01590
xxxMDINext(pwnd, pwndVictim,
FALSE);
01591
01592
01593
01594
01595
if (
SAMEWOWHANDLE(hwndVictim,
ACTIVE(pmdi))) {
01596
NtUserShowWindow(hwndVictim, SW_HIDE);
01597
01598
01599
01600
01601
01602
01603
if (
MAXED(pmdi)) {
01604 pwndParent =
REBASEPWND(pwnd, spwndParent);
01605
MDIRemoveSysMenu(
PtoH(
REBASE(pwndParent,spmenu)),
MAXED(pmdi));
01606
Unlock(&
MAXED(pmdi));
01607
ThreadLock(pwndParent, &tlpwndParent);
01608
xxxSetFrameTitle(pwndParent, pwnd, (LPWSTR)1
L);
01609
01610
01611
01612
01613
if (
TestWF(pwndParent,
WFVISIBLE))
01614
NtUserRedrawFrame(
HWq(pwndParent));
01615
ThreadUnlock(&tlpwndParent);
01616 }
01617
xxxMDIActivate(pwnd,
NULL);
01618 }
01619 }
01620
01621
01622
01623
01624
CKIDS(pmdi)--;
01625
if ((
int)
CKIDS(pmdi) < 0)
01626
CKIDS(pmdi) = 0;
01627
01628 hwnd =
HWq(pwnd);
01629
SendMessage(hwnd, WM_MDIREFRESHMENU, 0
L, 0
L);
01630
01631
01632
01633
01634
NtUserDestroyWindow(hwndVictim);
01635
01636
01637
01638
01639
01640
01641
if (
ValidateHwnd(hwnd) ==
NULL)
01642
return;
01643
01644
01645
01646
01647
RecalculateScrollRanges(pwnd,
FALSE);
01648 }
01649
01650
01651
01652
01653
01654
01655
01656
01657 LRESULT
MDIClientWndProcWorker(
01658
PWND pwnd,
01659 UINT message,
01660 WPARAM wParam,
01661 LPARAM lParam,
01662 DWORD fAnsi)
01663 {
01664 HWND hwnd =
HWq(pwnd);
01665 HWND hwndT;
01666
PWND pwndT;
01667
TL tlpwndT;
01668
PMDI pmdi;
01669
PWND pwndParent;
01670
01671
CheckLock(pwnd);
01672
01673
VALIDATECLASSANDSIZE(pwnd,
FNID_MDICLIENT);
01674
01675
01676
01677
01678
01679
01680 pmdi = ((
PMDIWND)pwnd)->pmdi;
01681
01682
if (pmdi ==
NULL) {
01683
switch (message) {
01684
case WM_MDICREATE:
01685
case WM_MDIMAXIMIZE:
01686
case WM_PARENTNOTIFY:
01687
case WM_CREATE:
01688
01689
01690
01691
01692
break;
01693
01694
default:
01695
01696
01697
01698
01699
goto CallDWP;
01700 }
01701 }
01702
01703
switch (message) {
01704
case WM_NCACTIVATE:
01705
01706
01707
01708
01709
if (
ACTIVE(pmdi) !=
NULL) {
01710
SendMessage(
ACTIVE(pmdi), WM_NCACTIVATE, wParam, lParam);
01711 }
01712
goto CallDWP;
01713
01714
case WM_MDIGETACTIVE:
01715
if (lParam != 0) {
01716 *((LPBOOL)lParam) = (
MAXED(pmdi) !=
NULL);
01717 }
01718
01719
return (LRESULT)
ACTIVE(pmdi);
01720
01721
case WM_MDIACTIVATE:
01722 hwndT = (HWND)wParam;
01723
if ((pwndT =
ValidateHwnd(hwndT)) ==
NULL)
01724
return 0;
01725
01726
if (
SAMEWOWHANDLE(hwndT,
ACTIVE(pmdi)))
01727
break;
01728
01729
NtUserSetWindowPos(hwndT, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
01730
break;
01731
01732
case WM_MDICASCADE:
01733 pmdi->
wScroll |=
SCROLLSUPPRESS;
01734
NtUserShowScrollBar(hwnd, SB_BOTH,
FALSE);
01735
01736
01737
01738
01739
#ifdef NEVER // Not in Chicago -- FritzS
01740
if (
MAXED(pmdi) !=
NULL) {
01741
NtUserShowWindow(
MAXED(pmdi), SW_SHOWNORMAL);
01742 }
01743
#endif
01744
01745
01746
01747 message = (
UINT)
CascadeWindows(hwnd, (
UINT)wParam,
NULL, 0,
NULL);
01748 pmdi->
wScroll &= ~
SCROLLCOUNT;
01749
return (LONG)message;
01750
break;
01751
01752
case WM_VSCROLL:
01753
case WM_HSCROLL:
01754 pmdi->
wScroll |=
SCROLLSUPPRESS;
01755
ScrollMDIChildren(hwnd, (message == WM_VSCROLL) ? SB_VERT : SB_HORZ,
01756 LOWORD(wParam), (
short)(HIWORD(wParam)));
01757 pmdi->
wScroll &= ~
SCROLLCOUNT;
01758
break;
01759
01760
case WM_MDICREATE:
01761 {
01762 LPMDICREATESTRUCTA lpMCSA = (LPMDICREATESTRUCTA)lParam;
01763 LPMDICREATESTRUCTW lpMCSW = (LPMDICREATESTRUCTW)lParam;
01764
DWORD exStyle =
WS_EX_MDICHILD;
01765
01766
01767
01768
01769 exStyle |= (pwnd->ExStyle & (WS_EX_RIGHT | WS_EX_RTLREADING | WS_EX_LEFTSCROLLBAR));
01770
01771
if (fAnsi) {
01772 hwndT = CreateWindowExA(exStyle, lpMCSA->szClass, lpMCSA->szTitle,
01773 lpMCSA->style, lpMCSA->x, lpMCSA->y, lpMCSA->cx, lpMCSA->cy,
01774 hwnd,
NULL, lpMCSA->hOwner, (LPSTR)lpMCSA->lParam);
01775 }
else {
01776 hwndT = CreateWindowExW(exStyle, lpMCSW->szClass, lpMCSW->szTitle,
01777 lpMCSW->style, lpMCSW->x, lpMCSW->y, lpMCSW->cx, lpMCSW->cy,
01778 hwnd,
NULL, lpMCSW->hOwner, (LPWSTR)lpMCSW->lParam);
01779 }
01780
01781
return((LRESULT)hwndT);
01782
01783 }
01784
01785
case WM_MDIDESTROY:
01786
xxxMDIDestroy(pwnd, (HWND)wParam);
01787
break;
01788
01789
case WM_MDIMAXIMIZE:
01790 hwndT = (HWND)wParam;
01791
if ((pwndT =
ValidateHwnd(hwndT)) ==
NULL)
01792
return 0;
01793
01794
01795
01796
01797
01798
if ((
TestWF(pwndT,
WFMAXBOX)) || !(
TestWF(pwndT,
WFWIN40COMPAT))) {
01799
NtUserShowWindow(hwndT, SW_SHOWMAXIMIZED);
01800 }
01801
break;
01802
01803
case WM_MDIRESTORE:
01804 hwndT = (HWND)wParam;
01805
if ((pwndT =
ValidateHwnd(hwndT)) ==
NULL)
01806
return 0;
01807
01808
NtUserShowWindow(hwndT, SW_SHOWNORMAL);
01809
break;
01810
01811
case WM_MDITILE:
01812 pmdi->
wScroll |=
SCROLLSUPPRESS;
01813
NtUserShowScrollBar(hwnd, SB_BOTH,
FALSE);
01814
01815
01816
01817
01818
#ifdef NEVER //Not in Chicago
01819
if (
MAXED(pmdi) !=
NULL) {
01820
NtUserShowWindow(
MAXED(pmdi), SW_SHOWNORMAL);
01821 }
01822
#endif
01823
01824
01825
01826 message = (
UINT)
TileWindows(hwnd, (
UINT)wParam,
NULL, 0,
NULL);
01827 pmdi->
wScroll &= ~
SCROLLCOUNT;
01828
return (LONG)message;
01829
break;
01830
01831
case WM_MDIICONARRANGE:
01832 pmdi->
wScroll |=
SCROLLSUPPRESS;
01833
NtUserArrangeIconicWindows(hwnd);
01834 pmdi->
wScroll &= ~
SCROLLCOUNT;
01835
RecalculateScrollRanges(pwnd,
TRUE);
01836
break;
01837
01838
case WM_MDINEXT:
01839
if (wParam) {
01840 hwndT = (HWND)wParam;
01841 }
else {
01842 hwndT =
ACTIVE(pmdi);
01843 }
01844
01845
if ((pwndT =
ValidateHwnd(hwndT)) ==
NULL) {
01846
return 0;
01847 }
01848
01849
01850
01851
01852
ThreadLockAlways(pwndT, &tlpwndT);
01853
xxxMDINext(pwnd, pwndT, (lParam == 0 ? 0 : 1));
01854
ThreadUnlock(&tlpwndT);
01855
break;
01856
01857
case WM_MDIREFRESHMENU:
01858
return (LRESULT)
MDISetMenu(pwnd,
TRUE,
NULL,
NULL);
01859
01860
case WM_MDISETMENU:
01861
return (LRESULT)
MDISetMenu(pwnd,
FALSE, (HMENU)wParam, (HMENU)lParam);
01862
01863
case WM_PARENTNOTIFY:
01864
if (wParam == WM_LBUTTONDOWN) {
01865 HWND hwndChild;
01866 POINT pt;
01867
01868
#ifdef USE_MIRRORING
01869
if ((pwndT =
ValidateHwnd(hwnd)) ==
NULL)
01870
return 0;
01871
#endif
01872
01873
01874
01875
01876 pt.x = (
int)MAKEPOINTS(lParam).x;
01877 pt.y = (
int)MAKEPOINTS(lParam).y;
01878
01879
#ifdef USE_MIRRORING
01880
01881
01882
01883
01884
01885
01886
01887
if (
TestWF(pwndT,WEFLAYOUTRTL)) {
01888 pt.x = (pwndT->
rcClient.right-pwndT->
rcClient.left)-pt.x;
01889 }
01890
#endif
01891
01892 hwndChild =
NtUserChildWindowFromPointEx(hwnd, pt,
01893 CWP_SKIPDISABLED | CWP_SKIPINVISIBLE);
01894
01895
if ((hwndChild) && (hwndChild != hwnd)) {
01896
01897
if (hwndChild !=
ACTIVE(pmdi)) {
01898
NtUserSetWindowPos(hwndChild, HWND_TOP, 0, 0, 0, 0,
01899 SWP_NOMOVE | SWP_NOSIZE);
01900 }
01901 }
01902 }
01903
break;
01904
01905
case WM_SETFOCUS:
01906
if (
ACTIVE(pmdi) !=
NULL && !
IsIconic(
ACTIVE(pmdi))) {
01907
NtUserSetFocus(
ACTIVE(pmdi));
01908 }
01909
break;
01910
01911
case WM_SIZE:
01912
if (
ACTIVE(pmdi) && (pwndT =
ValidateHwnd(
ACTIVE(pmdi))) &&
01913
TestWF(pwndT,
WFMAXIMIZED)) {
01914
01915 RECT rc;
01916
01917 rc.top = rc.left = 0;
01918 rc.right = (
int)MAKEPOINTS(lParam).x;
01919 rc.bottom = (
int)MAKEPOINTS(lParam).y;
01920
_AdjustWindowRectEx(&rc, pwndT->style,
FALSE,
01921 pwndT->ExStyle);
01922
NtUserMoveWindow(
ACTIVE(pmdi), rc.left, rc.top,
01923 rc.right - rc.left, rc.bottom - rc.top,
TRUE);
01924 }
else {
01925
RecalculateScrollRanges(pwnd,
FALSE);
01926 }
01927
goto CallDWP;
01928
01929
case MM_CALCSCROLL: {
01930
01931
if (
SCROLL(pmdi) &
SCROLLCOUNT)
01932
break;
01933
01934 {
01935 WORD sbj = pmdi->
wScroll & (
HAS_SBVERT |
HAS_SBHORZ);
01936
01937
if (sbj)
01938 {
01939
CalcClientScrolling(hwnd, sbj, (
BOOL) wParam);
01940
01941
SCROLL(pmdi) &= ~
CALCSCROLL;
01942 }
01943 }
01944
break;
01945 }
01946
01947
case WM_CREATE: {
01948 LPCLIENTCREATESTRUCT pccs = ((LPCREATESTRUCT)lParam)->lpCreateParams;
01949
01950
01951
01952
01953
if ((pmdi = (
PMDI)
UserLocalAlloc(HEAP_ZERO_MEMORY,
sizeof(
MDI)))) {
01954
NtUserSetWindowLongPtr(hwnd,
GWLP_MDIDATA, (LONG_PTR)pmdi,
FALSE);
01955 }
else {
01956
NtUserSetWindowFNID(hwnd,
FNID_CLEANEDUP_BIT);
01957
break;
01958 }
01959
01960 pwndParent =
REBASEPWND(pwnd, spwndParent);
01961
ACTIVE(pmdi) =
NULL;
01962
MAXED(pmdi) =
NULL;
01963
CKIDS(pmdi) = 0;
01964
WINDOW(pmdi) = pccs->hWindowMenu;
01965
01966
FIRST(pmdi) = pccs->idFirstChild;
01967
SCROLL(pmdi) = 0;
01968
HTITLE(pmdi) =
TextAlloc(
REBASE(pwndParent, strName.Buffer));
01969
01970
_DefSetText(
HW(pwndParent),
NULL,
FALSE);
01971
01972
ThreadLock(pwndParent, &tlpwndT);
01973
xxxSetFrameTitle(pwndParent, pwnd, (LPWSTR)2
L);
01974
ThreadUnlock(&tlpwndT);
01975
01976
if (
TestWF(pwnd,
WFVSCROLL))
01977
SCROLL(pmdi) |=
HAS_SBVERT;
01978
if (
TestWF(pwnd,
WFHSCROLL))
01979
SCROLL(pmdi) |=
HAS_SBHORZ;
01980
if (
SCROLL(pmdi)) {
01981
ClearWindowState(pwnd,
WFVSCROLL |
WFHSCROLL);
01982 }
01983
01984
01985
01986
01987
NtUserGetSystemMenu(
HW(pwndParent),
FALSE);
01988
01989
01990
01991
01992
01993
if (
SCROLL(pmdi)) {
01994
NtUserUpdateClientRect(hwnd);
01995 }
01996
break;
01997 }
01998
01999
case WM_DESTROY:
02000
case WM_FINALDESTROY:
02001
if (
MAXED(pmdi)) {
02002
PWND pwndParent;
02003
PMENU pmenu;
02004
02005 pwndParent =
REBASEPWND(pwnd, spwndParent);
02006 pmenu =
REBASE(pwndParent, spmenu);
02007
MDIRemoveSysMenu(
PtoH(pmenu),
MAXED(pmdi));
02008 }
02009
02010
02011
02012
02013
if (
HTITLE(pmdi)) {
02014
UserLocalFree(
HTITLE(pmdi));
02015
HTITLE(pmdi) =
NULL;
02016 }
02017
02018
02019
02020
02021
02022
02023
02024
02025
if (
IsMenu(
WINDOW(pmdi)) &&
CKIDS(pmdi)++) {
02026
UINT iPosition;
02027
02028
if (
CKIDS(pmdi) >
MAXITEMS + 1)
02029
CKIDS(pmdi) =
MAXITEMS + 1;
02030
02031 iPosition =
GetMenuItemCount(
WINDOW(pmdi));
02032
while (
CKIDS(pmdi)--) {
02033
NtUserDeleteMenu(
WINDOW(pmdi), --iPosition, MF_BYPOSITION);
02034 }
02035 }
02036
02037
02038
02039
02040
Unlock(&
MAXED(pmdi));
02041
Unlock(&
ACTIVE(pmdi));
02042
Unlock(&
WINDOW(pmdi));
02043
02044
02045
02046
02047
UserLocalFree(pmdi);
02048
NtUserSetWindowFNID(hwnd,
FNID_CLEANEDUP_BIT);
02049
02050
break;
02051
02052
default:
02053 CallDWP:
02054
return DefWindowProcWorker(pwnd, message, wParam, lParam, fAnsi);
02055 }
02056
return 0
L;
02057 }
02058
02059
02060
02061
02062
02063 LRESULT WINAPI
MDIClientWndProcA(
02064 HWND hwnd,
02065 UINT message,
02066 WPARAM wParam,
02067 LPARAM lParam)
02068 {
02069
PWND pwnd;
02070
02071
if ((pwnd =
ValidateHwnd(hwnd)) ==
NULL) {
02072
return 0;
02073 }
02074
02075
return MDIClientWndProcWorker(pwnd, message, wParam, lParam,
TRUE);
02076 }
02077
02078 LRESULT WINAPI
MDIClientWndProcW(
02079 HWND hwnd,
02080 UINT message,
02081 WPARAM wParam,
02082 LPARAM lParam)
02083 {
02084
PWND pwnd;
02085
02086
if ((pwnd =
ValidateHwnd(hwnd)) ==
NULL) {
02087
return 0;
02088 }
02089
02090
return MDIClientWndProcWorker(pwnd, message, wParam, lParam,
FALSE);
02091 }
02092
02093
02094
02095
02096
02097
02098
02099
02100
02101 LRESULT
DefFrameProcWorker(
02102 HWND hwnd,
02103 HWND hwndMDI,
02104 UINT wMsg,
02105 WPARAM wParam,
02106 LPARAM lParam,
02107 BOOL fAnsi)
02108 {
02109
PWND pwnd;
02110
PWND pwndMDI;
02111
PMDI pmdi;
02112
TL tlpwndT;
02113 HWND hwndT;
02114
PWND pwndT;
02115 PMDINEXTMENU pmnm;
02116 WINDOWPLACEMENT wp;
02117
02118
if ((pwnd =
ValidateHwnd(hwnd)) ==
NULL) {
02119
return (0
L);
02120 }
02121
CheckLock(pwnd);
02122
02123
if (hwndMDI ==
NULL) {
02124
goto CallDWP;
02125 }
02126
02127
if ((pwndMDI =
ValidateHwnd(hwndMDI)) ==
NULL) {
02128
return (0
L);
02129 }
02130
CheckLock(pwndMDI);
02131
02132
02133
02134
02135 pmdi = ((
PMDIWND)pwndMDI)->pmdi;
02136
02137
switch (wMsg) {
02138
02139
02140
02141
02142
case WM_SETTEXT: {
02143 LPWSTR lpwsz =
NULL;
02144
02145
if (fAnsi && lParam) {
02146
if (!MBToWCS((LPSTR)lParam, -1, &lpwsz, -1,
TRUE))
02147
return 0;
02148 lParam = (LPARAM)lpwsz;
02149 }
02150
xxxSetFrameTitle(pwnd, pwndMDI, (LPWSTR)lParam);
02151
02152
if (lpwsz)
02153
UserLocalFree(lpwsz);
02154
break;
02155 }
02156
case WM_NCACTIVATE:
02157
SendMessage(hwndMDI, WM_NCACTIVATE, wParam, lParam);
02158
goto CallDWP;
02159
02160
case WM_COMMAND:
02161
if ((
UINT)LOWORD(wParam) == (
FIRST(pmdi) +
MAXITEMS -1)) {
02162
02163
02164
02165
02166
if (fAnsi) {
02167 wParam =
DialogBoxParamA(
hmodUser,
02168 MAKEINTRESOURCEA(
IDD_MDI_ACTIVATE),
02169 hwnd,
02170
MDIActivateDlgProcA,
02171 (LPARAM)pwndMDI);
02172 }
else {
02173 wParam =
DialogBoxParamW(
hmodUser,
02174 MAKEINTRESOURCEW(
IDD_MDI_ACTIVATE),
02175 hwnd,
02176
MDIActivateDlgProcW,
02177 (LPARAM)pwndMDI);
02178 }
02179
if ((
int)wParam >= 0) {
02180 wParam +=
FIRST(pmdi);
02181
goto ActivateTheChild;
02182 }
02183 }
else if (((
UINT)LOWORD(wParam) >=
FIRST(pmdi)) &&
02184 ((
UINT)LOWORD(wParam) <
FIRST(pmdi) +
CKIDS(pmdi))) {
02185 ActivateTheChild:
02186 pwndT =
FindPwndChild(pwndMDI, (
UINT)LOWORD(wParam));
02187
ThreadLock(pwndT, &tlpwndT);
02188
02189
SendMessage(hwndMDI, WM_MDIACTIVATE, (WPARAM)
HW(pwndT), 0
L);
02190
02191
02192
02193
02194
if (pwndT !=
NULL &&
TestWF(pwndT,
WFMINIMIZED))
02195
02196
02197
02198
02199
SendMessage(
HWq(pwndT), WM_SYSCOMMAND, (WPARAM)SC_RESTORE, 0
L);
02200
ThreadUnlock(&tlpwndT);
02201
break;
02202 }
02203
02204
switch (wParam & 0xFFF0) {
02205
02206
02207
02208
02209
case SC_SIZE:
02210
case SC_MOVE:
02211
case SC_RESTORE:
02212
case SC_CLOSE:
02213
case SC_NEXTWINDOW:
02214
case SC_PREVWINDOW:
02215
case SC_MINIMIZE:
02216
case SC_MAXIMIZE:
02217 hwndT =
MAXED(pmdi);
02218
if (hwndT !=
NULL) {
02219
PWND pwndT =
ValidateHwnd(hwndT);
02220
if (pwndT ==
NULL)
02221
break;
02222
if ((wParam & 0xFFF0) == SC_CLOSE) {
02223
02224
02225
02226
02227
02228
BOOL fCanClose;
02229 UserAssert(!
TestWF(pwndT,
WFSYSMENU) && (pwndT->
spmenuSys !=
NULL));
02230
SetWindowState(pwndT,
WFSYSMENU);
02231 fCanClose =
xxxMNCanClose(pwndT);
02232
ClearWindowState(pwndT,
WFSYSMENU);
02233
if (!fCanClose) {
02234
break;
02235 }
02236 }
else if (((wParam & 0xFFF0) == SC_MINIMIZE) && !
TestWF(pwndT,
WFMINBOX)) {
02237
break;
02238 }
02239
02240
return SendMessage(hwndT, WM_SYSCOMMAND, wParam, lParam);
02241 }
02242 }
02243
goto CallDWP;
02244
02245
case WM_SIZE:
02246
if (wParam != SIZEICONIC) {
02247
NtUserMoveWindow(hwndMDI, 0, 0, LOWORD(lParam), HIWORD(lParam),
TRUE);
02248 }
else {
02249 wp.length =
sizeof(WINDOWPLACEMENT);
02250
if (
GetWindowPlacement(hwnd, &wp)) {
02251 RECT rcT;
02252
int clB;
02253
02254
02255
02256
02257
02258
02259 clB =
GetWindowBorders(pwnd->style, pwnd->ExStyle,
TRUE,
TRUE);
02260
02261
CopyInflateRect(&rcT, &wp.rcNormalPosition,
02262 -clB*
SYSMET(CXBORDER), -clB*
SYSMET(CYBORDER));
02263
02264
if (
TestWF(pwnd,
WFBORDERMASK) ==
LOBYTE(
WFCAPTION))
02265 rcT.top +=
SYSMET(CYCAPTION);
02266 rcT.top +=
SYSMET(CYMENU);
02267
02268
NtUserMoveWindow(hwndMDI, 0, 0, rcT.right-rcT.left,
02269 rcT.bottom-rcT.top,
TRUE);
02270 }
02271 }
02272
goto CallDWP;
02273
02274
case WM_SETFOCUS:
02275
NtUserSetFocus(hwndMDI);
02276
break;
02277
02278
case WM_NEXTMENU:
02279
if (
TestWF(pwnd,
WFSYSMENU) && !
TestWF(pwnd,
WFMINIMIZED) &&
02280
ACTIVE(pmdi) && !
MAXED(pmdi))
02281 {
02282
PMENU pmenuIn;
02283
02284
02285
02286
02287
02288 pmnm = (PMDINEXTMENU)lParam;
02289 pmenuIn =
RevalidateHmenu(pmnm->hmenuIn);
02290
02291
if (pmenuIn && ((wParam == VK_LEFT && pmenuIn ==
REBASE(pwnd, spmenu)) ||
02292 (wParam == VK_RIGHT && pmnm->hmenuIn ==
02293
NtUserGetSystemMenu(hwnd,
FALSE)))) {
02294
02295 HMENU hmenu;
02296
PWND pwndActive;
02297
02298
02299
02300
02301
if ((pwndActive =
ValidateHwnd(
ACTIVE(pmdi))) ==
NULL) {
02302
return 0;
02303 }
02304
02305
02306
02307
02308
02309
if (!
TestWF(pwndActive,
WFMAXIMIZED)) {
02310
NtUserSetSysMenu(
ACTIVE(pmdi));
02311 }
02312
02313 hmenu =
NtUserGetSystemMenu(
ACTIVE(pmdi),
FALSE);
02314 pmnm->hmenuNext = hmenu;
02315 pmnm->hwndNext =
ACTIVE(pmdi);
02316
02317
return TRUE;
02318 }
02319 }
02320
02321
02322
02323
02324
return 0
L;
02325
02326
case WM_MENUCHAR:
02327
if (!
TestWF(pwnd,
WFMINIMIZED) && LOWORD(wParam) == TEXT(
'-')) {
02328
if (
MAXED(pmdi))
02329
return MAKELONG(0, 2);
02330
else if (
ACTIVE(pmdi)) {
02331
PostMessage(
ACTIVE(pmdi), WM_SYSCOMMAND,
02332 SC_KEYMENU, MAKELONG(TEXT(
'-'), 0));
02333
return MAKELONG(0, 1);
02334 }
02335 }
02336
02337
02338
02339
02340
02341
default:
02342 CallDWP:
02343
return DefWindowProcWorker(pwnd, wMsg, wParam, lParam, fAnsi);
02344 }
02345
02346
return 0
L;
02347 }
02348
02349
02350 LRESULT WINAPI
DefFrameProcW(
02351 HWND hwnd,
02352 HWND hwndMDIClient,
02353 UINT message,
02354 WPARAM wParam,
02355 LPARAM lParam)
02356 {
02357
return DefFrameProcWorker(hwnd, hwndMDIClient, message, wParam, lParam,
02358
FALSE);
02359 }
02360
02361 LRESULT WINAPI
DefFrameProcA(
02362 HWND hwnd,
02363 HWND hwndMDIClient,
02364 UINT message,
02365 WPARAM wParam,
02366 LPARAM lParam)
02367 {
02368
return DefFrameProcWorker(hwnd, hwndMDIClient, message, wParam,
02369 lParam,
TRUE);
02370 }
02371
02372
02373
02374
02375
02376
02377
02378
02379
02380 void ChildMinMaxInfo(
02381
PWND pwnd,
02382 PMINMAXINFO pmmi)
02383 {
02384
PWND pwndParent =
REBASEPWND(pwnd, spwndParent);
02385 RECT rc;
02386
#ifdef USE_MIRRORING
02387
int SaveLeft;
02388
#endif
02389
UserAssert(
GETFNID(pwnd) !=
FNID_DESKTOP);
02390
02391
CopyRect(&rc, &pwndParent->
rcClient);
02392
_ScreenToClient(pwndParent, (LPPOINT)&rc.left);
02393
_ScreenToClient(pwndParent, (LPPOINT)&rc.right);
02394
02395
#ifdef USE_MIRRORING
02396
02397
02398
02399
if (
TestWF(pwnd,WEFLAYOUTRTL)) {
02400 SaveLeft = rc.left;
02401 rc.left = rc.right;
02402 rc.right = SaveLeft;
02403 }
02404
#endif
02405
02406
_AdjustWindowRectEx(&rc, pwnd->style,
FALSE, pwnd->ExStyle);
02407
02408
02409
02410
02411 pmmi->ptMaxPosition.x = rc.left;
02412 pmmi->ptMaxPosition.y = rc.top;
02413 pmmi->ptMaxSize.x = rc.right - rc.left;
02414 pmmi->ptMaxSize.y = rc.bottom - rc.top;
02415 }
02416
02417
02418
02419
02420
02421
02422
02423
02424
02425 void xxxChildResize(
02426
PWND pwnd,
02427 UINT wMode)
02428 {
02429
PWND pwndT;
02430
PWND pwndMDI =
REBASEPWND(pwnd, spwndParent);
02431
PWND pwndFrame =
REBASEPWND(pwndMDI, spwndParent);
02432 HWND hwndOldActive;
02433
PMDI pmdi;
02434 HWND hwndActive;
02435
TL tlpwndMDI;
02436
TL tlpwndFrame;
02437
TL tlpwndT;
02438
PMENU pmenu;
02439 HWND hwnd =
HWq(pwnd);
02440
02441
CheckLock(pwnd);
02442
02443
NtUserSetSysMenu(hwnd);
02444
02445
ThreadLock(pwndMDI, &tlpwndMDI);
02446
ThreadLock(pwndFrame, &tlpwndFrame);
02447
02448
02449
02450
02451 pmdi = ((
PMDIWND)pwndMDI)->pmdi;
02452 pmenu =
REBASE(pwndFrame, spmenu);
02453
02454
if (
MAXED(pmdi) == hwnd &&
wMode != SIZEFULLSCREEN) {
02455
02456
02457
02458
02459
if (!(
SCROLL(pmdi) &
OTHERMAXING)) {
02460
Unlock(&
MAXED(pmdi));
02461
MDIRemoveSysMenu(
PtoH(pmenu), hwnd);
02462
Unlock(&
MAXED(pmdi));
02463
xxxSetFrameTitle(pwndFrame, pwndMDI, (LPWSTR)1
L);
02464 }
02465 }
02466
02467
if (
wMode == SIZEFULLSCREEN) {
02468
02469
02470
02471
02472
if (hwnd ==
MAXED(pmdi))
02473
goto Exit;
02474
02475
02476
02477
02478
02479 pmdi->
wScroll |=
OTHERMAXING |
SCROLLCOUNT;
02480
02481
if (hwndOldActive =
MAXED(pmdi)) {
02482
SendMessage(hwndOldActive, WM_SETREDRAW,
FALSE, 0
L);
02483
MDIRemoveSysMenu(
PtoH(pmenu), hwndOldActive);
02484
NtUserMinMaximize(hwndOldActive,
SW_MDIRESTORE,
FALSE);
02485
SendMessage(hwndOldActive, WM_SETREDRAW,
TRUE, 0
L);
02486 }
02487
02488
Lock(&
MAXED(pmdi), hwnd);
02489
02490
02491
02492
02493
MDIAddSysMenu(
PtoH(pmenu), hwnd);
02494
xxxSetFrameTitle(pwndFrame, pwndMDI, (LPWSTR)1
L);
02495
02496 pmdi->
wScroll &= ~(
OTHERMAXING |
SCROLLCOUNT);
02497 }
02498
02499
if (
wMode == SIZEICONIC) {
02500
for (pwndT =
REBASEPWND(pwndMDI, spwndChild); pwndT;
02501 pwndT =
REBASEPWND(pwndT, spwndNext)) {
02502
if (!pwndT->
spwndOwner &&
TestWF(pwndT,
WFVISIBLE))
02503
break;
02504 }
02505
02506 hwndActive =
NtUserQueryWindow(hwnd, WindowActiveWindow);
02507
if ((pwndT !=
NULL) && (hwndActive !=
NULL) &&
02508
IsChild(hwndActive,
HWq(pwndMDI))) {
02509
ThreadLockAlways(pwndT, &tlpwndT);
02510
SendMessage(
HWq(pwndT), WM_CHILDACTIVATE, 0, 0
L);
02511
ThreadUnlock(&tlpwndT);
02512 }
02513 }
02514
02515
if (!(
SCROLL(pmdi) &
SCROLLCOUNT))
02516
RecalculateScrollRanges(pwndMDI,
FALSE);
02517
02518 Exit:
02519
ThreadUnlock(&tlpwndFrame);
02520
ThreadUnlock(&tlpwndMDI);
02521 }
02522
02523
02524
02525
02526
02527
02528
02529
02530
02531 LRESULT
DefMDIChildProcWorker(
02532 HWND hwnd,
02533 UINT wMsg,
02534 WPARAM wParam,
02535 LPARAM lParam,
02536 BOOL fAnsi)
02537 {
02538
PWND pwnd;
02539
PWND pwndParent;
02540
PMDI pmdi;
02541 PMDINEXTMENU pmnm;
02542 HWND hwndT;
02543
PWND pwndT;
02544
TL tlpwndT;
02545
TL tlpwndParent;
02546 LRESULT lRet;
02547
02548
if ((pwnd =
ValidateHwnd(hwnd)) ==
NULL) {
02549
return (0
L);
02550 }
02551
02552
CheckLock(pwnd);
02553
02554
02555
02556
02557 pwndParent =
REBASEPWND(pwnd, spwndParent);
02558
if (!pwndParent ||
GETFNID(pwndParent) !=
FNID_MDICLIENT) {
02559 RIPERR0(ERROR_NON_MDICHILD_WINDOW, RIP_VERBOSE,
"");
02560
return DefWindowProcWorker(pwnd, wMsg, wParam, lParam, fAnsi);
02561 }
02562
02563
02564
02565
02566 pmdi = ((
PMDIWND)pwndParent)->pmdi;
02567
if ((ULONG_PTR)pmdi == (ULONG_PTR)-1) {
02568
goto CallDWP;
02569 }
02570
02571
switch (wMsg) {
02572
case WM_SETFOCUS:
02573
if (
DIFFWOWHANDLE(hwnd,
ACTIVE(pmdi))) {
02574
ThreadLockAlways(pwndParent, &tlpwndParent);
02575
xxxMDIActivate(pwndParent, pwnd);
02576
ThreadUnlock(&tlpwndParent);
02577 }
02578
goto CallDWP;
02579
02580
case WM_NEXTMENU:
02581
02582
02583
02584
02585
02586 pmnm = (PMDINEXTMENU)lParam;
02587 pwndT =
REBASEPWND(pwndParent, spwndParent);
02588 pmnm->hwndNext =
HW(pwndT);
02589 pmnm->hmenuNext = (wParam == VK_LEFT) ?
02590
NtUserGetSystemMenu(pmnm->hwndNext,
FALSE) :
02591
GetMenu(pmnm->hwndNext);
02592
return TRUE;
02593
#if 0
02594
hWnd->hwndParent->hwndParent
02595
return (LONG)(((wParam == VK_LEFT) ?
02596
NtUserGetSystemMenu(
HW(pwndT),
FALSE):
02597 pwndT->
spmenu)
02598 );
02599
02600
02601
#endif
02602
case WM_CLOSE:
02603 hwndT =
GetParent(hwnd);
02604
if (hwndT !=
NULL) {
02605
SendMessage(hwndT, WM_MDIDESTROY, (WPARAM)hwnd, 0
L);
02606 }
02607
break;
02608
02609
case WM_MENUCHAR:
02610
PostMessage(
GetParent(
GetParent(hwnd)), WM_SYSCOMMAND,
02611 (
DWORD)SC_KEYMENU, (LONG)LOWORD(wParam));
02612
return 0x10000;
02613
02614
case WM_SETTEXT:
02615
DefWindowProcWorker(pwnd, wMsg, wParam, lParam, fAnsi);
02616
if (
WINDOW(pmdi))
02617
ModifyMenuItem(pwnd);
02618
02619
if (
TestWF(pwnd,
WFMAXIMIZED)) {
02620
02621
02622
02623
02624
02625 pwndT =
REBASEPWND(pwndParent, spwndParent);
02626
ThreadLock(pwndT, &tlpwndT);
02627
ThreadLock(pwndParent, &tlpwndParent);
02628
xxxSetFrameTitle(pwndT, pwndParent, (LPWSTR)3
L);
02629
ThreadUnlock(&tlpwndParent);
02630
ThreadUnlock(&tlpwndT);
02631 }
02632
break;
02633
02634
case WM_GETMINMAXINFO:
02635
ChildMinMaxInfo(pwnd, (PMINMAXINFO)lParam);
02636
break;
02637
02638
case WM_SIZE:
02639
xxxChildResize(pwnd, (
UINT)wParam);
02640
goto CallDWP;
02641
02642
case WM_MOVE:
02643
if (!
TestWF(pwnd,
WFMAXIMIZED))
02644
RecalculateScrollRanges(pwndParent,
FALSE);
02645
goto CallDWP;
02646
02647
case WM_CHILDACTIVATE:
02648
ThreadLock(pwndParent, &tlpwndParent);
02649
xxxMDIActivate(pwndParent, pwnd);
02650
ThreadUnlock(&tlpwndParent);
02651
break;
02652
02653
case WM_SYSCOMMAND:
02654
switch (wParam & 0xFFF0) {
02655
case SC_NEXTWINDOW:
02656
case SC_PREVWINDOW:
02657 hwndT =
GetParent(hwnd);
02658
SendMessage(hwndT, WM_MDINEXT, (WPARAM)hwnd,
02659 (
DWORD)((wParam & 0xFFF0) == SC_PREVWINDOW));
02660
break;
02661
02662
case SC_SIZE:
02663
case SC_MOVE:
02664
if (
SAMEWOWHANDLE(hwnd,
MAXED(pmdi))) {
02665
02666
02667
02668
02669
02670
break;
02671 }
else
02672
goto CallDWP;
02673
02674
case SC_MAXIMIZE:
02675
if (
SAMEWOWHANDLE(hwnd,
MAXED(pmdi))) {
02676
02677
02678
02679
02680
02681
02682
02683 pwndT =
REBASEPWND(pwndParent, spwndParent);
02684
ThreadLock(pwndT, &tlpwndT);
02685 lRet =
SendMessage(
HW(pwndT),
02686 WM_SYSCOMMAND, SC_MAXIMIZE, lParam);
02687
ThreadUnlock(&tlpwndT);
02688
return lRet;
02689 }
02690
02691
02692
02693
02694
02695
default:
02696
goto CallDWP;
02697 }
02698
break;
02699
02700
default:
02701 CallDWP:
02702
return DefWindowProcWorker(pwnd, wMsg, wParam, lParam, fAnsi);
02703 }
02704
02705
return 0
L;
02706 }
02707
02708
02709
02710
02711
02712
02713
02714
02715
02716
02717 LRESULT WINAPI
DefMDIChildProcW(
02718 HWND hwnd,
02719 UINT message,
02720 WPARAM wParam,
02721 LPARAM lParam)
02722 {
02723
return DefMDIChildProcWorker(hwnd, message, wParam, lParam,
FALSE);
02724 }
02725
02726 LRESULT WINAPI
DefMDIChildProcA(
02727 HWND hwnd,
02728 UINT message,
02729 WPARAM wParam,
02730 LPARAM lParam)
02731 {
02732
return DefMDIChildProcWorker(hwnd, message, wParam, lParam,
TRUE);
02733 }
02734
02735 BOOL MDICompleteChildCreation(HWND hwndChild, HMENU hSysMenu, BOOL fVisible, BOOL fDisabled) {
02736
PWND pwndChild;
02737
PWND pwndClient;
02738 HWND hwndClient;
02739
BOOL fHasOwnSysMenu;
02740
PMDI pmdi;
02741
02742 pwndChild =
ValidateHwnd(hwndChild);
02743 pwndClient =
REBASEPWND(pwndChild,spwndParent);
02744 hwndClient =
HWq(pwndClient);
02745
02746 fHasOwnSysMenu = (pwndChild->
spmenuSys) ?
TRUE :
FALSE;
02747
02748 pmdi = ((
PMDIWND)(pwndClient))->pmdi;
02749
02750
CKIDS(pmdi)++;
02751
ITILELEVEL(pmdi)++;
02752
if (
ITILELEVEL(pmdi) > 0x7ffe)
02753
ITILELEVEL(pmdi) = 0;
02754
02755
02756
if (fVisible && !fDisabled && (
CKIDS(pmdi) <=
MAXITEMS))
02757
SendMessage(hwndClient, WM_MDIREFRESHMENU, 0, 0
L);
02758
02759
02760
02761
02762
02763
02764
if (hSysMenu && (fHasOwnSysMenu || !
NtUserSetSystemMenu(hwndChild, hSysMenu)))
02765
NtUserDestroyMenu(hSysMenu);
02766
02767
if (fVisible)
02768 {
02769
if (!
TestWF(pwndChild,
WFMINIMIZED) || !
ACTIVE(pmdi))
02770 {
02771
NtUserSetWindowPos(hwndChild, HWND_TOP, 0, 0, 0, 0,
02772 SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
02773
02774
if (
TestWF(pwndChild,
WFMAXIMIZED) && !fHasOwnSysMenu)
02775 {
02776
PWND pwndParent =
REBASEPWND(pwndClient, spwndParent);
02777
PMENU pmenu =
REBASE(pwndParent, spmenu);
02778
MDIAddSysMenu(
PtoH(pmenu), hwndChild);
02779
NtUserRedrawFrame(
HW(pwndParent));
02780 }
02781 }
02782
else
02783 {
02784
NtUserShowWindow(hwndChild, SW_SHOWMINNOACTIVE);
02785 }
02786 }
02787
02788
02789
return TRUE;
02790 }
02791
02792
02793
BOOL
02794 CreateMDIChild(
02795
PSHORTCREATE psc,
02796 LPMDICREATESTRUCT pmcs,
02797 DWORD dwExpWinVerAndFlags,
02798 HMENU * phSysMenu,
02799
PWND pwndParent)
02800 {
02801
BOOL fVisible;
02802 RECT rcT;
02803 HMENU hSysMenu =
NULL;
02804 HWND hwndPrevMaxed;
02805
PMDI pmdi;
02806
02807
02808
02809
02810 pmdi = ((
PMDIWND)(pwndParent))->pmdi;
02811
02812 pmcs->style = psc->
style;
02813
02814
02815 psc->
style |= (WS_CHILD | WS_CLIPSIBLINGS);
02816
if (!(pwndParent->style & MDIS_ALLCHILDSTYLES))
02817 {
02818 psc->
style &=
WS_MDIALLOWED;
02819 psc->
style |= (
WS_MDISTYLE | WS_VISIBLE);
02820 }
02821
else if (psc->
style & WS_POPUP)
02822 {
02823 RIPMSG0(RIP_ERROR,
"CreateWindowEx: WS_POPUP not allowed on MDI children");
02824
if (LOWORD(dwExpWinVerAndFlags) >=
VER40)
02825
return FALSE;
02826 }
02827
02828 fVisible = ((psc->
style & WS_VISIBLE) != 0
L);
02829
02830
02831
02832
02833
02834 pmcs->x = rcT.left = psc->
x;
02835 pmcs->y = rcT.top = psc->
y;
02836 pmcs->cx = rcT.right = psc->
cx;
02837 pmcs->cy = rcT.bottom = psc->
cy;
02838
02839
MDICheckCascadeRect(pwndParent, &rcT);
02840
02841
02842
02843
02844 psc->
x = rcT.left;
02845 psc->
y = rcT.top;
02846 psc->
cx = rcT.right;
02847 psc->
cy = rcT.bottom;
02848
02849
02850
if (psc->
style & WS_SYSMENU) {
02851 hSysMenu =
xxxLoadSysMenu(
CHILDSYSMENU);
02852
if (hSysMenu ==
NULL) {
02853
return FALSE;
02854 }
02855 }
02856
02857
02858
02859
02860 hwndPrevMaxed =
MAXED(pmdi);
02861
if (fVisible &&
IsWindow(hwndPrevMaxed))
02862 {
02863
if (psc->
style & WS_MAXIMIZE)
02864
SendMessage(hwndPrevMaxed, WM_SETREDRAW, (WPARAM)
FALSE, 0
L);
02865
02866
02867
02868
02869
if (
IsWindow(hwndPrevMaxed) )
02870 {
02871
NtUserMinMaximize(hwndPrevMaxed, SW_SHOWNORMAL,
TRUE);
02872
02873
if ( psc->
style & WS_MAXIMIZE )
02874
SendMessage(hwndPrevMaxed, WM_SETREDRAW, (WPARAM)
TRUE, 0
L);
02875 }
02876
02877 }
02878
02879
02880 psc->
hMenu = (HMENU)UIntToPtr( (
FIRST(pmdi) +
CKIDS(pmdi)) );
02881
02882 *phSysMenu = hSysMenu;
02883
02884
return TRUE;
02885 }