00001 // $Id: progbar.cpp 1282 2006-06-09 09:46:49Z alex $ 00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE 00003 ================================XARAHEADERSTART=========================== 00004 00005 Xara LX, a vector drawing and manipulation program. 00006 Copyright (C) 1993-2006 Xara Group Ltd. 00007 Copyright on certain contributions may be held in joint with their 00008 respective authors. See AUTHORS file for details. 00009 00010 LICENSE TO USE AND MODIFY SOFTWARE 00011 ---------------------------------- 00012 00013 This file is part of Xara LX. 00014 00015 Xara LX is free software; you can redistribute it and/or modify it 00016 under the terms of the GNU General Public License version 2 as published 00017 by the Free Software Foundation. 00018 00019 Xara LX and its component source files are distributed in the hope 00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the 00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00022 See the GNU General Public License for more details. 00023 00024 You should have received a copy of the GNU General Public License along 00025 with Xara LX (see the file GPL in the root directory of the 00026 distribution); if not, write to the Free Software Foundation, Inc., 51 00027 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00028 00029 00030 ADDITIONAL RIGHTS 00031 ----------------- 00032 00033 Conditional upon your continuing compliance with the GNU General Public 00034 License described above, Xara Group Ltd grants to you certain additional 00035 rights. 00036 00037 The additional rights are to use, modify, and distribute the software 00038 together with the wxWidgets library, the wxXtra library, and the "CDraw" 00039 library and any other such library that any version of Xara LX relased 00040 by Xara Group Ltd requires in order to compile and execute, including 00041 the static linking of that library to XaraLX. In the case of the 00042 "CDraw" library, you may satisfy obligation under the GNU General Public 00043 License to provide source code by providing a binary copy of the library 00044 concerned and a copy of the license accompanying it. 00045 00046 Nothing in this section restricts any of the rights you have under 00047 the GNU General Public License. 00048 00049 00050 SCOPE OF LICENSE 00051 ---------------- 00052 00053 This license applies to this program (XaraLX) and its constituent source 00054 files only, and does not necessarily apply to other Xara products which may 00055 in part share the same code base, and are subject to their own licensing 00056 terms. 00057 00058 This license does not apply to files in the wxXtra directory, which 00059 are built into a separate library, and are subject to the wxWindows 00060 license contained within that directory in the file "WXXTRA-LICENSE". 00061 00062 This license does not apply to the binary libraries (if any) within 00063 the "libs" directory, which are subject to a separate license contained 00064 within that directory in the file "LIBS-LICENSE". 00065 00066 00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS 00068 ---------------------------------------------- 00069 00070 Subject to the terms of the GNU Public License (see above), you are 00071 free to do whatever you like with your modifications. However, you may 00072 (at your option) wish contribute them to Xara's source tree. You can 00073 find details of how to do this at: 00074 http://www.xaraxtreme.org/developers/ 00075 00076 Prior to contributing your modifications, you will need to complete our 00077 contributor agreement. This can be found at: 00078 http://www.xaraxtreme.org/developers/contribute/ 00079 00080 Please note that Xara will not accept modifications which modify any of 00081 the text between the start and end of this header (marked 00082 XARAHEADERSTART and XARAHEADEREND). 00083 00084 00085 MARKS 00086 ----- 00087 00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara 00089 designs are registered or unregistered trademarks, design-marks, and/or 00090 service marks of Xara Group Ltd. All rights in these marks are reserved. 00091 00092 00093 Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. 00094 http://www.xara.com/ 00095 00096 =================================XARAHEADEREND============================ 00097 */ 00098 // ProgBar.cpp - Implementation of progress bar window class 00099 00100 00101 /* 00102 */ 00103 00104 00105 // NOTE: This class is based upon the MFC CStatusWindow (see afxext.h, barcore.cpp) 00106 // It uses the AFX StatusBar window resource to create itself from, so as to 00107 // be the same size, position, etc. as the status bar. 00108 // 00109 // Note however, that it uses the system font instead of the same font as the 00110 // status bar. This is because (a) system font is bolder, and (b) because I 00111 // couldn't work out how to get 10 point high text, suggesting that either MFC 00112 // or the online documentation has a serious flaw in this area... This could 00113 // possibly mean that the bar comes up a different height from the status bar, 00114 // which will look a bit naff... 00115 00116 #include "camtypes.h" 00117 00118 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00119 #include "mainfrm.h" 00120 #include "statline.h" 00121 #include "progbar.h" 00122 #include "fonts.h" 00123 #include "camafx.h" 00124 #include "cstatbar.h" 00125 00126 00127 #if _MFC_VER == 0x400 00128 // Strangeness required for VC4... 00129 00130 #define AFX_WNDCONTROLBAR_REG (0x0002) 00131 00132 #define AfxDeferRegisterClass(fClass) \ 00133 ((afxRegisteredClasses & fClass) ? TRUE : AfxEndDeferRegisterClass(fClass)) 00134 00135 extern BOOL AFXAPI AfxEndDeferRegisterClass(short fClass); 00136 00137 #endif 00138 00139 // Stuff that is normally private to MFC AFX routines... 00140 // If you get a new version of MFC and the progress bar Goes South, then 00141 // these are a damn good place to start laying blame... 00142 00143 #if _MSC_VER >= 1200 00144 static char* _afxWndControlBar = "MyAfxControlBar"; 00145 #else 00146 #if WIN32 00147 #ifndef _AFXDLL 00148 extern const char NEAR _afxWndControlBar[]; // in mfc\src\wincore.cpp or similar 00149 #else 00150 // the variable isn't available in the DLL version of MFC, so we use this naughty method 00151 #define _afxWndControlBar "AfxControlBar" 00152 #endif 00153 #else 00154 extern const char BASED_CODE _afxWndControlBar[]; 00155 #endif 00156 #endif 00157 00158 #define CX_BORDER 1 00159 #define CY_BORDER 1 00160 00161 #include <afxpriv.h> 00162 00163 00164 00165 00166 00167 #ifdef _DEBUG 00168 00169 //#pragma message("") 00170 //#pragma message(" Special rendering debug is ENABLED in this build") 00171 //#pragma message("") 00172 00173 #define CHECKPEN(PTR) ((CPen *)CheckPtr((void *)(PTR), __LINE__)) 00174 #define CHECKBRUSH(PTR) ((CBrush *)CheckPtr((void *)(PTR), __LINE__)) 00175 #define CHECKFONT(PTR) ((CFont *)CheckPtr((void *)(PTR), __LINE__)) 00176 00177 static void *CheckPtr(void *Pointer, INT32 LineNum) 00178 { 00179 if (Pointer == NULL) 00180 { 00181 TRACE( _T("progbar.cpp, line %ld: CPen/CBrush/CFont returned was NULL!\n"), LineNum); 00182 TRACE( _T(" --> GetLastError claims the problem was: 0x%x\n"), (INT32)GetLastError()); 00183 } 00184 return(Pointer); 00185 } 00186 00187 #else 00188 #define CHECKPEN(Ptr) ((CPen *) (Ptr)) 00189 #define CHECKBRUSH(Ptr) ((CBrush *) (Ptr)) 00190 #define CHECKFONT(Ptr) ((CFont *) (Ptr)) 00191 #endif 00192 00193 00194 00195 00196 00197 00198 static const MAXBARWIDTH = 200; // Bar should never be > 200 pixels wide 00199 // - looks better, & leaves room for text 00200 00201 00202 IMPLEMENT_DYNAMIC(CProgressBar, CControlBar) 00203 00204 00205 00206 CProgressBar::CProgressBar() 00207 { 00208 m_hFont = FontFactory::GetFont(STOCKFONT_STATUSBAR); 00209 CurrentPercent = -1; 00210 } 00211 00212 00213 /******************************************************************************************** 00214 > BOOL CProgressBar::~CProgressBar() 00215 00216 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00217 Created: 15/02/94 00218 Inputs: - 00219 Outputs: - 00220 Returns: - 00221 Purpose: Destroys the object, as one might expect. 00222 Notes: IMPORTANT - After calling the destructor (delete ProgressBar) it is 00223 VITAL that you then call RecalcLayout() for the main frame window in 00224 which the Progress Bar is appearing (the one you passed in to PB::Create(). 00225 If you don't do this, the bar won't disappear until the next time the main 00226 window is resized or a tool is chosen. 00227 00228 ********************************************************************************************/ 00229 00230 CProgressBar::~CProgressBar() 00231 { 00232 if (JobDescription != NULL) 00233 delete JobDescription; 00234 00235 // ParentWindow->RecalcLayout(); // Cause ourself to be hidden 00236 // The above does not work, as it appears to be called before the window 00237 // has actually been deleted, and therefore has no effect. Thus, the 00238 // responsibility for doing this is passed on to the entity calling 'delete' 00239 } 00240 00241 00242 /******************************************************************************************** 00243 > BOOL CProgressBar::Create(CFrameWnd *ParentWnd, String_64 *JobDescription = NULL, 00244 DWORD dwstyle = WS_CHILD | WS_VISIBLE | CBRS_BOTTOM, 00245 UINT32 nID = _R(AFX_IDW_STATUS_BAR)); 00246 00247 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00248 Created: 15/02/94 00249 Inputs: ParentWnd - The parent frame window (in Camelot, there can be only one) 00250 JobDescription - A BRIEF string describing the job currently being undertaken. 00251 This will be displayed on the progress bar if possible 00252 dwstyle, nID - you shouldn't have to mess with these (cf CStatusBar) 00253 Outputs: - 00254 Returns: TRUE if the initialisation of the progress bar was successful. 00255 Purpose: Creates a window and associates it with this CProgressBar object. The window 00256 appears immediately over the status bar. 00257 Notes: This currently assumes that it'll only ever be opened at the bottom of the 00258 Main Frame window. 00259 SeeAlso: CProgressBar::SetPercent; CProgressBar::GetPercent 00260 ********************************************************************************************/ 00261 00262 BOOL CProgressBar::Create(CFrameWnd* pParentWnd, String_64 *JobDescrip, 00263 DWORD dwStyle, UINT32 nID) 00264 { 00265 ASSERT_VALID(pParentWnd); // must have a parent 00266 00267 CurrentPercent = -1; 00268 if (JobDescrip == NULL) 00269 JobDescription = NULL; 00270 else 00271 JobDescription = new String_64(*JobDescrip); 00272 #if WIN32 00273 // this element of CControlBar does not exist in MFC 2.5 16-bit 00274 m_dwStyle = dwStyle; 00275 #endif 00276 00277 #if _MFC_VER == 0x400 00278 // MFC 4 defers registering of window classes, so make sure the window class 00279 // is registered before we use it. 00280 // (code taken from mfc/src/bardock.cpp, in MFC 4) 00281 if (!AfxDeferRegisterClass(AFX_WNDCONTROLBAR_REG)) 00282 return FALSE; 00283 #endif 00284 00285 00286 // Work out the position of the bar. 00287 CRect rect; 00288 rect.SetRectEmpty(); 00289 00290 // create the window 00291 if (!CWnd::Create(_afxWndControlBar, NULL, dwStyle, rect, pParentWnd, nID)) 00292 return FALSE; 00293 // NOTE: Parent must resize itself for control bar to be resized 00294 00295 // set initial font and calculate bar height 00296 OnSetFont((WPARAM)m_hFont, 0); // initialize font height etc 00297 00298 00299 pParentWnd->RecalcLayout(); // Cause ourself to be shown 00300 SetPercent(0, TRUE); // Force redraw of window _including background_ 00301 00302 return TRUE; 00303 } 00304 00305 00306 00307 void CProgressBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler) 00308 // I'm not entirely sure how much of this is necessary, but it doesn't seem to 00309 // do any harm, and things didn't work properly until I put it in... 00310 { 00311 CCmdUI state; 00312 state.m_pOther = this; 00313 state.m_nIndexMax = (UINT32)m_nCount; 00314 00315 for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax; 00316 state.m_nIndex++) 00317 { 00318 state.m_nID = 0; 00319 state.DoUpdate(pTarget, bDisableIfNoHndler); 00320 } 00321 00322 // update the dialog controls added to the status bar (of which there are none) 00323 UpdateDialogControls(pTarget, bDisableIfNoHndler); 00324 } 00325 00326 00327 00328 /******************************************************************************************** 00329 > INT32 CProgressBar::GetPercent(void); 00330 00331 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00332 Created: 15/02/94 00333 Inputs: - 00334 Outputs: - 00335 Returns: The current percentage setting displayed in the progressbar window. 00336 Purpose: Reads the currently displayed percentage of the progress bar. 00337 SeeAlso: CProgressBar::SetPercent; CProgressBar::Create 00338 ********************************************************************************************/ 00339 00340 INT32 CProgressBar::GetPercent(void) const 00341 { 00342 return(CurrentPercent); 00343 } 00344 00345 00346 /******************************************************************************************** 00347 > BOOL CProgressBar::SetPercent(INT32 NewPercent, 00348 BOOL ClearBackground = FALSE, String_64 *JobDescrip = NULL) 00349 00350 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00351 Created: 15/02/94 00352 Inputs: NewPercent - the new percentage value to be displayed by the progress bar 00353 00354 ClearBackground - Clears the entire bar background and redraws everything, rather 00355 than doing a (far more efficient) update of the bar/percentage alone. Use the default 00356 of FALSE unless absolutely necessary! 00357 00358 JobDescrip - NULL, or a pointer to a new job description - pass NULL if this hasn't 00359 changed, as it makes a copy of the new string every time it is changed. If this is 00360 non-NULL, then the ClearBackground flag will be forced to TRUE to draw the new text. 00361 00362 Outputs: - 00363 Returns: TRUE if it successfully makes the change. 00364 Purpose: Sets the currently displayed percentage of the progress bar. The bar 00365 will be immediately redrawn to reflect the new value. Values outside the 00366 range 0..99 (inclusive) are clipped to 0 or 99. No redraw will be done if 00367 NewPercent equals the currently displayed value. 00368 SeeAlso: CProgressBar::GetPercent; CProgressBar::Create 00369 ********************************************************************************************/ 00370 00371 BOOL CProgressBar::SetPercent(INT32 NewPercent, BOOL ClearBackground /* =FALSE */, 00372 String_64 *JobDescrip /* =NULL */) 00373 // The extra argument ClearBackground is not mentioned in the help, because it 00374 // is used internally - When the window is first created, the background must be cleared, 00375 // but on normal updates this causes horrible flicker, so is to be avoided. 00376 { 00377 if (NewPercent < 0) NewPercent = 0; 00378 if (NewPercent > 99) NewPercent = 99; 00379 00380 // If there's no change, don't bother updating 00381 if (JobDescrip == NULL && NewPercent == CurrentPercent) 00382 return(TRUE); 00383 00384 CurrentPercent = NewPercent; 00385 00386 // If there is a new Job Description, change to use it 00387 if (JobDescrip != NULL) 00388 { 00389 delete JobDescription; 00390 JobDescription = new String_64(*JobDescrip); 00391 00392 ClearBackground = TRUE; // Ensure that the new text is drawn 00393 } 00394 00395 00396 #if FALSE 00397 /* 00398 CDC *DC = GetDC(); 00399 00400 if (ClearBackground) 00401 { 00402 CRect Rect; 00403 CBrush FillBrush(GetSysColor(COLOR_BTNFACE)); 00404 00405 GetClientRect(&Rect); // Get window position/area... 00406 DC->FillRect(Rect, &FillBrush); // [...& fill backgnd with grey] 00407 } 00408 00409 DoPaint(DC); // Force immediate redraw 00410 ReleaseDC(DC); 00411 */ 00412 #else 00413 Invalidate(ClearBackground); // Invalidate the window 00414 UpdateWindow(); // And redraw it immediately 00415 #endif 00416 00417 return(TRUE); 00418 } 00419 00420 00421 static void Paint3dPlinth(CDC* pDC, CRect *rect, BOOL Indent = TRUE) 00422 // Paints a 3-D plinth rectangle. If Indent is TRUE, it is indented, else it 00423 // is raised. Other 3-D effects are not supported 00424 // NOTE that the rectangle is drawn around the OUTSIDE of the given rectangle 00425 { 00426 // **** If 3d look is turned off, then we need to select black for BOTH of these 00427 00428 CPen Black(PS_SOLID, 0, GetSysColor(COLOR_BTNSHADOW)); 00429 CPen White(PS_SOLID, 0, GetSysColor(COLOR_BTNHIGHLIGHT)); 00430 00431 CPen *OldPen = CHECKPEN(pDC->SelectObject((Indent) ? &White : &Black)); 00432 00433 pDC->MoveTo(rect->left, rect->bottom-1); 00434 pDC->LineTo(rect->left, rect->top); 00435 pDC->LineTo(rect->right-1, rect->top); 00436 00437 CHECKPEN(pDC->SelectObject((Indent) ? &Black : &White)); 00438 pDC->MoveTo(rect->right-1, rect->top+1); // Ensure corner pixel is correct 00439 pDC->LineTo(rect->right-1, rect->bottom-1); 00440 pDC->LineTo(rect->left, rect->bottom-1); 00441 00442 CHECKPEN(pDC->SelectObject(OldPen)); 00443 } 00444 00445 00446 00447 void CProgressBar::DoPaint(CDC* pDC) 00448 // Paints the bar, assuming that the background has already been cleared to grey. 00449 // The bar has a percentage display on the left, followed by a progress bar 00450 // which is sized to fit the available space up to a maximum of MAXBARWIDTH pixels 00451 // If there is enough room, the current Job Description will also be displayed, to 00452 // the right of the bar. 00453 { 00454 ASSERT_VALID(this); 00455 ASSERT_VALID(pDC); 00456 00457 CControlBar::DoPaint(pDC); // draw border 00458 00459 CRect rect; 00460 GetClientRect(rect); 00461 CalcInsideRect(rect); 00462 00463 ASSERT(m_hFont != NULL); 00464 CFont *OurFont = CHECKFONT(CFont::FromHandle(m_hFont)); // Get a CFont* for this HFONT 00465 CFont *OldFont = CHECKFONT(pDC->SelectObject(OurFont)); 00466 00467 rect.InflateRect(-CX_BORDER, -CY_BORDER); 00468 00469 CString PercentText("00%"); // Generate %age string 00470 if (CurrentPercent > 0 && CurrentPercent < 100) 00471 { 00472 if (CurrentPercent > 9) 00473 PercentText.SetAt(0, (CurrentPercent / 10) + '0'); 00474 PercentText.SetAt(1, (CurrentPercent % 10) + '0'); 00475 } 00476 00477 pDC->SetTextColor(GetSysColor(COLOR_BTNTEXT)); // Draw %age string 00478 pDC->SetBkColor(GetSysColor(COLOR_BTNFACE)); 00479 pDC->SetBkMode(OPAQUE); 00480 SetTextAlign(pDC->m_hDC, TA_LEFT | TA_BOTTOM); 00481 pDC->TextOut(rect.left, rect.bottom, PercentText); 00482 00483 CSize TextSize = pDC->GetTextExtent(PercentText, 3); 00484 00485 INT32 BarStart = rect.left + TextSize.cx + 4; // Calc bar position, size 00486 INT32 WindowEnd = rect.right - 4; 00487 INT32 BarWidth = WindowEnd - BarStart; 00488 00489 if (BarWidth < 10) return; // Not enough room to do a bar! 00490 00491 if (BarWidth > MAXBARWIDTH) BarWidth = MAXBARWIDTH; 00492 00493 if (JobDescription != NULL && WindowEnd - BarStart > MAXBARWIDTH + 64) 00494 { // If enough room for some text, add the job description 00495 CString OutText = TEXT(*JobDescription); 00496 00497 rect.left = BarStart + BarWidth + 4; 00498 rect.right = WindowEnd; 00499 pDC->TextOut(rect.left, rect.bottom, OutText); 00500 } 00501 00502 CHECKFONT(pDC->SelectObject(OldFont)); // Restore previous font 00503 00504 rect.left = BarStart; // Finally, calc and paint the bar,,, 00505 rect.right = BarStart+BarWidth; 00506 rect.bottom -= m_FontDescent - 2; // Line up bar bottom with text baseline 00507 Paint3dPlinth(pDC, &rect, FALSE); 00508 00509 BarWidth -= 4; // Bar is 2 pixels inside plinth rectangle 00510 rect.left = BarStart + 2; 00511 rect.top += 2; 00512 rect.bottom -= 2; 00513 rect.right = rect.left + (INT32) (((WORD)BarWidth * (WORD)CurrentPercent) / 100); 00514 00515 CBrush BlueBrush(RGB(0,0,255)); 00516 pDC->FillRect(rect, &BlueBrush); 00517 } 00518 00519 00520 00521 BEGIN_MESSAGE_MAP(CProgressBar, CControlBar) 00522 //{{AFX_MSG_MAP(CProgressBar) 00523 // control messages 00524 ON_WM_SIZE() 00525 ON_MESSAGE(WM_SETFONT, OnSetFont) 00526 ON_MESSAGE(WM_GETFONT, OnGetFont) 00527 ON_MESSAGE(WM_SIZEPARENT, OnSizeParent) 00528 //}}AFX_MSG_MAP 00529 END_MESSAGE_MAP() 00530 00531 00532 void CProgressBar::OnSize(UINT32, INT32, INT32) 00533 { 00534 // force repaint on resize 00535 Invalidate(); 00536 } 00537 00538 00539 LRESULT CProgressBar::OnSizeParent(WPARAM, LPARAM lParam) 00540 // This overrides the normal OnSizeParent method (CControlBar) 00541 // Normal control bars can never overlap - each is opened using the parent's 00542 // client rectangle, and then their area is subtracted from the available client 00543 // area, so that they never overlap. 00544 // However, the progress bar wants to sit over the top of the status bar if 00545 // possible, so before allowing the normal action to proceed... 00546 // If the status window's client rectangle butts onto the layout rect passed in, 00547 // then we extend the layout rectangle to include the status bar, and hence we 00548 // will be placed over the top of the SB. 00549 // NOTE - currently only does this if attached to the BOTTOM of the window. 00550 // If this fails (sttaus bar not open, or at top of window, etc), the progress 00551 // bar will appear normally (above/below all other control bars) 00552 { 00553 AFX_SIZEPARENTPARAMS FAR* lpLayout = (AFX_SIZEPARENTPARAMS FAR*)lParam; 00554 CRect StatusRect; 00555 00556 ((CMainFrame *) AfxGetApp()->m_pMainWnd)->GetStatusBarWindowRect(&StatusRect); 00557 00558 if (!StatusRect.IsRectEmpty()) // Cover status bar (if open) 00559 { 00560 // JustinF says: this is a quick bodge so that the progress-bar respects any 00561 // overriding prefix displayed in the status line by StatusLine::SetPrefix. 00562 StatusRect.left = StatusLine::GetPrefixWidth(); 00563 00564 // We just move our window so it is covering the status bar, using the 00565 // HWDP supplied in the AFX_SIZEPARENTPARAMS structure. 00566 lpLayout->hDWP = ::DeferWindowPos(lpLayout->hDWP, m_hWnd, HWND_TOP, 00567 StatusRect.left, StatusRect.top, 00568 StatusRect.right - StatusRect.left, 00569 StatusRect.bottom - StatusRect.top, 00570 SWP_NOACTIVATE); 00571 } 00572 else 00573 { 00574 00575 #if _MFC_VER < 0x300 00576 // No status bar - just plonk the progress bar where we can... 00577 return (CControlBar::OnSizeParent((WPARAM)0, lParam)); 00578 #else 00579 // resize and reposition this control bar based on styles 00580 DWORD dwStyle = (m_dwStyle & (CBRS_ALIGN_ANY|CBRS_BORDER_ANY)) | 00581 (GetStyle() & WS_VISIBLE); 00582 00583 if ((dwStyle & WS_VISIBLE) && (dwStyle & CBRS_ALIGN_ANY) != 0) 00584 { 00585 // align the control bar 00586 CRect rect; 00587 00588 if (StatusRect.IsRectEmpty()) 00589 { 00590 // Status bar is not open - just fit in where we can. 00591 // (This code copied from barcore.cpp in MFC 3) 00592 rect.CopyRect(&lpLayout->rect); 00593 00594 CSize sizeAvail = rect.Size(); // maximum size available 00595 00596 // get maximum requested size 00597 CSize size = CalcFixedLayout(lpLayout->bStretch, 00598 (dwStyle & CBRS_ORIENT_HORZ) ? TRUE : FALSE); 00599 00600 size.cx = min(size.cx, sizeAvail.cx); 00601 size.cy = BarHeight; 00602 00603 lpLayout->sizeTotal.cy += size.cy; 00604 lpLayout->sizeTotal.cx = max(lpLayout->sizeTotal.cx, size.cx); 00605 rect.top = rect.bottom - size.cy; 00606 lpLayout->rect.bottom -= size.cy; 00607 00608 rect.right = rect.left + size.cx; 00609 rect.bottom = rect.top + size.cy; 00610 00611 // only resize the window if doing layout and not just rect query 00612 if (lpLayout->hDWP != NULL) 00613 { 00614 AfxRepositionWindow(lpLayout, m_hWnd, &rect); 00615 } 00616 } 00617 } 00618 #endif 00619 } 00620 00621 return 0; 00622 00623 } 00624 00625 00626 00627 LRESULT CProgressBar::OnSetFont(WPARAM wParam, LPARAM) 00628 // Copied verbatim from barcore.cpp 00629 { 00630 m_hFont = (HFONT)wParam; 00631 00632 ASSERT(m_hFont != NULL); 00633 00634 // recalculate based on font height + borders 00635 TEXTMETRIC tm; 00636 // get text metrics of font 00637 { 00638 CClientDC dcScreen(NULL); 00639 00640 CFont *OurFont = CHECKFONT(CFont::FromHandle(m_hFont)); 00641 CFont *OldFont = CHECKFONT(dcScreen.SelectObject(OurFont)); 00642 00643 VERIFY(dcScreen.GetTextMetrics(&tm)); 00644 CHECKFONT(dcScreen.SelectObject(OldFont)); 00645 } 00646 CRect rectSize; 00647 rectSize.SetRectEmpty(); 00648 CalcInsideRect(rectSize); // will be negative size 00649 00650 #if _MFC_VER < 0x300 00651 m_sizeFixedLayout.cy = (tm.tmHeight - tm.tmInternalLeading) + 00652 CY_BORDER*3 /* 1 extra on top, 2 on bottom */ - rectSize.Height(); 00653 ASSERT(m_sizeFixedLayout.cx == 32767); // max size 00654 #else 00655 BarHeight = (tm.tmHeight - tm.tmInternalLeading) + 00656 CY_BORDER*3 /* 1 extra on top, 2 on bottom */ - rectSize.Height(); 00657 #endif 00658 00659 m_FontDescent = tm.tmDescent; // Cache descent size 00660 00661 return 0L; // does not re-draw or invalidate - resize parent instead 00662 } 00663 00664 00665 LRESULT CProgressBar::OnGetFont(WPARAM, LPARAM) 00666 { 00667 return (LRESULT)(UINT32)m_hFont; 00668 } 00669 00670