scrlbutn.cpp

Go to the documentation of this file.
00001 // $Id: scrlbutn.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 //
00099 // Custom Windows scroll bar button.  This object is used by the (private)
00100 // implementation of CScroller.
00101 //
00102 
00103 
00104 #include "camtypes.h"
00105 
00106 #include "scroller.h"
00107 #include "scrlbutn.h"
00108 //#include "ensure.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00109 #include "mainfrm.h"
00110 //#include "errors.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00111 #include "brushmsg.h" 
00112 
00113 #ifdef _DEBUG
00114 #undef THIS_FILE
00115 static char BASED_CODE THIS_FILE[] = __FILE__;
00116 #endif
00117 
00118 
00119 DECLARE_SOURCE("$Revision: 1282 $");
00120 
00121 
00122 
00123 
00124 BEGIN_MESSAGE_MAP(CScrollerButton, CBitmapButton)
00125     //{{AFX_MSG_MAP(CScrollerButton)
00126         ON_WM_LBUTTONDOWN()
00127         ON_WM_LBUTTONUP()
00128         ON_WM_RBUTTONDOWN()
00129         ON_WM_RBUTTONUP()
00130         ON_WM_TIMER()
00131         ON_WM_CANCELMODE()
00132         ON_WM_LBUTTONDBLCLK()
00133         ON_WM_RBUTTONDBLCLK()
00134     //}}AFX_MSG_MAP
00135 END_MESSAGE_MAP()
00136 
00137 
00138 
00139 
00140 UINT32 CScrollerButton::BitmapNames[4][3] = 
00141 {
00142       { OBM_UPARROW,    OBM_UPARROWD,   OBM_UPARROWI },
00143       { OBM_DNARROW,    OBM_DNARROWD,   OBM_DNARROWI },
00144       { OBM_LFARROW,    OBM_LFARROWD,   OBM_LFARROWI },
00145       { OBM_RGARROW,    OBM_RGARROWD,   OBM_RGARROWI }
00146 };
00147 
00148 
00149 
00150 
00151 /*********************************************************************************************
00152 >   CScrollerButton::CScrollerButton(CScroller::Orientation ort, UINT32 msg)
00153 
00154     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00155     Created:    ages ago
00156     Inputs:     The orientation of the bitmap on the button's face, the message the button
00157                 button should send the CScroller parent when it is clicked.
00158     Outputs:    -
00159     Returns:    -
00160     Purpose:    Constructs a CScrollerButton with the appropriate face.
00161     Errors:     ENSURE failure if, for any stupid reason, the orientation is invalid.
00162     Scope:      Public
00163     SeeAlso:    CScrollerButton::Create(); CScroller::OnCreate()
00164 
00165 **********************************************************************************************/ 
00166 CScrollerButton::CScrollerButton(CScrollerButton::Orientation ort, UINT32 msg)
00167   : CBitmapButton(), Orient(ort), Message(msg)
00168 {
00169     // So far, very little to do here.
00170     ENSURE(ort >= CScrollerButton::UP && ort <= CScrollerButton::RIGHT,
00171            "Unknown orientation code passed to scroller button constructor!\n");
00172 }
00173 
00174 
00175 
00176 /*********************************************************************************************
00177 >   virtual BOOL CScrollerButton::Create(LPCTSTR, DWORD style, const RECT& rect,
00178                                          CWnd* parent, UINT32 id)
00179     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00180     Created:    ages ago
00181     Inputs:     A dummy long pointer, not used; the window-instance style flags, a rectangle
00182                 describing the button's size and position; a pointer to the parent window (a
00183                 CScroller derivative); a numeric child window identifier.
00184     Outputs:    -
00185     Returns:    TRUE if the button is successfully created, and all bitmaps it requires
00186                 are successfully extracted from the dislay driver.
00187     Purpose:    Try to connect the C++ button object to the appropriate Windows
00188                 interface object.  As an aid to the programmer we load the bitmaps
00189                 used for the button here, instead of requiring the owner to do it.
00190     Errors:     -
00191     Scope:      Public
00192     SeeAlso:    CScrollerButton::CScrollerButton(); CScroller::OnCreate()
00193 
00194 **********************************************************************************************/ 
00195 BOOL CScrollerButton::Create(LPCTSTR, DWORD style, const RECT& rect,
00196                              CWnd* parent, UINT32 id)
00197 {
00198     return CBitmapButton::Create("",
00199                                  style | WS_CLIPSIBLINGS | WS_VISIBLE | WS_CHILD
00200                                  | BS_OWNERDRAW | BS_PUSHBUTTON,
00201                                  rect,
00202                                  parent,
00203                                  id)
00204         && LoadOEMBitmaps(BitmapNames[Orient][0],           // button up
00205                           BitmapNames[Orient][1],           // button down
00206                           BitmapNames[Orient][2]);          // disabled
00207 }
00208 
00209 
00210 
00211 /*********************************************************************************************
00212 >   virtual BOOL CScrollerButton::LoadOEMBitmaps(UINT32 upID, UINT32 downID, UINT32 disableID)
00213 
00214     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00215     Created:    ages ago
00216     Inputs:     The resource identifier of the bitmap displayed on the button when it is
00217                 "up", ie. not clicked; the ID of the "down" bitmap; the ID of the "disabled"
00218                 bitmap.
00219     Outputs:    -
00220     Returns:    TRUE if the bitmaps are successfully extracted from the display driver, FALSE
00221                 if some essential bitmaps cannot be extracted.
00222     Purpose:    Some display drivers, such as the ET4000, do not contain a "disabled" bitmap
00223                 for scroll bars buttons.  In this case the function substitutes the "up"
00224                 bitmap for the "disabled" bitmap.
00225     Errors:     -
00226     Scope:      Private
00227     SeeAlso:    CScrollerButton::Create()
00228 
00229 **********************************************************************************************/ 
00230 BOOL CScrollerButton::LoadOEMBitmaps(UINT32 upID, UINT32 downID, UINT32 disableID)
00231 {
00232     m_bitmap.DeleteObject();
00233     m_bitmapSel.DeleteObject();
00234     m_bitmapDisabled.DeleteObject();
00235 
00236 #ifndef _MAC
00237     // The up/down bitmaps are essential and must be present.
00238     if (!m_bitmap.LoadOEMBitmap(upID) || !m_bitmapSel.LoadOEMBitmap(downID))
00239         return FALSE;
00240     
00241     // The disabled bitmap is not essential, and if not present, the up
00242     // bitmap can be substituted for it.
00243     if (!m_bitmapDisabled.LoadOEMBitmap(disableID))
00244         m_bitmapDisabled.LoadOEMBitmap(upID);
00245 #endif
00246     return TRUE;
00247 }
00248 
00249 
00250 
00252 // Implementation.
00253 
00254 
00255 /*********************************************************************************************
00256 >   void CScrollerButton::HandleButtonDown(BOOL reverse)
00257 
00258     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00259     Created:    ages ago
00260     Inputs:     A boolean which if TRUE indicates that the button is responding to a click
00261                 with the right mouse button, so the scroll is in the opposite direction.
00262     Outputs:    -
00263     Returns:    -
00264     Purpose:    Captures the mouse, to guarantee receiving a button-up message some time in
00265                 the future.  Sets a timer in case that the button is held down and further
00266                 messages must be processed (Windows buttons only send one notification
00267                 message, no matter how long they are held down for).  Sends a private
00268                 "button clicked" message to the parent CScroller object.
00269     Errors:     -
00270     Scope:      Private
00271     SeeAlso:    CScrollerButton::HandleButtonUp(); CScrollerButton::OnLButtonDown();
00272                 CScrollerButton::OnRButtonDown(); CScrollerButton::OnTimer()
00273                 CScroller::OnDecBtnClicked(); CScroller::OnIncBtnClicked()
00274 
00275 **********************************************************************************************/ 
00276 void CScrollerButton::HandleButtonDown(BOOL reverse)
00277 {
00278     // On the initial click, we set up an auto-repeat timer to start after the configured
00279     // keyboard auto-repeat delay
00280     UINT32 CallbackTime = 1000;
00281     UINT32 RepsPerSec;
00282 
00283     ::SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &RepsPerSec, 0);
00284     RepsPerSec = 4 - RepsPerSec;
00285     if (RepsPerSec > 1)
00286         CallbackTime = (UINT32) 1000 / RepsPerSec;
00287 
00288     TimerOn = ::FixSetTimer(m_hWnd, 3, CallbackTime, 0);
00289 
00290     #ifdef  _DEBUG
00291         if (!TimerOn)
00292             TRACE( _T("Unable to allocate a timer in CScrollerButton::HandleButtonDown()!\n"));
00293     #endif  // _DEBUG
00294 
00295     SetCapture();
00296     GetParent()->SendMessage(Message, WPARAM(Reversed = reverse));
00297     SetState(TRUE);
00298 }
00299 
00300 
00301 
00302 /*********************************************************************************************
00303 >   void CScrollerButton::HandleButtonUp()
00304 
00305     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00306     Created:    ages ago
00307     Inputs:     -
00308     Outputs:    -
00309     Returns:    -
00310     Purpose:    Releases the captured mouse and kills the timer set by HandleButtonDown().
00311     Errors:     -
00312     Scope:      Private
00313     SeeAlso:    CScrollerButton::HandleButtonDown(); CScrollerButton::OnLButtonUp();
00314                 CScrollerButton::OnRButtonUp(); CScrollerButton::OnTimer()
00315 
00316 **********************************************************************************************/ 
00317 void CScrollerButton::HandleButtonUp()
00318 {
00319     ReleaseCapture();
00320     if (TimerOn)
00321     {
00322         ::FixKillTimer(m_hWnd, 3);
00323         TimerOn = FALSE;
00324     }
00325     SetState(FALSE);
00326 
00327     // tell people things have changed on screen
00328     BROADCAST_TO_ALL(ScreenChangeMsg(TRUE));
00329 }
00330 
00331 
00332 
00334 // CScrollerButton message response functions.
00335 
00336 /*********************************************************************************************
00337 >   afx_msg void CScrollerButton::OnLButtonDown(UINT32 nFlags, CPoint point)
00338 
00339     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00340     Created:    ages ago
00341     Inputs:     Some flags detailing which buttons and keys were down when the mouse message
00342                 was generated; the coordinates of the mouse cursor.
00343     Outputs:    -
00344     Returns:    -
00345     Purpose:    We must override the default handling for push-buttons because scroll-bar
00346                 buttons generate a sequence of messages until they are released, whilst
00347                 normal buttons generate only one message when pressed.  This member function
00348                 passes the message on to HandleButtonDown() with a FALSE parameter.
00349     Errors:     -
00350     Scope:      Protected
00351     SeeAlso:    CScrollerButton::HandleButtonDown(); CScrollerButton::OnLButtonUp()
00352 
00353 **********************************************************************************************/ 
00354 void CScrollerButton::OnLButtonDown(UINT32 nFlags, CPoint point)
00355 {
00356     CBitmapButton::OnLButtonDown(nFlags, point);
00357     HandleButtonDown(FALSE);
00358 }
00359 
00360 
00361 
00362 /*********************************************************************************************
00363 >   afx_msg void CScrollerButton::OnLButtonUp(UINT32 nFlags, CPoint point)
00364 
00365     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00366     Created:    ages ago
00367     Inputs:     Some flags detailing which buttons and keys were down when the mouse message
00368                 was generated; the coordinates of the mouse cursor.
00369     Outputs:    -
00370     Returns:    -
00371     Purpose:    Passes message on to HandleButtonUp()
00372     Errors:     -
00373     Scope:      Protected
00374     SeeAlso:    CScrollerButton::HandleButtonUp(); CScrollerButton::OnLButtonDown()
00375 
00376 **********************************************************************************************/ 
00377 void CScrollerButton::OnLButtonUp(UINT32 nFlags, CPoint point)
00378 {
00379     CBitmapButton::OnLButtonUp(nFlags, point);
00380     SetState(FALSE);
00381     HandleButtonUp();
00382 }
00383 
00384 
00385 
00386 /*********************************************************************************************
00387 >   afx_msg void CScrollerButton::OnRButtonDown(UINT32 nFlags, CPoint point)
00388 
00389     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00390     Created:    ages ago
00391     Inputs:     Some flags detailing which buttons and keys were down when the mouse message
00392                 was generated; the coordinates of the mouse cursor.
00393     Outputs:    -
00394     Returns:    -
00395     Purpose:    We must override the default handling for push-buttons because Windows
00396                 buttons do not respond to clicks with the right mouse-button.  This member
00397                 function passes the message on to HandleButtonDown() with a TRUE parameter,
00398                 after calling CButton::SetState(TRUE) to "simulate" the button being clicked.
00399     Errors:     -
00400     Scope:      Protected
00401     SeeAlso:    CScrollerButton::HandleButtonDown(); CScrollerButton::OnRButtonUp()
00402 
00403 **********************************************************************************************/ 
00404 void CScrollerButton::OnRButtonDown(UINT32 nFlags, CPoint point)
00405 {
00406     SetState(TRUE);
00407     HandleButtonDown(TRUE);
00408 }
00409 
00410 
00411 
00412 /*********************************************************************************************
00413 >   afx_msg void CScrollerButton::OnRButtonUp(UINT32 nFlags, CPoint point)
00414 
00415     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00416     Created:    ages ago
00417     Inputs:     Some flags detailing which buttons and keys were down when the mouse message
00418                 was generated; the coordinates of the mouse cursor.
00419     Outputs:    -
00420     Returns:    -
00421     Purpose:    Passes message on to HandleButtonUp(), after calling CButton::SetState(FALSE)
00422                 to draw the button "undepressed".
00423     Errors:     -
00424     Scope:      Protected
00425     SeeAlso:    CScrollerButton::HandleButtonUp(); CScrollerButton::OnRButtonDown()
00426 
00427 **********************************************************************************************/ 
00428 void CScrollerButton::OnRButtonUp(UINT32 nFlags, CPoint point)
00429 {
00430     SetState(FALSE);
00431     HandleButtonUp();
00432 }
00433 
00434 
00435 
00436 /*********************************************************************************************
00437 >   afx_msg void CScrollerButton::OnLButtonDblClk(UINT32 nFlags, CPoint point)
00438 
00439     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00440     Created:    ages ago
00441     Inputs:     Some flags detailing which buttons and keys were down when the mouse message
00442                 was generated; the coordinates of the mouse cursor.
00443     Outputs:    -
00444     Returns:    -
00445     Purpose:    Calls CScrollerButton::OnLButtonDown(), to convert a double-click into
00446                 a single click (MFC buttons don't normally respond to double-clicks).
00447     Errors:     -
00448     Scope:      Protected
00449     SeeAlso:    CScrollerButton::OnLButtonDown(); CScrollerButton::OnRButtonDblClk()
00450 
00451 **********************************************************************************************/ 
00452 void CScrollerButton::OnLButtonDblClk(UINT32 nFlags, CPoint point)
00453 {
00454     OnLButtonDown(nFlags, point);
00455 }
00456 
00457 
00458 
00459 /*********************************************************************************************
00460 >   afx_msg void CScrollerButton::OnRButtonDblClk(UINT32 nFlags, CPoint point)
00461 
00462     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00463     Created:    ages ago
00464     Inputs:     Some flags detailing which buttons and keys were down when the mouse message
00465                 was generated; the coordinates of the mouse cursor.
00466     Outputs:    -
00467     Returns:    -
00468     Purpose:    Calls CScrollerButton::OnRButtonDown(), to convert a double-click into
00469                 a single click (MFC buttons don't normally respond to double-clicks).
00470     Errors:     -
00471     Scope:      Protected
00472     SeeAlso:    CScrollerButton::OnRButtonDown(); CScrollerButton::OnLButtonDblClk()
00473 
00474 **********************************************************************************************/ 
00475 void CScrollerButton::OnRButtonDblClk(UINT32 nFlags, CPoint point)
00476 {
00477     OnRButtonDown(nFlags, point);
00478 }
00479 
00480 
00481 
00482 /*********************************************************************************************
00483 >   afx_msg void CScrollerButton::OnTimer(UINT32 nIDEvent)
00484 
00485     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00486     Created:    ages ago
00487     Inputs:     The timer's numeric identifier (not used).
00488     Outputs:    -
00489     Returns:    -
00490     Purpose:    Responds to the elapsed timer, set in HandleButtonDown(), by repeating the
00491                 last "button-clicked" message sent to the parent CScroller.  This allows the
00492                 button to send a stream of messages until it is released - normally, Windows
00493                 buttons send only one message per click.
00494     Errors:     -
00495     Scope:      Protected
00496     SeeAlso:    CScrollerButton::HandleButtonDown(); CScrollerButton::HandleButtonUp()
00497 
00498 **********************************************************************************************/ 
00499 void CScrollerButton::OnTimer(UINT32)
00500 {
00501     // This checks for auto-repeat on the scroll button at the keyboard auto-repeat rate
00502     UINT32 CallbackTime = 1000;
00503     UINT32 RepsPerSec;
00504 
00505     ::SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &RepsPerSec, 0);
00506     CallbackTime = (UINT32) 1000 / (RepsPerSec + 1);
00507     TimerOn = ::FixSetTimer(m_hWnd, 3, CallbackTime, 0);
00508 
00509 #ifdef  _DEBUG
00510     if (!TimerOn) TRACE( _T("Unable to allocate a timer in CScrollerButton::OnTimer()!\n"));
00511 #endif  // _DEBUG
00512 
00513     GetParent()->SendMessage(Message, WPARAM(Reversed));
00514 }
00515 
00516 
00517 
00518 /*********************************************************************************************
00519 >   afx_msg void CScrollerButton::OnCancelMode()
00520 
00521     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00522     Created:    ages ago
00523     Inputs:     -
00524     Outputs:    -
00525     Returns:    -
00526     Purpose:    Sent by windows if the user hits ESCAPE or the dialog of another app. pops
00527                 up in the middle of some mouse capturing.  Gives this window a chance to
00528                 release the captured mouse and kill any running timer.
00529     Errors:     -
00530     Scope:      Protected
00531     SeeAlso:    CScrollerButton::HandleButtonDown(); CScrollerButton::OnTimer();
00532                 CScrollerButton::HandleButtonUp()
00533 
00534 **********************************************************************************************/ 
00535 void CScrollerButton::OnCancelMode()
00536 {
00537     CBitmapButton::OnCancelMode();
00538     if (TimerOn) HandleButtonUp();
00539 }
00540 
00541 
00542 
00543 /********************************************************************************************
00544 >   void PatB(CDC* hDC, INT32 x, INT32 y, INT32 dx, INT32 dy, COLORREF rgb)
00545 
00546     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> (Some MFC dude, actually)
00547     Created:    14/3/94
00548     Inputs:     hDC - destination DC
00549                 x,y,dx,dy - rectangle to fill
00550                 rgb - colour to fill with
00551     Purpose:    Paints a rectangle in the given (dithered) colour
00552                 It looks pretty hideous, but this is how the MFC buttonbar does it...
00553                 The conclusions that this leads to are left as an exercise for the reader.
00554                 (OK, so they're not. It suggest that either MFC sux, or plotting text is
00555                 easier/faster than creating a brush, in which case Windoze sux)
00556 ********************************************************************************************/
00557 
00558 static void NEAR PASCAL PatB(CDC* cDC, INT32 x, INT32 y, INT32 dx, INT32 dy, COLORREF rgb)
00559 {
00560     RECT rect;
00561     rect.left   = x;
00562     rect.top    = y;
00563     rect.right  = x + dx;
00564     rect.bottom = y + dy;
00565 
00566     cDC->SetBkColor(rgb);
00567     cDC->ExtTextOut(0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
00568 }
00569  
00570 
00571 /********************************************************************************************
00572 >   void PlotMaskedBitmap(CDC* destDC, CBitmap* srcBitmap, INT32 x, INT32 y, INT32 width, INT32 height)
00573 
00574     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> and Chris
00575     Created:    14/3/94
00576     Inputs:     destDC    - DC into which the BMP will be plotted
00577                 srcBitmap - NULL, or the source bitmap
00578                 x, y, width, height - rectangle to plot into
00579     Purpose:    Plots the given bitmap (srcDC) into the given rectangle of the destination
00580                 (destDC).
00581                 if srcDC == NULL, then just fills the button with grey, else...
00582 ********************************************************************************************/
00583 
00584 // Raster Ops, used to...
00585 
00586 // Plot colour in the glyph bitmaps transparent (grey) regions
00587 #define ROP_DSPDxax  0x00E20746L
00588 
00589 // Plot colour in the glyph bitmaps non-transparent (coloured) regions
00590 #define ROP_PSDPxax  0x00B8074AL
00591 
00592 
00593 
00594 BOOL CScrollerButton::PlotMaskedBitmap(CDC* destDC, CBitmap* srcBitmap, INT32 SrcOffset,
00595                                 INT32 xPlotOffset,INT32 yPlotOffset, INT32 width, INT32 height)
00596 {
00597     
00598     ERROR2IF(srcBitmap == NULL,FALSE,"NULL Bitmap in PlotMaskedBitmap()");
00599     ERROR2IF(destDC == NULL,FALSE,"NULL DC in PlotMaskedBitmap()");
00600 
00601     // always fill the entire background with BTNFACE to make sure we don't
00602     // miss any pixels 
00603 
00604     PatB(destDC, 0, 0, width, height, GetSysColor(COLOR_BTNFACE));
00605     
00606     // create a screen dc
00607     CDC scrDC ;
00608     scrDC.CreateCompatibleDC(destDC);
00609     
00610     // and select the bitmap into it
00611     CBitmap* OldSrcBitmap = (CBitmap *) scrDC.SelectObject(srcBitmap);
00612 
00613     // create a mask for the button glyph... First a DC
00614     CDC hDCMono ;
00615     hDCMono.CreateCompatibleDC(NULL);
00616 
00617     // create a mono bitmap for the mask
00618     CBitmap hbmMono ; 
00619     hbmMono.CreateBitmap(width, height, 1, 1, NULL);
00620     
00621     CBitmap * oldmonobitmap = (CBitmap *)hDCMono.SelectObject(&hbmMono);
00622 
00623     // initalize the bitmapto white (all 1's)
00624     hDCMono.PatBlt(0, 0, width, height, WHITENESS);
00625 
00626     // plot all non-lightgrey  pixels in the glyph as black in our mask
00627     scrDC.SetBkColor( RGB(192,192,192));
00628     hDCMono.BitBlt(xPlotOffset,yPlotOffset, width, height, &scrDC,
00629             SrcOffset, 0, SRCCOPY);
00630 
00631     destDC->SetTextColor(0L);                  // 0's in mono -> 0 (for ROP)
00632     destDC->SetBkColor((COLORREF)0x00FFFFFFL); // 1's in mono -> 1
00633 
00634     // plot the glyph 
00635     destDC->BitBlt( xPlotOffset, yPlotOffset, width, height,
00636                     &scrDC, SrcOffset, 0, SRCCOPY);
00637         
00638     // fill with the normal BTNFACE colour
00639     CBrush HighlightBrush ; 
00640     HighlightBrush.CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
00641 
00642     CBrush* hbrOld = (CBrush *) destDC->SelectObject(&HighlightBrush);
00643     if (hbrOld != NULL)
00644     {
00645         // draw highlight color where we have 0's in the mask
00646         destDC->BitBlt( xPlotOffset,yPlotOffset, width, height,  &hDCMono, 0, 0, ROP_DSPDxax);
00647         destDC->SelectObject(hbrOld);
00648     }
00649     
00650     // clean up DC's
00651     hDCMono.SelectObject(oldmonobitmap);
00652     scrDC.SelectObject(OldSrcBitmap);
00653     return TRUE;
00654 }
00655 
00656 
00657 void CScrollerButton::DrawItem (LPDRAWITEMSTRUCT    lpDIS)
00658 {
00659 
00660 
00661     ASSERT(lpDIS != NULL);
00662     // must have at least the first bitmap loaded before calling DrawItem
00663     ASSERT(m_bitmap.m_hObject != NULL);     // required
00664 
00665     // use the main bitmap for up, the selected bitmap for down
00666     CBitmap* pBitmap = &m_bitmap;
00667     UINT32 state = lpDIS->itemState;
00668     if ((state & ODS_SELECTED) && m_bitmapSel.m_hObject != NULL)
00669         pBitmap = &m_bitmapSel;
00670 
00671 #ifndef _MAC
00672     else if ((state & ODS_FOCUS) && m_bitmapFocus.m_hObject != NULL)
00673 #else
00674     else if ((state & ODS_FOCUS) && m_bitmapFocus.m_hObject != NULL &&
00675             (GetParent()->GetStyle() & DS_WINDOWSUI))
00676 #endif
00677         pBitmap = &m_bitmapFocus;   // third image for focused
00678     else if ((state & ODS_DISABLED) && m_bitmapDisabled.m_hObject != NULL)
00679         pBitmap = &m_bitmapDisabled;   // last image for disabled
00680 
00681     
00682 
00683     CDC* pDC = CDC::FromHandle(lpDIS->hDC);
00684     
00685     // New masked version
00686     //------------------------------------------------------------------------------
00687     CRect rect;
00688     rect.CopyRect(&lpDIS->rcItem);
00689     if(!IS_CHICAGO)  // UIC
00690     {
00691         // draw the whole button
00692         PlotMaskedBitmap(pDC,pBitmap,0,rect.left, rect.top, rect.Width(), rect.Height());
00693     }
00694     else
00695     { 
00696         UINT32 Flags =0;
00697         switch(Orient)
00698         {
00699         case UP:
00700             Flags = DFCS_SCROLLUP;
00701             break;
00702         case DOWN:
00703             Flags = DFCS_SCROLLDOWN;
00704             break;
00705         case LEFT:
00706             Flags = DFCS_SCROLLLEFT;
00707             break;
00708         case RIGHT:
00709             Flags = DFCS_SCROLLRIGHT;
00710             break;
00711         }
00712         if (state & ODS_SELECTED)
00713             Flags |= DFCS_PUSHED;
00714 
00715         pDC->DrawFrameControl(&rect,DFC_SCROLL, Flags);
00716     }
00717 
00718 
00719     //-------------------------------------------------------------------------------
00720     
00721     // Old "scrcopy" version
00722     //-------------------------------------------------------------------------------
00723     /*
00724     CDC memDC;
00725     memDC.CreateCompatibleDC(pDC);
00726     CBitmap* pOld = memDC.SelectObject(pBitmap);
00727     if (pOld == NULL)
00728         return;     // destructors will clean up
00729 
00730     CRect rect;
00731     rect.CopyRect(&lpDIS->rcItem);
00732     pDC->BitBlt(rect.left, rect.top, rect.Width(), rect.Height(),
00733         &memDC, 0, 0, SRCCOPY);
00734 
00735     memDC.SelectObject(pOld);
00736     */
00737     //-------------------------------------------------------------------------------
00738 }

Generated on Sat Nov 10 03:48:50 2007 for Camelot by  doxygen 1.4.4