none
我重绘了一个控件CAdjustSlider,继承自CSliderCtrl,但是当我用鼠标拖动滑块时,该控件的父窗口的OnHScroll函数不响应,这时为什么,或者有时响应,有时不响应 RRS feed

  • 问题

  • 源码如下,哪位高手指点一下我, 非常感谢!

    头文件:

    #if !defined(AFX_MYSLIDER_H__E434F151_26B7_45C1_89F0_2E59B3D642E2__INCLUDED_)
    #define AFX_MYSLIDER_H__E434F151_26B7_45C1_89F0_2E59B3D642E2__INCLUDED_

    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000

    // CAdjustSlider window

    class CAdjustSlider : public CSliderCtrl
    {
    // Construction
    public:
     CAdjustSlider();

    // Attributes
    public:

    // Operations
    public:

    // Overrides
     // ClassWizard generated virtual function overrides
     //{{AFX_VIRTUAL(CAdjustSlider)
    protected:
     virtual void PreSubclassWindow();
     //}}AFX_VIRTUAL

    // Implementation
    public:
     virtual ~CAdjustSlider();

     // Generated message map functions
    protected:
     //{{AFX_MSG(CAdjustSlider)
     afx_msg void OnPaint();
     afx_msg BOOL OnEraseBkgnd(CDC* pDC);
     afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
     afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
     afx_msg void OnMouseMove(UINT nFlags, CPoint point);
     //}}AFX_MSG
    private:
     bool m_flagLBtnDownInThumb;  // true:鼠标左键在thumb区域被按下;
     CRect m_rtClient;  // slider控件的客户区域;
     CRect m_rtChannel;  // channel的矩形区域大小;
     CRect m_rtThumb;  // thumb的矩形区域大小;
     CRect m_rtCurPosThumb;  // thumb当前的区域;
     CPoint m_ptInChannel;
     CBitmap m_ThumbMask;
     CBitmap m_ThumbBmp;
     COLORREF m_BackColor;  // thumb滑块区域的背景色,一般和控件所在对话框的颜色相同,重绘时,会用到该颜色;
    public:
     void SetBkcolor(COLORREF rgb);  // 设置m_BackColor;
     void SetPos(int nPos);
     DECLARE_MESSAGE_MAP()
     afx_msg void OnTimer(UINT_PTR nIDEvent);
    };

    /////////////////////////////////////////////////////////////////////////////

    //{{AFX_INSERT_LOCATION}}
    // Microsoft Visual C++ will insert additional declarations immediately before the previous line.

    #endif // !defined(AFX_MYSLIDER_H__E434F151_26B7_45C1_89F0_2E59B3D642E2__INCLUDED_)

    源文件:

    // MySlider.cpp : implementation file
    //

    #include "stdafx.h"
    #include "AdjustSlider.h"


    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif

    /////////////////////////////////////////////////////////////////////////////
    // CAdjustSlider

    CAdjustSlider::CAdjustSlider()
    {
     m_flagLBtnDownInThumb = false;
     m_ThumbMask.LoadBitmap(IDB_BITMAP_THUMBMASK);
     m_ThumbBmp.LoadBitmap(IDB_BITMAP_THUMB);
     m_BackColor = RGB(211, 211, 211);
    }

    CAdjustSlider::~CAdjustSlider()
    {
     if (m_ThumbBmp.m_hObject)
     {
      m_ThumbBmp.DeleteObject();
     }
     if (m_ThumbMask.m_hObject)
     {
      m_ThumbMask.DeleteObject();
     }
    }


    BEGIN_MESSAGE_MAP(CAdjustSlider, CSliderCtrl)
     //{{AFX_MSG_MAP(CAdjustSlider)
     ON_WM_PAINT()
     ON_WM_ERASEBKGND()
     ON_WM_LBUTTONUP()
     ON_WM_LBUTTONDOWN()
     ON_WM_MOUSEMOVE()
     //}}AFX_MSG_MAP
     ON_WM_TIMER()
    END_MESSAGE_MAP()

    /////////////////////////////////////////////////////////////////////////////
    // CAdjustSlider message handlers

    void CAdjustSlider::OnPaint()
    {
     CPaintDC dc(this); // device context for painting
     
     // TODO: Add your message handler code here
     
     dc.FillRect(&m_rtClient, &CBrush(m_BackColor));
     dc.FillRect(&m_rtChannel, &CBrush(RGB(255, 255, 255)));
     
     
     
     CDC *pDC, pMemDC, pMaskDC;
     pDC = GetDC();
     pMemDC.CreateCompatibleDC(pDC);
     pMaskDC.CreateCompatibleDC(pDC);

     pMemDC.SelectObject(&m_ThumbBmp);
     pMaskDC.SelectObject(&m_ThumbMask);

     pDC->BitBlt(m_rtCurPosThumb.left, m_rtCurPosThumb.top, m_rtThumb.Width(), m_rtThumb.Height(), &pMaskDC, 0, 0, MERGEPAINT);
     pDC->BitBlt(m_rtCurPosThumb.left, m_rtCurPosThumb.top, m_rtThumb.Width(), m_rtThumb.Height(), &pMemDC, 0, 0, SRCAND);

     ReleaseDC(pDC);

     // Do not call CSliderCtrl::OnPaint() for painting messages
    }

    BOOL CAdjustSlider::OnEraseBkgnd(CDC* pDC)
    {
     // TODO: Add your message handler code here and/or call default
     
     return true;
    }

    void CAdjustSlider::OnLButtonUp(UINT nFlags, CPoint point)
    {
     // TODO: Add your message handler code here and/or call default
     if (m_flagLBtnDownInThumb)
     {
      m_flagLBtnDownInThumb = false;
      ReleaseCapture();
     }
     
     CSliderCtrl::OnLButtonUp(nFlags, point);
    }

    void CAdjustSlider::OnLButtonDown(UINT nFlags, CPoint point)
    {
     // TODO: Add your message handler code here and/or call default
     if (m_rtCurPosThumb.PtInRect(point))
     {
      m_flagLBtnDownInThumb = true; 
      SetCapture();
     }
     else if (m_rtChannel.PtInRect(point))
     {
      int nMax = 0; 
      int nMin = 0; 
      GetRange(nMin,nMax); 
      int nPos = (nMax - nMin)*(point.x - m_rtClient.left - m_rtChannel.left)/(m_rtChannel.right - m_rtChannel.left);  
      nPos += nMin;
      SetPos(nPos);
      
      Invalidate();
      CSliderCtrl::OnLButtonDown(nFlags, point);
     }
    }

    void CAdjustSlider::OnMouseMove(UINT nFlags, CPoint point)
    {
     // TODO: Add your message handler code here and/or call default
     if (MK_LBUTTON == nFlags)
     {
      if (m_flagLBtnDownInThumb)
      {
       if (point.x > m_rtChannel.right)
       {
        point.x = m_rtChannel.right;
       }
       if (point.x < m_rtChannel.left)
       {
        point.x = m_rtChannel.left;
       }

       int nMax = 0; 
       int nMin = 0; 
       GetRange(nMin,nMax); 
       int nPos = (nMax - nMin)*(point.x - m_rtClient.left - m_rtChannel.left)/(m_rtChannel.right - m_rtChannel.left);  
       nPos += nMin;
       SetPos(nPos);
       Invalidate();
       //::SendMessage(GetParent()->GetSafeHwnd(), WM_HSCROLL, TB_THUMBTRACK, 0);
      }
     }

     CSliderCtrl::OnMouseMove(nFlags, point);
    }

     

    void CAdjustSlider::PreSubclassWindow()
    {
     // TODO: Add your specialized code here and/or call the base class
     GetClientRect(&m_rtClient);
     GetChannelRect(&m_rtChannel);
     GetThumbRect(&m_rtThumb);

     m_rtChannel.bottom = m_rtChannel.top + 5;
     m_rtThumb.top = m_rtChannel.bottom + 1;
     m_rtThumb.bottom = m_rtThumb.top + 11;
     m_rtThumb.left = m_rtChannel.left - 5;
     m_rtThumb.right = m_rtThumb.left + 11;

     m_rtCurPosThumb = m_rtThumb;

     m_ptInChannel.x = m_rtCurPosThumb.left + m_rtCurPosThumb.Width() / 2;
     m_ptInChannel .y = m_rtChannel.top + m_rtChannel.Height() / 2;


     CSliderCtrl::PreSubclassWindow();
    }

    void CAdjustSlider::SetBkcolor(COLORREF rgb)
    {
     m_BackColor = rgb;
    }

    void CAdjustSlider::SetPos(int nPos)
    {
     int min, max;
     GetRange(min, max);
     
     if (nPos < min)
     {
      nPos = min;
     }
     if (nPos > max)
     {
      nPos = max;
     }
     
     int temp = (m_rtChannel.right - m_rtChannel.left) * (nPos - min) / (max - min);
     m_rtCurPosThumb.left = m_rtChannel.left + temp - m_rtThumb.Width() / 2;
     if (m_rtCurPosThumb.left < m_rtChannel.left - m_rtThumb.Width() / 2)
     {
      m_rtCurPosThumb.left = m_rtChannel.left - m_rtThumb.Width() / 2;
     }
     if (m_rtCurPosThumb.left > m_rtChannel.right - m_rtThumb.Width() / 2)
     {
      m_rtCurPosThumb.left = m_rtChannel.right - m_rtThumb.Width() / 2;
     }
     m_rtCurPosThumb.right = m_rtCurPosThumb.left + m_rtThumb.Width();
     m_rtCurPosThumb.bottom = m_rtCurPosThumb.top + m_rtThumb.Height();
     m_rtCurPosThumb.top = m_rtChannel.bottom + 1;

     CSliderCtrl::SetPos(nPos);
    }

    void CAdjustSlider::OnTimer(UINT_PTR nIDEvent)
    {
     // TODO: Add your message handler code here and/or call default
     if (nIDEvent == 1)
     {
      SendMessage(WM_LBUTTONDOWN);
      //SetTimer(1, 100, NULL);
     }
     CSliderCtrl::OnTimer(nIDEvent);
    }

    2012年10月16日 6:25

