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

winmgr.c

Go to the documentation of this file.
00001 /****************************** Module Header ******************************\ 00002 * Module Name: winmgr.c 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * This module contains routines common to client and kernel. 00007 * 00008 * History: 00009 * 02-20-92 DarrinM Pulled functions from user\server. 00010 * 11-11-94 JimA Separated from client. 00011 \***************************************************************************/ 00012 00013 /***************************************************************************\ 00014 * FindNCHit 00015 * 00016 * History: 00017 * 11-09-90 DavidPe Ported. 00018 \***************************************************************************/ 00019 int FindNCHit( 00020 PWND pwnd, 00021 LONG lPt) 00022 { 00023 POINT pt; 00024 RECT rcWindow; 00025 RECT rcClient; 00026 RECT rcClientAdj; 00027 int cBorders; 00028 int dxButton; 00029 00030 pt.x = GET_X_LPARAM(lPt); 00031 pt.y = GET_Y_LPARAM(lPt); 00032 00033 if (!PtInRect(&((WND *)pwnd)->rcWindow, pt)) 00034 return HTNOWHERE; 00035 00036 if (TestWF(pwnd, WFMINIMIZED)) { 00037 CopyInflateRect(&rcWindow, &((WND *)pwnd)->rcWindow, 00038 -(SYSMETRTL(CXFIXEDFRAME) + SYSMETRTL(CXBORDER)), -(SYSMETRTL(CYFIXEDFRAME) + SYSMETRTL(CYBORDER))); 00039 00040 if (!PtInRect(&rcWindow, pt)) 00041 return HTCAPTION; 00042 00043 goto CaptionHit; 00044 } 00045 00046 // Get client rectangle 00047 rcClient = pwnd->rcClient; 00048 if (PtInRect(&rcClient, pt)) 00049 return HTCLIENT; 00050 00051 // Are we in "pseudo" client, i.e. the client & scrollbars & border 00052 if (TestWF(pwnd, WEFCLIENTEDGE)) 00053 CopyInflateRect(&rcClientAdj, &rcClient, SYSMETRTL(CXEDGE), SYSMETRTL(CYEDGE)); 00054 else 00055 rcClientAdj = rcClient; 00056 00057 if (TestWF(pwnd, WFVPRESENT)) { 00058 #ifdef USE_MIRRORING 00059 if ((!!TestWF(pwnd, WEFLEFTSCROLL)) ^ (!!TestWF(pwnd, WEFLAYOUTRTL))) 00060 #else 00061 if (TestWF(pwnd, WEFLEFTSCROLL)) 00062 #endif 00063 rcClientAdj.left -= SYSMETRTL(CXVSCROLL); 00064 else 00065 rcClientAdj.right += SYSMETRTL(CXVSCROLL); 00066 } 00067 if (TestWF(pwnd, WFHPRESENT)) 00068 rcClientAdj.bottom += SYSMETRTL(CYHSCROLL); 00069 00070 if (!PtInRect(&rcClientAdj, pt)) 00071 { 00072 // Subtract out window borders 00073 cBorders = GetWindowBorders(pwnd->style, pwnd->ExStyle, TRUE, FALSE); 00074 CopyInflateRect(&rcWindow, &((WND *)pwnd)->rcWindow, 00075 -cBorders*SYSMETRTL(CXBORDER), -cBorders*SYSMETRTL(CYBORDER)); 00076 00077 // Are we on the border? 00078 if (!PtInRect(&rcWindow, pt)) 00079 { 00080 // On a sizing border? 00081 if (!TestWF(pwnd, WFSIZEBOX)) { 00082 // 00083 // Old compatibility thing: For 3.x windows that just had 00084 // a border, we returned HTNOWHERE, believe it or not, 00085 // because our hit-testing code was so brain dead. 00086 // 00087 if (!TestWF(pwnd, WFWIN40COMPAT) && 00088 !TestWF(pwnd, WFDLGFRAME) && 00089 !TestWF(pwnd, WEFDLGMODALFRAME)) { 00090 return(HTNOWHERE); 00091 00092 } else { 00093 return(HTBORDER); // We are on a dlg frame. 00094 } 00095 } else { 00096 00097 int ht; 00098 00099 // 00100 // Note this improvement. The HT codes are numbered so that 00101 // if you subtract HTSIZEFIRST-1 from them all, they sum up. I.E., 00102 // (HTLEFT - HTSIZEFIRST + 1) + (HTTOP - HTSIZEFIRST + 1) == 00103 // (HTTOPLEFT - HTSIZEFIRST + 1). 00104 // 00105 00106 if (TestWF(pwnd, WEFTOOLWINDOW)) 00107 InflateRect(&rcWindow, -SYSMETRTL(CXSMSIZE), -SYSMETRTL(CYSMSIZE)); 00108 else 00109 InflateRect(&rcWindow, -SYSMETRTL(CXSIZE), -SYSMETRTL(CYSIZE)); 00110 00111 if (pt.y < rcWindow.top) 00112 ht = (HTTOP - HTSIZEFIRST + 1); 00113 else if (pt.y >= rcWindow.bottom) 00114 ht = (HTBOTTOM - HTSIZEFIRST + 1); 00115 else 00116 ht = 0; 00117 00118 if (pt.x < rcWindow.left) 00119 ht += (HTLEFT - HTSIZEFIRST + 1); 00120 else if (pt.x >= rcWindow.right) 00121 ht += (HTRIGHT - HTSIZEFIRST + 1); 00122 00123 return (ht + HTSIZEFIRST - 1); 00124 } 00125 } 00126 00127 // Are we above the client area? 00128 if (pt.y < rcClientAdj.top) 00129 { 00130 // Are we in the caption? 00131 if (TestWF(pwnd, WFBORDERMASK) == LOBYTE(WFCAPTION)) 00132 { 00133 CaptionHit: 00134 00135 #ifdef USE_MIRRORING 00136 if (TestWF(pwnd, WEFLAYOUTRTL)) { 00137 pt.x = pwnd->rcWindow.right - (pt.x - pwnd->rcWindow.left); 00138 } 00139 #endif 00140 00141 if (pt.y >= rcWindow.top) 00142 { 00143 if (TestWF(pwnd, WEFTOOLWINDOW)) 00144 { 00145 rcWindow.top += SYSMETRTL(CYSMCAPTION); 00146 dxButton = SYSMETRTL(CXSMSIZE); 00147 } 00148 else 00149 { 00150 rcWindow.top += SYSMETRTL(CYCAPTION); 00151 dxButton = SYSMETRTL(CXSIZE); 00152 } 00153 00154 if ((pt.y >= rcWindow.top) && TestWF(pwnd, WFMPRESENT)) 00155 return(HTMENU); 00156 00157 if ((pt.x >= rcWindow.left) && 00158 (pt.x < rcWindow.right) && 00159 (pt.y < rcWindow.top)) 00160 { 00161 // Are we in the window menu? 00162 if (TestWF(pwnd, WFSYSMENU)) 00163 { 00164 rcWindow.left += dxButton; 00165 if (pt.x < rcWindow.left) 00166 { 00167 if (!_HasCaptionIcon(pwnd)) 00168 // iconless windows have no sysmenu hit rect 00169 return(HTCAPTION); 00170 00171 return(HTSYSMENU); 00172 } 00173 } 00174 else if (TestWF(pwnd, WFWIN40COMPAT)) 00175 return(HTCAPTION); 00176 00177 // only a close button if window has a system menu 00178 00179 // Are we in the close button? 00180 rcWindow.right -= dxButton; 00181 if (pt.x >= rcWindow.right) 00182 return HTCLOSE; 00183 00184 if ((pt.x < rcWindow.right) && !TestWF(pwnd, WEFTOOLWINDOW)) 00185 { 00186 // Are we in the maximize/restore button? 00187 if (TestWF(pwnd, (WFMAXBOX | WFMINBOX))) 00188 { 00189 // Note that sizing buttons are same width for both 00190 // big captions and small captions. 00191 rcWindow.right -= dxButton; 00192 if (pt.x >= rcWindow.right) 00193 return HTZOOM; 00194 00195 // Are we in the minimize button? 00196 rcWindow.right -= dxButton; 00197 if (pt.x >= rcWindow.right) 00198 return HTREDUCE; 00199 } 00200 else if (TestWF(pwnd, WEFCONTEXTHELP)) 00201 { 00202 rcWindow.right -= dxButton; 00203 if (pt.x >= rcWindow.right) 00204 return HTHELP; 00205 } 00206 } 00207 } 00208 } 00209 00210 // We're in the caption proper 00211 return HTCAPTION; 00212 } 00213 00214 // 00215 // Are we in the menu? 00216 // 00217 if (TestWF(pwnd, WFMPRESENT)) 00218 return HTMENU; 00219 } 00220 } 00221 else 00222 { 00223 // 00224 // NOTE: 00225 // We can only be here if we are on the client edge, horz scroll, 00226 // sizebox, or vert scroll. Hence, if we are not on the first 3, 00227 // we must be on the last one. 00228 // 00229 00230 // 00231 // Are we on the client edge? 00232 // 00233 if (TestWF(pwnd, WEFCLIENTEDGE)) 00234 { 00235 InflateRect(&rcClientAdj, -SYSMETRTL(CXEDGE), -SYSMETRTL(CYEDGE)); 00236 if (!PtInRect(&rcClientAdj, pt)) 00237 return(HTBORDER); 00238 } 00239 00240 // 00241 // Are we on the scrollbars? 00242 // 00243 if (TestWF(pwnd, WFHPRESENT) && (pt.y >= rcClient.bottom)) 00244 { 00245 int iHitTest=HTHSCROLL; 00246 UserAssert(pt.y < rcClientAdj.bottom); 00247 00248 if (TestWF(pwnd, WFVPRESENT)) { 00249 PWND pwndSizeBox = SizeBoxHwnd(pwnd); 00250 00251 if(pt.x >= rcClient.right) 00252 return(pwndSizeBox ? HTBOTTOMRIGHT : HTGROWBOX); 00253 #ifdef USE_MIRRORING 00254 // 00255 // Mirror the grip box location so that it becomes 00256 // on the bottom-left side if this is a RTL mirrrored 00257 // windows. 00258 // 00259 else if (TestWF(pwnd, WEFLAYOUTRTL) && (pt.x < rcClient.left)) 00260 return(pwndSizeBox ? HTBOTTOMLEFT : HTGROWBOX); 00261 #endif 00262 } 00263 00264 return(iHitTest); 00265 } 00266 else 00267 { 00268 UserAssert(TestWF(pwnd, WFVPRESENT)); 00269 #ifdef USE_MIRRORING 00270 if ((!!TestWF(pwnd, WEFLEFTSCROLL)) ^ (!!TestWF(pwnd, WEFLAYOUTRTL))) { 00271 #else 00272 if (TestWF(pwnd, WEFLEFTSCROLL)) { 00273 #endif 00274 UserAssert(pt.x < rcClient.left); 00275 UserAssert(pt.x >= rcClientAdj.left); 00276 } else { 00277 UserAssert(pt.x >= rcClient.right); 00278 UserAssert(pt.x < rcClientAdj.right); 00279 } 00280 return(HTVSCROLL); 00281 } 00282 } 00283 00284 // 00285 // We give up. 00286 // 00287 // Win31 returned HTNOWHERE in this case; For compatibility, we will 00288 // keep it that way. 00289 // 00290 return(HTNOWHERE); 00291 00292 } 00293 00294 BOOL _FChildVisible( 00295 PWND pwnd) 00296 { 00297 while (TestwndChild(pwnd)) { 00298 pwnd = REBASEPWND(pwnd, spwndParent); 00299 if (pwnd == NULL) 00300 break; 00301 if (!TestWF(pwnd, WFVISIBLE)) 00302 return FALSE; 00303 } 00304 00305 return TRUE; 00306 } 00307 00308 /***************************************************************************\ 00309 * _MapWindowPoints 00310 * 00311 * 00312 * History: 00313 * 03-03-92 JimA Ported from Win 3.1 sources. 00314 \***************************************************************************/ 00315 00316 int _MapWindowPoints( 00317 PWND pwndFrom, 00318 PWND pwndTo, 00319 LPPOINT lppt, 00320 DWORD cpt) 00321 { 00322 #ifdef USE_MIRRORING 00323 int dx = 0, dy = 0; 00324 int SaveLeft, Sign = 1; 00325 RECT *pR = (RECT *)lppt; 00326 BOOL bMirrored = FALSE; 00327 #else 00328 int dx, dy; 00329 LPPOINT pptFrom, pptTo; 00330 #endif 00331 00332 /* 00333 * If a window is NULL, use the desktop window. 00334 * If the window is the desktop, don't offset by 00335 * the client rect, since it won't work if the screen 00336 * origin is not (0,0) - use zero instead. 00337 */ 00338 00339 /* 00340 * Compute deltas 00341 */ 00342 #ifdef USE_MIRRORING 00343 if (pwndFrom && GETFNID(pwndFrom) != FNID_DESKTOP) { 00344 if (TestWF(pwndFrom, WEFLAYOUTRTL)) { 00345 Sign = -Sign; 00346 dx = -pwndFrom->rcClient.right; 00347 bMirrored = (cpt == 2); 00348 } else { 00349 dx = pwndFrom->rcClient.left; 00350 } 00351 dy = pwndFrom->rcClient.top; 00352 } 00353 00354 if (pwndTo && GETFNID(pwndTo) != FNID_DESKTOP) { 00355 if (TestWF(pwndTo, WEFLAYOUTRTL)) { 00356 Sign = -Sign; 00357 dx = dx + Sign * pwndTo->rcClient.right; 00358 bMirrored = (cpt == 2); 00359 } else { 00360 dx = dx - Sign * pwndTo->rcClient.left; 00361 } 00362 dy = dy - pwndTo->rcClient.top; 00363 } 00364 00365 #else 00366 if (pwndFrom == NULL || GETFNID(pwndFrom) == FNID_DESKTOP) { 00367 pptFrom = PZERO(POINT); 00368 } else { 00369 pptFrom = (LPPOINT) &pwndFrom->rcClient; 00370 } 00371 00372 if (pwndTo == NULL || GETFNID(pwndTo) == FNID_DESKTOP) { 00373 pptTo = PZERO(POINT); 00374 } else { 00375 pptTo = (LPPOINT) &pwndTo->rcClient; 00376 } 00377 dx = pptFrom->x - pptTo->x; 00378 dy = pptFrom->y - pptTo->y; 00379 #endif 00380 00381 /* 00382 * Map the points 00383 */ 00384 while (cpt--) { 00385 lppt->x += dx; 00386 #ifdef USE_MIRRORING 00387 lppt->x *= Sign; 00388 #endif 00389 lppt->y += dy; 00390 ++lppt; 00391 } 00392 00393 #ifdef USE_MIRRORING 00394 if (bMirrored) { //Special case for Rect 00395 SaveLeft = min (pR->left, pR->right); 00396 pR->right = max (pR->left, pR->right); 00397 pR->left = SaveLeft; 00398 } 00399 #endif 00400 return MAKELONG(dx, dy); 00401 } 00402 00403 00404 /***************************************************************************\ 00405 * 00406 * GetRealClientRect() 00407 * 00408 * Gets real client rectangle, inc. scrolls and excl. one row or column 00409 * of minimized windows. 00410 * 00411 * If hwndParent is the desktop, then 00412 * * If pMonitor is NULL, use the primary monitor 00413 * * Otherwise use the appropriate monitor's rectangles 00414 * 00415 \***************************************************************************/ 00416 00417 void GetRealClientRect( 00418 PWND pwnd, 00419 LPRECT prc, 00420 UINT uFlags, 00421 PMONITOR pMonitor 00422 ) 00423 { 00424 if (GETFNID(pwnd) == FNID_DESKTOP) { 00425 if (!pMonitor) { 00426 pMonitor = GetPrimaryMonitor(); 00427 } 00428 *prc = (uFlags & GRC_FULLSCREEN) ? pMonitor->rcMonitor : pMonitor->rcWork; 00429 } else { 00430 GetRect(pwnd, prc, GRECT_CLIENT | GRECT_CLIENTCOORDS); 00431 if (uFlags & GRC_SCROLLS) { 00432 if (TestWF(pwnd, WFHPRESENT)){ 00433 prc->bottom += SYSMETRTL(CYHSCROLL); 00434 } 00435 00436 if (TestWF(pwnd, WFVPRESENT)) { 00437 prc->right += SYSMETRTL(CXVSCROLL); 00438 } 00439 } 00440 } 00441 00442 if (uFlags & GRC_MINWNDS) { 00443 switch (SYSMETRTL(ARRANGE) & ~ARW_HIDE) { 00444 case ARW_TOPLEFT | ARW_RIGHT: 00445 case ARW_TOPRIGHT | ARW_LEFT: 00446 // 00447 // Leave space on top for one row of min windows 00448 // 00449 prc->top += SYSMETRTL(CYMINSPACING); 00450 break; 00451 00452 case ARW_TOPLEFT | ARW_DOWN: 00453 case ARW_BOTTOMLEFT | ARW_UP: 00454 // 00455 // Leave space on left for one column of min windows 00456 // 00457 prc->left += SYSMETRTL(CXMINSPACING); 00458 break; 00459 00460 case ARW_TOPRIGHT | ARW_DOWN: 00461 case ARW_BOTTOMRIGHT | ARW_UP: 00462 // 00463 // Leave space on right for one column of min windows 00464 // 00465 prc->right -= SYSMETRTL(CXMINSPACING); 00466 break; 00467 00468 case ARW_BOTTOMLEFT | ARW_RIGHT: 00469 case ARW_BOTTOMRIGHT | ARW_LEFT: 00470 // 00471 // Leave space on bottom for one row of min windows 00472 // 00473 prc->bottom -= SYSMETRTL(CYMINSPACING); 00474 break; 00475 } 00476 } 00477 } 00478 00479 00480 /***************************************************************************\ 00481 * _GetLastActivePopup (API) 00482 * 00483 * 00484 * 00485 * History: 00486 * 11-27-90 darrinm Ported from Win 3.0 sources. 00487 * 02-19-91 JimA Added enum access check 00488 \***************************************************************************/ 00489 00490 PWND _GetLastActivePopup( 00491 PWND pwnd) 00492 { 00493 if (pwnd->spwndLastActive == NULL) 00494 return pwnd; 00495 00496 return REBASEPWND(pwnd, spwndLastActive); 00497 } 00498 00499 00500 /***************************************************************************\ 00501 * IsDescendant 00502 * 00503 * Internal version if IsChild that is a bit faster and ignores the WFCHILD 00504 * business. 00505 * 00506 * Returns TRUE if pwndChild == pwndParent (IsChild doesn't). 00507 * 00508 * History: 00509 * 07-22-91 darrinm Translated from Win 3.1 ASM code. 00510 * 03-03-94 Johnl Moved from server 00511 \***************************************************************************/ 00512 00513 BOOL _IsDescendant( 00514 PWND pwndParent, 00515 PWND pwndChild) 00516 { 00517 while (1) { 00518 if (pwndParent == pwndChild) 00519 return TRUE; 00520 if (GETFNID(pwndChild) == FNID_DESKTOP) 00521 break; 00522 pwndChild = REBASEPWND(pwndChild, spwndParent); 00523 } 00524 00525 return FALSE; 00526 } 00527 00528 /***************************************************************************\ 00529 * IsVisible 00530 * 00531 * Return whether or not a given window can be drawn in or not. 00532 * 00533 * History: 00534 * 07-22-91 darrinm Translated from Win 3.1 ASM code. 00535 \***************************************************************************/ 00536 00537 BOOL IsVisible( 00538 PWND pwnd) 00539 { 00540 PWND pwndT; 00541 00542 for (pwndT = pwnd; pwndT; pwndT = REBASEPWND(pwndT, spwndParent)) { 00543 00544 /* 00545 * Invisible windows are always invisible 00546 */ 00547 if (!TestWF(pwndT, WFVISIBLE)) 00548 return FALSE; 00549 00550 if (TestWF(pwndT, WFMINIMIZED)) { 00551 00552 /* 00553 * Children of minimized windows are always invisible. 00554 */ 00555 if (pwndT != pwnd) 00556 return FALSE; 00557 } 00558 00559 /* 00560 * If we're at the desktop, then we don't want to go any further. 00561 */ 00562 if (GETFNID(pwndT) == FNID_DESKTOP) 00563 break; 00564 } 00565 00566 return TRUE; 00567 } 00568 00569 00570 /***************************************************************************\ 00571 * 00572 * Function: GetWindowBorders 00573 * 00574 * Synopsis: Calculates # of borders around window 00575 * 00576 * Algorithm: Calculate # of window borders and # of client borders 00577 * 00578 * This routine is ported from Chicago wmclient.c -- FritzS 00579 * 00580 \***************************************************************************/ 00581 00582 int GetWindowBorders(LONG lStyle, DWORD dwExStyle, BOOL fWindow, BOOL fClient) 00583 { 00584 int cBorders = 0; 00585 00586 if (fWindow) { 00587 // 00588 // Is there a 3D border around the window? 00589 // 00590 if (dwExStyle & WS_EX_WINDOWEDGE) 00591 cBorders += 2; 00592 else if (dwExStyle & WS_EX_STATICEDGE) 00593 ++cBorders; 00594 00595 // 00596 // Is there a single flat border around the window? This is true for 00597 // WS_BORDER, WS_DLGFRAME, and WS_EX_DLGMODALFRAME windows. 00598 // 00599 if ( (lStyle & WS_CAPTION) || (dwExStyle & WS_EX_DLGMODALFRAME) ) 00600 ++cBorders; 00601 00602 // 00603 // Is there a sizing flat border around the window? 00604 // 00605 if (lStyle & WS_SIZEBOX) 00606 cBorders += gpsi->gclBorder; 00607 } 00608 00609 if (fClient) { 00610 // 00611 // Is there a 3D border around the client? 00612 // 00613 if (dwExStyle & WS_EX_CLIENTEDGE) 00614 cBorders += 2; 00615 } 00616 00617 return(cBorders); 00618 } 00619 00620 00621 00622 /***************************************************************************\ 00623 * SizeBoxHwnd() 00624 * 00625 * Returns the HWND that will be sized if the user drags in the given window's 00626 * sizebox -- If NULL, then the sizebox is not needed 00627 * 00628 * Criteria for choosing what window will be sized: 00629 * find first sizeable parent; if that parent is not maximized and the child's 00630 * bottom, right corner is within a scroll bar height and width of the parent's 00631 * bottom, right corner, that parent will be sized. 00632 * 00633 * From Chicago 00634 \***************************************************************************/ 00635 00636 PWND SizeBoxHwnd( 00637 PWND pwnd) 00638 { 00639 #ifdef USE_MIRRORING 00640 BOOL bMirroredSizeBox = (BOOL) TestWF(pwnd, WEFLAYOUTRTL); 00641 #endif 00642 00643 int xbrChild; 00644 int ybrChild = pwnd->rcWindow.bottom; 00645 00646 #ifdef USE_MIRRORING 00647 if (bMirroredSizeBox) { 00648 xbrChild = pwnd->rcWindow.left; 00649 } else 00650 #endif 00651 { 00652 xbrChild = pwnd->rcWindow.right; 00653 } 00654 00655 while (GETFNID(pwnd) != FNID_DESKTOP) { 00656 if (TestWF(pwnd, WFSIZEBOX)) { 00657 // First sizeable parent found 00658 int xbrParent; 00659 int ybrParent; 00660 00661 if (TestWF(pwnd, WFMAXIMIZED)) 00662 return(NULL); 00663 00664 #ifdef USE_MIRRORING 00665 if (bMirroredSizeBox) { 00666 xbrParent = pwnd->rcClient.left; 00667 } else 00668 #endif 00669 { 00670 xbrParent = pwnd->rcClient.right; 00671 } 00672 ybrParent = pwnd->rcClient.bottom; 00673 00674 /* If the sizebox dude is within an EDGE of the client's bottom 00675 * right corner (left corner for mirrored windows), let this succeed. 00676 * That way people who draw their own sunken clients will be happy. 00677 */ 00678 #ifdef USE_MIRRORING 00679 if (bMirroredSizeBox) { 00680 if ((xbrChild - SYSMETRTL(CXEDGE) > xbrParent) || (ybrChild + SYSMETRTL(CYEDGE) < ybrParent)) { 00681 // 00682 // Child's bottom, left corner of SIZEBOX isn't close enough 00683 // to bottom left of parent's client. 00684 // 00685 return(NULL); 00686 } 00687 } else 00688 #endif 00689 { 00690 if ((xbrChild + SYSMETRTL(CXEDGE) < xbrParent) || (ybrChild + SYSMETRTL(CYEDGE) < ybrParent)) { 00691 // 00692 // Child's bottom, right corner of SIZEBOX isn't close enough 00693 // to bottom right of parent's client. 00694 // 00695 return(NULL); 00696 } 00697 } 00698 00699 return(pwnd); 00700 } 00701 00702 if (!TestWF(pwnd, WFCHILD) || TestWF(pwnd, WFCPRESENT)) 00703 break; 00704 00705 pwnd = REBASEPWND(pwnd, spwndParent); 00706 } 00707 return(NULL); 00708 } 00709 00710 00711 00712 // -------------------------------------------------------------------------- 00713 // 00714 // NeedsWindowEdge() 00715 // 00716 // Modifies style/extended style to enforce WS_EX_WINDOWEDGE when we want 00717 // it. 00718 // 00719 // 00720 // When do we want WS_EX_WINDOWEDGE on a window? 00721 // (1) If the window has a caption 00722 // (2) If the window has the WS_DLGFRAME or WS_EX_DLGFRAME style (note 00723 // that this takes care of (1)) 00724 // (3) If the window has WS_THICKFRAME 00725 // 00726 // -------------------------------------------------------------------------- 00727 BOOL NeedsWindowEdge(DWORD dwStyle, DWORD dwExStyle, BOOL fNewApp) 00728 { 00729 BOOL fGetsWindowEdge; 00730 00731 fGetsWindowEdge = FALSE; 00732 00733 if (dwExStyle & WS_EX_DLGMODALFRAME) 00734 fGetsWindowEdge = TRUE; 00735 else if (dwExStyle & WS_EX_STATICEDGE) 00736 fGetsWindowEdge = FALSE; 00737 else if (dwStyle & WS_THICKFRAME) 00738 fGetsWindowEdge = TRUE; 00739 else switch (dwStyle & WS_CAPTION) 00740 { 00741 case WS_DLGFRAME: 00742 fGetsWindowEdge = TRUE; 00743 break; 00744 00745 case WS_CAPTION: 00746 fGetsWindowEdge = fNewApp; 00747 break; 00748 } 00749 00750 return(fGetsWindowEdge); 00751 } 00752 00753 00754 // -------------------------------------------------------------------------- 00755 // 00756 // HasCaptionIcon() 00757 // 00758 // TRUE if this is a window that should have an icon drawn in its caption 00759 // FALSE otherwise 00760 // 00761 // -------------------------------------------------------------------------- 00762 00763 BOOL _HasCaptionIcon(PWND pwnd) 00764 { 00765 HICON hIcon; 00766 PCLS pcls; 00767 00768 if (TestWF(pwnd, WEFTOOLWINDOW)) 00769 // it's a tool window -- it doesn't get an icon 00770 return(FALSE); 00771 00772 if ((TestWF(pwnd, WFBORDERMASK) != (BYTE)LOBYTE(WFDLGFRAME)) && 00773 !TestWF(pwnd, WEFDLGMODALFRAME)) 00774 // they are not trying to look like a dialog, they get an icon 00775 return TRUE; 00776 00777 if (!TestWF(pwnd, WFWIN40COMPAT) && 00778 (((PCLS)REBASEALWAYS(pwnd, pcls))->atomClassName == (ATOM)(ULONG_PTR)DIALOGCLASS)) 00779 // it's an older REAL dialog -- it doesn't get an icon 00780 return(FALSE); 00781 00782 hIcon = (HICON) _GetProp(pwnd, MAKEINTATOM(gpsi->atomIconSmProp), TRUE); 00783 00784 if (hIcon) { 00785 // it's a 4.0 dialog with a small icon -- if that small icon is 00786 // something other than the generic small windows icon, it gets an icon 00787 return(hIcon != gpsi->hIconSmWindows); 00788 } 00789 hIcon = (HICON) _GetProp(pwnd, MAKEINTATOM(gpsi->atomIconProp), TRUE); 00790 00791 if (hIcon && (hIcon != gpsi->hIcoWindows)) 00792 // it's a 4.0 dialog with no small icon, but instead a large icon 00793 // that's not the generic windows icon -- it gets an icon 00794 return(TRUE); 00795 00796 pcls = REBASEALWAYS(pwnd, pcls); 00797 if (pcls->spicnSm) { 00798 if (pcls->spicnSm != HMObjectFromHandle(gpsi->hIconSmWindows)) { 00799 // it's a 4.0 dialog with a class icon that's not the generic windows 00800 // icon -- it gets an icon 00801 return(TRUE); 00802 } 00803 } 00804 00805 // it's a 4.0 dialog with no small or large icon -- it doesn't get an icon 00806 return(FALSE); 00807 } 00808 00809 00810 /***************************************************************************\ 00811 * GetTopLevelWindow 00812 * 00813 * History: 00814 * 10-19-90 darrinm Ported from Win 3.0 sources. 00815 \***************************************************************************/ 00816 00817 PWND GetTopLevelWindow( 00818 PWND pwnd) 00819 { 00820 if (pwnd != NULL) { 00821 while (TestwndChild(pwnd)) 00822 pwnd = REBASEPWND(pwnd, spwndParent); 00823 } 00824 00825 return pwnd; 00826 } 00827 00828 00829 00830 /***************************************************************************\ 00831 * GetRect 00832 * 00833 * Returns a rect from pwnd (client or window) and returns it in 00834 * one of these coordinate schemes: 00835 * 00836 * (a) Own Client 00837 * (b) Own Window 00838 * (c) Parent Client 00839 * 00840 * Moreover, it does the right thing for case (d) when pwnd is top level. 00841 * In that case, we never want to offset by origin of the parent, which is the 00842 * desktop, since that will not work when the virtual screen has a 00843 * negative origin. And it does the right thing for cases (b) and (c) 00844 * if pwnd is the desktop. 00845 * 00846 * NOTE: The Win95 version of this function had a flag GRECT_SCREENCOORDS, 00847 * which would return the rectangle in screen coords. There's no reason to 00848 * call a function to do this, since the smallest and fastest to copy a 00849 * rectangle is simple assignment. Therefore, I removed GRECT_SCREENCOORDS. 00850 * 00851 * History: 00852 * 19-Sep-1996 adams Created. 00853 \***************************************************************************/ 00854 00855 void 00856 GetRect(PWND pwnd, LPRECT lprc, UINT uCoords) 00857 { 00858 PWND pwndParent; 00859 LPRECT lprcOffset; 00860 00861 UserAssert(lprc); 00862 UserAssert((uCoords & ~(GRECT_COORDMASK | GRECT_RECTMASK)) == 0); 00863 UserAssert(uCoords & GRECT_COORDMASK); 00864 UserAssert(uCoords & GRECT_RECTMASK); 00865 00866 *lprc = (uCoords & GRECT_WINDOW) ? pwnd->rcWindow : pwnd->rcClient; 00867 00868 /* 00869 * If this is the desktop window, we have what we want, whether we 00870 * are asking for GRECT_PARENTCOORDS, WINDOWCOORD or CLIENTCOORDS 00871 */ 00872 if (GETFNID(pwnd) == FNID_DESKTOP) 00873 return; 00874 00875 switch (uCoords & GRECT_COORDMASK) { 00876 case GRECT_PARENTCOORDS: 00877 pwndParent = REBASEPWND(pwnd, spwndParent); 00878 if (GETFNID(pwndParent) == FNID_DESKTOP) 00879 return; 00880 00881 lprcOffset = &pwndParent->rcClient; 00882 00883 #if defined(USE_MIRRORING) 00884 // 00885 // Let's mirror the edges of the child's window since the parent 00886 // is mirrored, so should the child window be. [samera] 00887 // 00888 if (TestWF(pwndParent,WEFLAYOUTRTL) && 00889 (uCoords & GRECT_WINDOW) && 00890 (TestWF(pwnd,WFCHILD))) { 00891 int iLeft; 00892 00893 // 00894 // I am using OffsetRect instead of implementing a new 00895 // OffsetMirrorRect API since this is the only place I am 00896 // doing it in. 00897 // 00898 // Since screen coordinates are not mirrored, the rect offsetting 00899 // should be done relative to prcOffset->right since it is the 00900 // leading edge for mirrored windows. [samera] 00901 // 00902 00903 UserVerify(OffsetRect(lprc, -lprcOffset->right, -lprcOffset->top)); 00904 00905 iLeft = lprc->left; 00906 lprc->left = (lprc->right * -1); 00907 lprc->right = (iLeft * -1); 00908 00909 return; 00910 } 00911 #endif 00912 00913 break; 00914 00915 case GRECT_WINDOWCOORDS: 00916 lprcOffset = &pwnd->rcWindow; 00917 break; 00918 00919 case GRECT_CLIENTCOORDS: 00920 lprcOffset = &pwnd->rcClient; 00921 break; 00922 00923 default: 00924 UserAssert(0 && "Logic error in _GetRect - invalid uCoords"); 00925 } 00926 00927 UserVerify(OffsetRect(lprc, -lprcOffset->left, -lprcOffset->top)); 00928 }

Generated on Sat May 15 19:42:25 2004 for test by doxygen 1.3.7