自定义滚动条CCustomerScroll

自制滚动条

思路
        利用CStatic派生出一个自定义的滚动条,在CStatic控件上利用位图绘制滚动条箭头,滚动块,滚动条的滚动区域,在绘制滚动条时,由于滚动块是可以被拖动,
所以需要频繁的绘制滚动条,为了防止屏幕闪烁,可以一个临时的CDC对象,将所有的绘图操作都在改临时对象上进行,然后在将临时的对象的内容绘制在滚动块的显示区域,可以将临时的CDC对象封装成CMemDC类,在改类释放的时候会自动将其自身的内容绘制到某一个显示区域。

#pragma once
#include "afxwin.h"

CMemDC 高版本中已经实现 会出现redefine  更名CMemCompatibleDC 

class CMemCompatibleDC :public CDC
{
public:
    CMemCompatibleDC(CDC* pDC, const CRect& rect);
    ~CMemCompatibleDC();
private:
    CBitmap* m_bmp;
    CBitmap* m_oldbmp;
    CDC* m_pDC;
    CRect m_Rect;
};
#include "stdafx.h"
#include "MemDC.h"
CMemCompatibleDC::CMemCompatibleDC(CDC* pDC, const CRect& rect) :CDC()
{
    CreateCompatibleDC(pDC);
    m_bmp = new CBitmap;
    m_bmp->CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
    m_oldbmp = SelectObject(m_bmp);
    m_pDC = pDC;
    m_Rect = rect;
}
CMemCompatibleDC::~CMemCompatibleDC()
{
    m_pDC->BitBlt(m_Rect.left, m_Rect.top, m_Rect.Width(), m_Rect.Height(), this, m_Rect.left, m_Rect.top, SRCCOPY);
    SelectObject(m_oldbmp);
    if (m_bmp != NULL)
    {
        delete m_bmp;
    }
}


