00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
#include "precomp.h"
00019
#pragma hdrstop
00020
00021
BOOL WantImeWindow(IN
PWND pwndParent, IN
PWND pwnd);
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 PWND xxxCreateWindowEx(
00034 DWORD dwExStyle,
00035
PLARGE_STRING cczpstrClass,
00036
PLARGE_STRING cczpstrName,
00037 DWORD style,
00038
int x,
00039
int y,
00040
int cx,
00041
int cy,
00042
PWND pwndParent,
00043
PMENU pMenu,
00044 HANDLE hInstance,
00045 LPVOID lpCreateParams,
00046 DWORD dwExpWinVerAndFlags)
00047 {
00048
00049
00050
00051
00052
UINT mask = 0;
00053
BOOL fChild;
00054
BOOL fDefPos =
FALSE;
00055
BOOL fStartup =
FALSE;
00056
PCLS pcls;
00057
PPCLS ppcls;
00058 RECT rc;
00059
int dx, dy;
00060
SIZERECT src;
00061
int sw = SW_SHOW;
00062
PWND pwnd;
00063
PWND pwndZOrder, pwndHardError;
00064
CREATESTRUCTEX csex;
00065
PDESKTOP pdesk;
00066 ATOM atomT;
00067
PTHREADINFO ptiCurrent;
00068
TL tlpwnd;
00069
TL tlpwndParent;
00070
TL tlpwndParentT;
00071
BOOL fLockParent =
FALSE;
00072 WORD wWFAnsiCreator = 0;
00073
DWORD dw;
00074
DWORD dwMinMax;
00075
PMONITOR pMonitor;
00076
BOOL fTiled;
00077
#ifdef USE_MIRRORING
00078
DWORD dwLayout;
00079
#endif
00080
00081
CheckLock(pwndParent);
00082 UserAssert(
IsWinEventNotifyDeferredOK());
00083
00084
00085
00086
00087
00088
00089
00090
00091
if (dwExStyle &
WS_EX_ANSICREATOR) {
00092 wWFAnsiCreator =
WFANSICREATOR;
00093 dwExStyle &= ~
WS_EX_ANSICREATOR;
00094 }
00095
00096 ptiCurrent =
PtiCurrent();
00097
00098
00099
00100
00101 UserAssert(!(ptiCurrent->
TIF_flags &
TIF_INCLEANUP));
00102 pdesk = ptiCurrent->
rpdesk;
00103
00104
00105
00106
00107
00108
if (pwndParent !=
NULL && pwndParent->
head.rpdesk != pdesk) {
00109 RIPERR0(ERROR_INVALID_PARAMETER, RIP_VERBOSE,
"");
00110
return NULL;
00111 }
00112
00113
00114
00115
00116 fChild = ((HIWORD(style) &
MaskWF(
WFTYPEMASK)) ==
MaskWF(
WFCHILD));
00117
00118
#ifdef USE_MIRRORING
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
if (!(dwExStyle & WS_EX_LAYOUTRTL)) {
00139
if (pwndParent !=
NULL) {
00140
if (fChild &&
TestWF(pwndParent, WEFLAYOUTRTL) && !
TestWF(pwndParent, WEFNOINHERITLAYOUT)) {
00141 dwExStyle |= WS_EX_LAYOUTRTL;
00142 }
00143 }
else if (!(!
IS_PTR(cczpstrClass) && (
PTR_TO_ID(cczpstrClass) ==
PTR_TO_ID(
DIALOGCLASS)))) {
00144
if ((_GetProcessDefaultLayout(&dwLayout)) && (dwLayout & LAYOUT_RTL)) {
00145 dwExStyle |= WS_EX_LAYOUTRTL;
00146 }
00147 }
00148 }
00149
#endif
00150
00151
00152
00153
00154
00155
if (ptiCurrent->
hdesk) {
00156
RETURN_IF_ACCESS_DENIED(
00157 ptiCurrent->
amdesk, DESKTOP_CREATEWINDOW,
NULL);
00158 }
00159
00160
if (fChild) {
00161
00162
00163
00164
00165
if (pwndParent ==
NULL) {
00166 RIPERR0(ERROR_TLW_WITH_WSCHILD, RIP_VERBOSE,
"");
00167
return NULL;
00168 }
00169
00170
if (!
ValidateParentDepth(
NULL, pwndParent)) {
00171 RIPERR0(ERROR_INVALID_PARAMETER, RIP_WARNING,
"Exceeded nested children limit");
00172
return NULL;
00173 }
00174 }
00175
00176
00177
00178
00179
if (
IS_PTR(cczpstrClass)) {
00180
00181
00182
00183 atomT =
UserFindAtom(cczpstrClass->
Buffer);
00184 }
else
00185 atomT =
PTR_TO_ID(cczpstrClass);
00186
00187
if (atomT == 0) {
00188 CantFindClassMessageAndFail:
00189
#if DBG
00190
if (
IS_PTR(cczpstrClass)) {
00191
try {
00192 RIPMSG1(RIP_WARNING,
00193
"Couldn't find class string %ws",
00194 cczpstrClass->
Buffer);
00195
00196 } except (W32ExceptionHandler(
FALSE, RIP_WARNING)) {
00197 }
00198 }
else {
00199 RIPMSG1(RIP_WARNING,
00200
"Couldn't find class atom %lx",
00201 cczpstrClass);
00202 }
00203
#endif
00204
00205 RIPERR0(ERROR_CANNOT_FIND_WND_CLASS, RIP_VERBOSE,
"");
00206
return NULL;
00207 }
00208
00209
00210
00211
00212
00213 ppcls =
GetClassPtr(atomT, ptiCurrent->
ppi, hInstance);
00214
if (ppcls ==
NULL) {
00215
goto CantFindClassMessageAndFail;
00216 }
00217
00218 pcls = *ppcls;
00219
00220
if (
NeedsWindowEdge(style, dwExStyle,
Is400Compat(dwExpWinVerAndFlags))) {
00221 dwExStyle |= WS_EX_WINDOWEDGE;
00222 }
else {
00223 dwExStyle &= ~WS_EX_WINDOWEDGE;
00224 }
00225
00226
00227
00228
00229 pwnd =
HMAllocObject(
00230 ptiCurrent, pdesk,
TYPE_WINDOW,
sizeof(
WND) + pcls->cbwndExtra);
00231
00232
if (pwnd ==
NULL) {
00233 RIPERR0(ERROR_OUTOFMEMORY,
00234 RIP_WARNING,
00235
"Out of pool in xxxCreateWindowEx");
00236
00237
return NULL;
00238 }
00239
00240
00241
00242
00243 pwnd->
pcls = pcls;
00244 pwnd->style = style & ~WS_VISIBLE;
00245
#ifdef REDIRECTION
00246
pwnd->ExStyle = dwExStyle & ~(WS_EX_LAYERED | WS_EX_REDIRECTED);
00247
#else
00248
pwnd->ExStyle = dwExStyle & ~WS_EX_LAYERED;
00249
#endif // REDIRECTION
00250
pwnd->
cbwndExtra = pcls->cbwndExtra;
00251
00252
00253
00254
00255
00256
00257
00258
if (!
ReferenceClass(pcls, pwnd)) {
00259
HMFreeObject(pwnd);
00260
goto CantFindClassMessageAndFail;
00261 }
00262
00263
00264
00265
00266
00267
if (atomT ==
gpsi->
atomSysClass[
ICLS_BUTTON]) {
00268 pwnd->
hImc =
NULL_HIMC;
00269 }
else {
00270 pwnd->
hImc = (HIMC)
PtoH(ptiCurrent->
spDefaultImc);
00271 }
00272
00273
00274
00275
00276
00277
00278 ptiCurrent->
cWindows++;
00279
00280
00281
00282
00283
00284 pcls = pwnd->
pcls;
00285
00286
00287
00288
00289
00290
00291
00292 RtlZeroMemory(&csex,
sizeof(csex));
00293 csex.cs.dwExStyle = dwExStyle;
00294 csex.cs.hInstance = hInstance;
00295
00296
if (!
IS_PTR(cczpstrClass)) {
00297 csex.cs.lpszClass = (LPWSTR)cczpstrClass;
00298 }
else {
00299
if (wWFAnsiCreator) {
00300 csex.cs.lpszClass = (LPWSTR)pcls->lpszAnsiClassName;
00301
if (
IS_PTR(csex.cs.lpszClass)) {
00302
RtlInitLargeAnsiString(
00303 (
PLARGE_ANSI_STRING)&csex.strClass,
00304 (LPSTR)csex.cs.lpszClass,
00305 (
UINT)-1);
00306 }
00307 }
else {
00308 csex.cs.lpszClass = cczpstrClass->
Buffer;
00309 csex.strClass = *cczpstrClass;
00310 }
00311 }
00312
00313
if (cczpstrName !=
NULL) {
00314 csex.cs.lpszName = cczpstrName->
Buffer;
00315 csex.strName = *cczpstrName;
00316 }
00317 csex.cs.style = style;
00318 csex.cs.x = x;
00319 csex.cs.y = y;
00320 csex.cs.cx = cx;
00321 csex.cs.cy =
cy;
00322 csex.cs.hwndParent =
HW(pwndParent);
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
if (fChild) {
00333 csex.cs.hMenu = (HMENU)pMenu;
00334
00335 pwnd->ExStyle |= pwndParent->ExStyle & (WS_EXP_FOCUSHIDDEN | WS_EXP_ACCELHIDDEN);
00336
#if WS_EXP_ACCELHIDDEN != 0x40000000
00337
#error Fix UISTATE bits copying if you moved the UISTATE bits from ExStyle
00338
#endif
00339
00340 }
else {
00341 csex.cs.hMenu =
PtoH(pMenu);
00342 }
00343
00344 csex.cs.lpCreateParams = lpCreateParams;
00345
00346
00347
00348
00349
ThreadLockAlwaysWithPti(ptiCurrent, pwnd, &tlpwnd);
00350
00351
00352
00353
00354
00355
00356
if (pwnd->
head.rpdesk) {
00357
Lock(&(pwnd->
spwndParent),
PWNDMESSAGE(pwnd));
00358 }
00359
00360
00361
00362
00363
00364
if (pcls->spicn && !pcls->spicnSm) {
00365
xxxCreateClassSmIcon(pcls);
00366 }
00367
00368
00369
00370
00371
00372
00373 pwnd->hModule = hInstance;
00374
00375
00376
00377
00378 pwnd->
lpfnWndProc = (
WNDPROC_PWND)
MapClientNeuterToClientPfn(pcls, 0, wWFAnsiCreator);
00379
00380
00381
00382
00383
00384
00385
if (pcls->
CSF_flags &
CSF_SERVERSIDEPROC) {
00386
SetWF(pwnd,
WFSERVERSIDEPROC);
00387 UserAssert(!(pcls->
CSF_flags &
CSF_ANSIPROC));
00388 }
00389
00390
00391
00392
00393
00394
00395
SetWF(pwnd, wWFAnsiCreator);
00396
00397
00398
00399
00400
00401
if ((pcls->
CSF_flags &
CSF_ANSIPROC) ||
00402 (wWFAnsiCreator &&
00403 ((atomT ==
gpsi->
atomSysClass[
ICLS_BUTTON]) ||
00404 (atomT ==
gpsi->
atomSysClass[
ICLS_COMBOBOX]) ||
00405 (atomT ==
gpsi->
atomSysClass[
ICLS_COMBOLISTBOX]) ||
00406 (atomT ==
gpsi->
atomSysClass[
ICLS_DIALOG]) ||
00407 (atomT ==
gpsi->
atomSysClass[
ICLS_EDIT]) ||
00408 (atomT ==
gpsi->
atomSysClass[
ICLS_LISTBOX]) ||
00409 (atomT ==
gpsi->
atomSysClass[
ICLS_MDICLIENT]) ||
00410 (atomT ==
gpsi->
atomSysClass[
ICLS_IME]) ||
00411 (atomT ==
gpsi->
atomSysClass[
ICLS_STATIC])))) {
00412
SetWF(pwnd,
WFANSIPROC);
00413 }
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423 dw =
GetAppCompatFlags(ptiCurrent);
00424
00425
if (dw & GACF_RANDOM3XUI) {
00426
SetWF(pwnd,
WFOLDUI);
00427
00428 dwExStyle &= 0x0000003f;
00429 csex.cs.dwExStyle &= 0x0000003f;
00430 }
00431
00432 pwnd->hMod16 = ((ptiCurrent->
TIF_flags &
TIF_16BIT) && !
TestWF(pwnd,
WFSERVERSIDEPROC))?
xxxClientWOWGetProcModule(pwnd->
lpfnWndProc):0;
00433
if (
Is310Compat(dwExpWinVerAndFlags)) {
00434
SetWF(pwnd,
WFWIN31COMPAT);
00435
if (
Is400Compat(dwExpWinVerAndFlags)) {
00436
SetWF(pwnd,
WFWIN40COMPAT);
00437
if (
Is500Compat(dwExpWinVerAndFlags)) {
00438
SetWF(pwnd,
WFWIN50COMPAT);
00439 }
00440 }
00441 }
else if (dw & GACF_ALWAYSSENDNCPAINT) {
00442
SetWF(pwnd,
WFALWAYSSENDNCPAINT);
00443 }
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
if (
IsHooked(ptiCurrent,
WHF_CBT)) {
00455 CBT_CREATEWND cbt;
00456
00457
00458
00459
00460
00461 cbt.lpcs = (LPCREATESTRUCT)&csex;
00462 cbt.hwndInsertAfter = HWND_TOP;
00463
00464
if ((
BOOL)
xxxCallHook(HCBT_CREATEWND, (WPARAM)
HWq(pwnd),
00465 (LPARAM)&cbt, WH_CBT)) {
00466
00467
goto MemError;
00468 }
else {
00469
00470
00471
00472
00473
00474
00475 x = csex.cs.x;
00476 y = csex.cs.y;
00477 cx = csex.cs.cx;
00478
cy = csex.cs.cy;
00479
00480
if (!
IS_PTR(cbt.hwndInsertAfter))
00481 pwndZOrder = (
PWND)cbt.hwndInsertAfter;
00482
else
00483 pwndZOrder =
RevalidateHwnd(cbt.hwndInsertAfter);
00484 }
00485 }
else {
00486 pwndZOrder = (
PWND)HWND_TOP;
00487 }
00488
00489
if (!(fTiled =
TestwndTiled(pwnd))) {
00490
00491
00492
00493
00494
00495
if (x == CW_USEDEFAULT || x ==
CW2_USEDEFAULT) {
00496 x = 0;
00497 y = 0;
00498 }
00499
00500
if (cx == CW_USEDEFAULT || cx ==
CW2_USEDEFAULT) {
00501 cx = 0;
00502
cy = 0;
00503 }
00504 }
00505
00506
00507
00508
00509 src.
x = x;
00510 src.
y = y;
00511 src.
cx = cx;
00512 src.
cy =
cy;
00513
00514
00515
00516
00517
if (fChild = (
BOOL)
TestwndChild(pwnd)) {
00518
00519
00520
00521
00522 UserAssert(pwndParent);
00523
if (pwndParent !=
PWNDDESKTOP(pwnd)) {
00524 src.
x += pwndParent->
rcClient.left;
00525 src.
y += pwndParent->
rcClient.top;
00526 }
00527
00528
00529
00530
00531 pwndZOrder =
PWND_BOTTOM;
00532 }
00533
00534
00535
00536
00537
00538
00539
00540
00541
if (fTiled) {
00542
00543
00544
00545
00546
00547
SetWF(pwnd,
WFCLIPSIBLINGS);
00548 mask =
MaskWF(
WFCAPTION) |
MaskWF(
WFBORDER);
00549
00550
00551
00552
00553
00554
00555
00556
if (
TestWF(pwnd,
WFWIN40COMPAT)) {
00557
00558
SetWF(pwnd,
WEFWINDOWEDGE);
00559 }
00560
00561
00562
00563
00564
SetWF(pwnd,
WFSENDSIZEMOVE);
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
if (x == CW_USEDEFAULT || x ==
CW2_USEDEFAULT) {
00588
00589
00590
00591
00592
if (src.
y != CW_USEDEFAULT && src.
y !=
CW2_USEDEFAULT) {
00593 sw = src.
y;
00594 }
00595 }
00596
00597
00598
00599
00600
00601 pMonitor =
NULL;
00602
if ( x == CW_USEDEFAULT ||
00603 x ==
CW2_USEDEFAULT ||
00604 cx == CW_USEDEFAULT ||
00605 cx ==
CW2_USEDEFAULT) {
00606
00607
if (ptiCurrent->
ppi->
hMonitor) {
00608 pMonitor =
ValidateHmonitor(ptiCurrent->
ppi->
hMonitor);
00609 }
else if (pwndParent) {
00610 pMonitor =
_MonitorFromWindow(pwndParent, MONITOR_DEFAULTTONEAREST);
00611 }
00612 }
00613
00614
if (!pMonitor) {
00615 pMonitor =
GetPrimaryMonitor();
00616 }
00617
00618
SetTiledRect(pwnd, &rc, pMonitor);
00619
00620
00621
00622
00623
if (x == CW_USEDEFAULT || x ==
CW2_USEDEFAULT) {
00624
00625
00626
00627
00628
if (ptiCurrent->
ppi->
usi.
dwFlags & STARTF_USEPOSITION ) {
00629 fStartup =
TRUE;
00630 x = src.
x = ptiCurrent->
ppi->
usi.
dwX;
00631 y = src.
y = ptiCurrent->
ppi->
usi.
dwY;
00632 }
else {
00633 x = src.
x = rc.left;
00634 y = src.
y = rc.top;
00635 }
00636 fDefPos =
TRUE;
00637
00638 }
else {
00639
00640
00641
00642
00643
00644
if (pMonitor->
cWndStack) {
00645 pMonitor->
cWndStack--;
00646 }
00647 }
00648
00649
00650
00651
00652
if (src.
cx == CW_USEDEFAULT || src.
cx ==
CW2_USEDEFAULT) {
00653
00654
00655
00656
00657
if (ptiCurrent->
ppi->
usi.
dwFlags & STARTF_USESIZE) {
00658 fStartup =
TRUE;
00659 src.
cx = ptiCurrent->
ppi->
usi.
dwXSize;
00660 src.
cy = ptiCurrent->
ppi->
usi.
dwYSize;
00661 }
else {
00662 src.
cx = rc.right - x;
00663 src.
cy = rc.bottom - y;
00664 }
00665 fDefPos =
TRUE;
00666
00667 }
else if (fDefPos) {
00668
00669
00670
00671
00672
00673 dx = (src.
x + src.
cx) - pMonitor->
rcMonitor.right;
00674 dy = (src.
y + src.
cy) - pMonitor->
rcMonitor.bottom;
00675
if (dx > 0) {
00676 x -= dx;
00677 src.
x = x;
00678
if (src.
x < pMonitor->
rcMonitor.left) {
00679 src.
x = x = pMonitor->
rcMonitor.left;
00680 }
00681 }
00682
00683
if (dy > 0) {
00684 y -= dy;
00685 src.
y = y;
00686
if (src.
y < pMonitor->
rcMonitor.top) {
00687 src.
y = y = pMonitor->
rcMonitor.top;
00688 }
00689 }
00690 }
00691 }
00692
00693
00694
00695
00696
00697
if (fStartup) {
00698 ptiCurrent->
ppi->
usi.
dwFlags &=
00699 ~(STARTF_USESIZE | STARTF_USEPOSITION);
00700 }
00701
00702
00703
00704
00705
00706
if (
TestwndPopup(pwnd)) {
00707
00708
if (pwnd !=
_GetDesktopWindow()) {
00709
00710
00711
00712
00713
SetWF(pwnd,
WFCLIPSIBLINGS);
00714 }
00715 }
00716
00717
00718
00719
00720 *(((WORD *)&pwnd->style) + 1) |= mask;
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
if (pMenu ==
NULL && !fChild && (pcls->lpszMenuName !=
NULL)) {
00731 UNICODE_STRING strMenuName;
00732
00733
RtlInitUnicodeStringOrId(&strMenuName, pcls->lpszMenuName);
00734 pMenu =
xxxClientLoadMenu(pcls->hModule, &strMenuName);
00735 csex.cs.hMenu =
PtoH(pMenu);
00736
00737
00738
00739
00740
00741 }
00742
00743
00744
00745
00746
if (
TestwndChild(pwnd)) {
00747
00748
00749
00750
00751 pwnd->
spmenu = pMenu;
00752 }
else {
00753
00754
00755
00756
00757
LockWndMenu(pwnd, &pwnd->
spmenu, pMenu);
00758 }
00759
00760
00761
00762
00763
00764
if (
TestCF(pwnd,
CFNOCLOSE)) {
00765
00766
00767
00768
00769
00770 pMenu =
xxxGetSystemMenu(pwnd,
FALSE);
00771
if (pMenu !=
NULL) {
00772
TL tlpMenu;
00773
00774
ThreadLock(pMenu, &tlpMenu);
00775
xxxDeleteMenu(pMenu, 5, MF_BYPOSITION);
00776
xxxDeleteMenu(pMenu, 5, MF_BYPOSITION);
00777
ThreadUnlock(&tlpMenu);
00778 }
00779 }
00780
00781
00782
00783
00784
00785
00786
00787
00788
if (!fChild) {
00789
Lock(&(pwnd->
spwndLastActive), pwnd);
00790
if ((pwndParent !=
NULL) &&
00791 (pwndParent != pwndParent->
head.rpdesk->spwndMessage) &&
00792 (pwndParent != pwndParent->
head.rpdesk->pDeskInfo->spwnd)) {
00793
00794
PWND pwndOwner =
GetTopLevelWindow(pwndParent);
00795
00796
if (!
ValidateOwnerDepth(pwnd, pwndOwner)) {
00797 RIPERR1(ERROR_INVALID_PARAMETER,
00798 RIP_WARNING,
00799
"Exceeded nested owner limit for pwnd %#p",
00800 pwnd);
00801
goto MemError;
00802 }
00803
00804
#if DBG
00805
if (pwnd->
pcls->
atomClassName ==
gpsi->
atomSysClass[
ICLS_IME]) {
00806 UserAssert(!
TestCF(pwndOwner,
CFIME));
00807 }
00808
#endif
00809
Lock(&(pwnd->
spwndOwner), pwndOwner);
00810
if (pwnd->
spwndOwner &&
TestWF(pwnd->
spwndOwner,
WEFTOPMOST)) {
00811
00812
00813
00814
00815
00816
SetWF(pwnd,
WEFTOPMOST);
00817 }
00818
00819
00820
00821
00822
00823
if (atomT !=
gpsi->
atomSysClass[
ICLS_IME] &&
00824 pwnd->
spwndOwner !=
NULL &&
00825
GETPTI(pwnd->
spwndOwner) != ptiCurrent) {
00826
00827
00828
00829
00830
00831
zzzAttachThreadInput(ptiCurrent,
GETPTI(pwnd->
spwndOwner),
TRUE);
00832 }
00833
00834 }
else {
00835 pwnd->
spwndOwner =
NULL;
00836 }
00837
00838
#if DBG
00839
if (ptiCurrent->
rpdesk !=
NULL) {
00840 UserAssert(!(ptiCurrent->
rpdesk->
dwDTFlags & (
DF_DESTROYED |
DF_DESKWNDDESTROYED |
DF_DYING)));
00841 }
00842
#endif
00843
if ((pwndParent ==
NULL) ||
00844 (pwndParent != pwndParent->
head.rpdesk->spwndMessage)) {
00845 pwndParent =
_GetDesktopWindow();
00846
00847
ThreadLockWithPti(ptiCurrent, pwndParent, &tlpwndParent);
00848 fLockParent =
TRUE;
00849 }
00850 }
00851
00852
00853
00854
00855
Lock(&(pwnd->
spwndParent), pwndParent);
00856
00857
00858
00859
00860
00861
if (!
TestWF(pwnd,
WFWIN31COMPAT)) {
00862
00863
00864
00865
00866
00867
00868
00869
if ((pcls->style & CS_PARENTDC) &&
00870 !
TestWF(pwndParent,
WFCLIPCHILDREN)) {
00871
#if DBG
00872
if (
TestWF(pwnd,
WFCLIPCHILDREN))
00873 RIPMSG0(RIP_WARNING,
"WS_CLIPCHILDREN overridden by CS_PARENTDC");
00874
if (
TestWF(pwnd,
WFCLIPSIBLINGS))
00875 RIPMSG0(RIP_WARNING,
"WS_CLIPSIBLINGS overridden by CS_PARENTDC");
00876
#endif
00877
ClrWF(pwnd, (
WFCLIPCHILDREN |
WFCLIPSIBLINGS));
00878 }
00879 }
00880
00881
00882
00883
00884
00885
00886
00887
00888
if (
TestwndChild(pwnd) && (pwndParent !=
PWNDDESKTOP(pwnd)) &&
00889 (ptiCurrent !=
GETPTI(pwndParent))) {
00890
00891
00892
00893
zzzAttachThreadInput(ptiCurrent,
GETPTI(pwndParent),
TRUE);
00894 }
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
xxxAdjustSize(pwnd, &src.
cx, &src.
cy);
00907
00908
00909
00910
00911
00912
00913
if ( pwnd->
head.rpdesk !=
NULL &&
00914 !
TestWF(pwnd,
WFCHILD) &&
00915 !
TestWF(pwnd,
WEFTOOLWINDOW)) {
00916
00917
xxxCheckFullScreen(pwnd, &src);
00918 }
00919
00920
if (src.
cx < 0) {
00921 RIPMSG1(RIP_WARNING,
"xxxCreateWindowEx: adjusted cx in pwnd %#p", pwnd);
00922 src.
cx = 0;
00923 }
00924
00925
if (src.
cy < 0) {
00926 RIPMSG1(RIP_WARNING,
"xxxCreateWindowEx: adjusted cy in pwnd %#p", pwnd);
00927 src.
cy = 0;
00928 }
00929
00930
00931
00932
00933
RECTFromSIZERECT(&pwnd->
rcWindow, &src);
00934
00935
if (dwExStyle & WS_EX_LAYERED) {
00936
if (!
xxxSetLayeredWindow(pwnd,
FALSE)) {
00937
goto MemError;
00938 }
00939 }
00940
00941
#ifdef REDIRECTION
00942
if (dwExStyle & WS_EX_REDIRECTED) {
00943
if (!SetRedirectedWindow(pwnd)) {
00944
goto MemError;
00945 }
00946 }
00947
#endif // REDIRECTION
00948
00949
if (
TestCF2(pcls,
CFOWNDC) ||
00950 (
TestCF2(pcls,
CFCLASSDC) && pcls->
pdce ==
NULL)) {
00951
if (
NULL ==
CreateCacheDC(pwnd, DCX_OWNDC,
NULL)) {
00952
00953 RIPMSG1(RIP_WARNING,
"xxxCreateWindowEx: pwnd %#p failed to create cached DC",
00954 pwnd);
00955
00956
goto MemError;
00957 }
00958 }
00959
00960
00961
00962
00963
00964 csex.cs.x = x;
00965 csex.cs.y = y;
00966 csex.cs.cx = cx;
00967 csex.cs.cy =
cy;
00968
00969
00970
00971
00972
if (!
xxxSendMessage(pwnd, WM_NCCREATE, 0
L, (LPARAM)&csex)) {
00973
00974 MemError:
00975
00976
#if DBG
00977
if (!
IS_PTR(cczpstrClass)) {
00978 RIPMSG2(RIP_WARNING,
00979 (pwndParent) ?
00980
"xxxCreateWindowEx failed, Class=%#.4x, ID=%d" :
00981
"xxxCreateWindowEx failed, Class=%#.4x",
00982
PTR_TO_ID(cczpstrClass),
00983 (LONG_PTR) pMenu);
00984 }
else {
00985 RIPMSG2(RIP_WARNING,
00986 (pwndParent) ?
00987
"xxxCreateWindowEx failed, Class=\"%s\", ID=%d" :
00988
"xxxCreateWindowEx failed, Class=\"%s\"",
00989 pcls->lpszAnsiClassName,
00990 (LONG_PTR) pMenu);
00991 }
00992
#endif
00993
00994
if (fLockParent)
00995
ThreadUnlock(&tlpwndParent);
00996
00997
00998
00999
01000
01001
01002
SetWF(pwnd,
WFDESTROYED);
01003
01004
01005
01006
01007
01008
if (
TestWF(pwnd,
WFVISIBLE)) {
01009
SetVisible(pwnd,
SV_UNSET);
01010 }
01011
01012
01013
01014
01015
xxxFreeWindow(pwnd, &tlpwnd);
01016
01017
return NULL;
01018 }
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
if (
TestWF(pwnd,
WFTITLESET))
01038
if (!(csex.strName.Buffer !=
NULL && csex.strName.Length == 0 &&
01039 pwnd->
strName.
Buffer ==
NULL)) {
01040 csex.cs.lpszName = pwnd->
strName.
Buffer;
01041 RtlCopyMemory(&csex.strName, &pwnd->
strName,
sizeof(
LARGE_STRING));
01042 }
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
if (
IS_IME_ENABLED() && ptiCurrent->
spwndDefaultIme ==
NULL) {
01054
01055
01056
01057
01058
if (
WantImeWindow(pwndParent, pwnd)) {
01059
01060
01061
01062
01063
01064 UserAssert(
gaOleMainThreadWndClass != atomT);
01065
01066
Lock(&(ptiCurrent->
spwndDefaultIme),
01067
xxxCreateDefaultImeWindow(pwnd, atomT, hInstance));
01068
01069
01070
01071
01072
01073
01074
#if _DBG
01075
if (ptiCurrent->
spDefaultImc ==
NULL) {
01076 RIPMSG1(RIP_WARNING,
"xxxCreateWindowEx: ptiCurrent(%08p)->spDefaultImc is NULL.", ptiCurrent);
01077 }
01078
ASSERT(ptiCurrent->
pClientInfo);
01079
#endif
01080
01081
if (ptiCurrent->
spwndDefaultIme && (ptiCurrent->
pClientInfo->
CI_flags &
CI_INPUTCONTEXT_REINIT)) {
01082
01083
TL tlpwndIme;
01084
01085 TAGMSG1(DBGTAG_IMM,
"xxxCreateDefaultImeWindow: ptiCurrent(%08p)->spDefaultImc->fNeedClientImcActivate is set.", ptiCurrent);
01086
01087
01088
01089
01090
01091
01092
01093
ThreadLock(ptiCurrent->
spwndDefaultIme, &tlpwndIme);
01094
xxxSendMessage(ptiCurrent->
spwndDefaultIme, WM_IME_SYSTEM, (WPARAM)IMS_ACTIVATETHREADLAYOUT, (LPARAM)ptiCurrent->
spklActive->
hkl);
01095
01096
01097 ptiCurrent->
pClientInfo->
CI_flags &= ~
CI_INPUTCONTEXT_REINIT;
01098
01099
ThreadUnlock(&tlpwndIme);
01100 }
01101 }
01102
else {
01103 RIPMSG0(RIP_VERBOSE,
"xxxCreateWindowEx: default IME window is not created.");
01104 }
01105 }
01106
01107
01108
01109
01110
01111
if (pwndParent !=
NULL) {
01112
if (!fChild && (pwndParent != pwndParent->
head.rpdesk->spwndMessage)) {
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
if (!
TestWF(pwnd,
WEFTOPMOST)) {
01124
if (pwndZOrder ==
PWND_TOP ||
01125
TestWF(pwndZOrder,
WEFTOPMOST)) {
01126 pwndZOrder =
CalcForegroundInsertAfter(pwnd);
01127 }
01128 }
else {
01129 pwndHardError =
GETTOPMOSTINSERTAFTER(pwnd);
01130
if (pwndHardError !=
NULL) {
01131 pwndZOrder = pwndHardError;
01132 }
01133 }
01134 }
01135
01136
LinkWindow(pwnd, pwndZOrder, pwndParent);
01137 }
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
#ifdef USE_MIRRORING
01149
if (fChild &&
TestWF(pwndParent, WEFLAYOUTRTL)) {
01150 cx = pwnd->
rcWindow.right - pwnd->
rcWindow.left;
01151 pwnd->
rcWindow.right = pwndParent->
rcClient.right - (pwnd->
rcWindow.left - pwndParent->
rcClient.left);
01152 pwnd->
rcWindow.left = pwnd->
rcWindow.right - cx;
01153 }
01154
#endif
01155
01156
CopyRect(&rc, &pwnd->
rcWindow);
01157
xxxSendMessage(pwnd, WM_NCCALCSIZE, 0
L, (LPARAM)&rc);
01158 pwnd->
rcClient = rc;
01159
01160
01161
01162
01163
if (
xxxSendMessage(pwnd, WM_CREATE, 0
L, (LPARAM)&csex) == -1
L) {
01164
#if DBG
01165
if (!
IS_PTR(cczpstrClass)) {
01166 RIPMSG1(RIP_WARNING,
01167
"CreateWindow() send of WM_CREATE failed, Class = 0x%x",
01168
PTR_TO_ID(cczpstrClass));
01169 }
else {
01170 RIPMSG1(RIP_WARNING,
01171
"CreateWindow() send of WM_CREATE failed, Class = \"%s\"",
01172 pcls->lpszAnsiClassName);
01173 }
01174
#endif
01175
if (fLockParent)
01176
ThreadUnlock(&tlpwndParent);
01177
01178
if (
ThreadUnlock(&tlpwnd))
01179
xxxDestroyWindow(pwnd);
01180
01181
return NULL;
01182 }
01183
01184
SetWF(pwnd,
WFISINITIALIZED);
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
if (
FWINABLE()) {
01199
xxxWindowEvent(EVENT_OBJECT_CREATE, pwnd, OBJID_WINDOW, INDEXID_OBJECT, 0);
01200 }
01201
01202
01203
01204
01205
if (!
TestWF(pwnd,
WFSENDSIZEMOVE)) {
01206
xxxSendSizeMessage(pwnd, SIZENORMAL);
01207
01208
if (pwndParent !=
NULL &&
PWNDDESKTOP(pwnd) != pwndParent) {
01209 rc.left -= pwndParent->
rcClient.left;
01210 rc.top -= pwndParent->
rcClient.top;
01211 }
01212
01213
xxxSendMessage(pwnd, WM_MOVE, 0
L, MAKELONG(rc.left, rc.top));
01214 }
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225 dwMinMax =
MINMAX_KEEPHIDDEN |
TEST_PUDF(
PUDF_ANIMATE);
01226
if (
TestWF(pwnd,
WFMINIMIZED)) {
01227
SetMinimize(pwnd,
SMIN_CLEAR);
01228
xxxMinMaximize(pwnd, SW_SHOWMINNOACTIVE, dwMinMax);
01229 }
else if (
TestWF(pwnd,
WFMAXIMIZED)) {
01230
ClrWF(pwnd,
WFMAXIMIZED);
01231
xxxMinMaximize(pwnd, SW_SHOWMAXIMIZED, dwMinMax);
01232 }
01233
01234
01235
01236
01237
01238
01239
01240
01241
if (fChild && !
TestWF(pwnd,
WEFNOPARENTNOTIFY) &&
01242 (pwnd->
spwndParent !=
NULL)) {
01243
ThreadLockAlwaysWithPti(ptiCurrent, pwnd->
spwndParent, &tlpwndParentT);
01244
xxxSendMessage(pwnd->
spwndParent, WM_PARENTNOTIFY,
01245 MAKELONG(WM_CREATE,
PTR_TO_ID(pwnd->
spmenu)), (LPARAM)
HWq(pwnd));
01246
ThreadUnlock(&tlpwndParentT);
01247 }
01248
01249
01250
01251
01252
if (style & WS_VISIBLE) {
01253
xxxShowWindow(pwnd, sw |
TEST_PUDF(
PUDF_ANIMATE));
01254 }
01255
01256
01257
01258
01259
01260
01261
if (
TestwndTiled(pwnd) ||
TestWF(pwnd,
WEFAPPWINDOW)) {
01262
if (ptiCurrent->
ppi->
dwHotkey) {
01263
01264
01265
01266
if (!(ptiCurrent->
TIF_flags &
TIF_16BIT) || (ptiCurrent->
ppi->
cThreads > 1)) {
01267
#ifdef LATER
01268
01269
01270
01271
01272
DWP_SetHotKey(pwnd, ptiCurrent->
ppi->
dwHotkey);
01273
#else
01274
xxxSendMessage(pwnd, WM_SETHOTKEY, ptiCurrent->
ppi->
dwHotkey, 0);
01275
#endif
01276
ptiCurrent->
ppi->
dwHotkey = 0;
01277 }
01278 }
01279 }
01280
01281
if (fLockParent)
01282
ThreadUnlock(&tlpwndParent);
01283
01284
return ThreadUnlock(&tlpwnd);
01285 }
01286
01287 BOOL WantImeWindow(IN
PWND pwndParent, IN
PWND pwnd)
01288 {
01289
PDESKTOP pdesk;
01290
01291 UserAssert(pwnd);
01292
01293
if (
PtiCurrent()->TIF_flags &
TIF_DISABLEIME) {
01294
return FALSE;
01295 }
01296
if (
TestWF(pwnd,
WFSERVERSIDEPROC)) {
01297
return FALSE;
01298 }
01299
01300 pdesk = pwnd->head.rpdesk;
01301
if (pdesk ==
NULL || pdesk->
rpwinstaParent ==
NULL) {
01302
return FALSE;
01303 }
01304
01305
01306
if (pdesk->
rpwinstaParent->
dwWSF_Flags &
WSF_NOIO) {
01307
return FALSE;
01308 }
01309
01310
01311
if (pwndParent) {
01312
PWND pwndT = pwndParent;
01313
01314
while (pwndT && pdesk == pwndT->
head.rpdesk) {
01315
if (pwndT == pdesk->spwndMessage) {
01316
return FALSE;
01317 }
01318 pwndT = pwndT->
spwndParent;
01319 }
01320 }
01321
01322
return TRUE;
01323 }
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333 void SetTiledRect(
01334
PWND pwnd,
01335 LPRECT lprc,
01336
PMONITOR pMonitor)
01337 {
01338 POINT pt;
01339 RECT rcT;
01340
01341 UserAssert(pMonitor->
cWndStack >= 0);
01342
01343
01344
01345
01346
GetRealClientRect(
PWNDDESKTOP(pwnd), &rcT,
GRC_MINWNDS, pMonitor);
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360 pt.x = pMonitor->
cWndStack * (
SYSMET(CXSIZEFRAME) +
SYSMET(CXSIZE));
01361 pt.y = pMonitor->
cWndStack * (
SYSMET(CYSIZEFRAME) +
SYSMET(CYSIZE));
01362
01363
01364
01365
01366
if ( (pt.x > ((rcT.right-rcT.left) / 4)) ||
01367 (pt.y > ((rcT.bottom-rcT.top) / 4)) ) {
01368
01369 pMonitor->
cWndStack = 0;
01370 pt.x = 0;
01371 pt.y = 0;
01372 }
01373
01374
01375
01376
01377 pt.x += rcT.left;
01378 pt.y += rcT.top;
01379
01380 lprc->left = pt.x;
01381 lprc->top = pt.y;
01382 lprc->right = pt.x +
MultDiv(rcT.right-rcT.left, 3, 4);
01383 lprc->bottom = pt.y +
MultDiv(rcT.bottom-rcT.top, 3, 4);
01384
01385
01386
01387
01388 pMonitor->
cWndStack++;
01389 }
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401 void xxxAdjustSize(
01402
PWND pwnd,
01403 LPINT lpcx,
01404 LPINT lpcy)
01405 {
01406 POINT ptmin,
01407 ptmax;
01408 MINMAXINFO mmi;
01409
01410
CheckLock(pwnd);
01411
01412
01413
01414
01415
if (
TestwndTiled(pwnd) ||
TestWF(pwnd,
WFSIZEBOX)) {
01416
01417
01418
01419
01420
xxxInitSendValidateMinMaxInfo(pwnd, &mmi);
01421
01422
if (
TestWF(pwnd,
WFMINIMIZED)) {
01423 ptmin = mmi.ptReserved;
01424 ptmax = mmi.ptMaxSize;
01425 }
else {
01426 ptmin = mmi.ptMinTrackSize;
01427 ptmax = mmi.ptMaxTrackSize;
01428 }
01429
01430
01431
01432
01433 *lpcx =
max(ptmin.x,
min(*lpcx, ptmax.x));
01434 *lpcy =
max(ptmin.y,
min(*lpcy, ptmax.y));
01435 }
01436 }
01437
01438
#if DBG
01439
01440
01441
01442
01443
01444
01445
void VerifyWindowLink (
PWND pwnd,
PWND pwndParent, BOOL fLink)
01446 {
01447
BOOL fFirstFound =
FALSE;
01448
BOOL fInFound =
FALSE;
01449
PWND pwndNext = pwndParent->
spwndChild;
01450
PWND pwndFirst = pwndNext;
01451
01452
while (pwndNext !=
NULL) {
01453
if (pwndFirst == pwndNext) {
01454
if (fFirstFound) {
01455 RIPMSG1(RIP_ERROR,
"Loop in %#p spwndNext chain", pwnd);
01456
return;
01457 }
else {
01458 fFirstFound =
TRUE;
01459 }
01460 }
01461
01462
if (pwndNext == pwnd) fInFound =
TRUE;
01463 pwndNext = pwndNext->
spwndNext;
01464 }
01465
01466
if (fLink && !fInFound) {
01467 RIPMSG1(RIP_ERROR,
"%#p not found in spwndNext chain", pwnd);
01468 }
01469 }
01470
#endif
01471
01472
01473
01474
01475
01476
01477
01478 void LinkWindow(
01479
PWND pwnd,
01480
PWND pwndInsert,
01481
PWND pwndParent)
01482 {
01483
if (pwndParent->
spwndChild == pwnd) {
01484 RIPMSG0(RIP_WARNING,
"Attempting to link a window to itself");
01485
return;
01486 }
01487 UserAssert(pwnd != pwndInsert);
01488 UserAssert((pwnd->
spwndParent ==
NULL) || (pwnd->
spwndParent == pwndParent));
01489
01490
if (pwndInsert ==
PWND_TOP) {
01491
01492
01493
01494
01495 LinkTop:
01496
#if DBG
01497
01498
01499
01500
01501
01502
01503
01504
01505
if (pwndParent ==
PWNDDESKTOP(pwndParent) &&
01506 pwndParent->spwndChild &&
01507
FSwpTopmost(pwndParent->spwndChild) &&
01508 pwndParent !=
PWNDMESSAGE(pwndParent) &&
01509
01510 !
TestCF(pwnd,
CFIME) && pwnd->
pcls->
atomClassName !=
gpsi->
atomSysClass[
ICLS_IME]) {
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
if (!
FSwpTopmost(pwnd)) {
01522 RIPMSG1(RIP_WARNING,
"LinkWindow pwnd:%p is not FSwpTopmost", pwnd);
01523 }
01524 }
01525
#endif
01526
01527
Lock(&pwnd->
spwndNext, pwndParent->
spwndChild);
01528
Lock(&(pwndParent->spwndChild), pwnd);
01529 }
else {
01530
if (pwndInsert ==
PWND_BOTTOM) {
01531
01532
01533
01534
01535
if (((pwndInsert = pwndParent->spwndChild) ==
NULL) ||
01536
TestWF(pwndInsert,
WFBOTTOMMOST))
01537
goto LinkTop;
01538
01539
01540
01541
01542
01543
01544
01545
01546
while (pwndInsert->spwndNext !=
NULL) {
01547
if (
TestWF(pwndInsert->spwndNext,
WFBOTTOMMOST)) {
01548
#if DBG
01549
UserAssert(pwnd != pwndInsert->
spwndNext);
01550
if (
TestWF(pwnd,
WFBOTTOMMOST))
01551 UserAssert(
FALSE);
01552
#endif
01553
break;
01554 }
01555
01556 pwndInsert = pwndInsert->spwndNext;
01557 }
01558 }
01559
01560 UserAssert(pwnd != pwndInsert);
01561 UserAssert(pwnd != pwndInsert->
spwndNext);
01562 UserAssert(!
TestWF(pwndInsert,
WFDESTROYED));
01563 UserAssert(!
TestWF(pwnd,
WEFTOPMOST) ||
TestWF(pwndInsert,
WEFTOPMOST) ||
TestWF(pwnd,
WFTOGGLETOPMOST) || (pwndParent !=
PWNDDESKTOP(pwndInsert)));
01564 UserAssert(pwnd->spwndParent == pwndInsert->spwndParent);
01565
01566
Lock(&pwnd->spwndNext, pwndInsert->spwndNext);
01567
Lock(&pwndInsert->spwndNext, pwnd);
01568 }
01569
01570
if (
TestWF(pwnd,
WEFLAYERED))
01571
TrackLayeredZorder(pwnd);
01572
01573
#if DBG
01574
VerifyWindowLink (pwnd, pwndParent,
TRUE);
01575
#endif
01576
01577 }
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591 BOOL xxxDestroyWindow(
01592
PWND pwnd)
01593 {
01594
PMENUSTATE pMenuState, pmnsEnd;
01595
PTHREADINFO pti =
PtiCurrent();
01596
TL tlpwnd;
01597
PWND pwndFocus;
01598
TL tlpwndFocus;
01599
TL tlpwndParent;
01600
BOOL fAlreadyDestroyed;
01601
DWORD dwDisableHooks;
01602
01603 dwDisableHooks = 0;
01604
ThreadLockWithPti(pti, pwnd, &tlpwnd);
01605
01606
01607
01608
01609
01610
01611
01612 fAlreadyDestroyed =
HMIsMarkDestroy(pwnd);
01613
if (fAlreadyDestroyed) {
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
if (
HMPheFromObject(pwnd)->pOwner != pti) {
01630 UserAssert(
PsGetCurrentThread()->Tcb.Win32Thread);
01631
HMChangeOwnerThread(pwnd, pti);
01632 }
01633 dwDisableHooks = pti->
TIF_flags &
TIF_DISABLEHOOKS;
01634 pti->
TIF_flags |=
TIF_DISABLEHOOKS;
01635 }
else {
01636
01637
01638
01639
01640
if (pti !=
GETPTI(pwnd)) {
01641 RIPERR0(ERROR_ACCESS_DENIED,
01642 RIP_WARNING,
01643
"Access denied in xxxDestroyWindow");
01644
01645
goto FalseReturn;
01646 }
01647 }
01648
01649
01650
01651
01652
01653
01654
01655
if (!fAlreadyDestroyed && !(pti->
TIF_flags &
TIF_INCLEANUP) &&
01656
IsHooked(pti,
WHF_CBT)) {
01657
if (
xxxCallHook(HCBT_DESTROYWND, (WPARAM)
HWq(pwnd), 0, WH_CBT)) {
01658
goto FalseReturn;
01659 }
01660 }
01661
01662
01663
01664
01665 pMenuState =
GetpMenuState(pwnd);
01666
if ((pMenuState !=
NULL)
01667 && (pwnd == pMenuState->
pGlobalPopupMenu->
spwndNotify)) {
01668
01669
MNEndMenuStateNotify(pMenuState);
01670
01671
01672
01673
01674
01675 pmnsEnd = pMenuState;
01676
do {
01677 UserAssert(pwnd == pMenuState->pGlobalPopupMenu->spwndNotify);
01678 pMenuState->fInsideMenuLoop =
FALSE;
01679 pMenuState = pMenuState->pmnsPrev;
01680 }
while (pMenuState !=
NULL) ;
01681
01682
01683
01684
01685
01686
01687
01688
01689
if (!pmnsEnd->
fModelessMenu) {
01690
xxxEndMenu(pmnsEnd);
01691 }
01692 }
01693
01694
if (
ghwndSwitch ==
HWq(pwnd))
01695
ghwndSwitch =
NULL;
01696
01697
if (!
TestWF(pwnd,
WFCHILD) && (pwnd->
spwndOwner ==
NULL)) {
01698
01699
if (
TestWF(pwnd,
WFHASPALETTE)) {
01700
xxxFlushPalette(pwnd);
01701 }
01702 }
01703
01704
01705
01706
01707
01708
if (pwnd->
pcls->
atomClassName !=
gpsi->
atomSysClass[
ICLS_IME] &&
01709 !
TestwndChild(pwnd) && pwnd->
spwndOwner !=
NULL &&
01710
GETPTI(pwnd->
spwndOwner) !=
GETPTI(pwnd)) {
01711
01712
01713
01714
zzzAttachThreadInput(
GETPTI(pwnd),
GETPTI(pwnd->
spwndOwner),
FALSE);
01715 }
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
if (
TestWF(pwnd,
WFCHILD) && !
TestWF(pwnd,
WEFNOPARENTNOTIFY) &&
01728 pwnd->
spwndParent !=
NULL) {
01729
01730
ThreadLockAlwaysWithPti(pti, pwnd->
spwndParent, &tlpwndParent);
01731
xxxSendMessage(pwnd->
spwndParent, WM_PARENTNOTIFY,
01732 MAKELONG(WM_DESTROY,
PTR_TO_ID(pwnd->
spmenu)), (LPARAM)
HWq(pwnd));
01733
ThreadUnlock(&tlpwndParent);
01734 }
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
if (pwnd->
spwndParent && (pwnd->
spwndParent->
head.rpdesk !=
NULL))
01749
SetWF(pwnd,
WFINDESTROY);
01750
01751
01752
01753
01754
if (
TestWF(pwnd,
WFVISIBLE)) {
01755
if (
TestWF(pwnd,
WFCHILD)) {
01756
xxxShowWindow(pwnd, SW_HIDE |
TEST_PUDF(
PUDF_ANIMATE));
01757 }
else {
01758
01759
01760
01761
01762
xxxSetWindowPos(pwnd,
NULL, 0, 0, 0, 0, SWP_HIDEWINDOW |
01763 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER |
01764 (fAlreadyDestroyed ? SWP_DEFERDRAWING : 0));
01765 }
01766
01767
01768
01769
01770
if (
TestWF(pwnd,
WFVISIBLE)) {
01771 RIPMSG0(RIP_WARNING,
"xxxDestroyWindow: normal hide failed");
01772
SetVisible(pwnd,
SV_UNSET);
01773
01774
01775
01776
01777
xxxRedrawWindow(
NULL, &pwnd->
rcWindow,
NULL, RDW_INVALIDATE |
01778 RDW_ERASE | RDW_ALLCHILDREN);
01779
01780 }
01781 }
else if (
IsTrayWindow(pwnd)) {
01782
PostShellHookMessages(HSHELL_WINDOWDESTROYED,
01783 (LPARAM)
PtoHq( pwnd ));
01784 }
01785
01786
01787
01788
01789
if (!
TestWF(pwnd,
WFCHILD)) {
01790
xxxDW_DestroyOwnedWindows(pwnd);
01791
01792
01793
01794
01795
DWP_SetHotKey(pwnd, 0);
01796 }
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807
if (!fAlreadyDestroyed) {
01808
PWND pwndActivate =
NULL;
01809
TL tlpwndActivate;
01810
UINT cmdActivate;
01811
01812
01813
01814
01815
01816
01817
01818
01819
01820
if (pwnd == pti->
pq->
spwndActive) {
01821
if (
TestWF(pwnd,
WFPOPUP) && pwnd->
spwndOwner) {
01822 pwndActivate = pwnd->
spwndOwner;
01823 cmdActivate =
AW_TRY;
01824
01825 }
else {
01826 pwndActivate = pwnd;
01827 cmdActivate =
AW_SKIP;
01828 }
01829 }
else if ((pti->
pq->
spwndActive ==
NULL) && (
gpqForeground == pti->
pq)) {
01830 pwndActivate = pwnd;
01831 cmdActivate =
AW_SKIP;
01832 }
01833
01834
if (pwndActivate) {
01835
ThreadLockAlwaysWithPti(pti, pwndActivate, &tlpwndActivate);
01836
01837
if (!
xxxActivateWindow(pwndActivate, cmdActivate) ||
01838 ((cmdActivate ==
AW_SKIP) && (pwnd == pti->
pq->
spwndActive))) {
01839
if ((cmdActivate ==
AW_SKIP) || (pwnd == pti->
pq->
spwndActive)) {
01840
Unlock(&pti->
pq->
spwndActive);
01841 pwndFocus =
Unlock(&pti->
pq->
spwndFocus);
01842
if (
IS_IME_ENABLED() && pwndFocus !=
NULL) {
01843
ThreadLockAlwaysWithPti(pti, pwndFocus, &tlpwndFocus);
01844
xxxFocusSetInputContext(pwndFocus,
FALSE,
FALSE);
01845
ThreadUnlock(&tlpwndFocus);
01846 }
01847
if (
FWINABLE() && (pti->
pq ==
gpqForeground)) {
01848
xxxWindowEvent(EVENT_OBJECT_FOCUS,
NULL, OBJID_CLIENT,
01849 INDEXID_CONTAINER, 0);
01850
xxxWindowEvent(EVENT_SYSTEM_FOREGROUND,
NULL, OBJID_WINDOW,
01851 INDEXID_CONTAINER,
WEF_USEPWNDTHREAD);
01852 }
01853
zzzInternalDestroyCaret();
01854 }
01855 }
01856
01857
ThreadUnlock(&tlpwndActivate);
01858 }
01859 }
01860
01861
01862
01863
01864 {
01865
PWND pwndOwner = pwnd->
spwndOwner;
01866
01867
if (pwndOwner !=
NULL) {
01868
while (pwndOwner->
spwndOwner !=
NULL) {
01869 pwndOwner = pwndOwner->
spwndOwner;
01870 }
01871
01872
if (pwnd == pwndOwner->
spwndLastActive) {
01873
Lock(&(pwndOwner->
spwndLastActive), pwnd->
spwndOwner);
01874 }
01875 }
01876 }
01877
01878
if (!fAlreadyDestroyed) {
01879
01880
01881
01882
01883
01884
if (
FWINABLE() && !
TestWF(pwnd,
WFDESTROYED)) {
01885
xxxWindowEvent(EVENT_OBJECT_DESTROY, pwnd, OBJID_WINDOW, INDEXID_CONTAINER, 0);
01886 }
01887
01888
01889
01890
01891
01892
xxxDW_SendDestroyMessages(pwnd);
01893 }
01894
01895
01896
01897
01898
01899
if (
IS_IME_ENABLED() && !(pti->
TIF_flags &
TIF_INCLEANUP) &&
01900 pti->
spwndDefaultIme !=
NULL &&
01901 !
TestCF(pwnd,
CFIME) &&
01902 pwnd->
pcls->
atomClassName !=
gpsi->
atomSysClass[
ICLS_IME]) {
01903
01904
if (fAlreadyDestroyed) {
01905 RIPMSG2(RIP_VERBOSE,
"xxxDestroyWindow: in final destruction of %#p, ime=%#p",
01906 pwnd, pti->
spwndDefaultIme);
01907 }
else {
01908
if (!
TestWF(pwnd,
WFCHILD)) {
01909
if (
ImeCanDestroyDefIME(pti->
spwndDefaultIme, pwnd)) {
01910 TAGMSG1(DBGTAG_IMM,
"xxxDestroyWindow: destroying (1) the default IME window=%p", pti->
spwndDefaultIme);
01911
xxxDestroyWindow(pti->
spwndDefaultIme);
01912 }
01913 }
01914
else if (pwnd->
spwndParent !=
NULL) {
01915
if (
ImeCanDestroyDefIMEforChild(pti->
spwndDefaultIme, pwnd)) {
01916 TAGMSG1(DBGTAG_IMM,
"xxxDestroyWindow: destroying (2) the default IME window=%p", pti->
spwndDefaultIme);
01917
xxxDestroyWindow(pti->
spwndDefaultIme);
01918 }
01919 }
01920 }
01921 }
01922
01923
if ((pwnd->
spwndParent !=
NULL) && !fAlreadyDestroyed) {
01924
01925
01926
01927
01928
01929
if (
TestwndChild(pwnd) && (pwnd->
spwndParent !=
PWNDDESKTOP(pwnd)) &&
01930 (
GETPTI(pwnd) !=
GETPTI(pwnd->
spwndParent))) {
01931
01932
01933
01934
CheckLock(pwnd);
01935
zzzAttachThreadInput(
GETPTI(pwnd),
GETPTI(pwnd->
spwndParent),
FALSE);
01936 }
01937
01938
UnlinkWindow(pwnd, pwnd->
spwndParent);
01939 }
01940
01941
01942
01943
01944
01945
01946
01947
01948
#if DBG
01949
if (pwnd == pti->
pq->
spwndActive) {
01950 RIPMSG1(RIP_WARNING,
"xxxDestroyWindow: pwnd == pti->pq->spwndActive (%#p)", pwnd);
01951 }
01952
#endif
01953
01954
01955
01956
01957
01958
01959
SetWF(pwnd,
WFDESTROYED);
01960
01961
01962
01963
01964
01965
xxxFreeWindow(pwnd, &tlpwnd);
01966
01967
if (fAlreadyDestroyed) {
01968 pti->
TIF_flags = (pti->
TIF_flags & ~
TIF_DISABLEHOOKS) | dwDisableHooks;
01969 }
01970
return TRUE;
01971
01972 FalseReturn:
01973
if (fAlreadyDestroyed) {
01974 pti->
TIF_flags = (pti->
TIF_flags & ~
TIF_DISABLEHOOKS) | dwDisableHooks;
01975 }
01976
ThreadUnlock(&tlpwnd);
01977
return FALSE;
01978 }
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989 void xxxDW_DestroyOwnedWindows(
01990
PWND pwndParent)
01991 {
01992
PWND pwnd, pwndDesktop;
01993
PDESKTOP pdeskParent;
01994
PWND pwndDefaultIme =
GETPTI(pwndParent)->spwndDefaultIme;
01995
01996
CheckLock(pwndParent);
01997
01998
if ((pdeskParent = pwndParent->
head.rpdesk) ==
NULL)
01999
return;
02000 pwndDesktop = pdeskParent->
pDeskInfo->
spwnd;
02001
02002
02003
02004
02005
02006
if (pwndDesktop ==
NULL)
02007
return;
02008
02009 pwnd = pwndDesktop->
spwndChild;
02010
02011
while (pwnd !=
NULL) {
02012
if (pwnd->
spwndOwner == pwndParent) {
02013
02014
02015
02016
02017
if (
IS_IME_ENABLED() && !(
GETPTI(pwndParent)->TIF_flags &
TIF_INCLEANUP) &&
02018 pwnd == pwndDefaultIme) {
02019
Unlock(&pwnd->
spwndOwner);
02020 pwnd = pwnd->
spwndNext;
02021
continue;
02022 }
02023
02024
02025
02026
02027
02028
02029
if (!
xxxDestroyWindow(pwnd)) {
02030
Unlock(&pwnd->
spwndOwner);
02031 }
02032
02033
02034
02035
02036
02037
02038 pwnd = pwndDesktop->
spwndChild;
02039 }
else {
02040 pwnd = pwnd->
spwndNext;
02041 }
02042 }
02043 }
02044
02045
02046
02047
02048
02049
02050
02051
02052
02053 void xxxDW_SendDestroyMessages(
02054
PWND pwnd)
02055 {
02056
PWND pwndChild;
02057
PWND pwndNext;
02058
TL tlpwndNext;
02059
TL tlpwndChild;
02060
PWINDOWSTATION pwinsta;
02061
02062
CheckLock(pwnd);
02063
02064
02065
02066
02067
xxxCheckFocus(pwnd);
02068
02069 pwinsta =
_GetProcessWindowStation(
NULL);
02070
if (pwinsta !=
NULL && pwnd == pwinsta->
spwndClipOwner) {
02071
02072
02073
02074
02075
02076
DisownClipboard(pwnd);
02077 }
02078
02079
02080
02081
02082
#if _DBG
02083
if (pwnd ==
PtiCurrent()->spwndDefaultIme) {
02084 TAGMSG2(DBGTAG_IMM,
"xxxDW_SendDestroyMessages: sending WM_DESTROY message to def IME=%p, pti=%p", pwnd,
PtiCurrent());
02085 }
02086
#endif
02087
xxxSendMessage(pwnd, WM_DESTROY, 0
L, 0
L);
02088
02089
02090
02091
02092
02093
02094
02095 pwndChild = pwnd->
spwndChild;
02096
02097
while (pwndChild !=
NULL) {
02098
02099 pwndNext = pwndChild->
spwndNext;
02100
02101
ThreadLock(pwndNext, &tlpwndNext);
02102
02103
ThreadLockAlways(pwndChild, &tlpwndChild);
02104
xxxDW_SendDestroyMessages(pwndChild);
02105
ThreadUnlock(&tlpwndChild);
02106 pwndChild = pwndNext;
02107
02108
02109
02110
02111
if (!
ThreadUnlock(&tlpwndNext))
02112
break;
02113 }
02114
02115
xxxCheckFocus(pwnd);
02116 }
02117
02118
02119
02120
02121
02122
02123
02124
02125
02126 void xxxFW_DestroyAllChildren(
02127
PWND pwnd)
02128 {
02129
PWND pwndChild;
02130
TL tlpwndChild;
02131
PTHREADINFO pti;
02132
PTHREADINFO ptiCurrent =
PtiCurrent();
02133
02134
CheckLock(pwnd);
02135
02136
while (pwnd->
spwndChild !=
NULL) {
02137 pwndChild = pwnd->
spwndChild;
02138
02139
02140
02141
02142
02143
ThreadLockAlwaysWithPti(ptiCurrent, pwndChild, &tlpwndChild);
02144
02145
02146
02147
02148
02149
02150
if (
TestWF(pwndChild,
WFVISIBLE)) {
02151
SetVisible(pwndChild,
SV_UNSET);
02152 }
02153
02154
UnlinkWindow(pwndChild, pwnd);
02155
02156
02157
02158
02159
02160
02161
SetWF(pwndChild,
WFDESTROYED);
02162
02163
02164
02165
02166
02167
02168 pti =
GETPTI(pwndChild);
02169
if (pti != ptiCurrent) {
02170
PostEventMessage(pti, pti->
pq,
QEVENT_DESTROYWINDOW,
02171
NULL, 0,
02172 (WPARAM)
HWq(pwndChild), 0);
02173
ThreadUnlock(&tlpwndChild);
02174 }
else {
02175
02176
02177
02178
xxxFreeWindow(pwndChild, &tlpwndChild);
02179 }
02180 }
02181 }
02182
02183
02184
02185
02186
02187
02188
02189
02190
02191
02192 VOID UnlockNotifyWindow(
02193
PMENU pmenu)
02194 {
02195
PITEM pItem;
02196
int i;
02197
02198
02199
02200
02201 pItem = pmenu->
rgItems;
02202
for (i = pmenu->
cItems; i--; ++pItem) {
02203
02204
if (pItem->
spSubMenu !=
NULL)
02205
UnlockNotifyWindow(pItem->
spSubMenu);
02206 }
02207
02208
Unlock(&pmenu->
spwndNotify);
02209 }
02210
02211
02212
02213
02214
02215
02216
02217
02218 VOID xxxFreeWindow(
02219
PWND pwnd,
02220
PTL ptlpwndFree)
02221 {
02222
PDCE *ppdce;
02223
PDCE pdce;
02224
UINT uDCERelease;
02225
PMENU pmenu;
02226
PQMSG pqmsg;
02227
PPCLS ppcls;
02228 WORD fnid;
02229
TL tlpdesk;
02230
PWINDOWSTATION pwinsta =
_GetProcessWindowStation(
NULL);
02231
PTHREADINFO pti =
PtiCurrent();
02232
PPROCESSINFO ppi;
02233
PMONITOR pMonitor;
02234
TL tlpMonitor;
02235
02236 UNREFERENCED_PARAMETER(ptlpwndFree);
02237
02238
CheckLock(pwnd);
02239
02240
02241
02242
02243
02244
if (pwnd->
head.rpdesk !=
NULL) {
02245
if (pwnd == pwnd->
head.rpdesk->pDeskInfo->spwndShell)
02246
Unlock(&pwnd->
head.rpdesk->pDeskInfo->spwndShell);
02247
if (pwnd == pwnd->
head.rpdesk->pDeskInfo->spwndBkGnd)
02248
Unlock(&pwnd->
head.rpdesk->pDeskInfo->spwndBkGnd);
02249
if (pwnd == pwnd->
head.rpdesk->pDeskInfo->spwndTaskman)
02250
Unlock(&pwnd->
head.rpdesk->pDeskInfo->spwndTaskman);
02251
if (pwnd == pwnd->
head.rpdesk->pDeskInfo->spwndProgman)
02252
Unlock(&pwnd->
head.rpdesk->pDeskInfo->spwndProgman);
02253
if (
TestWF(pwnd,
WFSHELLHOOKWND)) {
02254
_DeregisterShellHookWindow(pwnd);
02255 }
02256
02257
if (
TestWF(pwnd,
WFMSGBOX)) {
02258 pwnd->
head.rpdesk->pDeskInfo->cntMBox--;
02259
ClrWF(pwnd,
WFMSGBOX);
02260 }
02261 }
02262
02263
02264
02265
02266
02267
02268
02269
if (
HMIsMarkDestroy(pwnd))
02270
HMChangeOwnerThread(pwnd, pti);
02271
02272
02273
02274
02275
02276
02277
02278
02279
02280
xxxFW_DestroyAllChildren(pwnd);
02281
xxxSendMessage(pwnd, WM_NCDESTROY, 0, 0
L);
02282
02283 pMonitor =
_MonitorFromWindow(pwnd, MONITOR_DEFAULTTOPRIMARY);
02284
ThreadLockAlwaysWithPti(pti, pMonitor, &tlpMonitor);
02285
xxxRemoveFullScreen(pwnd, pMonitor);
02286
ThreadUnlock(&tlpMonitor);
02287
02288
02289
02290
02291
02292
02293
02294
02295 fnid =
GETFNID(pwnd);
02296
if ((fnid >=
FNID_WNDPROCSTART) && !(pwnd->fnid &
FNID_CLEANEDUP_BIT)) {
02297
02298
if (fnid <=
FNID_WNDPROCEND) {
02299
02300
FNID(fnid)(pwnd, WM_FINALDESTROY, 0, 0, 0);
02301
02302 }
else if (fnid <=
FNID_CONTROLEND && !(pti->
TIF_flags &
TIF_INCLEANUP)) {
02303
02304
CallClientWorkerProc(pwnd,
02305 WM_FINALDESTROY,
02306 0,
02307 0,
02308 (PROC)
FNID_TO_CLIENT_PFNWORKER(fnid));
02309 }
02310
02311 pwnd->fnid |=
FNID_CLEANEDUP_BIT;
02312 }
02313
02314 pwnd->fnid |=
FNID_DELETED_BIT;
02315
02316
02317
02318
02319
if (pwnd->
spwndOwner && (pwnd->
spwndOwner->
spwndLastActive == pwnd)) {
02320
Lock(&(pwnd->
spwndOwner->
spwndLastActive), pwnd->
spwndOwner);
02321 }
02322
02323
02324
02325
02326
02327
02328
if (pwinsta !=
NULL) {
02329
02330
if (pwnd == pwinsta->
spwndClipOpen) {
02331
Unlock(&pwinsta->
spwndClipOpen);
02332 pwinsta->
ptiClipLock =
NULL;
02333 }
02334
02335
if (pwnd == pwinsta->
spwndClipViewer) {
02336
Unlock(&pwinsta->
spwndClipViewer);
02337 }
02338 }
02339
02340
if (
IS_IME_ENABLED() && pwnd == pti->
spwndDefaultIme)
02341
Unlock(&pti->
spwndDefaultIme);
02342
02343
if (pwnd == pti->
pq->
spwndFocus)
02344
Unlock(&pti->
pq->
spwndFocus);
02345
02346
if (pwnd == pti->
pq->
spwndActivePrev)
02347
Unlock(&pti->
pq->
spwndActivePrev);
02348
02349
if (pwnd ==
gspwndActivate)
02350
Unlock(&
gspwndActivate);
02351
02352
if (pwnd->
head.rpdesk !=
NULL) {
02353
02354
if (pwnd == pwnd->
head.rpdesk->spwndForeground)
02355
Unlock(&pwnd->
head.rpdesk->spwndForeground);
02356
02357
if (pwnd == pwnd->
head.rpdesk->spwndTray)
02358
Unlock(&pwnd->
head.rpdesk->spwndTray);
02359
02360
if (pwnd == pwnd->
head.rpdesk->spwndTrack) {
02361
02362
02363
02364
if (
GETPDESK(pwnd)->dwDTFlags &
DF_TOOLTIPSHOWING) {
02365
PWND pwndTooltip =
GETPDESK(pwnd)->spwndTooltip;
02366
TL tlpwndTooltip;
02367
02368
ThreadLockAlways(pwndTooltip, &tlpwndTooltip);
02369
xxxResetTooltip((
PTOOLTIPWND)pwndTooltip);
02370
ThreadUnlock(&tlpwndTooltip);
02371 }
02372
02373
Unlock(&pwnd->
head.rpdesk->spwndTrack);
02374 pwnd->
head.rpdesk->dwDTFlags &= ~
DF_MOUSEMOVETRK;
02375 }
02376 }
02377
02378
if (pwnd == pti->
pq->
spwndCapture)
02379
xxxReleaseCapture();
02380
02381
02382
02383
02384
if (pwnd ==
gspwndMouseOwner)
02385
Unlock(&
gspwndMouseOwner);
02386
02387
02388
02389
02390
if (pwnd ==
gspwndCursor)
02391
Unlock(&
gspwndCursor);
02392
02393
DestroyWindowsTimers(pwnd);
02394
DestroyWindowsHotKeys(pwnd);
02395
02396
02397
02398
02399
ClearSendMessages(pwnd);
02400
02401
02402
02403
02404
if (
TestWF(pwnd,
WEFLAYERED)) {
02405
UnsetLayeredWindow(pwnd);
02406 }
02407
02408
#ifdef REDIRECTION
02409
if (
TestWF(pwnd, WEFREDIRECTED)) {
02410 UnsetRedirectedWindow(pwnd);
02411 }
02412
#endif // REDIRECTION
02413
02414
02415
02416
02417
if (
NEEDSPAINT(pwnd)) {
02418
02419
DecPaintCount(pwnd);
02420
02421
DeleteMaybeSpecialRgn(pwnd->
hrgnUpdate);
02422 pwnd->
hrgnUpdate =
NULL;
02423
ClrWF(pwnd,
WFINTERNALPAINT);
02424 }
02425
02426
02427
02428
02429
if (
NEEDSSYNCPAINT(pwnd)) {
02430
ClrWF(pwnd,
WFSENDNCPAINT);
02431
ClrWF(pwnd,
WFSENDERASEBKGND);
02432 }
02433
02434
02435
02436
02437
02438
ClearHungFlag(pwnd,
WFREDRAWIFHUNG);
02439
ClearHungFlag(pwnd,
WFREDRAWFRAMEIFHUNG);
02440
02441
02442
02443
02444
02445
02446
02447
02448
if (pti->
mlPost.
pqmsgRead !=
NULL) {
02449
02450
02451
02452
02453
if ((pqmsg =
FindQMsg(pti,
02454 &(pti->
mlPost),
02455 pwnd,
02456 WM_QUIT,
02457 WM_QUIT,
TRUE)) !=
NULL) {
02458
02459
_PostQuitMessage((
int)pqmsg->
msg.wParam);
02460 }
02461 }
02462
02463
if (!
TestwndChild(pwnd) && pwnd->
spmenu !=
NULL) {
02464 pmenu = (
PMENU)pwnd->
spmenu;
02465
if (
UnlockWndMenu(pwnd, &pwnd->
spmenu))
02466
_DestroyMenu(pmenu);
02467 }
02468
02469
if (pwnd->
spmenuSys !=
NULL) {
02470 pmenu = (
PMENU)pwnd->
spmenuSys;
02471
if (pmenu != pwnd->
head.rpdesk->spmenuDialogSys) {
02472
if (
UnlockWndMenu(pwnd, &pwnd->
spmenuSys)) {
02473
_DestroyMenu(pmenu);
02474 }
02475 }
else {
02476
UnlockWndMenu(pwnd, &pwnd->
spmenuSys);
02477 }
02478 }
02479
02480
02481
02482
02483
if (pwnd->
head.rpdesk !=
NULL) {
02484
if (pwnd->
head.rpdesk->spmenuSys !=
NULL &&
02485 pwnd == pwnd->
head.rpdesk->spmenuSys->spwndNotify) {
02486
02487
UnlockNotifyWindow(pwnd->head.rpdesk->spmenuSys);
02488 }
else if (pwnd->head.rpdesk->spmenuDialogSys !=
NULL &&
02489 pwnd == pwnd->head.rpdesk->spmenuDialogSys->spwndNotify) {
02490
02491
UnlockNotifyWindow(pwnd->head.rpdesk->spmenuDialogSys);
02492 }
02493
02494 }
02495
02496
02497
02498
02499
02500
if (
gcountPWO != 0) {
02501 PVOID pwo =
InternalRemoveProp(pwnd,
PROP_WNDOBJ,
TRUE);
02502
if (pwo !=
NULL) {
02503 GreLockDisplay(
gpDispInfo->
hDev);
02504 GreDeleteWnd(pwo);
02505
gcountPWO--;
02506 GreUnlockDisplay(
gpDispInfo->
hDev);
02507 }
02508 }
02509
02510
#ifdef HUNGAPP_GHOSTING
02511
02512
02513
02514
02515
02516 RemoveGhost(pwnd);
02517
02518
#endif // HUNGAPP_GHOSTING
02519
02520
02521
02522
02523
02524
02525
for (ppdce = &
gpDispInfo->
pdceFirst; *ppdce !=
NULL; ) {
02526
02527 pdce = *ppdce;
02528
if (pdce->
DCX_flags & DCX_INVALID) {
02529
goto NextEntry;
02530 }
02531
02532
if ((pdce->
pwndOrg == pwnd) || (pdce->
pwndClip == pwnd)) {
02533
02534
if (!(pdce->
DCX_flags & DCX_CACHE)) {
02535
02536
if (
TestCF(pwnd,
CFCLASSDC)) {
02537
02538 GreLockDisplay(
gpDispInfo->
hDev);
02539
02540
if (pdce->
DCX_flags & (DCX_EXCLUDERGN | DCX_INTERSECTRGN))
02541
DeleteHrgnClip(pdce);
02542
02543
MarkDCEInvalid(pdce);
02544 pdce->
pwndOrg =
NULL;
02545 pdce->
pwndClip =
NULL;
02546 pdce->
hrgnClip =
NULL;
02547
02548
02549
02550
02551
02552
02553
02554 GreSelectVisRgn(pdce->
hdc,
NULL, SVR_DELETEOLD);
02555 GreUnlockDisplay(
gpDispInfo->
hDev);
02556
02557 }
else if (
TestCF(pwnd,
CFOWNDC)) {
02558
DestroyCacheDC(ppdce, pdce->
hdc);
02559 }
else {
02560 UserAssert(
FALSE);
02561 }
02562
02563 }
else {
02564
02565
02566
02567
02568
02569
02570
02571
02572
02573
02574
02575 uDCERelease =
DCE_RELEASED;
02576
02577
if (pdce->
DCX_flags & DCX_INUSE) {
02578 uDCERelease =
ReleaseCacheDC(pdce->
hdc,
FALSE);
02579 }
else if (!GreSetDCOwner(pdce->
hdc, OBJECT_OWNER_NONE)) {
02580 uDCERelease =
DCE_NORELEASE;
02581 }
02582
02583
if (uDCERelease !=
DCE_FREED) {
02584
02585
if (uDCERelease ==
DCE_NORELEASE) {
02586
02587
02588
02589
02590
02591
02592
02593
02594
02595
02596
02597
02598
02599 pdce->
DCX_flags = DCX_DESTROYTHIS | DCX_INUSE | DCX_CACHE;
02600 pti->
ppi->W32PF_Flags |= W32PF_OWNDCCLEANUP;
02601
02602 }
else {
02603
02604
02605
02606
02607
02608
02609
MarkDCEInvalid(pdce);
02610 pdce->
hrgnClip =
NULL;
02611 }
02612
02613
02614
02615
02616
02617
02618
02619 pdce->
pwndOrg =
NULL;
02620 pdce->
pwndClip =
NULL;
02621
02622
02623
02624
02625
02626
02627
02628 GreLockDisplay(
gpDispInfo->
hDev);
02629 GreSelectVisRgn(pdce->
hdc,
NULL, SVR_DELETEOLD);
02630 GreUnlockDisplay(
gpDispInfo->
hDev);
02631 }
02632 }
02633 }
02634
02635
02636
02637
02638
02639
if (pdce == *ppdce)
02640 NextEntry:
02641 ppdce = &pdce->
pdceNext;
02642 }
02643
02644
02645
02646
02647
if (pwnd ==
gspwndLockUpdate) {
02648
FreeSpb(
FindSpb(pwnd));
02649
Unlock(&
gspwndLockUpdate);
02650
gptiLockUpdate =
NULL;
02651 }
02652
02653
if (
TestWF(pwnd,
WFHASSPB)) {
02654
FreeSpb(
FindSpb(pwnd));
02655 }
02656
02657
02658
02659
02660
02661
02662
if ( pwnd->
hrgnClip !=
NULL &&
02663 !
TestWF(pwnd,
WFMAXFAKEREGIONAL) &&
02664
GETFNID(pwnd) !=
FNID_DESKTOP) {
02665
02666 GreDeleteObject(pwnd->
hrgnClip);
02667 pwnd->
hrgnClip =
NULL;
02668 }
02669
02670
02671
02672
02673
if (pwnd->
pSBInfo) {
02674
DesktopFree(pwnd->
head.rpdesk, (HANDLE)(pwnd->
pSBInfo));
02675 pwnd->
pSBInfo =
NULL;
02676 }
02677
02678
02679
02680
02681
02682
02683
02684
02685
02686
02687
02688
if (pwnd->
strName.
Buffer !=
NULL) {
02689
DesktopFree(pwnd->
head.rpdesk, pwnd->
strName.
Buffer);
02690 pwnd->
strName.
Buffer =
NULL;
02691 pwnd->
strName.
Length = 0;
02692 }
02693
02694
02695
02696
02697
if (pwnd->
ppropList !=
NULL) {
02698
TL tlpDdeConv;
02699
PDDECONV pDdeConv;
02700
PDDEIMP pddei;
02701
02702
02703
02704
02705
DestroyWindowSmIcon(pwnd);
02706
InternalRemoveProp(pwnd,
MAKEINTATOM(
gpsi->
atomIconProp),
PROPF_INTERNAL);
02707
02708 pDdeConv = (
PDDECONV)
_GetProp(pwnd,
PROP_DDETRACK,
PROPF_INTERNAL);
02709
if (pDdeConv !=
NULL) {
02710
ThreadLockAlwaysWithPti(pti, pDdeConv, &tlpDdeConv);
02711
xxxDDETrackWindowDying(pwnd, pDdeConv);
02712
ThreadUnlock(&tlpDdeConv);
02713 }
02714 pddei = (
PDDEIMP)
InternalRemoveProp(pwnd,
PROP_DDEIMP,
PROPF_INTERNAL);
02715
if (pddei !=
NULL) {
02716 pddei->
cRefInit = 0;
02717
if (pddei->
cRefConv == 0) {
02718
02719
02720
02721
02722 UserFreePool(pddei);
02723 }
02724 }
02725 }
02726
02727
02728
02729
02730
02731
02732
02733
02734
02735
02736
02737
02738
02739
02740
02741
if (pwnd->
head.rpdesk !=
NULL &&
02742 pwnd != pwnd->
head.rpdesk->pDeskInfo->spwnd)
02743
Lock(&pwnd->
spwndParent, pwnd->
head.rpdesk->pDeskInfo->spwnd);
02744
else
02745
Unlock(&pwnd->
spwndParent);
02746
02747
Unlock(&pwnd->
spwndChild);
02748
Unlock(&pwnd->
spwndOwner);
02749
Unlock(&pwnd->
spwndLastActive);
02750
02751
02752
02753
02754
DereferenceClass(pwnd);
02755
02756
02757
02758
02759
02760
02761
02762
HMMarkObjectDestroy(pwnd);
02763
HMPheFromObject(pwnd)->bFlags |=
HANDLEF_INDESTROY;
02764
02765
02766
02767
02768
02769
02770
if (!
ThreadUnlock(ptlpwndFree))
02771
return;
02772
02773
02774
02775
02776
02777
02778
02779
02780
02781 pwnd->
pcls =
NULL;
02782
if (
HMMarkObjectDestroy(pwnd)) {
02783
02784
02785
02786
02787
02788
if (pwnd->
ppropList !=
NULL) {
02789
DeleteProperties(pwnd);
02790 }
02791
02792
#if DBG
02793
02794
02795
02796
02797
02798
02799
if (
TestWF(pwnd,
WFINDESTROY) &&
TestWF(pwnd,
WFVISIBLE))
02800 RIPMSG1(RIP_ERROR,
"xxxFreeWindow: Window should not be visible (pwnd == %#p)", pwnd);
02801
#endif
02802
02803 pti->
cWindows--;
02804
02805
02806
02807
02808
02809
Unlock(&pwnd->
spwndParent);
02810
02811
ThreadLockDesktop(pti, pwnd->
head.rpdesk, &tlpdesk, LDLT_FN_FREEWINDOW);
02812
HMFreeObject(pwnd);
02813
ThreadUnlockDesktop(pti, &tlpdesk, LDUT_FN_FREEWINDOW);
02814
return;
02815 }
02816
02817
02818
02819
02820
02821
02822 pwnd->
lpfnWndProc =
xxxDefWindowProc;
02823
if (pwnd->
head.rpdesk)
02824 ppi = pwnd->
head.rpdesk->rpwinstaParent->pTerm->ptiDesktop->ppi;
02825
else
02826 ppi =
PpiCurrent();
02827 ppcls =
GetClassPtr(
gpsi->
atomSysClass[
ICLS_ICONTITLE], ppi,
hModuleWin);
02828
02829 UserAssert(ppcls);
02830 pwnd->
pcls = *ppcls;
02831
02832
02833
02834
02835
02836
02837
02838
02839
02840 pwnd->
pcls->
cWndReferenceCount++;
02841
02842
SetWF(pwnd,
WFSERVERSIDEPROC);
02843
02844
02845
02846
02847
02848
ClrWF(pwnd,
WFHASPALETTE);
02849
02850
02851
02852
02853
02854
02855
ClrWF(pwnd,
WFTYPEMASK);
02856
SetWF(pwnd,
WFTILED);
02857 pwnd->
spmenu =
NULL;
02858 }
02859
02860
02861
02862
02863
02864
02865
02866
02867 VOID UnlinkWindow(
02868
PWND pwndUnlink,
02869
PWND pwndParent)
02870 {
02871
PWND pwnd;
02872
02873 pwnd = pwndParent->
spwndChild;
02874
02875
if (pwnd == pwndUnlink) {
02876
Lock(&(pwndParent->
spwndChild), pwndUnlink->
spwndNext);
02877
Unlock(&pwndUnlink->
spwndNext);
02878
02879
#if DBG
02880
VerifyWindowLink (pwnd, pwndParent,
FALSE);
02881
#endif
02882
02883
return;
02884 }
02885
02886
while (pwnd !=
NULL) {
02887 UserAssert(pwnd->
spwndParent == pwndParent);
02888
if (pwnd->
spwndNext == pwndUnlink) {
02889
Lock(&(pwnd->
spwndNext), pwndUnlink->
spwndNext);
02890
Unlock(&pwndUnlink->
spwndNext);
02891
02892
#if DBG
02893
VerifyWindowLink (pwnd, pwndParent,
FALSE);
02894
#endif
02895
return;
02896 }
02897
02898 pwnd = pwnd->
spwndNext;
02899 }
02900
02901
02902
02903
02904 RIPMSG1(RIP_WARNING,
02905
"Unlinking previously unlinked window %#p\n",
02906 pwndUnlink);
02907
02908
#if DBG
02909
VerifyWindowLink (pwnd, pwndParent,
FALSE);
02910
#endif
02911
02912
return;
02913 }
02914
02915
02916
02917
02918
02919
02920
02921
02922
02923 VOID DestroyCacheDCEntries(
02924
PTHREADINFO pti)
02925 {
02926
PDCE *ppdce;
02927
PDCE pdce;
02928
02929
02930
02931
02932
02933
02934
02935
for (ppdce = &
gpDispInfo->
pdceFirst; *ppdce !=
NULL; ) {
02936
02937
02938
02939
02940
02941
02942
02943
02944
02945
02946 pdce = *ppdce;
02947
if (pti == pdce->
ptiOwner) {
02948
02949
if (pdce->
DCX_flags & DCX_CACHE)
02950
DestroyCacheDC(ppdce, pdce->
hdc);
02951 }
02952
02953
02954
02955
02956
02957
if (pdce == *ppdce)
02958 ppdce = &pdce->
pdceNext;
02959 }
02960 }
02961
02962
02963
02964
02965
02966
02967
02968
02969
02970
02971
02972 VOID PatchThreadWindows(
02973
PTHREADINFO pti)
02974 {
02975
PHE pheT;
02976
PHE pheMax;
02977
PWND pwnd;
02978
02979
02980
02981
02982
02983 pheMax = &
gSharedInfo.
aheList[
giheLast];
02984
for (pheT =
gSharedInfo.
aheList; pheT <= pheMax; pheT++) {
02985
02986
02987
02988
02989
02990
if (pheT->
bType !=
TYPE_WINDOW)
02991
continue;
02992
02993
if (pheT->
bFlags &
HANDLEF_DESTROY)
02994
continue;
02995
02996
if ((
PTHREADINFO)pheT->
pOwner != pti)
02997
continue;
02998
02999
03000
03001
03002
if (pti->
rpdesk && (
PHEAD)pti->
rpdesk->
spwndMenu == pheT->
phead) {
03003
03004 ((
PTHROBJHEAD)pheT->
phead)->pti = pti->
rpdesk->
pDeskInfo->
spwnd->
head.pti;
03005 pheT->
pOwner = pti->
rpdesk->
pDeskInfo->
spwnd->
head.pti;
03006
03007
continue;
03008 }
03009
03010
03011
03012
03013
03014
03015
03016
03017 pwnd = (
PWND)pheT->
phead;
03018
03019
if ((pwnd->fnid >= (WORD)
FNID_WNDPROCSTART) &&
03020 (pwnd->fnid <= (WORD)
FNID_WNDPROCEND)) {
03021
03022 pwnd->
lpfnWndProc =
STOCID(pwnd->fnid);
03023
03024
if (pwnd->
lpfnWndProc ==
NULL)
03025 pwnd->
lpfnWndProc =
xxxDefWindowProc;
03026
03027 }
else {
03028
03029 pwnd->
lpfnWndProc =
xxxDefWindowProc;
03030 }
03031
03032
03033
03034
03035
SetWF(pwnd,
WFSERVERSIDEPROC);
03036
ClrWF(pwnd,
WFANSIPROC);
03037 }
03038 }