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

caption.c

Go to the documentation of this file.
00001 /****************************** Module Header ******************************\ 00002 * Module Name: caption.c (aka wmcap.c) 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * History: 00007 * 28-Oct-1990 MikeHar Ported functions from Win 3.0 sources. 00008 * 01-Feb-1991 MikeKe Added Revalidation code (None) 00009 * 03-Jan-1992 IanJa Neutralized (ANSI/wide-character) 00010 \***************************************************************************/ 00011 00012 #include "precomp.h" 00013 #pragma hdrstop 00014 00015 00016 #define MIN 0x01 00017 #define MAX 0x02 00018 #define NOMIN 0x04 00019 #define NOMAX 0x08 00020 #define NOCLOSE 0x10 00021 #define SMCAP 0x20 00022 #define NOSIZE (NOMIN | NOMAX) 00023 00024 /***************************************************************************\ 00025 * CalcCaptionButton 00026 * 00027 * This calculates the location of the caption button. 00028 \***************************************************************************/ 00029 00030 DWORD xxxCalcCaptionButton(PWND pwnd, int iButton, LPWORD pcmd, LPRECT prcBtn, LPWORD pbm) 00031 { 00032 int x, y, cBorders, cxS, cyS; 00033 00034 CheckLock(pwnd); 00035 00036 *pcmd = 0; 00037 00038 if (TestWF(pwnd, WFMINIMIZED)) { 00039 00040 x = -SYSMET(CXFIXEDFRAME); 00041 y = -SYSMET(CYFIXEDFRAME); 00042 00043 } else { 00044 00045 cBorders = GetWindowBorders(pwnd->style, pwnd->ExStyle, TRUE, FALSE); 00046 x = -cBorders * SYSMET(CXBORDER); 00047 y = -cBorders * SYSMET(CYBORDER); 00048 } 00049 00050 CopyInflateRect(prcBtn, &pwnd->rcWindow, x, y); 00051 00052 x = -pwnd->rcWindow.left; 00053 y = -pwnd->rcWindow.top; 00054 00055 /* 00056 * Get real caption area: subtract final border underneath caption 00057 * that separates it from everything else. 00058 */ 00059 if (TestWF(pwnd, WEFTOOLWINDOW)) { 00060 cxS = SYSMET(CXSMSIZE); 00061 cyS = SYSMET(CYSMSIZE); 00062 } else { 00063 cxS = SYSMET(CXSIZE); 00064 cyS = SYSMET(CYSIZE); 00065 } 00066 00067 if (iButton == INDEX_TITLEBAR_CLOSEBUTTON) { 00068 00069 if (xxxMNCanClose(pwnd)) { 00070 *pbm = TestWF(pwnd, WEFTOOLWINDOW) ? OBI_CLOSE_PAL : OBI_CLOSE; 00071 *pcmd = SC_CLOSE; 00072 } 00073 00074 } else if (iButton == INDEX_TITLEBAR_MINBUTTON) { 00075 00076 /* 00077 * Reduce button isn't last button, so shift left by one button 00078 */ 00079 if (TestWF(pwnd, WFMINBOX)) { 00080 00081 prcBtn->right -= cxS * 2; 00082 x += SYSMET(CXEDGE); 00083 00084 if (TestWF(pwnd, WFMINIMIZED)) { 00085 *pbm = OBI_RESTORE; 00086 *pcmd = SC_RESTORE; 00087 } else { 00088 *pbm = OBI_REDUCE; 00089 *pcmd = SC_MINIMIZE; 00090 } 00091 } 00092 00093 } else if (iButton == INDEX_TITLEBAR_MAXBUTTON) { 00094 00095 if (TestWF(pwnd, WFMAXBOX)) { 00096 00097 prcBtn->right -= cxS; 00098 00099 if (TestWF(pwnd, WFMAXIMIZED)) { 00100 *pbm = OBI_RESTORE; 00101 *pcmd = SC_RESTORE; 00102 } else { 00103 *pbm = OBI_ZOOM; 00104 *pcmd = SC_MAXIMIZE; 00105 } 00106 } 00107 00108 } else { // iButton == INDEX_TITLEBAR_HELPBUTTON 00109 00110 if (TestWF(pwnd, WEFCONTEXTHELP)) { 00111 prcBtn->right -= cxS; 00112 00113 *pbm = OBI_HELP; 00114 *pcmd = SC_CONTEXTHELP; 00115 } 00116 } 00117 00118 if (*pcmd) { 00119 00120 prcBtn->bottom = prcBtn->top + cyS; 00121 prcBtn->left = prcBtn->right - cxS; 00122 00123 /* 00124 * Adjust 'x' and 'y' to window coordinates 00125 */ 00126 x += prcBtn->left; 00127 y += prcBtn->top + SYSMET(CYEDGE); 00128 00129 /* 00130 * rcBtn (screen coords hit rect) has a one-border tolerance all 00131 * around 00132 */ 00133 InflateRect(prcBtn, SYSMET(CXBORDER), SYSMET(CYBORDER)); 00134 #ifdef USE_MIRRORING 00135 //Mirror the rect because the buttons in the left hand side of the window if it mirrored 00136 if (TestWF(pwnd, WEFLAYOUTRTL)) { 00137 cxS = prcBtn->right - prcBtn->left; 00138 prcBtn->right = pwnd->rcWindow.right - (prcBtn->left - pwnd->rcWindow.left); 00139 prcBtn->left = prcBtn->right - cxS; 00140 } 00141 #endif 00142 } 00143 00144 return (DWORD)MAKELONG(x, y); 00145 } 00146 00147 /***************************************************************************\ 00148 * xxxTrackCaptionButton 00149 * 00150 * Handles clicking and dragging on caption buttons. 00151 * We draw the button depressed then track the mouse. If the user moves 00152 * outside of the button, undepress it. When the mouse button is finally 00153 * released, we return whether the mouse was inside the button or not. I.E., 00154 * whether the button was clicked. 00155 * 00156 \***************************************************************************/ 00157 00158 WORD xxxTrackCaptionButton( 00159 PWND pwnd, 00160 UINT hit) 00161 { 00162 WORD cmd; 00163 MSG msg; 00164 HDC hdc; 00165 WORD bm; 00166 int x; 00167 int y; 00168 WORD wState; 00169 WORD wNewState; 00170 BOOL fMouseUp = FALSE; 00171 RECT rcBtn; 00172 DWORD dwWhere; 00173 int iButton; 00174 WORD wf; 00175 UserAssert(IsWinEventNotifyDeferredOK()); 00176 00177 CheckLock(pwnd); 00178 00179 /* 00180 * Set up iButton for this and future STATECHANGE events 00181 */ 00182 switch (hit) { 00183 case HTCLOSE: 00184 iButton = INDEX_TITLEBAR_CLOSEBUTTON; 00185 wf = WFCLOSEBUTTONDOWN; 00186 break; 00187 00188 case HTREDUCE: 00189 iButton = INDEX_TITLEBAR_MINBUTTON; 00190 wf = WFREDUCEBUTTONDOWN; 00191 break; 00192 00193 case HTZOOM: 00194 iButton = INDEX_TITLEBAR_MAXBUTTON; 00195 wf = WFZOOMBUTTONDOWN; 00196 break; 00197 00198 case HTHELP: 00199 iButton = INDEX_TITLEBAR_HELPBUTTON; 00200 wf = WFHELPBUTTONDOWN; 00201 break; 00202 00203 default: 00204 UserAssert(FALSE); 00205 } 00206 dwWhere = xxxCalcCaptionButton(pwnd, iButton, &cmd, &rcBtn, &bm); 00207 x = GET_X_LPARAM(dwWhere); 00208 y = GET_Y_LPARAM(dwWhere); 00209 00210 if (cmd) { 00211 /* 00212 * Draw the image in its depressed state. 00213 */ 00214 hdc = _GetDCEx(pwnd, NULL, DCX_WINDOW | DCX_USESTYLE); 00215 BitBltSysBmp(hdc, x, y, bm + DOBI_PUSHED); 00216 _ReleaseDC(hdc); 00217 00218 wState = DOBI_PUSHED; 00219 00220 /* 00221 * Notification of button press. 00222 */ 00223 00224 SetWF(pwnd, wf); 00225 00226 if (FWINABLE()) { 00227 xxxWindowEvent(EVENT_OBJECT_STATECHANGE, pwnd, OBJID_TITLEBAR, 00228 iButton, 0); 00229 } 00230 } else { 00231 iButton = 0; 00232 } 00233 00234 xxxSetCapture(pwnd); 00235 00236 while (!fMouseUp) { 00237 00238 if (xxxPeekMessage(&msg, NULL, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE)) { 00239 if (msg.message == WM_LBUTTONUP) { 00240 00241 xxxReleaseCapture(); 00242 fMouseUp = TRUE; 00243 00244 } else if ((msg.message == WM_MOUSEMOVE) && cmd) { 00245 00246 wNewState = PtInRect(&rcBtn, msg.pt) ? DOBI_PUSHED : DOBI_NORMAL; 00247 00248 if (wState != wNewState) { 00249 wState = wNewState; 00250 00251 hdc = _GetDCEx(pwnd, NULL, DCX_WINDOW | DCX_USESTYLE); 00252 BitBltSysBmp(hdc, x, y, bm + wState); 00253 _ReleaseDC(hdc); 00254 00255 if (wState == DOBI_PUSHED) { 00256 SetWF(pwnd, wf); 00257 } else { 00258 ClrWF(pwnd, wf); 00259 } 00260 00261 if (FWINABLE()) { 00262 xxxWindowEvent(EVENT_OBJECT_STATECHANGE, pwnd, OBJID_TITLEBAR, 00263 iButton, 0); 00264 } 00265 } 00266 } 00267 } else if (!xxxSleepThread(QS_MOUSE, 0, TRUE)) { 00268 break; 00269 } 00270 if (pwnd != PtiCurrent()->pq->spwndCapture) { 00271 /* 00272 * We lost capture. This could have happened during 00273 * the WM_CAPTURECHANGED callback or later if we 00274 * are/were not in the foreground queue. 00275 */ 00276 break; 00277 } 00278 } 00279 00280 if (!cmd) 00281 return 0; 00282 00283 if (wState && (cmd != SC_CONTEXTHELP)) { 00284 hdc = _GetDCEx(pwnd, NULL, DCX_WINDOW | DCX_USESTYLE); 00285 BitBltSysBmp(hdc, x, y, bm); 00286 _ReleaseDC(hdc); 00287 00288 ClrWF(pwnd, wf); 00289 00290 if (FWINABLE()) { 00291 xxxWindowEvent(EVENT_OBJECT_STATECHANGE, pwnd, OBJID_TITLEBAR, 00292 iButton, 0); 00293 } 00294 } 00295 00296 return (fMouseUp && PtInRect(&rcBtn, msg.pt)) ? cmd : 0; 00297 } 00298 00299 /***************************************************************************\ 00300 * GetWindowSmIcon 00301 * 00302 * Gets icon to draw in caption of window 00303 * 00304 \***************************************************************************/ 00305 00306 PCURSOR xxxGetWindowSmIcon( 00307 PWND pwnd, 00308 BOOL fDontSendMsg) 00309 { 00310 PCURSOR pcursor = NULL; 00311 HICON hico = NULL; 00312 PCLS pcls = pwnd->pcls; 00313 DWORD dwResult = 0; 00314 00315 CheckLock(pwnd); 00316 00317 /* 00318 * We check per-window stuff first then per-class stuff, preferring a 00319 * real small icon over a stretched big one. 00320 * 00321 * Per-window small icon 00322 * Per-window big icon stretched small 00323 * Per-class small icon 00324 * Per-class big icon stretched small 00325 * WM_QUERYDRAGICON big icon stretched small (for 3.x dudes) 00326 * 00327 * Try window small icon first 00328 * NOTE: The WM_SETICON and WM_GETICON messags are for ISVs only. 00329 */ 00330 if ((hico = (HICON)_GetProp(pwnd, MAKEINTATOM(gpsi->atomIconSmProp), PROPF_INTERNAL)) != NULL) { 00331 00332 if (pcursor = (PCURSOR)HMValidateHandleNoSecure(hico, TYPE_CURSOR)) { 00333 return pcursor; 00334 } else { 00335 RIPMSG1(RIP_WARNING,"GetWindowSmIcon: Invalid small icon handle (0x%p)", hico); 00336 } 00337 } 00338 00339 /* 00340 * Try class small icon next 00341 */ 00342 pcursor = pcls->spicnSm; 00343 if (pcursor != NULL) 00344 return pcursor; 00345 00346 if (!TestWF(pwnd, WFWIN40COMPAT) && 00347 (!TestWF(pwnd, WFOLDUI) || 00348 !TestWF(pwnd, WEFMDICHILD)) && 00349 !fDontSendMsg) { 00350 00351 ULONG_PTR dwResult; 00352 00353 /* 00354 * A few old apps like Corel don't set their class icon and other 00355 * data until long after we need it. If we send them WM_QUERYDRAGICON, 00356 * they will fault because they don't check the return from GWL to 00357 * get their data. WFOLDUI apps won't ever get a WM_QUERYDRAGICON, 00358 * sorry. Currently the apps with this hack (not for this reason 00359 * necessarily) 00360 * Corel Photo-Paint 5.0 00361 * Myst 2.0 00362 * Visual Baler 3.0 00363 * Quicken 00364 */ 00365 if (xxxSendMessageTimeout(pwnd, 00366 WM_QUERYDRAGICON, 00367 0, 00368 0, 00369 SMTO_NORMAL, 00370 100, 00371 &dwResult)) { 00372 00373 hico = (HICON)dwResult; 00374 } 00375 00376 if (hico) { 00377 00378 hico = xxxCreateWindowSmIcon(pwnd, hico, FALSE); 00379 pcursor = (PCURSOR)HMValidateHandleNoSecure(hico, TYPE_CURSOR); 00380 00381 if (pcursor == NULL) 00382 hico = NULL; 00383 } 00384 } 00385 00386 if (pcursor == NULL) { 00387 pcursor = SYSICO(WINLOGO); 00388 } 00389 00390 return pcursor; 00391 } 00392 00393 /***************************************************************************\ 00394 * BltMe4Times 00395 * 00396 * This routine blts out two copies of the specified caption icon. One 00397 * with for an active window and one for an inactive window. 00398 * 00399 \***************************************************************************/ 00400 00401 VOID BltMe4Times( 00402 POEMBITMAPINFO pOem, 00403 int cxySlot, 00404 int cxyIcon, 00405 HDC hdcSrc, 00406 PCURSOR pcursor, 00407 UINT flags) 00408 { 00409 RECT rc; 00410 int i; 00411 int j; 00412 BOOL fMask = TRUE; 00413 LONG rop; 00414 HBRUSH hBrush; 00415 00416 hBrush = (flags & DC_INBUTTON) ? SYSHBR(3DHILIGHT) : SYSHBR(ACTIVECAPTION); 00417 00418 for (i = 0; i < 2; i++) { 00419 00420 rop = SRCAND; 00421 00422 rc.left = pOem->x; 00423 rc.top = pOem->y; 00424 rc.right = rc.left + pOem->cx; 00425 rc.bottom = rc.top + pOem->cy; 00426 FillRect(HDCBITS(), &rc, hBrush); 00427 00428 rc.top += (cxySlot - cxyIcon) / 2; 00429 rc.left += SYSMET(CXBORDER) + (cxySlot - cxyIcon) / 2; 00430 00431 for (j = 0; j < 2; j++) { 00432 BltIcon( 00433 HDCBITS(), 00434 rc.left, 00435 rc.top, 00436 cxyIcon, 00437 cxyIcon, 00438 hdcSrc, 00439 pcursor, 00440 fMask, 00441 rop); 00442 00443 fMask = !fMask; 00444 rop = SRCINVERT; 00445 } 00446 00447 pOem += DOBI_CAPOFF; 00448 hBrush = (flags & DC_INBUTTON) ? SYSHBR(3DFACE) : SYSHBR(INACTIVECAPTION); 00449 } 00450 } 00451 00452 /***************************************************************************\ 00453 * 00454 * DrawCaptionIcon 00455 * 00456 * In order to speed up the drawing of caption icons a cache is maintained. 00457 * Within the cache, the first entry, 0, is for the tray's depressed caption 00458 * look. Items 1..CCACHEDCAPTIONS are for the actual caption's icons. 00459 * 00460 \***************************************************************************/ 00461 00462 VOID DrawCaptionIcon( 00463 HDC hdc, 00464 LPRECT lprc, 00465 PCURSOR pcursor, 00466 HBRUSH hbrFill, 00467 UINT flags) 00468 { 00469 int i; 00470 int xStart = 0; 00471 int cxySlot; 00472 POEMBITMAPINFO pOem; 00473 RECT rc; 00474 CAPTIONCACHE ccTemp; 00475 00476 /* 00477 * Check the size of the icon to see if it matches the size of the 00478 * cache we created. Most of the time this will match. Also, if 00479 * we are drawing with DC_INBUTTON in 16 colors, don't cache. 00480 */ 00481 cxySlot = lprc->bottom - lprc->top; 00482 00483 if ((cxySlot != gpsi->oembmi[OBI_CAPCACHE1].cy) || (hbrFill == gpsi->hbrGray)) { 00484 00485 rc.left = lprc->left; 00486 rc.top = lprc->top; 00487 rc.right = lprc->left + cxySlot; 00488 rc.bottom = lprc->top + cxySlot; 00489 00490 FillRect(hdc, &rc, hbrFill); 00491 00492 rc.left += SYSMET(CXBORDER) + (cxySlot - SYSMET(CXSMICON)) / 2; 00493 rc.top += (cxySlot - SYSMET(CYSMICON)) / 2; 00494 00495 _DrawIconEx(hdc, 00496 rc.left, 00497 rc.top, 00498 pcursor, 00499 SYSMET(CXSMICON), 00500 SYSMET(CYSMICON), 00501 0, 00502 NULL, 00503 DI_NORMAL); 00504 00505 goto Done; 00506 } 00507 00508 if (flags & DC_INBUTTON) { 00509 00510 /* 00511 * The DC_INBUTTON icons is always slot 0. 00512 */ 00513 i = ((gcachedCaptions[0].spcursor == pcursor) ? 0 : CCACHEDCAPTIONS); 00514 00515 } else { 00516 00517 /* 00518 * Search the cache to see if this cursor is currently cached. 00519 */ 00520 for (i = 1; i < CCACHEDCAPTIONS; i++) { 00521 if (gcachedCaptions[i].spcursor == pcursor) 00522 break; 00523 } 00524 } 00525 00526 if (i >= CCACHEDCAPTIONS) { 00527 00528 /* 00529 * Icon wasn't cached, so try and add it to the cache 00530 */ 00531 if (flags & DC_INBUTTON) { 00532 00533 /* 00534 * The tray's special DC_INBUTTON style always goes in slot 0. 00535 */ 00536 i = 0; 00537 00538 } else { 00539 00540 /* 00541 * Look for an empty slot in the cache. If we can't find one, 00542 * stuff the new icon at the end of the cache. The result will 00543 * be that the last item will be deleted. 00544 */ 00545 for (i = 1; i < CCACHEDCAPTIONS - 1; i++) { 00546 if (gcachedCaptions[i].spcursor == NULL) 00547 break; 00548 } 00549 } 00550 00551 /* 00552 * Add an item to the cache by blting an active and inactive copy of 00553 * the icon. 00554 */ 00555 BltMe4Times(gcachedCaptions[i].pOem, 00556 cxySlot, 00557 SYSMET(CXSMICON), 00558 ghdcMem, 00559 pcursor, 00560 flags); 00561 00562 Lock(&(gcachedCaptions[i].spcursor), pcursor); 00563 #if DBG 00564 gcachedCaptions[i].hico = (HICON)PtoH(pcursor); 00565 #endif 00566 } 00567 00568 /* 00569 * We have a hit, so move that cached icon to the front of the cache. 00570 * This means that the least recently used icon will be the last 00571 * icon in the cache. Remember, we never update index 0 because it 00572 * is reserved for the DC_INBUTTON icon. 00573 */ 00574 for ( ; i > 1; i-- ) { 00575 00576 /* 00577 * Move the entry toward the front 00578 */ 00579 ccTemp = gcachedCaptions[i]; 00580 gcachedCaptions[i] = gcachedCaptions[i - 1]; 00581 gcachedCaptions[i - 1] = ccTemp; 00582 00583 #if DEBUGTAGS 00584 /* 00585 * In checked builds we need to adjust the lock records for 00586 * the cursor so it has the correct address. 00587 */ 00588 if (IsDbgTagEnabled(DBGTAG_TrackLocks)) { 00589 if (gcachedCaptions[i].spcursor) 00590 HMRelocateLockRecord(&(gcachedCaptions[i].spcursor), (int)sizeof(CAPTIONCACHE)); 00591 if (gcachedCaptions[i - 1].spcursor) 00592 HMRelocateLockRecord(&(gcachedCaptions[i - 1].spcursor), -(int)sizeof(CAPTIONCACHE)); 00593 } 00594 #endif 00595 } 00596 00597 00598 #if DBG 00599 /* 00600 * Make sure the icon we want to draw is the one 00601 * that we hit in the cache. 00602 */ 00603 UserAssert( gcachedCaptions[i].hico == PtoH(pcursor) ); 00604 #endif 00605 00606 /* 00607 * Determine what cached bitmap to blt. 00608 */ 00609 pOem = gcachedCaptions[i].pOem; 00610 if (!(flags & DC_ACTIVE)) 00611 pOem += DOBI_CAPOFF; 00612 00613 GreBitBlt(hdc, 00614 lprc->left, 00615 lprc->top, 00616 cxySlot, 00617 cxySlot, 00618 HDCBITS(), 00619 pOem->x, 00620 pOem->y, 00621 SRCCOPY, 00622 0); 00623 00624 Done: 00625 /* 00626 * Adjust the given rectangle for the icon we just drew 00627 */ 00628 lprc->left += cxySlot; 00629 } 00630 00631 /***************************************************************************\ 00632 * FillGradient 00633 * 00634 * The rectangle is broken into two triangles: {0, 1, 2} and {0, 2, 3}. 00635 * Color on {0, 3} is black, and on {1, 2) is the active caption color. 00636 * 00637 * 0 1 00638 * 3 2 00639 * 00640 * 12/06/96 vadimg created 00641 \***************************************************************************/ 00642 00643 void FillGradient(HDC hdc, LPCRECT prc, COLORREF rgbLeft, COLORREF rgbRight) 00644 { 00645 TRIVERTEX avert[4]; 00646 static GRADIENT_RECT auRect[1] = {0,1}; 00647 #define GetCOLOR16(RGB, clr) ((COLOR16)(Get ## RGB ## Value(clr) << 8)) 00648 00649 avert[0].Red = GetCOLOR16(R, rgbLeft); 00650 avert[0].Green = GetCOLOR16(G, rgbLeft); 00651 avert[0].Blue = GetCOLOR16(B, rgbLeft); 00652 00653 avert[1].Red = GetCOLOR16(R, rgbRight); 00654 avert[1].Green = GetCOLOR16(G, rgbRight); 00655 avert[1].Blue = GetCOLOR16(B, rgbRight); 00656 00657 avert[0].x = prc->left; 00658 avert[0].y = prc->top; 00659 avert[1].x = prc->right; 00660 avert[1].y = prc->bottom; 00661 00662 GreGradientFill(hdc, avert, 2,(PVOID)auRect, 1, GRADIENT_FILL_RECT_H); 00663 } 00664 00665 void FillCaptionGradient(HDC hdc, LPCRECT prc, BOOL fActive) 00666 { 00667 COLORREF rgbLeft, rgbRight; 00668 00669 if (fActive) { 00670 rgbLeft = gpsi->argbSystem[COLOR_ACTIVECAPTION]; 00671 rgbRight = gpsi->argbSystem[COLOR_GRADIENTACTIVECAPTION]; 00672 } else { 00673 rgbLeft = gpsi->argbSystem[COLOR_INACTIVECAPTION]; 00674 rgbRight = gpsi->argbSystem[COLOR_GRADIENTINACTIVECAPTION]; 00675 } 00676 if (rgbLeft != rgbRight) { 00677 FillGradient(hdc, prc, rgbLeft, rgbRight); 00678 } else { 00679 FillRect(hdc, prc, fActive ? SYSHBR(ACTIVECAPTION) : SYSHBR(INACTIVECAPTION)); 00680 } 00681 } 00682 00683 /***************************************************************************\ 00684 * DrawCaptionTemp 00685 * 00686 \***************************************************************************/ 00687 00688 BOOL xxxDrawCaptionTemp( 00689 PWND pwnd, // pwnd may be NULL! 00690 HDC hdc, 00691 LPRECT lprc, 00692 HFONT hFont, 00693 PCURSOR pcursor, 00694 PUNICODE_STRING pstrText, 00695 UINT flags) 00696 { 00697 int iOldMode; 00698 HBRUSH hbrFill; 00699 LONG clrOldText; 00700 LONG clrOldBk; 00701 BOOL fItFit = TRUE; 00702 BOOL fGradient = FALSE; 00703 SIZE size; 00704 UINT oldAlign; 00705 00706 CheckLock(pwnd); 00707 00708 if (lprc->right <= lprc->left) 00709 return FALSE; 00710 00711 if (pwnd != NULL) { 00712 00713 if (!pcursor && 00714 _HasCaptionIcon(pwnd) && 00715 !(flags & DC_SMALLCAP) && 00716 TestWF(pwnd, WFSYSMENU)) { 00717 00718 /* 00719 * Only get the icon if we can send messages AND the window has 00720 * a system menu. 00721 */ 00722 pcursor = xxxGetWindowSmIcon(pwnd, (flags & DC_NOSENDMSG)); 00723 } 00724 } 00725 00726 /* 00727 * Set up the colors 00728 */ 00729 if (flags & DC_ACTIVE) { 00730 00731 if (flags & DC_INBUTTON) { 00732 if (gpsi->BitCount < 8 || 00733 SYSRGB(3DHILIGHT) != SYSRGB(SCROLLBAR) || 00734 SYSRGB(3DHILIGHT) == SYSRGB(WINDOW)) { 00735 clrOldText = SYSRGB(3DFACE); 00736 clrOldBk = SYSRGB(3DHILIGHT); 00737 hbrFill = gpsi->hbrGray; 00738 iOldMode = GreSetBkMode(hdc, TRANSPARENT); 00739 } else { 00740 clrOldText = SYSRGB(BTNTEXT); 00741 clrOldBk = SYSRGB(3DHILIGHT); 00742 hbrFill = SYSHBR(3DHILIGHT); 00743 } 00744 00745 } else { 00746 clrOldText = SYSRGB(CAPTIONTEXT); 00747 clrOldBk = SYSRGB(ACTIVECAPTION); 00748 hbrFill = SYSHBR(ACTIVECAPTION); 00749 00750 if (flags & DC_GRADIENT) { 00751 fGradient = TRUE; 00752 iOldMode = GreSetBkMode(hdc, TRANSPARENT); 00753 } 00754 } 00755 00756 } else { 00757 00758 if (flags & DC_INBUTTON) { 00759 clrOldText = SYSRGB(BTNTEXT); 00760 clrOldBk = SYSRGB(3DFACE); 00761 hbrFill = SYSHBR(3DFACE); 00762 } else { 00763 clrOldText = SYSRGB(INACTIVECAPTIONTEXT); 00764 clrOldBk = SYSRGB(INACTIVECAPTION); 00765 hbrFill = SYSHBR(INACTIVECAPTION); 00766 00767 if (flags & DC_GRADIENT) { 00768 fGradient = TRUE; 00769 iOldMode = GreSetBkMode(hdc, TRANSPARENT); 00770 } 00771 } 00772 } 00773 00774 00775 /* 00776 * Set up drawing colors. 00777 */ 00778 clrOldText = GreSetTextColor(hdc, clrOldText); 00779 clrOldBk = GreSetBkColor(hdc, clrOldBk); 00780 00781 if (pcursor && !(flags & DC_SMALLCAP)) { 00782 00783 if (flags & DC_ICON) { 00784 #ifdef USE_MIRRORING 00785 /* 00786 * Preserve icon shape when BitBlitting it to a 00787 * mirrored DC. This way we don't violate copyright 00788 * issues on icons. [samera] 00789 */ 00790 DWORD dwLayout=0L; 00791 if ((dwLayout=GreGetLayout(hdc)) & LAYOUT_RTL) 00792 GreSetLayout(hdc, -1, dwLayout|LAYOUT_BITMAPORIENTATIONPRESERVED); 00793 #endif 00794 DrawCaptionIcon(hdc, lprc, pcursor, hbrFill, flags); 00795 00796 #ifdef USE_MIRRORING 00797 /* 00798 * Restore the DC to its previous layout state. 00799 */ 00800 if (dwLayout & LAYOUT_RTL) 00801 GreSetLayout(hdc, -1, dwLayout); 00802 #endif 00803 00804 } else { 00805 lprc->left += lprc->bottom - lprc->top; 00806 } 00807 } 00808 00809 if (flags & DC_TEXT) { 00810 int cch; 00811 HFONT hfnOld; 00812 int yCentered; 00813 WCHAR szText[CCHTITLEMAX]; 00814 UNICODE_STRING strTmp; 00815 PTHREADINFO ptiCurrent = PtiCurrentShared(); 00816 00817 /* 00818 * Note -- the DC_NOSENDMSG check is not in Chicago. It needs to be, 00819 * since GetWindowText calls back to the window. FritzS 00820 */ 00821 00822 /* 00823 * Get the text for the caption. 00824 */ 00825 if (pstrText == NULL) { 00826 00827 if ((pwnd == NULL) || (flags & DC_NOSENDMSG)) { 00828 00829 if (pwnd && pwnd->strName.Length) { 00830 cch = TextCopy(&pwnd->strName, szText, CCHTITLEMAX - 1); 00831 strTmp.Length = (USHORT)(cch * sizeof(WCHAR)); 00832 } else { 00833 szText[0] = TEXT('\0'); 00834 cch = strTmp.Length = 0; 00835 } 00836 00837 } else { 00838 cch = xxxGetWindowText(pwnd, szText, CCHTITLEMAX - 1); 00839 strTmp.Length = (USHORT)(cch * sizeof(WCHAR)); 00840 } 00841 00842 /* 00843 * We don't use RtlInitUnicodeString() to initialize the string 00844 * because it does a wstrlen() on the string, which is a waste 00845 * since we already know its length. 00846 */ 00847 strTmp.Buffer = szText; 00848 strTmp.MaximumLength = strTmp.Length + sizeof(UNICODE_NULL); 00849 pstrText = &strTmp; 00850 00851 } else { 00852 cch = pstrText->Length / sizeof(WCHAR); 00853 UserAssert(pstrText->Length < pstrText->MaximumLength); 00854 UserAssert(pstrText->Buffer[cch] == 0); 00855 } 00856 00857 /* 00858 * We need to set up font first, in case we're centering caption. 00859 * Fortunately, no text at all is uncommon... 00860 */ 00861 if (hFont == NULL) { 00862 00863 if (flags & DC_SMALLCAP) { 00864 hFont = ghSmCaptionFont; 00865 yCentered = gcySmCaptionFontChar; 00866 } else { 00867 hFont = gpsi->hCaptionFont; 00868 yCentered = gcyCaptionFontChar; 00869 } 00870 00871 yCentered = (lprc->top + lprc->bottom - yCentered) / 2; 00872 00873 hfnOld = GreSelectFont(hdc, hFont); 00874 00875 } else { 00876 00877 TEXTMETRICW tm; 00878 00879 /* 00880 * UNCOMMON case: only for control panel 00881 */ 00882 hfnOld = GreSelectFont(hdc, hFont); 00883 00884 if (!_GetTextMetricsW(hdc, &tm)) { 00885 RIPMSG0(RIP_WARNING, "xxxDrawCaptionTemp: _GetTextMetricsW Failed"); 00886 tm.tmHeight = gpsi->tmSysFont.tmHeight; 00887 } 00888 yCentered = (lprc->top + lprc->bottom - tm.tmHeight) / 2; 00889 } 00890 00891 /* 00892 * Draw text 00893 */ 00894 if (fGradient) { 00895 FillCaptionGradient(hdc, lprc, flags & DC_ACTIVE); 00896 } else { 00897 FillRect(hdc, lprc, hbrFill); 00898 } 00899 00900 if (hbrFill == gpsi->hbrGray) { 00901 GreSetTextColor(hdc, SYSRGB(BTNTEXT)); 00902 GreSetBkColor(hdc, SYSRGB(GRAYTEXT)); 00903 } 00904 00905 /* 00906 * GDI doesn't do callbacks to the LPK. If an LPK is installed 00907 * and we're not in thread cleanup mode, call the appropriate 00908 * client side GDI routines. 00909 */ 00910 if (CALL_LPK(ptiCurrent)) { 00911 xxxClientGetTextExtentPointW(hdc, pstrText->Buffer, cch, &size); 00912 } else { 00913 GreGetTextExtentW(hdc, pstrText->Buffer, cch, &size, GGTE_WIN3_EXTENT); 00914 } 00915 00916 if (pwnd && TestWF(pwnd, WEFRTLREADING)) { 00917 oldAlign = GreSetTextAlign(hdc, TA_RTLREADING | GreGetTextAlign(hdc)); 00918 } 00919 if (!(flags & DC_CENTER) && (!cch || (size.cx <= (lprc->right - lprc->left - SYSMET(CXEDGE))))) { 00920 if (pwnd && TestWF(pwnd, WEFRIGHT)) { 00921 if (CALL_LPK(ptiCurrent)) { 00922 xxxClientExtTextOutW(hdc, lprc->right - (size.cx + SYSMET(CXEDGE)), yCentered, 00923 ETO_CLIPPED, lprc, pstrText->Buffer, cch, NULL); 00924 } 00925 else { 00926 GreExtTextOutW(hdc, lprc->right - (size.cx + SYSMET(CXEDGE)), yCentered, 00927 ETO_CLIPPED, lprc, pstrText->Buffer, cch, NULL); 00928 } 00929 } else { 00930 if (CALL_LPK(ptiCurrent)) { 00931 xxxClientExtTextOutW(hdc, lprc->left + SYSMET(CXEDGE), yCentered, 00932 ETO_CLIPPED, lprc, pstrText->Buffer, cch, NULL); 00933 } 00934 else { 00935 GreExtTextOutW(hdc, lprc->left + SYSMET(CXEDGE), yCentered, 00936 ETO_CLIPPED, lprc, pstrText->Buffer, cch, NULL); 00937 } 00938 } 00939 } else { 00940 00941 DRAWTEXTPARAMS dtp; 00942 UINT wSide; 00943 00944 dtp.cbSize = sizeof(DRAWTEXTPARAMS); 00945 dtp.iLeftMargin = SYSMET(CXEDGE); 00946 dtp.iRightMargin = 0; 00947 00948 wSide = (flags & DC_CENTER) ? DT_CENTER 00949 : ((pwnd && TestWF(pwnd, WEFRIGHT)) ? DT_RIGHT : 0); 00950 00951 DrawTextEx(hdc, 00952 pstrText->Buffer, 00953 cch, 00954 lprc, 00955 DT_NOPREFIX | DT_END_ELLIPSIS | DT_SINGLELINE | DT_VCENTER | 00956 wSide, &dtp); 00957 00958 fItFit = FALSE; 00959 } 00960 00961 if (pwnd && TestWF(pwnd, WEFRTLREADING)) 00962 GreSetTextAlign(hdc, oldAlign); 00963 00964 if (hfnOld) 00965 GreSelectFont(hdc, hfnOld); 00966 } 00967 00968 /* 00969 * Restore colors 00970 */ 00971 GreSetTextColor(hdc, clrOldText); 00972 GreSetBkColor(hdc, clrOldBk); 00973 00974 if (hbrFill == gpsi->hbrGray) 00975 GreSetBkMode(hdc, iOldMode); 00976 00977 return fItFit; 00978 } 00979 00980 /***************************************************************************\ 00981 * xxxDrawCaptionBar 00982 * 00983 * 00984 \***************************************************************************/ 00985 00986 VOID xxxDrawCaptionBar( 00987 PWND pwnd, 00988 HDC hdc, 00989 UINT wFlags) 00990 { 00991 UINT bm = OBI_CLOSE; 00992 RECT rcWindow; 00993 HBRUSH hBrush = NULL; 00994 HBRUSH hCapBrush; 00995 int colorBorder; 00996 UINT wBtns; 00997 UINT wCode; 00998 00999 CheckLock(pwnd); 01000 01001 /* 01002 * If we're not currently showing on the screen, return. 01003 * NOTE 01004 * If you remove the IsVisible() check from DrawWindowFrame(), then 01005 * be careful to remove the NC_NOVISIBLE flag too. This is a smallish 01006 * speed thing, so that we don't have to call IsVisible() twice on a 01007 * window. DrawWindowFrame() already checks. 01008 */ 01009 if (!(wFlags & DC_NOVISIBLE) && !IsVisible(pwnd)) 01010 return; 01011 01012 /* 01013 * Clear this flag so we know the frame has been drawn. 01014 */ 01015 ClearHungFlag(pwnd, WFREDRAWFRAMEIFHUNG); 01016 01017 GetRect(pwnd, &rcWindow, GRECT_WINDOW | GRECT_WINDOWCOORDS); 01018 if (TestALPHA(GRADIENTCAPTIONS)) { 01019 hCapBrush = (wFlags & DC_ACTIVE) ? SYSHBR(GRADIENTACTIVECAPTION) : SYSHBR(GRADIENTINACTIVECAPTION); 01020 } else { 01021 hCapBrush = (wFlags & DC_ACTIVE) ? SYSHBR(ACTIVECAPTION) : SYSHBR(INACTIVECAPTION); 01022 } 01023 01024 wCode = 0; 01025 01026 if (!xxxMNCanClose(pwnd)) 01027 wCode |= NOCLOSE; 01028 01029 if (!TestWF(pwnd, WFMAXBOX)) 01030 wCode |= NOMAX; 01031 else if (TestWF(pwnd, WFMAXIMIZED)) 01032 wCode |= MAX; 01033 01034 if (!TestWF(pwnd, WFMINBOX)) 01035 wCode |= NOMIN; 01036 else if(TestWF(pwnd, WFMINIMIZED)) 01037 wCode |= MIN; 01038 01039 if (TestWF(pwnd, WFMINIMIZED)) { 01040 01041 if (wFlags & DC_FRAME) { 01042 01043 /* 01044 * Raised outer edge + border 01045 */ 01046 DrawEdge(hdc, &rcWindow, EDGE_RAISED, (BF_RECT | BF_ADJUST)); 01047 DrawFrame(hdc, &rcWindow, 1, DF_3DFACE); 01048 InflateRect(&rcWindow, -SYSMET(CXBORDER), -SYSMET(CYBORDER)); 01049 01050 } else { 01051 InflateRect(&rcWindow, -SYSMET(CXFIXEDFRAME), -SYSMET(CYFIXEDFRAME)); 01052 } 01053 01054 rcWindow.bottom = rcWindow.top + SYSMET(CYSIZE); 01055 01056 hBrush = GreSelectBrush(hdc, hCapBrush); 01057 01058 } else { 01059 /* 01060 * BOGUS 01061 * What color should we draw borders in? The check is NOT simple. 01062 * At create time, we set the 3D bits. NCCREATE will also 01063 * set them for listboxes, edit fields,e tc. 01064 */ 01065 colorBorder = (TestWF(pwnd, WEFEDGEMASK) && !TestWF(pwnd, WFOLDUI)) ? COLOR_3DFACE : COLOR_WINDOWFRAME; 01066 01067 /* 01068 * Draw the window frame. 01069 */ 01070 if (wFlags & DC_FRAME) { 01071 /* 01072 * Window edge 01073 */ 01074 if (TestWF(pwnd, WEFWINDOWEDGE)) 01075 DrawEdge(hdc, &rcWindow, EDGE_RAISED, BF_RECT | BF_ADJUST); 01076 else if (TestWF(pwnd, WEFSTATICEDGE)) 01077 DrawEdge(hdc, &rcWindow, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST); 01078 01079 /* 01080 * Size border 01081 */ 01082 if (TestWF(pwnd, WFSIZEBOX)) { 01083 01084 DrawFrame(hdc, 01085 &rcWindow, 01086 gpsi->gclBorder, 01087 ((wFlags & DC_ACTIVE) ? DF_ACTIVEBORDER : DF_INACTIVEBORDER)); 01088 01089 InflateRect(&rcWindow, 01090 -gpsi->gclBorder * SYSMET(CXBORDER), 01091 -gpsi->gclBorder * SYSMET(CYBORDER)); 01092 } 01093 01094 /* 01095 * Normal border 01096 */ 01097 if (TestWF(pwnd, WFBORDERMASK) || TestWF(pwnd, WEFDLGMODALFRAME)) { 01098 DrawFrame(hdc, &rcWindow, 1, (colorBorder << 3)); 01099 InflateRect(&rcWindow, -SYSMET(CXBORDER), -SYSMET(CYBORDER)); 01100 } 01101 } else { 01102 01103 int cBorders; 01104 01105 cBorders = GetWindowBorders(pwnd->style, pwnd->ExStyle, TRUE, FALSE); 01106 01107 InflateRect(&rcWindow, 01108 -cBorders * SYSMET(CXBORDER), 01109 -cBorders * SYSMET(CYBORDER)); 01110 } 01111 01112 /* 01113 * Punt if the window doesn't have a caption currently showing on screen. 01114 */ 01115 if (!TestWF(pwnd, WFCPRESENT)) 01116 return; 01117 01118 if (TestWF(pwnd, WEFTOOLWINDOW)) { 01119 wCode |= SMCAP; 01120 rcWindow.bottom = rcWindow.top + SYSMET(CYSMSIZE); 01121 bm = OBI_CLOSE_PAL; 01122 } else 01123 rcWindow.bottom = rcWindow.top + SYSMET(CYSIZE); 01124 01125 #if 0 01126 /* Draw the border beneath the caption. 01127 * 01128 * 01129 * hBrush = GreSelectBrush(hdc, gpsi->ahbrSystem[colorBorder]); 01130 *GrePatBlt(hdc, rcWindow.left, rcWindow.bottom, 01131 * rcWindow.right - rcWindow.left, 01132 * SYSMET(CYBORDER), PATCOPY); 01133 */ 01134 #endif 01135 01136 { 01137 POLYPATBLT PolyData; 01138 01139 PolyData.x = rcWindow.left; 01140 PolyData.y = rcWindow.bottom; 01141 PolyData.cx = rcWindow.right - rcWindow.left; 01142 PolyData.cy = SYSMET(CYBORDER); 01143 PolyData.BrClr.hbr = SYSHBRUSH(colorBorder); 01144 01145 GrePolyPatBlt(hdc,PATCOPY,&PolyData,1,PPB_BRUSH); 01146 } 01147 01148 GreSelectBrush(hdc, hCapBrush); 01149 } 01150 01151 if (!TestWF(pwnd, WFSYSMENU) && TestWF(pwnd, WFWIN40COMPAT)) 01152 goto JustDrawIt; 01153 01154 /* 01155 * New Rules: 01156 * (1) The caption has a horz border beneath it separating it from the 01157 * menu or client. 01158 * (2) The caption text area has an edge of space on the left and right 01159 * before the characters. 01160 * (3) We account for the descent below the baseline of the caption char 01161 */ 01162 wBtns = 1; 01163 01164 if (!(wFlags & DC_BUTTONS)) { 01165 01166 if ((!wCode) || (!(wCode & SMCAP) && ((wCode & NOSIZE) != NOSIZE))) { 01167 01168 wBtns += 2; 01169 01170 } else { 01171 01172 rcWindow.right -= SYSMET(CXEDGE); 01173 01174 if ((wCode == NOSIZE) && (wCode && TestWF(pwnd, WEFCONTEXTHELP))) 01175 wBtns++; 01176 } 01177 01178 rcWindow.right -= wBtns * ((wCode & SMCAP) ? SYSMET(CXSMSIZE) : SYSMET(CXSIZE)); 01179 01180 goto JustDrawIt; 01181 } 01182 01183 if (!wCode || (wCode == NOSIZE)) { 01184 POEMBITMAPINFO pOem = gpsi->oembmi + OBI_CAPBTNS; 01185 int cx; 01186 01187 cx = (wCode ? SYSMET(CXSIZE) + SYSMET(CXEDGE) : SYSMET(CXSIZE) * 3); 01188 01189 if (!(wFlags & DC_ACTIVE)) 01190 pOem += DOBI_CAPOFF; 01191 01192 rcWindow.right -= cx; 01193 01194 GreBitBlt(hdc, 01195 rcWindow.right, 01196 rcWindow.top, 01197 cx, 01198 pOem->cy, 01199 HDCBITS(), 01200 pOem->x + pOem->cx - SYSMET(CXSIZE) - cx, 01201 pOem->y, 01202 SRCCOPY, 01203 0); 01204 01205 if (wCode && TestWF(pwnd, WEFCONTEXTHELP)) { 01206 01207 rcWindow.right -= SYSMET(CXSIZE) - SYSMET(CXEDGE); 01208 01209 GreBitBlt(hdc, 01210 rcWindow.right, 01211 rcWindow.top, 01212 SYSMET(CXSIZE), 01213 pOem->cy, 01214 HDCBITS(), 01215 pOem->x + pOem->cx - SYSMET(CXSIZE), 01216 pOem->y, 01217 SRCCOPY, 01218 0); 01219 #ifdef USE_MIRRORING 01220 /* 01221 * If the UI language is Hebrew we do not want to mirror the ? mark only 01222 * Then redraw ? with out the button frame. 01223 */ 01224 if (HEBREW_UI_LANGID() && TestWF(pwnd, WEFLAYOUTRTL)) { 01225 GreBitBlt(hdc, 01226 rcWindow.right-SYSMET(CXEDGE), 01227 rcWindow.top+2, 01228 SYSMET(CXSIZE)-SYSMET(CXEDGE)*2, 01229 pOem->cy-4, 01230 HDCBITS(), 01231 pOem->x + pOem->cx - SYSMET(CXSIZE) + SYSMET(CXEDGE), 01232 pOem->y + SYSMET(CXEDGE), 01233 SRCCOPY|NOMIRRORBITMAP, 01234 0); 01235 } 01236 #endif 01237 } 01238 goto JustDrawIt; 01239 } 01240 01241 /* 01242 * Draw the caption buttons 01243 */ 01244 rcWindow.top += SYSMET(CYEDGE); 01245 rcWindow.bottom -= SYSMET(CYEDGE); 01246 01247 rcWindow.right -= SYSMET(CXEDGE); 01248 01249 GrePatBlt(hdc, 01250 rcWindow.right, 01251 rcWindow.top, 01252 SYSMET(CXEDGE), 01253 rcWindow.bottom - rcWindow.top, 01254 PATCOPY); 01255 01256 if (wCode & NOCLOSE) { 01257 bm += DOBI_INACTIVE; 01258 } 01259 01260 rcWindow.right -= gpsi->oembmi[bm].cx; 01261 BitBltSysBmp(hdc, rcWindow.right, rcWindow.top, bm); 01262 01263 if (!(wCode & SMCAP) && ((wCode & NOSIZE) != NOSIZE)) { 01264 01265 rcWindow.right -= SYSMET(CXEDGE); 01266 01267 GrePatBlt(hdc, 01268 rcWindow.right, 01269 rcWindow.top, 01270 SYSMET(CXEDGE), 01271 rcWindow.bottom - rcWindow.top, 01272 PATCOPY); 01273 01274 /* 01275 * Max Box 01276 * If window is maximized use the restore bitmap; 01277 * otherwise use the regular zoom bitmap 01278 */ 01279 bm = (wCode & MAX) ? OBI_RESTORE : ((wCode & NOMAX) ? OBI_ZOOM_I : OBI_ZOOM); 01280 rcWindow.right -= gpsi->oembmi[bm].cx; 01281 BitBltSysBmp(hdc, rcWindow.right, rcWindow.top, bm); 01282 01283 /* 01284 * Min Box 01285 */ 01286 bm = (wCode & MIN) ? OBI_RESTORE : ((wCode & NOMIN) ? OBI_REDUCE_I : OBI_REDUCE); 01287 rcWindow.right -= gpsi->oembmi[bm].cx; 01288 BitBltSysBmp(hdc, rcWindow.right, rcWindow.top, bm); 01289 rcWindow.right -= SYSMET(CXEDGE); 01290 GrePatBlt(hdc, 01291 rcWindow.right, 01292 rcWindow.top, 01293 SYSMET(CXEDGE), 01294 rcWindow.bottom - rcWindow.top, 01295 PATCOPY); 01296 01297 wBtns += 2; 01298 } 01299 01300 if ((wCode & (NOCLOSE | NOSIZE)) && 01301 (!(wCode & SMCAP)) && TestWF(pwnd, WEFCONTEXTHELP)) { 01302 01303 rcWindow.right -= SYSMET(CXEDGE); 01304 01305 GrePatBlt(hdc, 01306 rcWindow.right, 01307 rcWindow.top, 01308 SYSMET(CXEDGE), 01309 rcWindow.bottom - rcWindow.top, 01310 PATCOPY); 01311 01312 01313 bm = OBI_HELP; 01314 rcWindow.right -= gpsi->oembmi[bm].cx; 01315 BitBltSysBmp(hdc, rcWindow.right, rcWindow.top, bm); 01316 01317 wBtns++; 01318 } 01319 01320 rcWindow.top -= SYSMET(CYEDGE); 01321 rcWindow.bottom += SYSMET(CYEDGE); 01322 01323 wBtns *= (wCode & SMCAP) ? SYSMET(CXSMSIZE) : SYSMET(CXSIZE); 01324 01325 { 01326 POLYPATBLT PolyData[2]; 01327 01328 PolyData[0].x = rcWindow.right; 01329 PolyData[0].y = rcWindow.top; 01330 PolyData[0].cx = wBtns; 01331 PolyData[0].cy = SYSMET(CYEDGE); 01332 PolyData[0].BrClr.hbr = NULL; 01333 01334 PolyData[1].x = rcWindow.right; 01335 PolyData[1].y = rcWindow.bottom - SYSMET(CYEDGE); 01336 PolyData[1].cx = wBtns; 01337 PolyData[1].cy = SYSMET(CYEDGE); 01338 PolyData[1].BrClr.hbr = NULL; 01339 01340 GrePolyPatBlt(hdc,PATCOPY,&PolyData[0],2,PPB_BRUSH); 01341 } 01342 01343 #if 0 01344 GrePatBlt(hdc, rcWindow.right, rcWindow.top, wBtns, SYSMET(CYEDGE), PATCOPY); 01345 GrePatBlt(hdc, rcWindow.right, rcWindow.bottom - SYSMET(CYEDGE), wBtns, SYSMET(CYEDGE), PATCOPY); 01346 #endif 01347 01348 /* 01349 * We're going to release this DC--we don't need to bother reselecting 01350 * in the old brush 01351 */ 01352 if (hBrush) 01353 GreSelectBrush(hdc, hBrush); 01354 01355 JustDrawIt: 01356 01357 /* 01358 * Call DrawCaption only if we need to draw the icon or the text 01359 * If the text gets truncated, set the window flag for 01360 * the caption tooltip 01361 */ 01362 if (wFlags & (DC_TEXT | DC_ICON)) { 01363 if (!xxxDrawCaptionTemp(pwnd, 01364 hdc, 01365 &rcWindow, 01366 NULL, 01367 NULL, 01368 NULL, 01369 wFlags | ((wCode & SMCAP) ? DC_SMALLCAP : 0) | 01370 (TestALPHA(GRADIENTCAPTIONS) ? DC_GRADIENT : 0))) { 01371 SetWF(pwnd, WEFTRUNCATEDCAPTION); 01372 } else { 01373 ClrWF(pwnd, WEFTRUNCATEDCAPTION); 01374 } 01375 } 01376 }

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