#pragma once
#include "afxwin.h"
class CCustomScroll :
    public CStatic
{
public:
    CCustomScroll();
    ~CCustomScroll();
    UINT m_ThumbWidth;                //  滚动快和箭头宽度
    UINT m_ThumbHeight;                // 滚动块和箭头高度
    CWnd* m_pParent;                // 父窗口
    CRect m_ClientRect;                // 窗口客户区域
    CRect m_ThumbRect;                // 滚动块区域
    BOOL  m_ButtonDown;                // 鼠标是否单击滚动块
    CPoint m_StartPt;                // 鼠标按下时的起点
    BOOL m_IsLeft;                    // 滚动块是否超过左箭头
    BOOL m_IsLeftArrow;                // 是否单击左滚动条按钮
    BOOL m_IsRightArrow;            // 是否单击右滚动条按钮
    BOOL m_IsLeftRange;                // 是否单击左滚动区域
    BOOL m_IsRightRange;            // 是否单击右滚动区域
    UINT  m_MinRange;                // 最小滚动范围
    UINT m_MaxRange;                // 最大滚动范围
    UINT m_CurPos;                    // 当前位置(逻辑单位)
    double m_Rate;                    // 物理像素和逻辑单位比率
    UINT m_LeftArrow;                // 左箭头位图ID
    UINT m_RightArrow;                // 右箭头位图ID
    UINT m_ChanelBK;                // 背景位图ID
    UINT m_ThumbBK;                    // 滚动块位图ID
public:
    BOOL CreateStatic(CWnd* pParent, DWORD dwStyle, UINT nIDStatic, UINT nID);
    void SetScrollRange(int minRange, int maxRange);
    void DrawHorScroll();
    void DrawControl();
public:
    DECLARE_MESSAGE_MAP()
    afx_msg void OnPaint();
    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 void OnTimer(UINT_PTR nIDEvent);
};
#include "stdafx.h"
#include "CustomScroll.h"
#include "MemDC.h"
#include "resource.h"
CCustomScroll::CCustomScroll()
{
    m_ButtonDown = FALSE;
    m_IsLeft = FALSE;
    m_MinRange = 0;
    m_MaxRange = 200;
    m_CurPos = 0;
    m_IsLeftArrow = FALSE;
    m_IsRightArrow = FALSE;
    m_IsLeftRange = FALSE;
    m_IsRightRange = FALSE;
}
CCustomScroll::~CCustomScroll()
{
}
BOOL CCustomScroll::CreateStatic(CWnd* pParent, DWORD dwStyle, UINT nIDStatic, UINT nID)
{
    m_pParent = pParent;
    ASSERT(m_pParent);
    ASSERT(::IsWindow(pParent->GetDlgItem(nIDStatic)->m_hWnd));
    CRect recttemp;
    pParent->GetDlgItem(nIDStatic)->GetWindowRect(&recttemp);
    pParent->ScreenToClient(&recttemp);
    m_ClientRect = recttemp;
    pParent->GetDlgItem(nIDStatic)->ShowWindow(SW_HIDE);
    BOOL ret = CStatic::Create("", dwStyle, m_ClientRect, pParent, nID);
    pParent->GetDlgItem(nIDStatic)->GetClientRect(m_ClientRect);
    if (ret)
    {
        CBitmap bmp;
        bmp.LoadBitmap(m_LeftArrow);
        BITMAP binfo;
        bmp.GetBitmap(&binfo);
        m_ThumbWidth = binfo.bmWidth;
        m_ThumbHeight = binfo.bmHeight;
        if (bmp.GetSafeHandle())
        {
            bmp.DeleteObject();
        }
        bmp.LoadBitmap(IDB_THUMB);
        bmp.GetBitmap(&binfo);
        m_ThumbRect.CopyRect(CRect(m_ThumbWidth, 0, m_ThumbWidth + binfo.bmWidth, binfo.bmHeight));
        if (bmp.GetSafeHandle())
        {
            bmp.DeleteObject();
        }
        SetScrollRange(m_MinRange, m_MaxRange);
    }
    ShowWindow(SW_SHOW);
    return ret;
}
void CCustomScroll::SetScrollRange(int minRange, int maxRange)
{
    m_MinRange = minRange;
    m_MaxRange = maxRange;
    int ScorllRange = m_ClientRect.Width() - 2 * m_ThumbWidth - m_ThumbRect.Width();
    m_Rate = (m_MaxRange - m_MinRange) / (double)ScorllRange;
    Invalidate();
}
void CCustomScroll::DrawHorScroll()
{
    CClientDC dc(this);
    CMemCompatibleDC memdc(&dc, m_ClientRect);
    CDC bmpdc;
    bmpdc.CreateCompatibleDC(&dc);
    CBitmap bmp;
    bmp.LoadBitmap(m_LeftArrow);
    CBitmap* pOldbmp = bmpdc.SelectObject(&bmp);
    CRect LeftArrowRect(m_ClientRect.left, m_ClientRect.top, m_ClientRect.left + m_ThumbWidth, m_ClientRect.bottom);
    memdc.StretchBlt(m_ClientRect.left, m_ClientRect.top, m_ThumbWidth, m_ThumbHeight, &bmpdc, 0, 0, m_ThumbWidth, m_ThumbHeight, SRCCOPY);
    if (pOldbmp)
        bmpdc.SelectObject(pOldbmp);
    if (bmp.GetSafeHandle())
        bmp.DeleteObject();
    pOldbmp = NULL;
    //通道的开始位置和宽度
    int nChanelStart = m_ClientRect.left + m_ThumbWidth;
    int nChanelWidth = m_ClientRect.Width() - 2 * m_ThumbWidth;
    //绘制通道
    bmp.LoadBitmap(m_ChanelBK);
    pOldbmp = bmpdc.SelectObject(&bmp);
    memdc.StretchBlt(nChanelStart, m_ClientRect.top, nChanelWidth, m_ClientRect.Height(), &bmpdc, 0, 0, 1, 10, SRCCOPY);
    if (pOldbmp)
        bmpdc.SelectObject(pOldbmp);
    if (bmp.GetSafeHandle())
        bmp.DeleteObject();
    //绘制右箭头
    bmp.LoadBitmap(m_RightArrow);
    pOldbmp = bmpdc.SelectObject(&bmp);
    int nRArrowStart = m_ThumbWidth + nChanelWidth;
    memdc.StretchBlt(nRArrowStart, m_ClientRect.top, m_ThumbWidth, m_ClientRect.Height(), &bmpdc, 0, 0, m_ThumbWidth, m_ThumbHeight, SRCCOPY);
    //绘制滚动块
    if (bmp.GetSafeHandle())
        bmp.DeleteObject();
    bmp.LoadBitmap(m_ThumbBK);
    pOldbmp = bmpdc.SelectObject(&bmp);
    memdc.StretchBlt(m_ThumbRect.left, m_ThumbRect.top, m_ThumbRect.Width() + 1, m_ThumbRect.Height(), &bmpdc, 0, 0, m_ThumbRect.Width(), m_ThumbRect.Height(), SRCCOPY);
}
// 绘制水平 垂直滑块
void CCustomScroll::DrawControl(){
    this->DrawHorScroll();
}
BEGIN_MESSAGE_MAP(CCustomScroll, CStatic)
    ON_WM_PAINT()
    ON_WM_LBUTTONUP()
    ON_WM_LBUTTONDOWN()
    ON_WM_MOUSEMOVE()
    ON_WM_TIMER()
