Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

dwp.c

Go to the documentation of this file.
00001 /****************************** Module Header ******************************\ 00002 * Module Name: dwp.c 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * This module contains xxxDefWindowProc and related functions. 00007 * 00008 * History: 00009 * 10-22-90 DarrinM Created stubs. 00010 * 13-Feb-1991 mikeke Added Revalidation code 00011 \***************************************************************************/ 00012 00013 #include "precomp.h" 00014 #pragma hdrstop 00015 00016 /***************************************************************************\ 00017 * 00018 * DWP_DrawItem() 00019 * 00020 * Does default WM_DRAWITEM handling. 00021 * 00022 \***************************************************************************/ 00023 00024 void DWP_DrawItem( 00025 LPDRAWITEMSTRUCT lpdis) 00026 { 00027 if (lpdis->CtlType == ODT_LISTBOX) { 00028 /* 00029 * Default OwnerDraw Listbox Item Drawing 00030 */ 00031 if ( (lpdis->itemAction == ODA_FOCUS) 00032 || ( lpdis->itemAction == ODA_DRAWENTIRE 00033 && lpdis->itemState & ODS_FOCUS) 00034 ) { 00035 ClientFrame(lpdis->hDC, &lpdis->rcItem, gpsi->hbrGray, PATINVERT); 00036 } 00037 } 00038 } 00039 00040 00041 /***************************************************************************\ 00042 * xxxDWP_SetRedraw 00043 * 00044 * This routine sets/resets the VISIBLE flag for windows who don't want any 00045 * redrawing. Although a fast way of preventing paints, it is the apps 00046 * responsibility to reset this flag once they need painting. Otherwise, 00047 * the window will be rendered transparent (could leave turds on the 00048 * screen). 00049 * 00050 * 00051 * History: 00052 * 07-24-91 darrinm Ported from Win 3.1 sources. 00053 \***************************************************************************/ 00054 00055 void xxxDWP_SetRedraw( 00056 PWND pwnd, 00057 BOOL fRedraw) 00058 { 00059 CheckLock(pwnd); 00060 UserAssert(IsWinEventNotifyDeferredOK()); 00061 00062 if (fRedraw) { 00063 if (!TestWF(pwnd, WFVISIBLE)) { 00064 SetVisible(pwnd, SV_SET); 00065 00066 /* 00067 * We made this window visible - if it is behind any SPBs, 00068 * then we need to go invalidate them. 00069 * 00070 * We do this AFTER we make the window visible, so that 00071 * SpbCheckHwnd won't ignore it. 00072 */ 00073 if (AnySpbs()) 00074 SpbCheckPwnd(pwnd); 00075 00076 /* 00077 * Now we need to invalidate/recalculate any affected cache entries 00078 * This call must be AFTER the window state change 00079 * No need to DeferWinEventNotify() since pwnd is threadlocked. 00080 */ 00081 zzzInvalidateDCCache(pwnd, IDC_DEFAULT); 00082 00083 /* 00084 * Because 3.1 sometimes doesn't draw window frames when 3.0 did, 00085 * we need to ensure that the frame gets drawn if the window is 00086 * later invalidated after a WM_SETREDRAW(TRUE) 00087 */ 00088 SetWF(pwnd, WFSENDNCPAINT); 00089 } 00090 } else { 00091 if (TestWF(pwnd, WFVISIBLE)) { 00092 00093 /* 00094 * Invalidate any SPBs. 00095 * 00096 * We do this BEFORE we make the window invisible, so 00097 * SpbCheckHwnd() won't ignore it. 00098 */ 00099 if (AnySpbs()) 00100 SpbCheckPwnd(pwnd); 00101 00102 /* 00103 * Clear WFVISIBLE and delete any update regions lying around. 00104 */ 00105 SetVisible(pwnd, SV_UNSET | (TestWF(pwnd, WFWIN31COMPAT) ? SV_CLRFTRUEVIS : 0)); 00106 00107 /* 00108 * Now we need to invalidate/recalc affected cache entries 00109 * This call must be AFTER the window state change 00110 * No need to DeferWinEventNotify() since we're about to return. 00111 */ 00112 zzzInvalidateDCCache(pwnd, IDC_DEFAULT); 00113 } 00114 } 00115 } 00116 00117 00118 /***************************************************************************\ 00119 * DWP_GetEnabledPopup 00120 * 00121 * History: 00122 * 10-28-90 MikeHar Ported from Windows. 00123 \***************************************************************************/ 00124 00125 PWND DWP_GetEnabledPopup( 00126 PWND pwndStart) 00127 { 00128 PWND pwndT, pwnd; 00129 PTHREADINFO ptiStart; 00130 00131 ptiStart = GETPTI(pwndStart); 00132 pwnd = pwndStart->spwndNext; 00133 00134 #ifdef SYSMODALWINDOWS 00135 if (gspwndSysModal) 00136 return NULL; 00137 #endif 00138 00139 /* 00140 * The user clicked on a window that is disabled. That window is pwndStart. 00141 * This loop is designed to evaluate what application this window is 00142 * associated with, and activate that "application", by finding what window 00143 * associated with that application can be activated. This is done by 00144 * enumerating top level windows, searching for a top level enabled 00145 * and visible ownee associated with this application. 00146 */ 00147 while (pwnd != pwndStart) { 00148 if (pwnd == NULL) { 00149 00150 /* 00151 * Warning! Win 3.1 had PWNDDESKTOP(pwndStart)->spwndChild 00152 * which could loop forever if pwndStart was a child window 00153 */ 00154 pwnd = pwndStart->spwndParent->spwndChild; 00155 continue; 00156 } 00157 00158 /* 00159 * We have two cases we need to watch out for here. The first is when 00160 * applications call AssociateThreadInput() to tie two threads 00161 * together to share input state. If the threads own the same queue, 00162 * then associate them together: this way, when two threads call 00163 * AttachThreadInput(), one created the main window, one created the 00164 * dialog window, when you click on the main window, they'll both 00165 * come to the top (rather than beeping). In this case we want to 00166 * compare queues. When Control Panel starts Setup in the Network 00167 * applet is one type of example of attached input. 00168 * 00169 * The second case is WOW apps. All wow apps have the same queue 00170 * so to retain Win 3.1 compatibility, we want to treat each app 00171 * as an individual task (Win 3.1 tests hqs), so we will compare 00172 * PTI's for WOW apps. 00173 * 00174 * To see this case start 16 bit notepad and 16 bit write. Do file 00175 * open on write and then give notepad the focus now click on write's 00176 * main window and the write file open dialog should activate. 00177 * 00178 * Another related case is powerpnt. This case is interesting because 00179 * it tests that we do not find another window to activate when nested 00180 * windows are up and you click on a owner's owner. Run Powerpnt, do 00181 * Edit-Insert-Picture and Object-Recolor Picture will bring up a 00182 * dialog with combos, drop down one of the color combo and then click 00183 * on powerpnt's main window - focus should stay with the dialogs 00184 * combo and it should stay dropped down. 00185 */ 00186 if (((ptiStart->TIF_flags & TIF_16BIT) && (GETPTI(pwnd) == ptiStart)) || 00187 (!(ptiStart->TIF_flags & TIF_16BIT) && (GETPTI(pwnd)->pq == ptiStart->pq))) { 00188 00189 if (!TestWF(pwnd, WFDISABLED) && TestWF(pwnd, WFVISIBLE)) { 00190 pwndT = pwnd->spwndOwner; 00191 00192 /* 00193 * If this window is the parent of a popup window, 00194 * bring up only one. 00195 */ 00196 while (pwndT) { 00197 if (pwndT == pwndStart) 00198 return pwnd; 00199 00200 pwndT = pwndT->spwndOwner; 00201 } 00202 00203 /* 00204 * Win9x continues looping only if pwnd is WEFTOPMOST. NT4 just returns, like Win3.1 00205 * As soon as we find a window on the queue, we stop. So if the queue owns 00206 * multiple top level unowned windows, then this code will probably not find 00207 * the enabled popup. Note that owned windows are supposed to be on top of the 00208 * owner, usally right on top of it (ie, pwnd->spwndNext == pwnd->spwndOwner) 00209 * so this code used to find any other top level unowned windows before the enabled 00210 * popup and bail. Odd. 00211 * So let's continue looping. Hopefully this won't cause any compatibility problems 00212 */ 00213 // return NULL; 00214 } 00215 } 00216 pwnd = pwnd->spwndNext; 00217 } 00218 00219 return NULL; 00220 } 00221 /***************************************************************************\ 00222 * xxxDWP_ProcessVirtKey 00223 * 00224 * History: 00225 * 10-28-90 MikeHar Ported from Windows. 00226 \***************************************************************************/ 00227 00228 void xxxDWP_ProcessVirtKey( 00229 UINT wKey) 00230 { 00231 PTHREADINFO pti; 00232 TL tlpwndActive; 00233 00234 pti = PtiCurrent(); 00235 if (pti->pq->spwndActive == NULL) 00236 return; 00237 00238 switch (wKey) { 00239 00240 case VK_F4: 00241 if (TestCF(pti->pq->spwndActive, CFNOCLOSE)) 00242 break; 00243 00244 /* 00245 * Don't change the focus if the child window has it. 00246 */ 00247 if (pti->pq->spwndFocus == NULL || 00248 GetTopLevelWindow(pti->pq->spwndFocus) != 00249 pti->pq->spwndActive) { 00250 ThreadLockAlwaysWithPti(pti, pti->pq->spwndActive, &tlpwndActive); 00251 xxxSetFocus(pti->pq->spwndActive); 00252 ThreadUnlock(&tlpwndActive); 00253 } 00254 _PostMessage(pti->pq->spwndActive, WM_SYSCOMMAND, SC_CLOSE, 0L); 00255 break; 00256 00257 case VK_TAB: 00258 /* 00259 * If alt-tab is reserved by console, don't bring up the alt-tab 00260 * window. 00261 */ 00262 if (GETPTI(pti->pq->spwndActive)->fsReserveKeys & CONSOLE_ALTTAB) 00263 break; 00264 00265 case VK_ESCAPE: 00266 case VK_F6: 00267 ThreadLockAlwaysWithPti(pti, pti->pq->spwndActive, &tlpwndActive); 00268 xxxSendMessage(pti->pq->spwndActive, WM_SYSCOMMAND, 00269 (UINT)(_GetKeyState(VK_SHIFT) < 0 ? SC_NEXTWINDOW : SC_PREVWINDOW), 00270 (LONG)(DWORD)(WORD)wKey); 00271 ThreadUnlock(&tlpwndActive); 00272 break; 00273 } 00274 } 00275 00276 00277 /***************************************************************************\ 00278 * xxxDWP_Paint 00279 * 00280 * Handle WM_PAINT and WM_PAINTICON messages. 00281 * 00282 * History: 00283 * 07-24-91 darrinm Ported from Win 3.1 sources. 00284 \***************************************************************************/ 00285 00286 void xxxDWP_Paint( 00287 PWND pwnd) 00288 { 00289 PAINTSTRUCT ps; 00290 00291 CheckLock(pwnd); 00292 00293 /* 00294 * Bad handling of a WM_PAINT message, the application called 00295 * BeginPaint/EndPaint and is now calling DefWindowProc for the same 00296 * WM_PAINT message. Just return so we don't get full drag problems. 00297 * (Word and Excel do this). 00298 * 00299 * Added the check for empty-client-rects. ObjectVision has a problem 00300 * with empty-windows being invalidated during a full-drag. They used 00301 * to get blocked at the STARTPAINT and couldn't get through to 00302 * xxxBeginPaint to validate their update-rgn. 00303 * 00304 * i.e. 00305 * a) Parent has a child-window with an empty rect. On a full 00306 * drag of the parent, we process SetWindowPos() to paint 00307 * the new position. 00308 * 00309 * b) During the parents processing of WM_PAINT, it calls 00310 * GetUpdateRect() on the empty-child, which sets the STARTPAINT 00311 * on its window. 00312 * 00313 * c) On return to the parent WM_PAINT handler, it calls 00314 * UpdateWindow() on the child, and used to get blocked here 00315 * because the STARTPAINT bit was set. The Child never gets 00316 * updated, causing an infinite loop. 00317 * 00318 * *) By checking for an empty-rectangle, we will let it through 00319 * to validate. 00320 * 00321 */ 00322 if (TestWF(pwnd, WFSTARTPAINT) && !IsRectEmpty(&(pwnd->rcClient))) { 00323 return; 00324 } 00325 00326 if (xxxBeginPaint(pwnd, &ps)) { 00327 xxxEndPaint(pwnd, &ps); 00328 } 00329 } 00330 00331 00332 /***************************************************************************\ 00333 * xxxDWP_EraseBkgnd 00334 * 00335 * 00336 * History: 00337 * 07-24-91 darrinm Ported from Win 3.1 sources. 00338 \***************************************************************************/ 00339 00340 BOOL xxxDWP_EraseBkgnd( 00341 PWND pwnd, 00342 UINT msg, 00343 HDC hdc) 00344 { 00345 HBRUSH hbr; 00346 00347 CheckLock(pwnd); 00348 00349 switch (msg) { 00350 case WM_ICONERASEBKGND: 00351 // 00352 // Old compatibility: Many hack apps use this to paint the 00353 // desktop wallpaper. We never send WM_ICONERASEBKGND anymore 00354 // because we don't have client areas in our minimized windows. 00355 // 00356 if (!TestWF(pwnd, WFCHILD)) { 00357 xxxInternalPaintDesktop(pwnd, hdc, TRUE); 00358 } else { 00359 return FALSE; 00360 } 00361 break; 00362 00363 case WM_ERASEBKGND: 00364 if (hbr = pwnd->pcls->hbrBackground) { 00365 // Convert sys colors to proper brush 00366 if (hbr <= (HBRUSH)COLOR_MAX) 00367 hbr = SYSHBRUSH((ULONG_PTR)hbr - 1); 00368 00369 /* 00370 * Remove call to UnrealizeObject. GDI handles this 00371 * for brushes on NT. 00372 * 00373 * if (hbr != SYSHBR(DESKTOP)) 00374 * GreUnrealizeObject(hbr); 00375 */ 00376 00377 xxxFillWindow(pwnd, pwnd, hdc, hbr); 00378 } else { 00379 return FALSE; 00380 } 00381 } 00382 return TRUE; 00383 } 00384 00385 00386 /***************************************************************************\ 00387 * xxxDWP_SetCursorInfo 00388 * 00389 * 00390 * History: 00391 * 26-Apr-1994 mikeke Created 00392 \***************************************************************************/ 00393 00394 /***************************************************************************\ 00395 * xxxDWP_SetCursor 00396 * 00397 * 00398 * History: 00399 * 07-24-91 darrinm Ported from Win 3.1 sources. 00400 \***************************************************************************/ 00401 00402 BOOL xxxDWP_SetCursor( 00403 PWND pwnd, 00404 HWND hwndHit, 00405 int codeHT, 00406 UINT msg) 00407 { 00408 PWND pwndParent, pwndPopup, pwndHit; 00409 PCURSOR pcur; 00410 LRESULT lt; 00411 TL tlpwndParent; 00412 TL tlpwndPopup; 00413 00414 CheckLock(pwnd); 00415 UserAssert(IsWinEventNotifyDeferredOK()); 00416 00417 /* 00418 * wParam == pwndHit == pwnd that cursor is over 00419 * lParamL == ht == Hit test area code (result of WM_NCHITTEST) 00420 * lParamH == msg == Mouse message number 00421 */ 00422 if (msg) 00423 { 00424 switch (codeHT) 00425 { 00426 case HTLEFT: 00427 case HTRIGHT: 00428 pcur = SYSCUR(SIZEWE); 00429 break; 00430 case HTTOP: 00431 case HTBOTTOM: 00432 pcur = SYSCUR(SIZENS); 00433 break; 00434 case HTTOPLEFT: 00435 case HTBOTTOMRIGHT: 00436 pcur = SYSCUR(SIZENWSE); 00437 break; 00438 case HTTOPRIGHT: 00439 case HTBOTTOMLEFT: 00440 pcur = SYSCUR(SIZENESW); 00441 break; 00442 00443 default: 00444 goto NotSize; 00445 } 00446 00447 pwndHit = RevalidateHwnd(hwndHit); 00448 if (pwndHit == NULL) 00449 return FALSE; 00450 00451 if (TestWF(pwndHit, WFSYSMENU)) { 00452 TL tlpwndHit; 00453 DWORD dwState; 00454 00455 ThreadLockAlways(pwndHit, &tlpwndHit); 00456 dwState = _GetMenuState( 00457 xxxGetSysMenu(pwndHit, TRUE), SC_SIZE, MF_BYCOMMAND); 00458 ThreadUnlock(&tlpwndHit); 00459 00460 if ((dwState != (DWORD) -1) && (dwState & MFS_GRAYED)) 00461 goto UseNormalCursor; 00462 } 00463 /* 00464 * No need to DeferWinEventNotify() - we're about to return 00465 */ 00466 zzzSetCursor(pcur); 00467 return TRUE; 00468 } 00469 00470 NotSize: 00471 00472 pwndParent = GetChildParent(pwnd); 00473 00474 /* 00475 * Some windows (like the list boxes of comboboxes), are marked with 00476 * the child bit but are actually child of the desktop (can happen 00477 * if you call SetParent()). Make this special case check for 00478 * the desktop here. 00479 */ 00480 if (pwndParent == PWNDDESKTOP(pwnd)) 00481 pwndParent = NULL; 00482 00483 if (pwndParent != NULL) { 00484 ThreadLockAlways(pwndParent, &tlpwndParent); 00485 lt = xxxSendMessage(pwndParent, WM_SETCURSOR, (WPARAM)hwndHit, 00486 MAKELONG(codeHT, msg)); 00487 ThreadUnlock(&tlpwndParent); 00488 if (lt != 0) 00489 return TRUE; 00490 } 00491 00492 if (msg == 0) { 00493 /* 00494 * No need to DeferWinEventNotify() - we're about to return 00495 */ 00496 zzzSetCursor(SYSCUR(ARROW)); 00497 00498 } else { 00499 pwndHit = RevalidateHwnd(hwndHit); 00500 if (pwndHit == NULL) 00501 return FALSE; 00502 00503 switch (codeHT) { 00504 case HTCLIENT: 00505 if (pwndHit->pcls->spcur != NULL) { 00506 /* 00507 * No need to DeferWinEventNotify() - we're about to return 00508 */ 00509 zzzSetCursor(pwndHit->pcls->spcur); 00510 } 00511 break; 00512 00513 case HTERROR: 00514 switch (msg) { 00515 case WM_MOUSEMOVE: 00516 if (TestUP(ACTIVEWINDOWTRACKING)) { 00517 xxxActiveWindowTracking(pwnd, WM_SETCURSOR, codeHT); 00518 } 00519 break; 00520 00521 case WM_LBUTTONDOWN: 00522 if ((pwndPopup = DWP_GetEnabledPopup(pwnd)) != NULL) { 00523 if (pwndPopup != PWNDDESKTOP(pwnd)->spwndChild) { 00524 PWND pwndActiveOld; 00525 00526 pwndActiveOld = PtiCurrent()->pq->spwndActive; 00527 00528 ThreadLockAlways(pwndPopup, &tlpwndPopup); 00529 00530 xxxSetWindowPos(pwnd, NULL, 0, 0, 0, 0, 00531 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); 00532 00533 xxxSetActiveWindow(pwndPopup); 00534 00535 ThreadUnlock(&tlpwndPopup); 00536 00537 if (pwndActiveOld != PtiCurrent()->pq->spwndActive) 00538 break; 00539 00540 /* 00541 *** ELSE FALL THRU ** 00542 */ 00543 } 00544 } 00545 00546 /* 00547 *** FALL THRU ** 00548 */ 00549 00550 case WM_RBUTTONDOWN: 00551 case WM_MBUTTONDOWN: 00552 case WM_XBUTTONDOWN: 00553 { 00554 PWND pwndDlg; 00555 00556 pwndDlg = DWP_GetEnabledPopup(pwnd); 00557 00558 if (pwndDlg != NULL) { 00559 00560 ThreadLockAlways(pwndDlg, &tlpwndPopup); 00561 00562 xxxFlashWindow(pwndDlg, 00563 MAKELONG(FLASHW_ALL, UP(FOREGROUNDFLASHCOUNT)), 00564 (gpsi->dtCaretBlink >> 3)); 00565 00566 ThreadUnlock(&tlpwndPopup); 00567 } 00568 00569 xxxMessageBeep(0); 00570 00571 break; 00572 } 00573 } 00574 00575 /* 00576 *** FALL THRU ** 00577 */ 00578 00579 default: 00580 UseNormalCursor: 00581 /* 00582 * No need to DeferWinEventNotify() - we're about to return 00583 */ 00584 zzzSetCursor(SYSCUR(ARROW)); 00585 break; 00586 } 00587 } 00588 00589 return FALSE; 00590 } 00591 00592 00593 /***************************************************************************\ 00594 * xxxDWP_NCMouse 00595 * 00596 * 00597 * History: 00598 * 07-24-91 darrinm Ported from Win 3.1 sources. 00599 \***************************************************************************/ 00600 00601 void xxxDWP_NCMouse( 00602 PWND pwnd, 00603 UINT msg, 00604 UINT ht, 00605 LPARAM lParam) 00606 { 00607 UINT cmd; 00608 00609 CheckLock(pwnd); 00610 00611 cmd = 0; 00612 switch (msg) { 00613 case WM_NCLBUTTONDOWN: 00614 00615 switch (ht) { 00616 case HTZOOM: 00617 case HTREDUCE: 00618 case HTCLOSE: 00619 case HTHELP: 00620 cmd = xxxTrackCaptionButton(pwnd, ht); 00621 break; 00622 00623 default: 00624 // Change into a MV/SZ command 00625 if (ht >= HTSIZEFIRST && ht <= HTSIZELAST) 00626 cmd = SC_SIZE + (ht - HTSIZEFIRST + WMSZ_SIZEFIRST); 00627 break; 00628 } 00629 00630 if (cmd != 0) { 00631 // 00632 // For SysCommands on system menu, don't do if menu item is 00633 // disabled. 00634 // 00635 if ( cmd != SC_CONTEXTHELP 00636 && TestWF(pwnd, WFSYSMENU) 00637 && !TestwndChild(pwnd) 00638 ) { 00639 if (_GetMenuState(xxxGetSysMenu(pwnd, TRUE), cmd & 0xFFF0, 00640 MF_BYCOMMAND) & MFS_GRAYED) 00641 break; 00642 } 00643 00644 xxxSendMessage(pwnd, WM_SYSCOMMAND, cmd, lParam); 00645 break; 00646 } 00647 // FALL THRU 00648 00649 case WM_NCLBUTTONUP: 00650 case WM_NCLBUTTONDBLCLK: 00651 xxxHandleNCMouseGuys(pwnd, msg, ht, lParam); 00652 break; 00653 } 00654 } 00655 00656 /***************************************************************************\ 00657 * 00658 * History: 00659 * 09-Mar-1992 mikeke From win3.1 00660 \***************************************************************************/ 00661 00662 UINT AreNonClientAreasToBePainted( 00663 PWND pwnd) 00664 { 00665 WORD wRetValue = 0; 00666 00667 /* 00668 * Check if Active and Inactive captions have same color 00669 */ 00670 if (SYSRGB(ACTIVECAPTION) != SYSRGB(INACTIVECAPTION) || 00671 SYSRGB(CAPTIONTEXT) != SYSRGB(INACTIVECAPTIONTEXT)) { 00672 wRetValue = DC_CAPTION; 00673 } 00674 00675 /* 00676 * We want to repaint the borders if we're not minimized and 00677 * we have a sizing border and the active/inactive colors are 00678 * different. 00679 */ 00680 if (!TestWF(pwnd, WFMINIMIZED) && TestWF(pwnd, WFSIZEBOX) && 00681 (SYSRGB(ACTIVEBORDER) != SYSRGB(INACTIVEBORDER))) { 00682 // We need to redraw the sizing border. 00683 wRetValue |= DC_FRAME; 00684 } 00685 00686 return wRetValue; 00687 } 00688 00689 /***************************************************************************\ 00690 * 00691 * History: 00692 * 09-Mar-1992 mikeke From win3.1 00693 * 07-Aug-1996 vadimg Added menu grayout and underline code 00694 \***************************************************************************/ 00695 00696 VOID xxxDWP_DoNCActivate( 00697 PWND pwnd, 00698 DWORD dwFlags, 00699 HRGN hrgnClip) 00700 { 00701 UINT wFlags = DC_CAPTION; 00702 00703 CheckLock(pwnd); 00704 00705 /* 00706 * Later5.0 Gerardob. Since activation must follow focus, modeless 00707 * menu windows are activated so they can receive keyboard input; 00708 * however, we want the notification frame on, even when inactive. 00709 * (so it looks just like regular menus). 00710 * There are other scenarios when we want focus and activation on 00711 * different parent-child chains so we should consider allowing this. 00712 */ 00713 if ((dwFlags & NCA_ACTIVE) 00714 || (!(dwFlags & NCA_FORCEFRAMEOFF) 00715 && IsModelessMenuNotificationWindow(pwnd))) { 00716 00717 SetWF(pwnd, WFFRAMEON); 00718 wFlags |= DC_ACTIVE; 00719 } else { 00720 00721 ClrWF(pwnd, WFFRAMEON); 00722 } 00723 00724 if (TestWF(pwnd, WFVISIBLE) && !TestWF(pwnd, WFNONCPAINT)) { 00725 00726 HDC hdc; 00727 WORD wBorderOrCap = (WORD)AreNonClientAreasToBePainted(pwnd); 00728 00729 if (wBorderOrCap) { 00730 00731 /* 00732 * Validate and Copy the region for our use. Since we 00733 * hand this off to GetWindowDC() we won't have to delete 00734 * the region (done in ReleaseDC()). Regardless, the region 00735 * passed in from the user is its responsibility to delete. 00736 */ 00737 hrgnClip = UserValidateCopyRgn(hrgnClip); 00738 00739 if (hdc = _GetDCEx(pwnd, hrgnClip, DCX_WINDOW | DCX_USESTYLE)) { 00740 /* 00741 * Draw the menu for grayout and underlines 00742 */ 00743 if (TestWF(pwnd, WFMPRESENT)) { 00744 int cxFrame, cyFrame; 00745 cxFrame = cyFrame = GetWindowBorders(pwnd->style, 00746 pwnd->ExStyle, TRUE, FALSE); 00747 cxFrame *= SYSMET(CXBORDER); 00748 cyFrame *= SYSMET(CYBORDER); 00749 xxxMenuBarDraw(pwnd, hdc, cxFrame, cyFrame); 00750 } 00751 xxxDrawCaptionBar(pwnd, hdc, wBorderOrCap | wFlags); 00752 _ReleaseDC(hdc); 00753 } else { 00754 GreDeleteObject(hrgnClip); 00755 } 00756 } 00757 } 00758 } 00759 00760 /***************************************************************************\ 00761 * 00762 * History: 00763 * 09-Mar-1992 mikeke From win3.1 00764 \***************************************************************************/ 00765 00766 BOOL xxxRedrawTitle( 00767 PWND pwnd, UINT wFlags) 00768 { 00769 BOOL fDrawn = TRUE; 00770 00771 CheckLock(pwnd); 00772 00773 if (TestWF(pwnd, WFVISIBLE)) { 00774 00775 if (TestWF(pwnd, WFBORDERMASK) == (BYTE)LOBYTE(WFCAPTION)) { 00776 00777 HDC hdc = _GetWindowDC(pwnd); 00778 if (TestwndFrameOn(pwnd)) 00779 wFlags |= DC_ACTIVE; 00780 xxxDrawCaptionBar(pwnd, hdc, wFlags); 00781 _ReleaseDC(hdc); 00782 } 00783 else 00784 fDrawn = FALSE; 00785 } 00786 00787 if ( IsTrayWindow(pwnd) && (wFlags & (DC_ICON | DC_TEXT)) ) { 00788 HWND hw = HWq(pwnd); 00789 xxxCallHook(HSHELL_REDRAW, (WPARAM)hw, 0L, WH_SHELL); 00790 PostShellHookMessages(HSHELL_REDRAW, (LPARAM)hw); 00791 00792 } 00793 return(fDrawn); 00794 } 00795 00796 /***************************************************************************\ 00797 * 00798 * History: 00799 * 09-Mar-1992 mikeke From win3.1 00800 \***************************************************************************/ 00801 00802 void xxxDWP_DoCancelMode( 00803 PWND pwnd) 00804 { 00805 PTHREADINFO pti = PtiCurrent(); 00806 PWND pwndCapture = pti->pq->spwndCapture; 00807 PMENUSTATE pMenuState; 00808 00809 /* 00810 * If the below menu lines are changed in any way, then SQLWin 00811 * won't work if in design mode you drop some text, double click on 00812 * it, then try to use the heirarchical menus. 00813 */ 00814 pMenuState = GetpMenuState(pwnd); 00815 if ((pMenuState != NULL) 00816 && (pwnd == pMenuState->pGlobalPopupMenu->spwndNotify) 00817 && !pMenuState->fModelessMenu) { 00818 00819 xxxEndMenu(pMenuState); 00820 } 00821 00822 if (pwndCapture == pwnd) { 00823 PSBTRACK pSBTrack = PWNDTOPSBTRACK(pwnd); 00824 if (pSBTrack && (pSBTrack->xxxpfnSB != NULL)) 00825 xxxEndScroll(pwnd, TRUE); 00826 00827 if (pti->pmsd != NULL) { 00828 pti->pmsd->fTrackCancelled = TRUE; 00829 pti->TIF_flags &= ~TIF_MOVESIZETRACKING; 00830 00831 /* 00832 * Also clip the cursor back to the whole screen 00833 * so we don't get confused in xxxMoveSize. 00834 * This fix bug 64166. 00835 */ 00836 zzzClipCursor((LPRECT)NULL); 00837 } 00838 00839 /* 00840 * If the capture is still set, just release at this point. 00841 */ 00842 xxxReleaseCapture(); 00843 } 00844 } 00845 00846 BOOL xxxDWPPrint( 00847 PWND pwnd, 00848 HDC hdc, 00849 LPARAM lParam) 00850 { 00851 POINT pt; 00852 int iDC; 00853 LPRECT lprc; 00854 PWND pwndSave = pwnd; 00855 LPARAM lParamSave = lParam; 00856 BOOL fNotVisible; 00857 PBWL pbwl; 00858 HWND *phwnd; 00859 TL tlpwnd; 00860 #ifdef USE_MIRRORING 00861 DWORD dwOldLayout; 00862 BOOL bMirrorDC; 00863 #endif 00864 int iMirrorOffset=0; 00865 00866 CheckLock(pwnd); 00867 00868 if ((lParam & PRF_CHECKVISIBLE) && !_IsWindowVisible(pwnd)) 00869 return(FALSE); 00870 00871 #ifdef USE_MIRRORING 00872 bMirrorDC = (TestWF(pwnd, WEFLAYOUTRTL) && !MIRRORED_HDC(hdc)); 00873 /* 00874 * If the DC will be mirrored then we shift the clip rect by one 00875 * to include the right most pixel 00876 */ 00877 if (bMirrorDC) 00878 iMirrorOffset=1; 00879 #endif 00880 00881 if (lParam & PRF_NONCLIENT) { 00882 00883 /* 00884 * draw non-client area first 00885 */ 00886 if (fNotVisible = !TestWF(pwnd, WFVISIBLE)) 00887 SetVisible(pwnd, SV_SET); 00888 00889 SetWF(pwnd, WFMENUDRAW); 00890 00891 #ifdef USE_MIRRORING 00892 if (bMirrorDC) { 00893 dwOldLayout = GreSetLayout(hdc, pwnd->rcWindow.right - pwnd->rcWindow.left, LAYOUT_RTL); 00894 xxxDrawWindowFrame(pwnd, hdc, FALSE, TestWF(pwnd, WFFRAMEON)); 00895 GreSetLayout(hdc, pwnd->rcWindow.right - pwnd->rcWindow.left, dwOldLayout); 00896 } else 00897 #endif 00898 { 00899 xxxDrawWindowFrame(pwnd, hdc, FALSE, TestWF(pwnd, WFFRAMEON)); 00900 } 00901 00902 ClrWF(pwnd, WFMENUDRAW); 00903 00904 if (fNotVisible) 00905 SetVisible(pwnd, SV_UNSET); 00906 } 00907 00908 if (lParam & PRF_CLIENT) { 00909 00910 /* 00911 * draw client area second 00912 */ 00913 iDC = GreSaveDC(hdc); 00914 GreGetWindowOrg(hdc, &pt); 00915 00916 if (lParam & PRF_NONCLIENT) { 00917 int xBorders, yBorders; 00918 00919 /* 00920 * adjust for non-client area 00921 */ 00922 xBorders = pwnd->rcClient.left - pwnd->rcWindow.left; 00923 yBorders = pwnd->rcClient.top - pwnd->rcWindow.top; 00924 GreSetWindowOrg(hdc, pt.x - xBorders, pt.y - yBorders, NULL); 00925 } 00926 00927 lprc = &pwnd->rcClient; 00928 GreIntersectClipRect(hdc, iMirrorOffset, 0, lprc->right - lprc->left + iMirrorOffset, lprc->bottom - lprc->top); 00929 00930 #ifdef USE_MIRRORING 00931 if (bMirrorDC) { 00932 dwOldLayout = GreSetLayout(hdc, pwnd->rcClient.right - pwnd->rcClient.left, LAYOUT_RTL); 00933 if (lParam & PRF_ERASEBKGND) 00934 xxxSendMessage(pwnd, WM_ERASEBKGND, (WPARAM) hdc, 0L); 00935 xxxSendMessage(pwnd, WM_PRINTCLIENT, (WPARAM) hdc, lParam); 00936 GreSetLayout(hdc, pwnd->rcClient.right - pwnd->rcClient.left, dwOldLayout); 00937 } else 00938 #endif 00939 { 00940 00941 if (lParam & PRF_ERASEBKGND) 00942 xxxSendMessage(pwnd, WM_ERASEBKGND, (WPARAM) hdc, 0L); 00943 xxxSendMessage(pwnd, WM_PRINTCLIENT, (WPARAM) hdc, lParam); 00944 } 00945 00946 GreRestoreDC(hdc, iDC); 00947 00948 pt.x += pwnd->rcWindow.left; 00949 pt.y += pwnd->rcWindow.top; 00950 00951 if (lParam & PRF_CHILDREN) { 00952 00953 /* 00954 * when drawing children, always include nonclient area 00955 */ 00956 lParam |= PRF_NONCLIENT | PRF_ERASEBKGND; 00957 00958 lParam &= ~PRF_CHECKVISIBLE; 00959 00960 /* 00961 * draw children last 00962 */ 00963 pbwl = BuildHwndList(pwnd->spwndChild, BWL_ENUMLIST, NULL); 00964 if (pbwl != NULL) { 00965 for (phwnd = pbwl->rghwnd; *phwnd != (HWND)1; phwnd++) { 00966 if ((pwnd = RevalidateHwnd(*phwnd)) == NULL) 00967 continue; 00968 00969 if (TestWF(pwnd, WFVISIBLE)) { 00970 lprc = &pwnd->rcWindow; 00971 iDC = GreSaveDC(hdc); 00972 GreSetWindowOrg(hdc, pt.x - lprc->left, pt.y - lprc->top, NULL); 00973 if (!TestCF(pwnd, CFPARENTDC)) { 00974 GreIntersectClipRect(hdc, 0, 0, lprc->right - lprc->left, lprc->bottom - lprc->top); 00975 } 00976 ThreadLockAlways(pwnd, &tlpwnd); 00977 xxxSendMessage(pwnd, WM_PRINT, (WPARAM) hdc, lParam); 00978 ThreadUnlock(&tlpwnd); 00979 GreRestoreDC(hdc, iDC); 00980 } 00981 } 00982 FreeHwndList(pbwl); 00983 } 00984 } 00985 00986 if (lParam & PRF_OWNED) { 00987 pbwl = BuildHwndList((PWNDDESKTOP(pwnd))->spwndChild, BWL_ENUMLIST, NULL); 00988 if (pbwl != NULL) { 00989 for (phwnd = pbwl->rghwnd; *phwnd != (HWND)1; phwnd++) { 00990 00991 if ((pwnd = RevalidateHwnd(*phwnd)) == NULL) 00992 continue; 00993 00994 if ((pwnd->spwndOwner == pwndSave) && TestWF(pwnd, WFVISIBLE)) { 00995 iDC = GreSaveDC(hdc); 00996 GreSetWindowOrg(hdc, pt.x - pwnd->rcWindow.left, pt.y - pwnd->rcWindow.top, NULL); 00997 ThreadLockAlways(pwnd, &tlpwnd); 00998 xxxSendMessage(pwnd, WM_PRINT, (WPARAM) hdc, lParamSave); 00999 ThreadUnlock(&tlpwnd); 01000 GreRestoreDC(hdc, iDC); 01001 } 01002 } 01003 FreeHwndList(pbwl); 01004 } 01005 } 01006 } 01007 01008 return TRUE; 01009 } 01010 01011 01012 01013 /***************************************************************************\ 01014 * 01015 * DWP_GetIcon() 01016 * 01017 * Gets the small or big icon for a window. For small icons, if we created 01018 * the thing, we don't let the app see it. 01019 * 01020 \***************************************************************************/ 01021 01022 HICON DWP_GetIcon( 01023 PWND pwnd, 01024 UINT uType) 01025 { 01026 HICON hicoTemp; 01027 01028 if (uType < ICON_SMALL || uType > ICON_BIG) 01029 { 01030 RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "WM_GETICON: Invalid wParam value (0x%X)", uType); 01031 return (HICON)NULL; 01032 } 01033 01034 /* 01035 * Get the icon from the window 01036 */ 01037 hicoTemp = (HICON)_GetProp(pwnd, 01038 MAKEINTATOM(uType == ICON_SMALL ? gpsi->atomIconSmProp : gpsi->atomIconProp), 01039 PROPF_INTERNAL); 01040 01041 /* 01042 * If it's a USER created small icon don't return it. 01043 */ 01044 if (uType == ICON_SMALL && hicoTemp) { 01045 PCURSOR pcurTemp; 01046 01047 pcurTemp = (PCURSOR)HMValidateHandleNoRip((HCURSOR)hicoTemp, TYPE_CURSOR); 01048 if (pcurTemp != NULL && (pcurTemp->CURSORF_flags & CURSORF_SECRET)) { 01049 hicoTemp = (HICON)NULL; 01050 } 01051 } 01052 01053 return hicoTemp; 01054 } 01055 01056 01057 /***************************************************************************\ 01058 * 01059 * DestroyWindowSmIcon() 01060 * 01061 * Destroys the small icon of a window if we've created a cached one. 01062 * This is because it's called in winrare.c when the caption height 01063 * changes. 01064 * 01065 \***************************************************************************/ 01066 01067 BOOL DestroyWindowSmIcon( 01068 PWND pwnd) 01069 { 01070 HCURSOR hcursor; 01071 PCURSOR pcursor; 01072 01073 // 01074 // Get the small icon property first... 01075 // 01076 hcursor = (HCURSOR)_GetProp(pwnd, MAKEINTATOM(gpsi->atomIconSmProp), PROPF_INTERNAL); 01077 if (hcursor == NULL) 01078 return FALSE; 01079 01080 pcursor = (PCURSOR)HMValidateHandleNoRip(hcursor, TYPE_CURSOR); 01081 if (pcursor == NULL) 01082 return FALSE; 01083 01084 // 01085 // Remove it if it's a secretly created one 01086 // 01087 01088 if (pcursor->CURSORF_flags & CURSORF_SECRET) 01089 { 01090 ClrWF(pwnd, WFSMQUERYDRAGICON); 01091 InternalRemoveProp(pwnd, MAKEINTATOM(gpsi->atomIconSmProp), PROPF_INTERNAL); 01092 _DestroyCursor(pcursor, CURSOR_ALWAYSDESTROY); 01093 return(TRUE); 01094 } 01095 else 01096 return(FALSE); 01097 } 01098 01099 01100 /***************************************************************************\ 01101 * 01102 * xxxDWP_SetIcon() 01103 * 01104 * Sets the small or big icon for a window, and returns back the previous 01105 * one. 01106 * 01107 \***************************************************************************/ 01108 01109 HICON xxxDWP_SetIcon( 01110 PWND pwnd, 01111 WPARAM wType, 01112 HICON hicoNew) 01113 { 01114 HICON hIcon; 01115 HICON hIconSm; 01116 HICON hOld; 01117 BOOL fRedraw; 01118 01119 CheckLock(pwnd); 01120 01121 #if DBG 01122 if (hicoNew && !IS_PTR(hicoNew)) { 01123 RIPMSG1(RIP_WARNING, "WM_SETICON: Icon handle missing HIWORD (0x%08X)", hicoNew); 01124 } 01125 #endif 01126 01127 if (wType < ICON_SMALL || wType > ICON_RECREATE) 01128 { 01129 RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "WM_SETICON: Invalid wParam value (0x%0X)", wType); 01130 return (HICON)NULL; 01131 } 01132 01133 /* 01134 * Regenerate small icons if requested. 01135 */ 01136 if (wType == ICON_RECREATE) { 01137 xxxRecreateSmallIcons(pwnd); 01138 return 0L; 01139 } 01140 01141 /* 01142 * Save old icon 01143 */ 01144 hIcon = (HICON)_GetProp(pwnd, MAKEINTATOM(gpsi->atomIconProp), PROPF_INTERNAL); 01145 hIconSm = (HICON)_GetProp(pwnd, MAKEINTATOM(gpsi->atomIconSmProp), PROPF_INTERNAL); 01146 hOld = ((wType == ICON_SMALL) ? hIconSm : hIcon); 01147 01148 /* 01149 * Only update the icons if they have changed 01150 */ 01151 if (hOld != hicoNew) 01152 { 01153 PCURSOR pcursor; 01154 BOOL fWasCache = FALSE; 01155 01156 fRedraw = TRUE; 01157 01158 /* 01159 * Always remove the small icon because it is either being replaced or 01160 * will be recreated if the big icon is being set. 01161 */ 01162 pcursor = (PCURSOR)HMValidateHandleNoRip(hIconSm, TYPE_CURSOR); 01163 if (pcursor && (pcursor->CURSORF_flags & CURSORF_SECRET)) { 01164 fWasCache = TRUE; 01165 _DestroyCursor(pcursor, CURSOR_ALWAYSDESTROY); 01166 } 01167 01168 if (wType == ICON_SMALL) { 01169 /* 01170 * Apps never see the icons that USER creates behind their backs 01171 * from big icons. 01172 */ 01173 if (fWasCache) 01174 hOld = NULL; 01175 01176 hIconSm = hicoNew; 01177 } else { 01178 if (fWasCache) { 01179 /* 01180 * Force us to recalc the small icon to match the new big icon 01181 */ 01182 hIconSm = NULL; 01183 } else if (hIconSm) { 01184 /* 01185 * Redraw of the caption isn't needed because the small icon 01186 * didn't change. 01187 */ 01188 fRedraw = FALSE; 01189 } 01190 01191 hIcon = hicoNew; 01192 } 01193 01194 01195 /* 01196 * Store the icons off the window as properties 01197 */ 01198 InternalSetProp(pwnd, MAKEINTATOM(gpsi->atomIconProp), (HANDLE)hIcon, PROPF_INTERNAL | PROPF_NOPOOL); 01199 InternalSetProp(pwnd, MAKEINTATOM(gpsi->atomIconSmProp), (HANDLE)hIconSm, PROPF_INTERNAL | PROPF_NOPOOL); 01200 01201 /* 01202 * Create the small icon if it doesn't exist. 01203 */ 01204 if (hIcon && !hIconSm) 01205 xxxCreateWindowSmIcon(pwnd, hIcon, TRUE); 01206 01207 /* 01208 * Redraw caption if the small icon has changed 01209 */ 01210 if (fRedraw) 01211 xxxRedrawTitle(pwnd, DC_ICON); 01212 } 01213 return hOld; 01214 } 01215 01216 // -------------------------------------------------------------------------- 01217 // 01218 // CreateWindowSmIcon() 01219 // 01220 // Makes a per-window small icon copy of a big icon. 01221 // 01222 // -------------------------------------------------------------------------- 01223 HICON xxxCreateWindowSmIcon( 01224 PWND pwnd, 01225 HICON hIconBig, 01226 BOOL fNotQueryDrag) 01227 { 01228 HICON hIconSm = NULL; 01229 PCURSOR pcurs = NULL,pcursBig; 01230 01231 CheckLock(pwnd); 01232 UserAssert(hIconBig); 01233 01234 pcursBig = (PCURSOR)HMValidateHandleNoRip(hIconBig, TYPE_CURSOR); 01235 01236 if (pcursBig) { 01237 pcurs = xxxClientCopyImage(PtoHq(pcursBig), 01238 pcursBig->rt == PTR_TO_ID(RT_ICON) ? IMAGE_ICON : IMAGE_CURSOR, 01239 SYSMET(CXSMICON), 01240 SYSMET(CYSMICON), 01241 LR_DEFAULTCOLOR | (fNotQueryDrag ? LR_COPYFROMRESOURCE : 0)); 01242 if (pcurs != NULL) 01243 hIconSm = PtoHq(pcurs); 01244 } 01245 if (hIconSm) { 01246 pcurs->CURSORF_flags |= CURSORF_SECRET; 01247 InternalSetProp(pwnd, MAKEINTATOM(gpsi->atomIconSmProp), (HANDLE)hIconSm, PROPF_INTERNAL | PROPF_NOPOOL); 01248 if (!fNotQueryDrag) 01249 SetWF(pwnd, WFSMQUERYDRAGICON); 01250 } 01251 01252 return(hIconSm); 01253 } 01254 01255 01256 /***************************************************************************\ 01257 * xxxDefWindowProc (API) 01258 * 01259 * History: 01260 * 10-23-90 MikeHar Ported from WaWaWaWindows. 01261 * 12-07-90 IanJa CTLCOLOR handling round right way 01262 \***************************************************************************/ 01263 01264 LRESULT xxxDefWindowProc( 01265 PWND pwnd, 01266 UINT message, 01267 WPARAM wParam, 01268 LPARAM lParam) 01269 { 01270 LRESULT lt; 01271 PWND pwndT; 01272 TL tlpwndParent; 01273 TL tlpwndT; 01274 int icolBack; 01275 int icolFore; 01276 int i; 01277 01278 CheckLock(pwnd); 01279 01280 if (pwnd == (PWND)-1) { 01281 return 0; 01282 } 01283 01284 if (message > WM_USER) { 01285 return 0; 01286 } 01287 01288 /* 01289 * Important: If you add cases to the switch statement below, 01290 * and those messages can originate on the client 01291 * side, add the messages to server.c's gawDefWindowMsgs 01292 * array or else the client will short-circuit the call 01293 * and return 0. 01294 */ 01295 01296 switch (message) { 01297 case WM_CLIENTSHUTDOWN: 01298 return xxxClientShutdown(pwnd, wParam); 01299 01300 case WM_NCACTIVATE: 01301 xxxDWP_DoNCActivate(pwnd, (LOWORD(wParam) ? NCA_ACTIVE : 0), (HRGN)lParam); 01302 return (LONG)TRUE; 01303 01304 case WM_NCHITTEST: 01305 return FindNCHit(pwnd, (LONG)lParam); 01306 01307 case WM_NCCALCSIZE: 01308 01309 /* 01310 * wParam = fCalcValidRects 01311 * lParam = LPRECT rgrc[3]: 01312 * lprc[0] = rcWindowNew = New window rectangle 01313 * if fCalcValidRects: 01314 * lprc[1] = rcWindowOld = Old window rectangle 01315 * lprc[2] = rcClientOld = Old client rectangle 01316 * 01317 * On return: 01318 * rgrc[0] = rcClientNew = New client rect 01319 * if fCalcValidRects: 01320 * rgrc[1] = rcValidDst = Destination valid rectangle 01321 * rgrc[2] = rcValidSrc = Source valid rectangle 01322 */ 01323 xxxCalcClientRect(pwnd, (LPRECT)lParam, FALSE); 01324 break; 01325 01326 case WM_NCLBUTTONDOWN: 01327 case WM_NCLBUTTONUP: 01328 case WM_NCLBUTTONDBLCLK: 01329 xxxDWP_NCMouse(pwnd, message, (UINT)wParam, lParam); 01330 break; 01331 01332 case WM_CANCELMODE: 01333 { 01334 /* 01335 * Terminate any modes the system might 01336 * be in, such as scrollbar tracking, menu mode, 01337 * button capture, etc. 01338 */ 01339 xxxDWP_DoCancelMode(pwnd); 01340 } 01341 break; 01342 01343 case WM_NCCREATE: 01344 if (TestWF(pwnd, (WFHSCROLL | WFVSCROLL))) { 01345 if (_InitPwSB(pwnd) == NULL) 01346 return (LONG)FALSE; 01347 } 01348 01349 #ifdef FE_SB // xxxDefWindowProc() 01350 /* 01351 * If CREATESTRUCTEX.strName contains resource id, we don't 01352 * need to call DefSetText(). because it is a numeric number, 01353 * it does not need Ansi <-> Unicode translation. 01354 */ 01355 if (lParam) { 01356 PLARGE_STRING pstr = &((PCREATESTRUCTEX)lParam)->strName; 01357 01358 if (pwnd->head.rpdesk == NULL || pstr == NULL || pstr->Buffer == NULL) { 01359 pwnd->strName.Length = 0; 01360 return TRUE; 01361 } 01362 01363 if ((pstr->bAnsi && (pstr->Length >= sizeof(BYTE)) && 01364 (*(PBYTE)(pstr->Buffer) == 0xff)) || 01365 (!pstr->bAnsi && (pstr->Length >= sizeof(WCHAR)) && 01366 (*(PWCHAR)(pstr->Buffer) == 0xffff))) { 01367 /* 01368 * This is Resource ID, we just return here with TRUE. 01369 */ 01370 return (LONG)TRUE; 01371 } 01372 } 01373 #endif // FE_SB 01374 01375 SetWF(pwnd, WFTITLESET); 01376 01377 return (LONG)DefSetText(pwnd, &((PCREATESTRUCTEX)lParam)->strName); 01378 01379 case WM_PRINT: 01380 return((LRESULT)xxxDWPPrint(pwnd, (HDC) wParam, lParam)); 01381 01382 case WM_NCPAINT: 01383 { 01384 HDC hdc; 01385 /* 01386 * Force the drawing of the menu. 01387 */ 01388 SetWF(pwnd, WFMENUDRAW); 01389 01390 /* 01391 * Get a window DC intersected with hrgnClip, 01392 * but make sure that hrgnClip doesn't get deleted. 01393 */ 01394 hdc = _GetDCEx(pwnd, 01395 (HRGN)wParam, 01396 DCX_USESTYLE | 01397 DCX_WINDOW | 01398 DCX_INTERSECTRGN | 01399 DCX_NODELETERGN | 01400 DCX_LOCKWINDOWUPDATE); 01401 01402 xxxDrawWindowFrame(pwnd, 01403 hdc, 01404 FALSE, 01405 (TestWF(pwnd, WFFRAMEON) && 01406 (GETPTI(pwnd)->pq == gpqForeground))); 01407 01408 _ReleaseDC(hdc); 01409 ClrWF(pwnd, WFMENUDRAW); 01410 } 01411 break; 01412 01413 case WM_ISACTIVEICON: 01414 return TestWF(pwnd, WFFRAMEON) != 0; 01415 01416 case WM_SETTEXT: 01417 /* 01418 * At one time we added an optimization to do nothing if the new 01419 * text was the same as the old text but found that QCcase does not work 01420 * because it calls SetWindowText not to change the text but 01421 * cause the title bar to redraw after it had added the sysmenu 01422 * through SetWindowLong 01423 */ 01424 if (lt = DefSetText(pwnd, (PLARGE_STRING)lParam)) { 01425 /* 01426 * Text was set, so redraw title bar 01427 */ 01428 xxxRedrawTitle(pwnd, DC_TEXT); 01429 if (FWINABLE()) { 01430 xxxWindowEvent(EVENT_OBJECT_NAMECHANGE, pwnd, OBJID_WINDOW, INDEXID_CONTAINER, 0); 01431 } 01432 } 01433 return lt; 01434 01435 case WM_GETTEXT: 01436 if (wParam != 0) { 01437 PLARGE_STRING pstr = (PLARGE_STRING)lParam; 01438 01439 if (pwnd->strName.Length) { 01440 if (pstr->bAnsi) { 01441 i = WCSToMB(pwnd->strName.Buffer, 01442 pwnd->strName.Length / sizeof(WCHAR), 01443 (LPSTR *)&pstr->Buffer, pstr->MaximumLength - 1, FALSE); 01444 ((LPSTR)pstr->Buffer)[i] = 0; 01445 pstr->Length = i; 01446 } else { 01447 i = TextCopy(&pwnd->strName, pstr->Buffer, (UINT)wParam); 01448 pstr->Length = i * sizeof(WCHAR); 01449 } 01450 return i; 01451 } 01452 01453 /* 01454 * else Null terminate the text buffer since there is no text. 01455 */ 01456 if (pstr->bAnsi) { 01457 *(LPSTR)pstr->Buffer = 0; 01458 } else { 01459 *(LPWSTR)pstr->Buffer = 0; 01460 } 01461 } 01462 return 0L; 01463 01464 case WM_GETTEXTLENGTH: 01465 if (pwnd->strName.Length) { 01466 UINT cch; 01467 if (lParam) { 01468 RtlUnicodeToMultiByteSize(&cch, 01469 pwnd->strName.Buffer, 01470 pwnd->strName.Length); 01471 } else { 01472 cch = pwnd->strName.Length / sizeof(WCHAR); 01473 } 01474 return cch; 01475 } 01476 return 0L; 01477 01478 case WM_CLOSE: 01479 xxxDestroyWindow(pwnd); 01480 break; 01481 01482 case WM_PAINT: 01483 case WM_PAINTICON: 01484 xxxDWP_Paint(pwnd); 01485 break; 01486 01487 case WM_ERASEBKGND: 01488 case WM_ICONERASEBKGND: 01489 return (LONG)xxxDWP_EraseBkgnd(pwnd, message, (HDC)wParam); 01490 01491 case WM_SYNCPAINT: 01492 01493 /* 01494 * Clear our sync-paint pending flag. 01495 */ 01496 ClrWF(pwnd, WFSYNCPAINTPENDING); 01497 01498 /* 01499 * This message is sent when SetWindowPos() is trying 01500 * to get the screen looking nice after window rearrangement, 01501 * and one of the windows involved is of another task. 01502 * This message avoids lots of inter-app message traffic 01503 * by switching to the other task and continuing the 01504 * recursion there. 01505 * 01506 * wParam = flags 01507 * LOWORD(lParam) = hrgnClip 01508 * HIWORD(lParam) = pwndSkip (not used; always NULL) 01509 * 01510 * pwndSkip is now always NULL. 01511 * 01512 * NOTE: THIS MESSAGE IS FOR INTERNAL USE ONLY! ITS BEHAVIOR 01513 * IS DIFFERENT IN 3.1 THAN IN 3.0!! 01514 */ 01515 xxxInternalDoSyncPaint(pwnd, (DWORD)wParam); 01516 break; 01517 01518 case WM_QUERYOPEN: 01519 case WM_QUERYENDSESSION: 01520 case WM_DEVICECHANGE: 01521 case WM_POWERBROADCAST: 01522 return (LONG)TRUE; 01523 01524 // Default handling for WM_CONTEXTMENU support 01525 case WM_RBUTTONUP: 01526 #ifdef USE_MIRRORING 01527 if (TestWF(pwnd, WEFLAYOUTRTL)) { 01528 lParam = MAKELPARAM(pwnd->rcClient.right - GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) + pwnd->rcClient.top); 01529 } else 01530 #endif 01531 { 01532 lParam = MAKELONG(GET_X_LPARAM(lParam) + pwnd->rcClient.left, GET_Y_LPARAM(lParam) + pwnd->rcClient.top); 01533 } 01534 xxxSendMessage(pwnd, WM_CONTEXTMENU, (WPARAM) HWq(pwnd), lParam); 01535 break; 01536 01537 case WM_NCRBUTTONDOWN: 01538 { 01539 int nHit; 01540 MSG msg; 01541 LONG spt; 01542 PTHREADINFO pti = PtiCurrent(); 01543 01544 nHit = FindNCHit(pwnd, (LONG)lParam); 01545 if (nHit == HTVSCROLL || nHit == HTHSCROLL) { 01546 if (!_IsDescendant(pti->pq->spwndActive, pwnd)) { 01547 break; 01548 } 01549 } else if (nHit == HTCAPTION || nHit == HTSYSMENU) { 01550 if (pwnd != pti->pq->spwndActive) { 01551 break; 01552 } 01553 } else { 01554 break; 01555 } 01556 01557 xxxSetCapture(pwnd); 01558 01559 while (TRUE) 01560 { 01561 if (xxxPeekMessage(&msg, NULL, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE)) 01562 { 01563 if (msg.message == WM_RBUTTONUP) 01564 { 01565 xxxReleaseCapture(); 01566 spt = POINTTOPOINTS(msg.pt); 01567 nHit = FindNCHit(pwnd, spt); 01568 if ((nHit == HTCAPTION) || (nHit == HTSYSMENU) || 01569 (nHit == HTVSCROLL) || (nHit == HTHSCROLL)) { 01570 xxxSendMessage(pwnd, WM_CONTEXTMENU, (WPARAM) HWq(pwnd), spt); 01571 } 01572 break; 01573 } 01574 } 01575 if (pwnd != pti->pq->spwndCapture) 01576 // Someone else grabbed the capture. Bail out. 01577 break; 01578 // xxxWaitMessage(); 01579 if (!xxxSleepThread(QS_MOUSE, 0, TRUE)) 01580 break; 01581 } 01582 } 01583 break; 01584 01585 /* 01586 * Default handling for WM_APPCOMMAND support 01587 */ 01588 case WM_NCXBUTTONUP: 01589 case WM_XBUTTONUP: 01590 { 01591 WORD cmd; 01592 WORD keystate; 01593 LPARAM lParamAppCommand; 01594 01595 cmd = 0; 01596 switch (GET_XBUTTON_WPARAM(wParam)) { 01597 case XBUTTON1: 01598 cmd = APPCOMMAND_BROWSER_BACKWARD; 01599 break; 01600 01601 case XBUTTON2: 01602 cmd = APPCOMMAND_BROWSER_FORWARD; 01603 break; 01604 01605 default: 01606 break; 01607 } 01608 01609 if (cmd == 0) { 01610 break; 01611 } 01612 01613 cmd |= FAPPCOMMAND_MOUSE; 01614 if (message == WM_XBUTTONUP) { 01615 keystate = GET_KEYSTATE_WPARAM(wParam); 01616 } else { 01617 keystate = (WORD)GetMouseKeyFlags(PtiCurrent()->pq); 01618 } 01619 01620 lParamAppCommand = MAKELPARAM(keystate, cmd); 01621 xxxSendMessage(pwnd, WM_APPCOMMAND, (WPARAM) HWq(pwnd), lParamAppCommand); 01622 break; 01623 } 01624 01625 case WM_MOUSEWHEEL: 01626 if (TestwndChild(pwnd)) { 01627 ThreadLockAlways(pwnd->spwndParent, &tlpwndParent); 01628 xxxSendMessage(pwnd->spwndParent, WM_MOUSEWHEEL, wParam, lParam); 01629 ThreadUnlock(&tlpwndParent); 01630 } 01631 break; 01632 01633 case WM_CONTEXTMENU: 01634 { 01635 int nHit; 01636 01637 nHit = FindNCHit(pwnd, (LONG)lParam); 01638 01639 /* 01640 * Put up a context menu if we clicked on a scroll bar 01641 */ 01642 if ((nHit == HTVSCROLL) || (nHit == HTHSCROLL)) { 01643 if (_IsDescendant(PtiCurrent()->pq->spwndActive, pwnd)) { 01644 xxxDoScrollMenu(pwnd, NULL, nHit - HTHSCROLL, lParam); 01645 } 01646 break; 01647 } 01648 01649 if (TestwndChild(pwnd)) { 01650 ThreadLockAlways(pwnd->spwndParent, &tlpwndParent); 01651 xxxSendMessage(pwnd->spwndParent, WM_CONTEXTMENU, (WPARAM) HWq(pwnd), lParam); 01652 ThreadUnlock(&tlpwndParent); 01653 } else { 01654 /* 01655 * Do default context menu if right clicked on caption 01656 */ 01657 if (pwnd == PtiCurrent()->pq->spwndActive) 01658 { 01659 if (nHit == HTCAPTION) 01660 goto DoTheDefaultThang; 01661 else if (nHit == HTSYSMENU) 01662 { 01663 i = SC_CLOSE; 01664 goto DoTheSysMenuThang; 01665 } 01666 01667 /* 01668 * If this was generated by the keyboard (apps key), then simulate a shift-f10 01669 * for old apps so they get a crack at putting up their context menu. 01670 */ 01671 if (lParam == KEYBOARD_MENU && !TestWF(pwnd, WFWIN40COMPAT)) 01672 xxxSimulateShiftF10(); 01673 } 01674 } 01675 } 01676 break; 01677 01678 case WM_APPCOMMAND: 01679 /* 01680 * Bubble the message to the parent 01681 */ 01682 if (TestwndChild(pwnd)) { 01683 ThreadLockAlways(pwnd->spwndParent, &tlpwndParent); 01684 lt = xxxSendMessage(pwnd->spwndParent, WM_APPCOMMAND, wParam, lParam); 01685 ThreadUnlock(&tlpwndParent); 01686 return lt; 01687 } else if (pwnd != PWNDDESKTOP(pwnd) ) { 01688 /* 01689 * Notify listeners on the SHELLHOOK that a WM_APPCOMMAND message was not handled 01690 * We also post this message to the shell queue so they don't need to load themselves 01691 * into every process with a hook. 01692 * We don't bother about the desktop since csrss services it and it doesn't accept 01693 * shell hooks so there is no point. 01694 */ 01695 if (IsHooked(PtiCurrent(), WHF_SHELL)) 01696 xxxCallHook(HSHELL_APPCOMMAND, wParam, lParam, WH_SHELL); 01697 01698 /* 01699 * Still post messages to the shell window even if there isn't a hook installed 01700 */ 01701 PostShellHookMessages(HSHELL_APPCOMMAND, lParam); 01702 } 01703 break; 01704 01705 case WM_KEYF1: 01706 xxxSendHelpMessage(pwnd, HELPINFO_WINDOW, 01707 (int) (TestwndChild(pwnd) ? PTR_TO_ID(pwnd->spmenu) : 0), 01708 HWq(pwnd), GetContextHelpId(pwnd)); 01709 break; 01710 01711 case WM_SYSCOMMAND: 01712 xxxSysCommand(pwnd, (UINT)wParam, lParam); 01713 break; 01714 01715 case WM_KEYDOWN: 01716 if (wParam == VK_F10) { 01717 PtiCurrent()->pq->QF_flags |= QF_FF10STATUS; 01718 HandleF10: 01719 /* 01720 * Generate a WM_CONTEXTMENU for new apps for shift-f10. 01721 */ 01722 if (_GetKeyState(VK_SHIFT) < 0 && TestWF(pwnd, WFWIN40COMPAT)) { 01723 xxxSendMessage(pwnd, WM_CONTEXTMENU, (WPARAM)HWq(pwnd), KEYBOARD_MENU); 01724 } 01725 } 01726 break; 01727 01728 case WM_HELP: 01729 // If this window is a child window, Help message must be passed on 01730 // to it's parent; Else, this must be passed on to the owner window. 01731 pwndT = (TestwndChild(pwnd)? pwnd->spwndParent : pwnd->spwndOwner); 01732 if (pwndT && (pwndT != _GetDesktopWindow())) { 01733 ThreadLockAlways(pwndT, &tlpwndT); 01734 lt = xxxSendMessage(pwndT, WM_HELP, wParam, lParam); 01735 ThreadUnlock(&tlpwndT); 01736 return lt; 01737 } 01738 return 0L; 01739 01740 case WM_SYSKEYDOWN: 01741 { 01742 PTHREADINFO pti = PtiCurrent(); 01743 01744 /* 01745 * Is the ALT key down? 01746 */ 01747 if (HIWORD(lParam) & SYS_ALTERNATE) { 01748 /* 01749 * Toggle QF_FMENUSTATUS iff this is NOT a repeat KEYDOWN 01750 * message; Only if the prev key state was 0, then this is the 01751 * first KEYDOWN message and then we consider toggling menu 01752 * status; Fix for Bugs #4531 & #4566 --SANKAR-- 10-02-89. 01753 */ 01754 if ((HIWORD(lParam) & SYS_PREVKEYSTATE) == 0) { 01755 01756 /* 01757 * Don't have to lock pwndActive because it's 01758 * processing this key. 01759 */ 01760 if ((wParam == VK_MENU) && 01761 !(pti->pq->QF_flags & QF_FMENUSTATUS)) { 01762 pti->pq->QF_flags |= QF_FMENUSTATUS; 01763 xxxDrawMenuBarUnderlines(pwnd, TRUE); 01764 } else { 01765 pti->pq->QF_flags &= ~(QF_FMENUSTATUS|QF_FMENUSTATUSBREAK); 01766 } 01767 } 01768 01769 pti->pq->QF_flags &= ~QF_FF10STATUS; 01770 01771 xxxDWP_ProcessVirtKey((UINT)wParam); 01772 01773 } else { 01774 if (wParam == VK_F10) { 01775 pti->pq->QF_flags |= QF_FF10STATUS; 01776 goto HandleF10; 01777 } 01778 } 01779 } 01780 break; 01781 01782 case WM_SYSKEYUP: 01783 case WM_KEYUP: 01784 { 01785 PTHREADINFO pti = PtiCurrent(); 01786 01787 /* 01788 * press and release F10 or ALT. Send this only to top-level windows, 01789 * otherwise MDI gets confused. The fix in which DefMDIChildProc() 01790 * passed up the message was insufficient in the case a child window 01791 * of the MDI child had the focus. 01792 * Also make sure the sys-menu activation wasn't broken by a mouse 01793 * up or down when the Alt was down (QF_MENUSTATUSBREAK). 01794 */ 01795 if ((wParam == VK_MENU && !(pti->pq->QF_flags & QF_TABSWITCHING) && ((pti->pq->QF_flags & 01796 (QF_FMENUSTATUS | QF_FMENUSTATUSBREAK)) == QF_FMENUSTATUS)) || 01797 (wParam == VK_F10 && (pti->pq->QF_flags & QF_FF10STATUS ))) { 01798 pwndT = GetTopLevelWindow(pwnd); 01799 if (gspwndFullScreen != pwndT) { 01800 01801 ThreadLockWithPti(pti, pwndT, &tlpwndT); 01802 /* 01803 * Draw the underlines for F10. This was already down for ALT 01804 * when the key went down. 01805 */ 01806 if (wParam == VK_F10) { 01807 xxxDrawMenuBarUnderlines(pwnd, TRUE); 01808 } 01809 xxxSendMessage(pwndT, WM_SYSCOMMAND, SC_KEYMENU, 0); 01810 ThreadUnlock(&tlpwndT); 01811 } 01812 } 01813 01814 /* 01815 * Turn off bit for tab-switching. This is set in the _KeyEvent() 01816 * routine when it's been determined we're doing switching. This 01817 * is necessary for cases where the ALT-KEY is release before the 01818 * TAB-KEY. In which case, the FMENUSTATUS bit would be cleared 01819 * by the ALT-KEY-UP and would have forced us into a syscommand 01820 * loop. This guarentees that we don't enter that condition. 01821 */ 01822 if (wParam == VK_MENU) { 01823 pti->pq->QF_flags &= ~QF_TABSWITCHING; 01824 xxxDrawMenuBarUnderlines(pwnd, FALSE); 01825 } 01826 01827 pti->pq->QF_flags &= ~(QF_FMENUSTATUS | QF_FMENUSTATUSBREAK | QF_FF10STATUS); 01828 } 01829 break; 01830 01831 case WM_SYSCHAR: 01832 { 01833 PTHREADINFO pti = PtiCurrent(); 01834 01835 /* 01836 * If syskey is down and we have a char... 01837 */ 01838 pti->pq->QF_flags &= ~(QF_FMENUSTATUS | QF_FMENUSTATUSBREAK); 01839 01840 if (wParam == VK_RETURN && TestWF(pwnd, WFMINIMIZED)) { 01841 01842 /* 01843 * If the window is iconic and user hits RETURN, we want to 01844 * restore this window. 01845 */ 01846 _PostMessage(pwnd, WM_SYSCOMMAND, SC_RESTORE, 0L); 01847 break; 01848 } 01849 01850 if ((HIWORD(lParam) & SYS_ALTERNATE) && wParam) { 01851 if (wParam == VK_TAB || wParam == VK_ESCAPE) 01852 break; 01853 01854 /* 01855 * Send ALT-SPACE only to top-level windows. 01856 */ 01857 if ((wParam == MENUSYSMENU) && (TestwndChild(pwnd))) { 01858 ThreadLockAlwaysWithPti(pti, pwnd->spwndParent, &tlpwndParent); 01859 xxxSendMessage(pwnd->spwndParent, message, wParam, lParam); 01860 ThreadUnlock(&tlpwndParent); 01861 } else { 01862 xxxSendMessage(pwnd, WM_SYSCOMMAND, SC_KEYMENU, (DWORD)wParam); 01863 } 01864 } else { 01865 01866 /* 01867 * Ctrl-Esc produces a WM_SYSCHAR, But should not beep; 01868 */ 01869 if (wParam != VK_ESCAPE) 01870 xxxMessageBeep(0); 01871 } 01872 } 01873 break; 01874 01875 case WM_CHARTOITEM: 01876 case WM_VKEYTOITEM: 01877 01878 /* 01879 * Do default processing for keystrokes into owner draw listboxes. 01880 */ 01881 return -1L; 01882 01883 case WM_ACTIVATE: 01884 if (wParam) 01885 xxxSetFocus(pwnd); 01886 break; 01887 01888 case WM_INPUTLANGCHANGEREQUEST: 01889 { 01890 PWND pwndFocus = PtiCurrent()->pq->spwndFocus; 01891 01892 /* 01893 * #115190 01894 * Dialog does not forward I.L.Reqest to the focused window. 01895 * (Memphis compatible issue) 01896 */ 01897 if (pwndFocus && (pwndFocus != pwnd) && 01898 pwnd->pcls->atomClassName != gpsi->atomSysClass[ICLS_DIALOG]) { 01899 /* 01900 * pass message to focus'ed window. Old app, pass on to 01901 * focus'ed window which may be ML aware. (edit class 01902 * for example). 01903 */ 01904 ThreadLockAlways(pwndFocus, &tlpwndT); 01905 xxxSendMessage(pwndFocus, message, wParam, lParam); 01906 ThreadUnlock(&tlpwndT); 01907 } else if (!xxxActivateKeyboardLayout(_GetProcessWindowStation(NULL), 01908 (HKL)lParam, KLF_SETFORPROCESS, pwnd)) { 01909 RIPERR1(ERROR_INVALID_KEYBOARD_HANDLE, RIP_WARNING, "WM_INPUTLANGCHANGEREQUEST: Invalid keyboard handle (0x%08lx)", lParam); 01910 } 01911 break; 01912 } 01913 01914 case WM_INPUTLANGCHANGE: 01915 { 01916 PBWL pbwl; 01917 HWND *phwnd; 01918 TL tlpwnd; 01919 01920 pbwl = BuildHwndList(pwnd->spwndChild, BWL_ENUMLIST, NULL); 01921 if (pbwl == NULL) 01922 return 0; 01923 01924 for (phwnd = pbwl->rghwnd; *phwnd != (HWND)1; phwnd++) { 01925 /* 01926 * Make sure this hwnd is still around. 01927 */ 01928 if ((pwnd = RevalidateHwnd(*phwnd)) == NULL) 01929 continue; 01930 01931 ThreadLockAlways(pwnd, &tlpwnd); 01932 RIPMSG1(RIP_VERBOSE, "WM_INPUTLANGCHANGE: Sending message to pwnd %#p", pwnd); 01933 xxxSendMessage(pwnd, message, wParam, lParam); 01934 ThreadUnlock(&tlpwnd); 01935 } 01936 FreeHwndList(pbwl); 01937 01938 break; 01939 } 01940 01941 case WM_SETREDRAW: 01942 xxxDWP_SetRedraw(pwnd, wParam != 0); 01943 break; 01944 01945 case WM_WINDOWPOSCHANGING: 01946 { 01947 /* 01948 * If the window's size is changing, adjust the passed-in size 01949 */ 01950 WINDOWPOS *ppos = ((WINDOWPOS *)lParam); 01951 if (!(ppos->flags & SWP_NOSIZE)) { 01952 xxxAdjustSize(pwnd, &ppos->cx, &ppos->cy); 01953 } 01954 } 01955 break; 01956 01957 case WM_WINDOWPOSCHANGED: 01958 xxxHandleWindowPosChanged(pwnd, (PWINDOWPOS)lParam); 01959 break; 01960 01961 case WM_CTLCOLORSCROLLBAR: 01962 if (gpsi->BitCount < 8 || 01963 SYSRGB(3DHILIGHT) != SYSRGB(SCROLLBAR) || 01964 SYSRGB(3DHILIGHT) == SYSRGB(WINDOW)) 01965 { 01966 /* 01967 * Remove call to UnrealizeObject. GDI handles this 01968 * for brushes on NT. 01969 * 01970 * GreUnrealizeObject(ghbrGray); 01971 */ 01972 01973 GreSetBkColor((HDC)wParam, SYSRGB(3DHILIGHT)); 01974 GreSetTextColor((HDC)wParam, SYSRGB(3DFACE)); 01975 return((LRESULT)gpsi->hbrGray); 01976 } 01977 01978 icolBack = COLOR_3DHILIGHT; 01979 icolFore = COLOR_BTNTEXT; 01980 goto SetColor; 01981 01982 case WM_CTLCOLORBTN: 01983 if (TestWF(pwnd, WFWIN40COMPAT)) { 01984 icolBack = COLOR_3DFACE; 01985 icolFore = COLOR_BTNTEXT; 01986 } else { 01987 goto ColorDefault; 01988 } 01989 goto SetColor; 01990 01991 case WM_CTLCOLORSTATIC: 01992 case WM_CTLCOLORDLG: 01993 case WM_CTLCOLORMSGBOX: 01994 // We want static controls in dialogs to have the 3D 01995 // background color, but statics in windows to inherit 01996 // their parents' background. 01997 if (TestWF(pwnd, WFWIN40COMPAT) 01998 ) { 01999 icolBack = COLOR_3DFACE; 02000 icolFore = COLOR_WINDOWTEXT; 02001 goto SetColor; 02002 } 02003 // ELSE FALL THRU... 02004 02005 case WM_CTLCOLOR: // here for WOW only 02006 case WM_CTLCOLORLISTBOX: 02007 case WM_CTLCOLOREDIT: 02008 ColorDefault: 02009 icolBack = COLOR_WINDOW; 02010 icolFore = COLOR_WINDOWTEXT; 02011 02012 SetColor: 02013 GreSetBkColor((HDC)wParam, gpsi->argbSystem[icolBack]); 02014 GreSetTextColor((HDC)wParam, gpsi->argbSystem[icolFore]); 02015 return (LRESULT)(SYSHBRUSH(icolBack)); 02016 02017 case WM_SETCURSOR: 02018 02019 /* 02020 * wParam == pwndHit == pwnd that cursor is over 02021 * lParamL == ht == Hit test area code (result of WM_NCHITTEST) 02022 * lParamH == msg == Mouse message number 02023 */ 02024 return (LONG)xxxDWP_SetCursor(pwnd, (HWND)wParam, (int)(SHORT)lParam, 02025 HIWORD(lParam)); 02026 02027 case WM_MOUSEACTIVATE: 02028 pwndT = GetChildParent(pwnd); 02029 if (pwndT != NULL) { 02030 ThreadLockAlways(pwndT, &tlpwndT); 02031 lt = xxxSendMessage(pwndT, WM_MOUSEACTIVATE, wParam, lParam); 02032 ThreadUnlock(&tlpwndT); 02033 if (lt != 0) 02034 return lt; 02035 } 02036 02037 /* 02038 * Moving, sizing or minimizing? Activate AFTER we take action. 02039 * If the user LEFT clicked in the title bar, don't activate now: 02040 */ 02041 return ( (LOWORD(lParam) == HTCAPTION) 02042 && (HIWORD(lParam) == WM_LBUTTONDOWN) 02043 ) 02044 ? (LONG)MA_NOACTIVATE 02045 : (LONG)MA_ACTIVATE; 02046 02047 case WM_SHOWWINDOW: 02048 02049 /* 02050 * If we are being called because our owner window is being shown, 02051 * hidden, minimized, or un-minimized, then we must hide or show 02052 * show ourself as appropriate. 02053 * 02054 * This behavior occurs for popup windows or owned windows only. 02055 * It's not designed for use with child windows. 02056 */ 02057 if (LOWORD(lParam) != 0 && (TestwndPopup(pwnd) || pwnd->spwndOwner)) { 02058 02059 /* 02060 * The WFHIDDENPOPUP flag is an internal flag that indicates 02061 * that the window was hidden because its owner was hidden. 02062 * This way we only show windows that were hidden by this code, 02063 * not intentionally by the application. 02064 * 02065 * Go ahead and hide or show this window, but only if: 02066 * 02067 * a) we need to be hidden, or 02068 * b) we need to be shown, and we were hidden by 02069 * an earlier WM_SHOWWINDOW message 02070 */ 02071 if ((!wParam && TestWF(pwnd, WFVISIBLE)) || 02072 (wParam && !TestWF(pwnd, WFVISIBLE) && 02073 TestWF(pwnd, WFHIDDENPOPUP))) { 02074 02075 /* 02076 * Remember that we were hidden by WM_SHOWWINDOW processing 02077 */ 02078 ClrWF(pwnd, WFHIDDENPOPUP); 02079 if (!wParam) 02080 SetWF(pwnd, WFHIDDENPOPUP); 02081 02082 xxxShowWindow( 02083 pwnd, 02084 (wParam ? SW_SHOWNOACTIVATE : SW_HIDE) | TEST_PUDF(PUDF_ANIMATE)); 02085 } 02086 } 02087 break; 02088 02089 case WM_SYSMENU: 02090 if ( !TestWF(pwnd, WFDISABLED) 02091 && ( (GETPTI(pwnd)->pq == gpqForeground) 02092 || xxxSetForegroundWindow(pwnd, FALSE)) 02093 ) 02094 { 02095 PMENU pMenu; 02096 TL tpmenu; 02097 DoTheDefaultThang: 02098 if (TestWF(pwnd, WFMAXIMIZED) || TestWF(pwnd, WFMINIMIZED)) 02099 i = SC_RESTORE; 02100 else 02101 i = SC_MAXIMIZE; 02102 02103 DoTheSysMenuThang: 02104 if ((pMenu = xxxGetSysMenu(pwnd, TRUE)) != NULL) 02105 { 02106 _SetMenuDefaultItem(pMenu, i, MF_BYCOMMAND); 02107 02108 // Tell the shell we are bringing it up the system menu 02109 PostShellHookMessages(HSHELL_SYSMENU, (LPARAM)HWq(pwnd)); 02110 02111 ThreadLockAlways(pMenu, &tpmenu); 02112 if (lParam == 0xFFFFFFFF) 02113 { 02114 // this is a keyboard generated WM_SYSMENU 02115 if (FDoTray()) 02116 { 02117 TPMPARAMS tpm; 02118 02119 tpm.cbSize = sizeof(TPMPARAMS); 02120 02121 if (xxxSendMinRectMessages(pwnd, &tpm.rcExclude)) { 02122 xxxTrackPopupMenuEx(pMenu, TPM_SYSMENU | TPM_VERTICAL, 02123 tpm.rcExclude.left, tpm.rcExclude.top, pwnd, &tpm); 02124 } 02125 } 02126 } 02127 else 02128 { 02129 xxxTrackPopupMenuEx(pMenu, TPM_RIGHTBUTTON | TPM_SYSMENU, 02130 GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), pwnd, NULL); 02131 } 02132 ThreadUnlock(&tpmenu); 02133 } 02134 } 02135 break; 02136 02137 case WM_DRAWITEM: 02138 DWP_DrawItem((LPDRAWITEMSTRUCT)lParam); 02139 break; 02140 02141 case WM_GETHOTKEY: 02142 return (LONG)DWP_GetHotKey(pwnd); 02143 break; 02144 02145 case WM_SETHOTKEY: 02146 return (LONG)DWP_SetHotKey(pwnd, (DWORD)wParam); 02147 break; 02148 02149 case WM_GETICON: 02150 return (LRESULT)DWP_GetIcon(pwnd, (BOOL)wParam); 02151 02152 case WM_SETICON: 02153 return (LRESULT)xxxDWP_SetIcon(pwnd, wParam, (HICON)lParam); 02154 02155 case WM_COPYGLOBALDATA: 02156 /* 02157 * This message is used to thunk WM_DROPFILES messages along 02158 * with other things. If we end up here with it, directly 02159 * call the client back to finish processing of this message. 02160 * This assumes that the ultimate destination of the 02161 * WM_DROPFILES message is in the client side's process context. 02162 */ 02163 return(SfnCOPYGLOBALDATA(NULL, 0, wParam, lParam, 0, 0, 0, NULL)); 02164 02165 case WM_QUERYDROPOBJECT: 02166 /* 02167 * if the app has registered interest in drops, return TRUE 02168 */ 02169 return (LRESULT)(TestWF(pwnd, WEFACCEPTFILES) ? TRUE : FALSE); 02170 02171 case WM_DROPOBJECT: 02172 return DO_DROPFILE; 02173 02174 case WM_ACCESS_WINDOW: 02175 if (ValidateHwnd((HWND)wParam)) { 02176 // SECURITY: set ACL for this window to no-access 02177 return TRUE; 02178 } 02179 return FALSE; 02180 02181 case WM_NOTIFYFORMAT: 02182 if(lParam == NF_QUERY) 02183 return(TestWF(pwnd, WFANSICREATOR) ? NFR_ANSI : NFR_UNICODE); 02184 break; 02185 02186 case WM_CHANGEUISTATE: 02187 { 02188 WORD wAction = LOWORD(wParam); 02189 WORD wFlags = HIWORD(wParam); 02190 BOOL bRealChange = FALSE; 02191 02192 if (wFlags & ~UISF_VALID || wAction > UIS_LASTVALID || 02193 lParam || !TEST_KbdCuesPUSIF) { 02194 return 0; 02195 } 02196 02197 if (wAction == UIS_INITIALIZE) { 02198 if (gpsi->bLastRITWasKeyboard) { 02199 wAction = UIS_CLEAR; 02200 } else { 02201 wAction = UIS_SET; 02202 } 02203 wFlags = UISF_HIDEFOCUS | UISF_HIDEACCEL; 02204 wParam = MAKEWPARAM(wAction, wFlags); 02205 } 02206 02207 UserAssert(wAction == UIS_SET || wAction == UIS_CLEAR); 02208 /* 02209 * If the state is not going to change, there's nothing to do here 02210 */ 02211 if (wFlags & UISF_HIDEFOCUS) { 02212 bRealChange = (!!TestWF(pwnd, WEFPUIFOCUSHIDDEN)) ^ (wAction == UIS_SET); 02213 } 02214 if (wFlags & UISF_HIDEACCEL) { 02215 bRealChange |= (!!TestWF(pwnd, WEFPUIACCELHIDDEN)) ^ (wAction == UIS_SET); 02216 } 02217 02218 if (!bRealChange) { 02219 break; 02220 } 02221 02222 /* 02223 * Children pass this message up 02224 * Top level windows update their children's state and 02225 * send down to their imediate children WM_UPDATEUISTATE. 02226 */ 02227 if (TestwndChild(pwnd)) { 02228 ThreadLockAlways(pwnd->spwndParent, &tlpwndParent); 02229 lt = xxxSendMessage(pwnd->spwndParent, WM_CHANGEUISTATE, wParam, lParam); 02230 ThreadUnlock(&tlpwndParent); 02231 return lt; 02232 } else { 02233 return xxxSendMessage(pwnd, WM_UPDATEUISTATE, wParam, lParam); 02234 } 02235 02236 } 02237 break; 02238 02239 case WM_QUERYUISTATE: 02240 return (TestWF(pwnd, WEFPUIFOCUSHIDDEN) ? UISF_HIDEFOCUS : 0) | 02241 (TestWF(pwnd, WEFPUIACCELHIDDEN) ? UISF_HIDEACCEL : 0); 02242 break; 02243 02244 case WM_UPDATEUISTATE: 02245 { 02246 WORD wAction = LOWORD(wParam); 02247 WORD wFlags = HIWORD(wParam); 02248 02249 if (wFlags & ~UISF_VALID || wAction > UIS_LASTVALID || 02250 lParam || !TEST_KbdCuesPUSIF) { 02251 return 0; 02252 } 02253 02254 switch (wAction) { 02255 case UIS_INITIALIZE: 02256 /* 02257 * UISTATE: UIS_INITIALIZE sets the UIState bits 02258 * based on the last input type 02259 */ 02260 if (!gpsi->bLastRITWasKeyboard) { 02261 SetWF(pwnd, WEFPUIFOCUSHIDDEN); 02262 SetWF(pwnd, WEFPUIACCELHIDDEN); 02263 wParam = MAKEWPARAM(UIS_SET, UISF_HIDEACCEL | UISF_HIDEFOCUS); 02264 } else { 02265 ClrWF(pwnd, WEFPUIFOCUSHIDDEN); 02266 ClrWF(pwnd, WEFPUIACCELHIDDEN); 02267 wParam = MAKEWPARAM(UIS_CLEAR, UISF_HIDEACCEL | UISF_HIDEFOCUS); 02268 } 02269 break; 02270 02271 case UIS_SET: 02272 if (wFlags & UISF_HIDEACCEL) { 02273 SetWF(pwnd, WEFPUIACCELHIDDEN); 02274 } 02275 if (wFlags & UISF_HIDEFOCUS) { 02276 SetWF(pwnd, WEFPUIFOCUSHIDDEN); 02277 } 02278 break; 02279 02280 case UIS_CLEAR: 02281 if (wFlags & UISF_HIDEACCEL) { 02282 ClrWF(pwnd, WEFPUIACCELHIDDEN); 02283 } 02284 if (wFlags & UISF_HIDEFOCUS) { 02285 ClrWF(pwnd, WEFPUIFOCUSHIDDEN); 02286 } 02287 break; 02288 02289 default: 02290 break; 02291 } 02292 02293 /* 02294 * Send it down to its immediate children if any 02295 */ 02296 if (pwnd->spwndChild) { 02297 02298 PBWL pbwl; 02299 HWND *phwnd; 02300 TL tlpwnd; 02301 02302 pbwl = BuildHwndList(pwnd->spwndChild, BWL_ENUMLIST, NULL); 02303 if (pbwl == NULL) 02304 return 0; 02305 02306 for (phwnd = pbwl->rghwnd; *phwnd != (HWND)1; phwnd++) { 02307 /* 02308 * Make sure this hwnd is still around. 02309 */ 02310 if ((pwnd = RevalidateHwnd(*phwnd)) == NULL) 02311 continue; 02312 02313 ThreadLockAlways(pwnd, &tlpwnd); 02314 xxxSendMessage(pwnd, message, wParam, lParam); 02315 ThreadUnlock(&tlpwnd); 02316 } 02317 FreeHwndList(pbwl); 02318 } 02319 } 02320 break; 02321 02322 #ifdef PENWIN20 02323 // LATER mikeke 02324 default: 02325 // BOGUS 02326 // 32-bit ize DefPenWindowProc 02327 // 02328 // call DefPenWindowProc if penwin is loaded 02329 if ( (message >= WM_HANDHELDFIRST) 02330 && (message <= WM_HANDHELDLAST) 02331 ) { 02332 if (lpfnHandHeld != NULL) 02333 return (*lpfnHandHeld)(HW16(pwnd), message, wParamLo, lParam); 02334 } else if ( (message >= WM_PENWINFIRST) 02335 && (message <= WM_PENWINLAST) 02336 ) { 02337 if (SYSMET(PENWINDOWS)) 02338 return DefPenWindowProc(pwnd, message, wParamLo, lParam); 02339 } 02340 02341 #endif // PENWIN20 02342 } 02343 02344 return 0; 02345 }

Generated on Sat May 15 19:39:47 2004 for test by doxygen 1.3.7