答案

  • void CAdjustSlider::OnLButtonDown(UINT nFlags, CPoint point) 
    {
     // TODO: Add your message handler code here and/or call default
     if (m_rtCurPosThumb.PtInRect(point))
     {
      m_flagLBtnDownInThumb = true; 
      SetCapture();
     }
     else if (m_rtChannel.PtInRect(point))
     {
      int nMax = 0;  
      int nMin = 0;  
      GetRange(nMin,nMax);  
      int nPos = (nMax - nMin)*(point.x - m_rtClient.left - m_rtChannel.left)/(m_rtChannel.right - m_rtChannel.left);   
      nPos += nMin;
      SetPos(nPos); 
      
      Invalidate();
      // CSliderCtrl::OnLButtonDown(nFlags, point); // 这里注释掉
     }
     // 这里需要调用基类的OnLButtonDown(...);
     CSliderCtrl::OnLButtonDown(nFlags, point);
    }


    Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development.

    2012年10月17日 3:11
    版主

全部回复

  • WM_HSCROLL是滚动条的消息

    不是Slider的消息


    新浪微博http://weibo.com/xianglitian,欢迎围观

    2012年10月17日 2:20
  • void CAdjustSlider::OnLButtonDown(UINT nFlags, CPoint point) 
    {
     // TODO: Add your message handler code here and/or call default
     if (m_rtCurPosThumb.PtInRect(point))
     {
      m_flagLBtnDownInThumb = true; 
      SetCapture();
     }
     else if (m_rtChannel.PtInRect(point))
     {
      int nMax = 0;  
      int nMin = 0;  
      GetRange(nMin,nMax);  
      int nPos = (nMax - nMin)*(point.x - m_rtClient.left - m_rtChannel.left)/(m_rtChannel.right - m_rtChannel.left);   
      nPos += nMin;
      SetPos(nPos); 
      
      Invalidate();
      // CSliderCtrl::OnLButtonDown(nFlags, point); // 这里注释掉
     }
     // 这里需要调用基类的OnLButtonDown(...);
     CSliderCtrl::OnLButtonDown(nFlags, point);
    }


    Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development.

    2012年10月17日 3:11
    版主