END_MESSAGE_MAP()
void CCustomScroll::OnPaint()
{
    CPaintDC dc(this); // device context for painting
    // TODO:  在此处添加消息处理程序代码
    // 不为绘图消息调用 CStatic::OnPaint()
    DrawControl();
}
void CCustomScroll::OnLButtonUp(UINT nFlags, CPoint point)
{
    // TODO:  在此添加消息处理程序代码和/或调用默认值
    ReleaseCapture();
    m_ButtonDown = FALSE;
    m_IsLeftRange = FALSE;
    m_IsRightRange = FALSE;
    if (m_IsLeftArrow)
    {
        m_IsLeftArrow = FALSE;
        KillTimer(1);
    }
    if (m_IsRightArrow)
    {
        m_IsRightArrow = FALSE;
        KillTimer(1);
    }
    CStatic::OnLButtonUp(nFlags, point);
}
void CCustomScroll::OnLButtonDown(UINT nFlags, CPoint point)
{
    // TODO:  在此添加消息处理程序代码和/或调用默认值
    m_StartPt = point;
    // 确定滚动区域
    CRect rcScroll = m_ClientRect;
    rcScroll.left += m_ThumbWidth;
    rcScroll.right -= m_ThumbWidth;
    DWORD wparam;
    SetCapture();
    if (m_ThumbRect.PtInRect(point))
    {
        m_ButtonDown = TRUE;
    }
    else if (rcScroll.PtInRect(point)){   // 单击滚动区域
        
        CPoint centerPt = m_ThumbRect.CenterPoint();
        int offset = point.x - centerPt.x;
        if ((int)point.x < m_ThumbRect.left)
        {
            m_IsLeftRange = TRUE;
        }
        if ((int)point.x > m_ThumbRect.right)
        {
            m_IsRightRange = TRUE;
        }
        m_ThumbRect.OffsetRect(offset, 0);
        int left = m_ThumbRect.left;
        int right = m_ThumbRect.right;
        if ((int) left < (int) m_ThumbWidth) //判断当前滚动量是否超出了滚动范围
        {
            int width = m_ThumbRect.Width();
            m_ThumbRect.left = m_ThumbWidth;
            m_ThumbRect.right = m_ThumbRect.left + width;
            m_CurPos = m_MinRange;
            wparam = MAKELONG(SB_PAGELEFT, m_CurPos);
            ::SendMessage(GetParent()->m_hWnd, WM_HSCROLL, wparam, (LPARAM)m_hWnd);
            DrawControl();
            return;
        }
        else if (right>(int)(m_ClientRect.Width()-m_ThumbWidth)){
            int width = m_ThumbRect.Width();
            m_ThumbRect.right = m_ThumbRect.Width() - m_ThumbWidth;
            m_ThumbRect.left = m_ThumbRect.right - width;
            m_CurPos = m_MaxRange;
            wparam = MAKELONG(SB_PAGELEFT, m_CurPos);
            ::SendMessage(GetParent()->m_hWnd, WM_HSCROLL, wparam, (LPARAM)m_hWnd);
            DrawControl();
            return;
        }
        int range = m_ThumbRect.left - m_ThumbWidth;
        m_CurPos = m_Rate *(range);
        if (m_IsLeftRange)
        {
            wparam = MAKELONG(SB_PAGELEFT, m_CurPos);
            ::SendMessage(GetParent()->m_hWnd, WM_HSCROLL, wparam, (LPARAM)m_hWnd);
        }
        else if (m_IsRightRange){
            wparam = MAKELONG(SB_PAGERIGHT, m_CurPos);
            ::SendMessage(GetParent()->m_hWnd, WM_HSCROLL, wparam, (LPARAM)m_hWnd);
        }
        DrawControl();
    }
    else{
        // 单击箭头
        if (point.x <= (int)m_ThumbWidth) //单击左箭头
        {
            if (m_CurPos > m_MinRange)
                wparam = MAKELONG(SB_LINELEFT, 1);
            else
                wparam = MAKELONG(SB_LINELEFT, 0);
            ::SendMessage(GetParent()->m_hWnd, WM_HSCROLL, wparam, (LPARAM)m_hWnd);
            if (m_CurPos > m_MinRange)
                m_CurPos -= 1;
            m_IsLeftArrow = TRUE;
        }
        else //单击右箭头
        {
            if (m_CurPos >= m_MaxRange)
                wparam = MAKELONG(SB_LINERIGHT, 0);
            else
                wparam = MAKELONG(SB_LINERIGHT, 1);
            ::SendMessage(GetParent()->m_hWnd, WM_HSCROLL, wparam, (LPARAM)m_hWnd);
            if (m_CurPos < m_MaxRange)
                m_CurPos += 1;
            m_IsRightArrow = TRUE;
        }
        int factpos = m_CurPos / m_Rate;
        int width = m_ThumbRect.Width();
        m_ThumbRect.left = m_ThumbWidth + factpos;
        m_ThumbRect.right = m_ThumbRect.left + width;
        DrawControl();
        SetTimer(1, 100, NULL);
    }
    CStatic::OnLButtonDown(nFlags, point);
}
void CCustomScroll::OnMouseMove(UINT nFlags, CPoint point)
{
    // TODO:  在此添加消息处理程序代码和/或调用默认值
    if (m_ButtonDown)
    {
        int offset = point.x - m_StartPt.x;
        m_StartPt = point;
        DWORD wparam;
        if (offset <=0)
        {
            if (m_ThumbRect.left <= (int)m_ThumbWidth)
            {
                return;
            }
            else if (abs(offset) > (int) m_ThumbRect.left - m_ThumbWidth){
                int width = m_ThumbRect.Width();
                m_ThumbRect.left = m_ThumbWidth;
                m_ThumbRect.right = m_ThumbRect.left + width;
                m_CurPos = 0;
                wparam = MAKELONG(SB_THUMBPOSITION, m_CurPos);
                ::SendMessage(GetParent()->m_hWnd, WM_HSCROLL, wparam, (LPARAM)m_hWnd);
                DrawControl();
                return;
            }
        }
        else if (offset > 0){
            if (m_ThumbRect.right >= m_ClientRect.Width() - m_ThumbWidth) //超出右箭头
            {
                return;
            }
            else if (offset > m_ClientRect.Width() - m_ThumbWidth - m_ThumbRect.right) //判断当前滚动量是否超出了滚动范围
            {
                int width = m_ThumbRect.Width();
                m_ThumbRect.right = m_ClientRect.Width() - m_ThumbWidth;
                m_ThumbRect.left = m_ThumbRect.right - width;
                m_CurPos = m_MaxRange;
                wparam = MAKELONG(SB_THUMBPOSITION, m_CurPos);
                ::SendMessage(GetParent()->m_hWnd, WM_HSCROLL, wparam, (LPARAM)m_hWnd);
                DrawControl();
                return;
            }
        }
        m_ThumbRect.OffsetRect(offset, 0);
        int range = m_ThumbRect.left - m_ThumbWidth;
        m_CurPos = m_Rate*(range);
        wparam = MAKELONG(SB_THUMBPOSITION, m_CurPos);
        ::SendMessage(GetParent()->m_hWnd, WM_HSCROLL, wparam, (LPARAM)m_hWnd);
        DrawHorScroll();
    }
    CStatic::OnMouseMove(nFlags, point);
}
void CCustomScroll::OnTimer(UINT_PTR nIDEvent)
{
    // TODO:  在此添加消息处理程序代码和/或调用默认值
    DWORD wparam;
    if (m_IsLeftArrow)
    {
        if (m_CurPos > m_MinRange)
            wparam = MAKELONG(SB_LINELEFT, 1);
        else
            wparam = MAKELONG(SB_LINELEFT, 0);
        ::SendMessage(GetParent()->m_hWnd, WM_HSCROLL, wparam, (LPARAM)m_hWnd);
        if (m_CurPos > m_MinRange)
            m_CurPos -= 1;
    }
    else if (m_IsRightArrow)
    {
        if (m_CurPos < m_MaxRange)
            wparam = MAKELONG(SB_LINERIGHT, 1);
        else
            wparam = MAKELONG(SB_LINERIGHT, 0);
        ::SendMessage(GetParent()->m_hWnd, WM_HSCROLL, wparam, (LPARAM)m_hWnd);
        if (m_CurPos < m_MaxRange)
            m_CurPos += 1;
    }
    int factpos = m_CurPos / m_Rate;
    int width = m_ThumbRect.Width();
    m_ThumbRect.left = m_ThumbWidth + factpos;
    m_ThumbRect.right = m_ThumbRect.left + width;
    DrawControl();
    
    CStatic::OnTimer(nIDEvent);
}
测试代码
// SkinDlg.h : 头文件
//
#pragma once
#include "CustomScroll.h"
// CSkinDlg 对话框
class CSkinDlg : public CDialogEx
{
// 构造
public:
    CSkinDlg(CWnd* pParent = NULL);    // 标准构造函数
    CScrollBar* m_pScroll;
    CCustomScroll  m_Red;
    CCustomScroll  m_Green;
    CCustomScroll  m_Blue;
    
