www.pudn.com > vc开发的精美界面.zip > bcgoutlookbar.cpp
//******************************************************************************* // COPYRIGHT NOTES // --------------- // This source code is a part of BCGControlBar library. // You may use, compile or redistribute it as part of your application // for free. You cannot redistribute it as a part of a software development // library without the agreement of the author. If the sources are // distributed along with the application, you should leave the original // copyright notes in the source code without any changes. // This code can be used WITHOUT ANY WARRANTIES on your own risk. // // For the latest updates to this library, check my site: // http://welcome.to/bcgsoft // // Stas Levin//******************************************************************************* // bcgoutlookbar.cpp : implementation file // #include "stdafx.h" #include "bcgoutlookbar.h" #include "MenuImages.h" #include "bcgbarres.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #define BORDER_SIZE 3 #define MARGIN_SIZE 2 #define SCROLL_BUTTON_OFFSET 5 static const UINT idScrollUp = 1; static const UINT idScrollDn = 2; static const UINT uiScrollDelay = 200; // ms ///////////////////////////////////////////////////////////////////////////// // CBCGOutlookBar IMPLEMENT_DYNAMIC(CBCGOutlookBar, CBCGToolBar) CBCGOutlookBar::CBCGOutlookBar() { m_iScrollOffset = 0; m_iFirstVisibleButton = 0; m_bScrollDown = FALSE; m_clrRegText = ::GetSysColor (COLOR_WINDOW); m_clrBackColor = ::GetSysColor (COLOR_3DSHADOW); m_clrTransparentColor = RGB (255, 0, 255); m_Images.SetTransparentColor (m_clrTransparentColor); m_csImage = CSize (0, 0); m_uiBackImageId = 0; m_btnUp.m_nFlatStyle = CBCGButton::BUTTONSTYLE_3D; m_btnDown.m_nFlatStyle = CBCGButton::BUTTONSTYLE_3D; m_bDrawShadedHighlight = FALSE; } //************************************************************************************* CBCGOutlookBar::~CBCGOutlookBar() { while (!m_Buttons.IsEmpty ()) { delete m_Buttons.RemoveHead (); } } BEGIN_MESSAGE_MAP(CBCGOutlookBar, CBCGToolBar) //{{AFX_MSG_MAP(CBCGOutlookBar) ON_WM_ERASEBKGND() ON_WM_SIZE() ON_WM_CREATE() ON_WM_NCCALCSIZE() ON_WM_SYSCOLORCHANGE() ON_WM_TIMER() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CBCGOutlookBar message handlers BOOL CBCGOutlookBar::Create(CWnd* pParentWnd, DWORD dwStyle, UINT nID) { // initialize common controls VERIFY(AfxDeferRegisterClass(AFX_WNDCOMMCTLS_REG)); return CBCGToolBar::Create (pParentWnd, dwStyle | WS_CHILD | WS_VISIBLE, nID); } //************************************************************************************* BOOL CBCGOutlookBar::OnEraseBkgnd(CDC* /*pDC*/) { return TRUE; } //************************************************************************************* BOOL CBCGOutlookBar::AddButton (UINT uiImage, UINT uiLabel, UINT iIdCommand) { CString strLable; strLable.LoadString (uiLabel); return AddButton (uiImage, strLable, iIdCommand); } //************************************************************************************* BOOL CBCGOutlookBar::AddButton (UINT uiImage, LPCTSTR lpszLabel, UINT iIdCommand) { int iImageIndex = -1; if (uiImage != 0) { CBitmap bmp; if (!bmp.LoadBitmap (uiImage)) { TRACE(_T("Can't load bitmap resource: %d"), uiImage); return FALSE; } BITMAP bitmap; bmp.GetBitmap (&bitmap); CSize csImage = CSize (bitmap.bmWidth, bitmap.bmHeight); if (m_Images.GetCount () == 0) // First image { m_csImage = csImage; m_Images.SetImageSize (csImage); } else { ASSERT (m_csImage == csImage); // All buttons should be of the same size! } iImageIndex = m_Images.AddImage (bmp); } CBCGOutlookButton* pButton = new CBCGOutlookButton; ASSERT (pButton != NULL); pButton->m_nID = iIdCommand; pButton->m_strText = (lpszLabel == NULL) ? _T("") : lpszLabel; pButton->SetImage (iImageIndex); pButton->m_bTextBelow = m_bTextLabels; InsertButton (pButton, m_Buttons.GetCount () - 1); AdjustLayout (); return TRUE; } //************************************************************************************** BOOL CBCGOutlookBar::RemoveButton (UINT iIdCommand) { for (POSITION pos = m_Buttons.GetHeadPosition (); pos != NULL;) { POSITION posSave = pos; CBCGOutlookButton* pButton = (CBCGOutlookButton*) m_Buttons.GetNext (pos); ASSERT (pButton != NULL); if (pButton->m_nID == iIdCommand) { m_Buttons.RemoveAt (posSave); delete pButton; AdjustLocations (); UpdateWindow (); Invalidate (); return TRUE; } } return FALSE; } //************************************************************************************* void CBCGOutlookBar::OnSize(UINT nType, int cx, int cy) { CBCGToolBar::OnSize(nType, cx, cy); int iButtons = m_Buttons.GetCount (); if (iButtons > 0) { AdjustLayout (); POSITION posLast = m_Buttons.FindIndex (iButtons - 1); CBCGOutlookButton* pButtonLast = (CBCGOutlookButton*) m_Buttons.GetAt (posLast); ASSERT (pButtonLast != NULL); while (m_iScrollOffset > 0 && pButtonLast->Rect ().bottom < cy) { ScrollUp (); } } } //************************************************************************************* void CBCGOutlookBar::SetTextColor (COLORREF clrRegText, COLORREF/* clrSelText obsolete*/) { m_clrRegText = clrRegText; if (GetSafeHwnd () != NULL) { Invalidate (); UpdateWindow (); } } //************************************************************************************* int CBCGOutlookBar::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CBCGToolBar::OnCreate(lpCreateStruct) == -1) return -1; SetBarStyle (m_dwStyle & ~(CBRS_BORDER_ANY | CBRS_GRIPPER)); m_cxLeftBorder = m_cxRightBorder = 0; m_cyTopBorder = m_cyBottomBorder = 0; //------------------------------------------- // Adjust Z-order in the parent frame window: //------------------------------------------- BOOL bVert = (m_dwStyle & CBRS_ORIENT_HORZ) == 0; if (bVert) { SetWindowPos(&wndBottom, 0,0,0,0,SWP_NOSIZE|SWP_NOMOVE); } else { CFrameWnd* pParent = GetParentFrame (); ASSERT (pParent != NULL); CWnd* pWndStatusBar = pParent->GetDlgItem (AFX_IDW_STATUS_BAR); if (pWndStatusBar != NULL) { SetWindowPos(pWndStatusBar, 0,0,0,0,SWP_NOSIZE|SWP_NOMOVE); } } //----------------------- // Create scroll buttons: //----------------------- CRect rectDummy (CPoint (0, 0), CMenuImages::Size ()); rectDummy.InflateRect (MARGIN_SIZE, MARGIN_SIZE); m_btnUp.Create (_T(""), WS_CHILD | BS_PUSHBUTTON, rectDummy, this, idScrollUp); m_btnUp.SetStdImage (bVert ? CMenuImages::IdArowUp : CMenuImages::IdArowLeft); m_btnDown.Create (_T(""), WS_CHILD | BS_PUSHBUTTON, rectDummy, this, idScrollDn); m_btnDown.SetStdImage (bVert ? CMenuImages::IdArowDown : CMenuImages::IdArowRight); SetWindowText (_T("Shortcuts bar")); return 0; } //************************************************************************************* void CBCGOutlookBar::ScrollUp () { if (m_iScrollOffset <= 0 || m_iFirstVisibleButton <= 0) { KillTimer (idScrollUp); return; } POSITION pos = m_Buttons.FindIndex (--m_iFirstVisibleButton); CBCGOutlookButton* pButton = (CBCGOutlookButton*) m_Buttons.GetAt (pos); ASSERT (pButton != NULL); BOOL bVert = (m_dwStyle & CBRS_ORIENT_HORZ) == 0; if (bVert) { m_iScrollOffset -= pButton->Rect ().Height (); } else { m_iScrollOffset -= pButton->Rect ().Width (); } if (m_iFirstVisibleButton == 0) { m_iScrollOffset = 0; } ASSERT (m_iScrollOffset >= 0); AdjustLayout (); } //************************************************************************************* void CBCGOutlookBar::ScrollDown () { if (!m_bScrollDown || m_iFirstVisibleButton + 1 >= m_Buttons.GetCount ()) { KillTimer (idScrollDn); return; } POSITION pos = m_Buttons.FindIndex (++m_iFirstVisibleButton); CBCGOutlookButton* pButton = (CBCGOutlookButton*) m_Buttons.GetAt (pos); ASSERT (pButton != NULL); BOOL bVert = (m_dwStyle & CBRS_ORIENT_HORZ) == 0; if (bVert) { m_iScrollOffset += pButton->Rect ().Height (); } else { m_iScrollOffset += pButton->Rect ().Width (); } AdjustLayout (); } //************************************************************************************* CSize CBCGOutlookBar::CalcFixedLayout (BOOL /*bStretch*/, BOOL bHorz) { int iMinSize = (bHorz) ? m_csImage.cy + 2 * MARGIN_SIZE + 2 * BORDER_SIZE: m_csImage.cx + 2 * MARGIN_SIZE + 2 * BORDER_SIZE; if (m_bTextLabels) { CClientDC dc (this); for (POSITION pos = m_Buttons.GetHeadPosition (); pos != NULL;) { CBCGOutlookButton* pButton = (CBCGOutlookButton*) m_Buttons.GetNext (pos); ASSERT (pButton != NULL); CRect rectText (0, 0, 1, 1); dc.DrawText (pButton->m_strText, rectText, DT_CALCRECT | DT_WORDBREAK); if (!bHorz) { iMinSize = max (iMinSize, rectText.Width ()); } else { iMinSize = max (iMinSize, rectText.Height ()); } } } CSize size = (bHorz) ? CSize (32767, iMinSize) : CSize (iMinSize, 32767); return size; } //************************************************************************************* void CBCGOutlookBar::OnNcCalcSize(BOOL /*bCalcValidRects*/, NCCALCSIZE_PARAMS FAR* lpncsp) { CRect rect; rect.SetRectEmpty(); BOOL bHorz = (m_dwStyle & CBRS_ORIENT_HORZ) != 0; CControlBar::CalcInsideRect(rect, bHorz); // adjust non-client area for border space lpncsp->rgrc[0].left += rect.left; lpncsp->rgrc[0].top += rect.top; lpncsp->rgrc[0].right += rect.right; lpncsp->rgrc[0].bottom += rect.bottom; } //************************************************************************************* void CBCGOutlookBar::SetBackImage (UINT uiImageID) { if (m_uiBackImageId == uiImageID) { return; } m_bDrawShadedHighlight = FALSE; if (m_bmpBack.GetCount () > 0) { m_bmpBack.Clear (); } m_uiBackImageId = 0; if (uiImageID != 0) { HBITMAP hbmp = (HBITMAP) ::LoadImage ( AfxGetResourceHandle (), MAKEINTRESOURCE (uiImageID), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_LOADMAP3DCOLORS); if (hbmp != NULL) { BITMAP bitmap; ::GetObject (hbmp, sizeof (BITMAP), (LPVOID) &bitmap); m_bmpBack.SetImageSize (CSize (bitmap.bmWidth, bitmap.bmHeight)); m_bmpBack.AddImage (hbmp); m_uiBackImageId = uiImageID; } m_bDrawShadedHighlight = (globalData.m_nBitsPerPixel > 8); // For 16 bits or greater } if (GetSafeHwnd () != NULL) { Invalidate (); UpdateWindow (); } } //************************************************************************************* void CBCGOutlookBar::SetBackColor (COLORREF color) { m_clrBackColor = color; if (GetSafeHwnd () != NULL) { Invalidate (); UpdateWindow (); } } //************************************************************************************* void CBCGOutlookBar::SetTransparentColor (COLORREF color) { m_clrTransparentColor = color; if (GetSafeHwnd () != NULL) { m_Images.SetTransparentColor (m_clrTransparentColor); Invalidate (); UpdateWindow (); } } //************************************************************************************* void CBCGOutlookBar::OnSysColorChange() { CBCGToolBar::OnSysColorChange(); m_clrBackColor = ::GetSysColor (COLOR_3DSHADOW); if (m_uiBackImageId != 0) { int uiImage = m_uiBackImageId; m_uiBackImageId = (UINT) -1; SetBackImage (uiImage); } else { m_clrRegText = ::GetSysColor (COLOR_WINDOW); Invalidate (); } } //***************************************************************************************** void CBCGOutlookBar::AdjustLocations () { if (GetSafeHwnd () == NULL) { return; } ASSERT_VALID(this); if (m_Buttons.IsEmpty ()) { return; } CSize sizeScrollBtn = CMenuImages::Size () + CSize (MARGIN_SIZE, MARGIN_SIZE); BOOL bVert = (m_dwStyle & CBRS_ORIENT_HORZ) == 0; CClientDC dc (this); CFont* pOldFont = dc.SelectObject (&globalData.fontRegular); CRect rectClient; GetClientRect (&rectClient); CSize sizeDefault; if (bVert) { rectClient.InflateRect (-BORDER_SIZE, -2); sizeDefault = CSize (rectClient.Width () - 2 * MARGIN_SIZE, m_csImage.cy); } else { rectClient.InflateRect (-1, -BORDER_SIZE); sizeDefault = CSize (m_csImage.cx, rectClient.Height () - 2 * MARGIN_SIZE); } int iOffset = bVert ? rectClient.top - m_iScrollOffset + SCROLL_BUTTON_OFFSET: rectClient.left - m_iScrollOffset + SCROLL_BUTTON_OFFSET; if (m_iFirstVisibleButton > 0) { m_btnUp.SetWindowPos (NULL, rectClient.right - sizeScrollBtn.cx - SCROLL_BUTTON_OFFSET, rectClient.top + SCROLL_BUTTON_OFFSET, -1, -1, SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER); m_btnUp.ShowWindow (SW_SHOWNOACTIVATE); } else { m_btnUp.ShowWindow (SW_HIDE); } int iIndex = 1; for (POSITION pos = m_Buttons.GetHeadPosition (); pos != NULL; iIndex ++) { CBCGOutlookButton* pButton = (CBCGOutlookButton*) m_Buttons.GetNext (pos); ASSERT (pButton != NULL); pButton->m_bTextBelow = m_bTextLabels; CSize sizeButton = pButton->OnCalculateSize (&dc, sizeDefault, !bVert); CRect rectButton; if (bVert) { rectButton = CRect (rectClient.left + MARGIN_SIZE, iOffset, rectClient.right - 1, iOffset + sizeButton.cy); iOffset = rectButton.bottom; } else { rectButton = CRect (rectClient.left + iOffset, rectClient.top + MARGIN_SIZE, rectClient.left + iOffset + sizeButton.cx, rectClient.bottom - 1); iOffset = rectButton.right; } pButton->SetRect (rectButton); } if (bVert) { m_bScrollDown = (iOffset > rectClient.bottom); } else { m_bScrollDown = (iOffset > rectClient.right); } if (m_bScrollDown) { m_btnDown.SetWindowPos (&wndTop, rectClient.right - sizeScrollBtn.cx - SCROLL_BUTTON_OFFSET, bVert ? rectClient.bottom - sizeScrollBtn.cy - SCROLL_BUTTON_OFFSET : rectClient.top + SCROLL_BUTTON_OFFSET, -1, -1, SWP_NOSIZE | SWP_NOACTIVATE); m_btnDown.ShowWindow (SW_SHOWNOACTIVATE); } else { m_btnDown.ShowWindow (SW_HIDE); } dc.SelectObject (pOldFont); OnMouseLeave (0, 0); } //************************************************************************************* void CBCGOutlookBar::DoPaint(CDC* pDCPaint) { ASSERT_VALID(this); ASSERT_VALID(pDCPaint); CRect rectClip; pDCPaint->GetClipBox (rectClip); BOOL bHorz = m_dwStyle & CBRS_ORIENT_HORZ ? TRUE : FALSE; CRect rectClient; GetClientRect (rectClient); CDC* pDC = pDCPaint; BOOL m_bMemDC = FALSE; CDC dcMem; CBitmap bmp; CBitmap* pOldBmp = NULL; if (dcMem.CreateCompatibleDC (pDCPaint) && bmp.CreateCompatibleBitmap (pDCPaint, rectClient.Width (), rectClient.Height ())) { //------------------------------------------------------------- // Off-screen DC successfully created. Better paint to it then! //------------------------------------------------------------- m_bMemDC = TRUE; pOldBmp = dcMem.SelectObject (&bmp); pDC = &dcMem; } if (m_bmpBack.GetCount () == 0) { pDC->FillSolidRect (rectClient, m_clrBackColor); } else { ASSERT (m_bmpBack.GetCount () == 1); CBCGDrawState ds; m_bmpBack.PrepareDrawImage (ds); CSize sizeBack = m_bmpBack.GetImageSize (); for (int x = 0; x < rectClient.Width (); x += sizeBack.cx) { for (int y = 0; y < rectClient.Height (); y += sizeBack.cy) { m_bmpBack.Draw (pDC, x, y, 0); } } m_bmpBack.EndDrawImage (ds); } pDC->SetTextColor (globalData.clrBtnText); pDC->SetBkMode (TRANSPARENT); CRect rectBorder = rectClient; if (!bHorz) { rectBorder.InflateRect (0, 2); rectBorder.left = rectBorder.right - BORDER_SIZE; } else { rectBorder.InflateRect (2, 0); rectBorder.bottom = rectBorder.top + BORDER_SIZE; } pDC->FillRect (rectBorder, &globalData.brBtnFace); pDC->Draw3dRect (rectBorder, ::GetSysColor (COLOR_3DHILIGHT), ::GetSysColor (COLOR_3DSHADOW)); CRect rectSpace = rectClient; if (!bHorz) { CRect rectLeft = rectClient; rectLeft.right = BORDER_SIZE; pDC->FillRect (rectLeft, &globalData.brBtnFace); rectSpace.left = rectLeft.right; rectSpace.right = rectBorder.left; } else { CRect rectBottom = rectClient; rectBottom.top = rectBottom.bottom - BORDER_SIZE; pDC->FillRect (rectBottom, &globalData.brBtnFace); rectSpace.top = rectBorder.bottom; rectSpace.bottom = rectBottom.top; } pDC->Draw3dRect (rectSpace, ::GetSysColor (COLOR_3DSHADOW), ::GetSysColor (COLOR_3DHILIGHT)); if (!bHorz) { rectSpace.InflateRect (0, -1); rectSpace.left ++; } else { rectSpace.InflateRect (-1, 0); rectSpace.top ++; } pDC->Draw3dRect (rectSpace, ::GetSysColor (COLOR_3DDKSHADOW), ::GetSysColor (COLOR_3DLIGHT)); CBCGDrawState ds; if (!m_Images.PrepareDrawImage (ds)) { return; // something went wrong } CFont* pOldFont = pDC->SelectObject (&globalData.fontRegular); //-------------- // Draw buttons: //-------------- if (!bHorz) { rectClient.InflateRect (-BORDER_SIZE, -2); } else { rectClient.InflateRect (-1, -BORDER_SIZE); } CRgn rgn; rgn.CreateRectRgnIndirect (rectClient); pDC->SelectClipRgn (&rgn); POSITION pos = m_Buttons.GetHeadPosition (); int iButton = 1; m_Buttons.GetNext (pos); // Skip "Up" button BOOL bStop = FALSE; for (; !bStop; iButton ++) { CBCGOutlookButton* pButton = NULL; if (pos == NULL) { pButton = (CBCGOutlookButton*) m_Buttons.GetHead (); iButton = 0; bStop = TRUE; } else { pButton = (CBCGOutlookButton*) m_Buttons.GetNext (pos); } ASSERT_VALID (pButton); CRect rect = pButton->Rect (); BOOL bHighlighted = FALSE; if (IsCustomizeMode () && !m_bLocked) { bHighlighted = FALSE; } else { bHighlighted = ((iButton == m_iHighlighted || iButton == m_iButtonCapture) && (m_iButtonCapture == -1 || iButton == m_iButtonCapture)); } CRect rectInter; if (rectInter.IntersectRect (rect, rectClip)) { pButton->OnDraw (pDC, rect, &m_Images, bHorz, IsCustomizeMode (), bHighlighted); } } //------------------------------------------------------------- // Highlight selected button in the toolbar customization mode: //------------------------------------------------------------- if (m_iSelected >= m_Buttons.GetCount ()) { m_iSelected = -1; } if (IsCustomizeMode () && m_iSelected >= 0 && !m_bLocked) { CBCGToolbarButton* pSelButton = GetButton (m_iSelected); ASSERT (pSelButton != NULL); if (pSelButton != NULL && pSelButton->CanBeStored ()) { CRect rectDrag = pSelButton->Rect (); if (pSelButton->GetHwnd () != NULL) { rectDrag.InflateRect (0, 1); } pDC->DrawDragRect (&rectDrag, CSize (2, 2), NULL, CSize (2, 2)); } } if (IsCustomizeMode () && m_iDragIndex >= 0 && !m_bLocked) { DrawDragMarker (pDC); } pDC->SelectClipRgn (NULL); pDC->SelectObject (pOldFont); m_Images.EndDrawImage (ds); if (m_bMemDC) { //-------------------------------------- // Copy the results to the on-screen DC: //-------------------------------------- pDCPaint->BitBlt (rectClip.left, rectClip.top, rectClip.Width(), rectClip.Height(), &dcMem, rectClip.left, rectClip.top, SRCCOPY); dcMem.SelectObject(pOldBmp); } } //**************************************************************************************** int CBCGOutlookBar::HitTest(CPoint point) { CRect rect; m_btnDown.GetClientRect (rect); m_btnDown.MapWindowPoints (this, rect); if (rect.PtInRect (point)) { return -1; } m_btnUp.GetClientRect (rect); m_btnUp.MapWindowPoints (this, rect); if (rect.PtInRect (point)) { return -1; } return CBCGToolBar::HitTest (point); } //**************************************************************************************** DROPEFFECT CBCGOutlookBar::OnDragOver(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point) { CBCGToolbarButton* pButton = CBCGToolbarButton::CreateFromOleData (pDataObject); if (pButton == NULL) { return DROPEFFECT_NONE; } BOOL bAllowDrop = pButton->IsKindOf (RUNTIME_CLASS (CBCGOutlookButton)); delete pButton; if (!bAllowDrop) { return DROPEFFECT_NONE; } int iHit = HitTest (point); if (iHit == 0) { ScrollUp (); return DROPEFFECT_NONE; } if (iHit == m_Buttons.GetCount () - 1) { ScrollDown (); return DROPEFFECT_NONE; } return CBCGToolBar::OnDragOver (pDataObject, dwKeyState, point); } //*************************************************************************************** BOOL CBCGOutlookBar::EnableContextMenuItems (CBCGToolbarButton* pButton, CMenu* pPopup) { ASSERT_VALID (pButton); ASSERT_VALID (pPopup); if (IsCustomizeMode ()) { pPopup->EnableMenuItem (ID_BCGBARRES_TOOLBAR_IMAGE, MF_GRAYED | MF_BYCOMMAND); pPopup->EnableMenuItem (ID_BCGBARRES_TOOLBAR_TEXT, MF_GRAYED | MF_BYCOMMAND); pPopup->EnableMenuItem (ID_BCGBARRES_TOOLBAR_IMAGE_AND_TEXT, MF_GRAYED | MF_BYCOMMAND); pPopup->EnableMenuItem (ID_BCGBARRES_TOOLBAR_APPEARANCE, MF_GRAYED | MF_BYCOMMAND); pPopup->EnableMenuItem (ID_BCGBARRES_TOOLBAR_START_GROUP, MF_GRAYED | MF_BYCOMMAND); pPopup->EnableMenuItem (ID_BCGBARRES_TOOLBAR_RESET, MF_GRAYED | MF_BYCOMMAND); pPopup->EnableMenuItem (ID_BCGBARRES_COPY_IMAGE, MF_GRAYED | MF_BYCOMMAND); } CBCGToolBar::EnableContextMenuItems (pButton, pPopup); return TRUE; } //************************************************************************************** BOOL CBCGOutlookBar::PreTranslateMessage(MSG* pMsg) { switch (pMsg->message) { case WM_LBUTTONUP: KillTimer (idScrollUp); KillTimer (idScrollDn); case WM_LBUTTONDOWN: case WM_MOUSEMOVE: { CPoint ptCursor; ::GetCursorPos (&ptCursor); ScreenToClient (&ptCursor); CRect rect; m_btnDown.GetClientRect (rect); m_btnDown.MapWindowPoints (this, rect); if (rect.PtInRect (ptCursor)) { m_btnDown.SendMessage (pMsg->message, pMsg->wParam, pMsg->wParam); if (pMsg->message == WM_LBUTTONDOWN) { SetTimer (idScrollDn, uiScrollDelay, NULL); ScrollDown (); } return TRUE; } m_btnUp.GetClientRect (rect); m_btnUp.MapWindowPoints (this, rect); if (rect.PtInRect (ptCursor)) { m_btnUp.SendMessage (pMsg->message, pMsg->wParam, pMsg->wParam); if (pMsg->message == WM_LBUTTONDOWN) { SetTimer (idScrollUp, uiScrollDelay, NULL); ScrollUp (); } return TRUE; } } } return CBCGToolBar::PreTranslateMessage(pMsg); } //************************************************************************************** void CBCGOutlookBar::OnTimer(UINT nIDEvent) { switch (nIDEvent) { case idScrollUp: if (m_btnUp.IsPressed ()) { ScrollUp (); } return; case idScrollDn: if (m_btnDown.IsPressed ()) { ScrollDown (); } return; } CBCGToolBar::OnTimer(nIDEvent); }