    BYTE m_Rvalue;
    BYTE m_Gvalue;
    BYTE m_Bvalue;
// 对话框数据
    enum { IDD = IDD_SKIN_DIALOG };
    CStatic    m_Color;
    CString    m_Rtext;
    CString    m_Gtext;
    CString    m_Btext;
    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
    void DrawColor();
// 实现
protected:
    HICON m_hIcon;
    // 生成的消息映射函数
    virtual BOOL OnInitDialog();
    afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
    afx_msg void OnPaint();
    afx_msg HCURSOR OnQueryDragIcon();
    DECLARE_MESSAGE_MAP()
public:
    afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
};
// SkinDlg.cpp : 实现文件
//
#include "stdafx.h"
#include "Skin.h"
#include "SkinDlg.h"
#include "afxdialogex.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
class CAboutDlg : public CDialogEx
{
public:
    CAboutDlg();
// 对话框数据
    enum { IDD = IDD_ABOUTBOX };
    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
// 实现
protected:
    DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()
// CSkinDlg 对话框
CSkinDlg::CSkinDlg(CWnd* pParent /*=NULL*/)
    : CDialogEx(CSkinDlg::IDD, pParent)
{
    m_Rtext = _T("");
    m_Gtext = _T("");
    m_Btext = _T("");
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CSkinDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_COLOR, m_Color);
    DDX_Text(pDX, IDC_STATIC1, m_Rtext);
    DDX_Text(pDX, IDC_STATIC2, m_Gtext);
    DDX_Text(pDX, IDC_STATIC3, m_Btext);
}
BEGIN_MESSAGE_MAP(CSkinDlg, CDialogEx)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_WM_HSCROLL()
END_MESSAGE_MAP()
// CSkinDlg 消息处理程序
BOOL CSkinDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();
    // 将“关于...”菜单项添加到系统菜单中。
    // IDM_ABOUTBOX 必须在系统命令范围内。
    ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
    ASSERT(IDM_ABOUTBOX < 0xF000);
    CMenu* pSysMenu = GetSystemMenu(FALSE);
    if (pSysMenu != NULL)
    {
        BOOL bNameValid;
        CString strAboutMenu;
        bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
        ASSERT(bNameValid);
        if (!strAboutMenu.IsEmpty())
        {
            pSysMenu->AppendMenu(MF_SEPARATOR);
            pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
        }
    }
    // 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
    //  执行此操作
    SetIcon(m_hIcon, TRUE);            // 设置大图标
    SetIcon(m_hIcon, FALSE);        // 设置小图标
    // TODO:  在此添加额外的初始化代码
    m_Red.m_LeftArrow = IDB_REDLEFT;
    m_Red.m_RightArrow = IDB_REDRIGHT;
    m_Red.m_ChanelBK = IDB_REDBK;
    m_Red.m_ThumbBK = IDB_REDTHUMB;
    m_Red.CreateStatic(this, SBS_HORZ | WS_CHILD | SS_LEFT | SS_NOTIFY | WS_VISIBLE, IDC_RED, 465);
    m_Red.SetScrollRange(0, 255);
    m_Green.m_LeftArrow = IDB_GLEFTARROW;
    m_Green.m_RightArrow = IDB_GRIGHTARROW;
    m_Green.m_ChanelBK = IDB_GCHANELBK;
    m_Green.m_ThumbBK = IDB_GTHUMB;
    m_Green.CreateStatic(this, SBS_HORZ | WS_CHILD | SS_LEFT | SS_NOTIFY | WS_VISIBLE, IDC_GREEN, 466);
    m_Green.SetScrollRange(0, 255);
    m_Blue.m_LeftArrow = IDB_BLEFTARROW;
    m_Blue.m_RightArrow = IDB_BRIGHTARROW;
    m_Blue.m_ChanelBK = IDB_BCHANELBK;
    m_Blue.m_ThumbBK = IDB_BTHUMB;
    m_Blue.CreateStatic(this, SBS_HORZ | WS_CHILD | SS_LEFT | SS_NOTIFY | WS_VISIBLE, IDC_BLUE, 467);
    m_Blue.SetScrollRange(0, 255);
    m_Rvalue = 0;
    m_Bvalue = 0;
    m_Gvalue = 0;
    m_Rtext.Format("%i", m_Rvalue);
    m_Gtext.Format("%i", m_Gvalue);
    m_Btext.Format("%i", m_Bvalue);
    UpdateData(FALSE);
    return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}
void CSkinDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
    if ((nID & 0xFFF0) == IDM_ABOUTBOX)
    {
        CAboutDlg dlgAbout;
        dlgAbout.DoModal();
    }
    else
    {
        CDialogEx::OnSysCommand(nID, lParam);
    }
}
// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。
void CSkinDlg::OnPaint()
{
    if (IsIconic())
    {
        CPaintDC dc(this); // 用于绘制的设备上下文
        SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
        // 使图标在工作区矩形中居中
        int cxIcon = GetSystemMetrics(SM_CXICON);
        int cyIcon = GetSystemMetrics(SM_CYICON);
        CRect rect;
        GetClientRect(&rect);
        int x = (rect.Width() - cxIcon + 1) / 2;
        int y = (rect.Height() - cyIcon + 1) / 2;
        // 绘制图标
        dc.DrawIcon(x, y, m_hIcon);
    }
    else
    {
        CDialogEx::OnPaint();
    }
    DrawColor();
}
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CSkinDlg::OnQueryDragIcon()
{
    return static_cast<HCURSOR>(m_hIcon);
}
void CSkinDlg::DrawColor()
{
    CDC* pDC = m_Color.GetDC();
    CRect rect;
    m_Color.GetClientRect(rect);
    CBrush brush(RGB(m_Rvalue, m_Gvalue, m_Bvalue));
    pDC->FillRect(rect, &brush);
}
void CSkinDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
    // TODO:  在此添加消息处理程序代码和/或调用默认值
    CString str;
    CCustomScroll* temp = (CCustomScroll*)(CWnd*)pScrollBar;
    int pos;
    if (temp == NULL)
        return;
    if (nSBCode == SB_LINELEFT)
    {
        pos = temp->m_CurPos - nPos;
    }
    else if (nSBCode == SB_LINERIGHT)
    {
        pos = temp->m_CurPos + nPos;
    }
    else
    {
        pos = nPos;
    }
    if (temp->m_hWnd == m_Red.m_hWnd)
        m_Rvalue = pos;
    else if (temp->m_hWnd == m_Green.m_hWnd)
        m_Gvalue = pos;
    else if (temp->m_hWnd == m_Blue.m_hWnd)
        m_Bvalue = pos;
    m_Rtext.Format("%i", m_Rvalue);
    m_Gtext.Format("%i", m_Gvalue);
    m_Btext.Format("%i", m_Bvalue);
    UpdateData(FALSE);
    DrawColor();
    CDialogEx::OnHScroll(nSBCode, nPos, pScrollBar);
}

 


注意
        CStatic设置大小为图片的大小,如果大了就会出现拉伸的状态

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CScrollWnd 这是一个从MFC的源码中扒出来的一个滚动窗口类,功能基本类似于CScrollView, 但是它的基类是CWnd,这样为一些不需要使用Document View结构但又想使用滚动窗口的小程序提供了比较方便的方法,他的接口除了两个坐标转换函数以外与CScrollView基本相同,同时在画的地方采用了内存DC缓冲,避免了闪烁,这下你可以随意的刷新了(当然刷新太多了对效率还是有一些影响的) 因为是工作需要,所以设计了这个类,目前只测试了基本的功能,映射模式为MM_TEXT在屏幕上显示正常,至于打印的支持还没有做。 因为跟CScrollView功能基本相同,所以没有写什么注释,大家可以查MSDN中CScrollView的帮助,如果发现跟CScrollView不一致的地方给我mail吧。 使用方法,跟CScrollView一样,在你的类中继承,实现OnInitialUpdate和OnDraw就成了。 CTabSheet 一个TabCtrl,可以方便的把各种窗口加入到其中,做成属性页的形式,功能很简单,但是很 实用。 CStaticSplitter 静态切分窗口,这个类是从WTL的SplitterWnd里面扒出来的,因为MF C的SplitterWnd实在是太太太难用了,而且很难看,看到WTL里面的这个不错,想拿来用,不过如果是MFC程序的话再加上WTL的风格有些不协调,就干脆把它的形式改成MFC的风格了,函数看着挺多,不过常用并不多,至于注释嘛,我只是在经常用的函数声明上大概写了几句,相知道具体实现,那就去看代码吧:)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值