vc模仿qq的选择头像功能

环境:xp sp3,vs2008

主对话框

//qqfaceDlg.h : 头文件
CHeadPanel                            m_HeadPanel;

// qqfaceDlg.cpp : 实现文件

BOOL CqqfaceDlg::OnInitDialog()
{
    CDialog::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_HeadPanel.AddImage2(IDB_BITMAP1, IDB_BITMAP100);//for(i=IDB_BITMAP1;i<=IDB_BITMAP100;i++)
    CRect rcHeadPanel;
    GetClientRect(rcHeadPanel);
    rcHeadPanel = CRect(10,10, 440,365);
    m_HeadPanel.Create(NULL,NULL,WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_CHILD,rcHeadPanel,this,NULL);

    return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

 

头像设置框

//headpanel.h

#pragma once

#include <vector>

class CHeadPanel : public CWnd
{
    //函数定义
public:
    //构造函数
    CHeadPanel(void);
    //析构函数
    ~CHeadPanel(void);

public:
    afx_msg void OnPaint();
    afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar * pScrollBar);
    afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
    afx_msg void OnMouseMove(UINT nFlags, CPoint point);
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    int AddImage(int nResID);
    int AddImage2(int nResIDStart, int nResIDEnd);

    DECLARE_MESSAGE_MAP()
private:
    std::vector <CBitmap*> m_vecBitmap;    //所有加载的位图图片
    int m_nColPerRow;
    void SetScroll();
    int m_nCurSrollPos;
    int m_nMaxSrollPos;
    int m_nRows;
    int m_iSelect;
};

//headpanel.cpp

#include "StdAfx.h"
#include "HeadPanel.h"
//
BEGIN_MESSAGE_MAP(CHeadPanel,CWnd)
    ON_WM_VSCROLL()
    ON_WM_PAINT()
    ON_WM_MOUSEWHEEL()
    ON_WM_LBUTTONDOWN()
    ON_WM_CREATE()
    ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()

CHeadPanel::CHeadPanel(void)
{
    m_nColPerRow = 8;
    m_nCurSrollPos = 0;
    m_nMaxSrollPos = 0;
    m_nRows = 0;
    m_iSelect = -1;
    m_iMove = -1;
}

CHeadPanel::~CHeadPanel(void)
{
    int i=0;
    for(i=0; i<(int)m_vecBitmap.size(); i++)
    {
        delete m_vecBitmap[i];
        m_vecBitmap[i] = NULL;
    }
}

void CHeadPanel::OnPaint()
{
    CPaintDC dc(this);

    CRect rcClient;
    GetClientRect(rcClient);

    int memHeight = max(50*m_nRows, rcClient.Height());    //内存中图片高度
    int memWidth = rcClient.Width();        //内存中图片宽度
    int xSrc = 0;                            //内存中图片绘制区起始位置y
    int ySrc = m_nCurSrollPos;                            //内存中图片绘制区起始位置y

    CBitmap bitmap;
    CDC MemeDc;
    MemeDc.CreateCompatibleDC(&dc);
    bitmap.CreateCompatibleBitmap(&dc, memWidth, memHeight);
    CBitmap *pOldBitmap = MemeDc.SelectObject(&bitmap);
    MemeDc.FillSolidRect(0,0,memWidth,memHeight,RGB(236, 243, 246));
    
    int i=0;
    for(; i<(int)m_vecBitmap.size(); i++)
    {
        int nCurRow = i/m_nColPerRow;
        int nCurCol = i%m_nColPerRow;

        CDC dcMem2;
        dcMem2.CreateCompatibleDC(&MemeDc);
        CBitmap *pOldBitmap1 = dcMem2.SelectObject(m_vecBitmap[i]);
        if(i==m_iSelect)    //鼠标点击或移动到某头像的上方
        {
            MemeDc.FillSolidRect(10+50*nCurCol-3,10+50*nCurRow-3,46,46,RGB(255,0,0));
        }
        if(i==m_iMove)
        {
            MemeDc.FillSolidRect(10+50*nCurCol-3,10+50*nCurRow-3,46,46,RGB(55,189,250));
        }

        MemeDc.BitBlt(10+50*nCurCol,10+50*nCurRow,40,40,&dcMem2,0,0,SRCCOPY);  //加载位图ok

        dcMem2.SelectObject(pOldBitmap1);
        dcMem2.DeleteDC();
    }

    dc.BitBlt( rcClient.left, rcClient.top, rcClient.Width(), rcClient.Height(), &MemeDc, 0, ySrc, SRCCOPY);

    MemeDc.SelectObject(pOldBitmap);
    MemeDc.DeleteDC();
}

void CHeadPanel::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar * pScrollBar)
{
    SCROLLINFO si;
    si.fMask=SIF_ALL;
    GetScrollInfo(SB_VERT,&si,SIF_ALL);
    
    CRect rcClient;
    GetClientRect(&rcClient);

    int iPage = rcClient.Height();
    int iLastPos = m_nCurSrollPos;

    //移动坐标
    switch (nSBCode)
    {
    case SB_TOP:
        {
            iLastPos=0;
            break;
        }
    case SB_BOTTOM:
        {
            iLastPos=m_nMaxSrollPos-rcClient.Height();
            break;
        }
    case SB_LINEUP:
        {
            iLastPos-=1;
            break;
        }
    case SB_PAGEUP:
        {
            iLastPos-=iPage;
            break;
        }
    case SB_LINEDOWN:
        {
            iLastPos+=1;
            break;
        }
    case SB_PAGEDOWN:
        {
            iLastPos += iPage;
            break;
        }
    case SB_THUMBTRACK:
        {
            iLastPos=nPos;
            break;
        }    
    }

    //调整位置
    iLastPos = min(iLastPos,m_nMaxSrollPos-rcClient.Height());
    iLastPos = max(iLastPos,0);
    if (iLastPos!=m_nCurSrollPos)
    {
        m_nCurSrollPos = iLastPos;
        si.nPos=iLastPos;
        if(si.nPos>(int)(si.nMax-si.nMin-si.nPage+1)) si.nPos=si.nMax-si.nMin-si.nPage+1;
        if(si.nPos<si.nMin) si.nPos=si.nMin;
        si.fMask=SIF_POS;
        SetScrollInfo(SB_VERT,&si);

        Invalidate(TRUE);
    }
}

BOOL CHeadPanel::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
    CRect rcClient;
    GetClientRect(&rcClient);
    
    int iLastPos = m_nCurSrollPos;
    iLastPos -= (zDelta/120)*(rcClient.Width()/6);

    iLastPos = min(iLastPos,m_nMaxSrollPos-rcClient.Height());
    iLastPos = max(iLastPos,0);

    m_nCurSrollPos = iLastPos;
    SetScrollPos(SB_VERT,m_nCurSrollPos);

    Invalidate();
    return TRUE;
}
void CHeadPanel::OnLButtonDown(UINT nFlags, CPoint point)
{
    SetFocus();

    CRect rcClient;
    GetClientRect(rcClient);

    int nCol = -1;
    int nDivx = point.x/50;
    if(point.x>=(nDivx*50+10) && point.x<=(nDivx*50+50))
    {
        nCol = nDivx;
    }

    int nRow = -1;
    int nDivy = (m_nCurSrollPos + point.y)/50;
    if((m_nCurSrollPos+point.y)>=(nDivy*50+10) && (m_nCurSrollPos+point.y)<=(nDivy*50+50))
    {
        nRow = nDivy;
    }

    if(nCol==-1 || nRow==-1)
    {
        m_iSelect = -1;
    }
    else
    {
        m_iSelect = nRow*m_nColPerRow + nCol;
    }

    Invalidate(TRUE);

    __super::OnLButtonDown(nFlags,point);
}

int CHeadPanel::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CWnd::OnCreate(lpCreateStruct) == -1)
        return -1;

    //设置滚动条
    SetScroll();
    return 0;
}

int CHeadPanel::AddImage(int nResID)
{
    CBitmap* pBitmap = new CBitmap;
    pBitmap->LoadBitmap(nResID);
    m_vecBitmap.push_back(pBitmap);

    int nSize = m_vecBitmap.size();
    int nMod = nSize%m_nColPerRow;
    m_nRows = nSize/m_nColPerRow;
    if(nMod!=0)
    {
        m_nRows++;
    }

    return nSize;
}

int CHeadPanel::AddImage2(int nResIDStart, int nResIDEnd)
{
    for(int i=nResIDStart; i<=nResIDEnd; i++)
    {
        CBitmap* pBitmap = new CBitmap;
        pBitmap->LoadBitmap(i);
        m_vecBitmap.push_back(pBitmap);
    }

    int nSize = m_vecBitmap.size();
    int nMod = nSize%m_nColPerRow;
    m_nRows = nSize/m_nColPerRow;
    if(nMod!=0)
    {
        m_nRows++;
    }
    
    return nSize;
}

void CHeadPanel::SetScroll()
{
    //-计算页数
    m_nMaxSrollPos = m_nRows*50;

    CRect rcClient;
    GetClientRect(rcClient);

    SCROLLINFO vinfo;
    vinfo.cbSize = sizeof(vinfo);
    vinfo.fMask = SIF_ALL;
    vinfo.nPage = rcClient.Height();    //滚动条所占页数
    vinfo.nMax= m_nMaxSrollPos;        //最大页
    vinfo.nMin = 0;        //最大页
    vinfo.nTrackPos = 0;
    vinfo.nPos = m_nCurSrollPos;
    SetScrollInfo(SB_VERT,&vinfo);
}

void CHeadPanel::OnMouseMove(UINT nFlags, CPoint point)
{
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    CRect rcClient;
    GetClientRect(rcClient);

    int nCol = -1;
    int nDivx = point.x/50;
    if(point.x>=(nDivx*50+10) && point.x<=(nDivx*50+50))
    {
        nCol = nDivx;
    }

    int nRow = -1;
    int nDivy = (m_nCurSrollPos + point.y)/50;
    if((m_nCurSrollPos+point.y)>=(nDivy*50+10) && (m_nCurSrollPos+point.y)<=(nDivy*50+50))
    {
        nRow = nDivy;
    }

    if(nCol==-1 || nRow==-1)
    {
        m_iMove = -1;
    }
    else
    {
        m_iMove = nRow*m_nColPerRow + nCol;
    }

    Invalidate(TRUE);

    CWnd::OnMouseMove(nFlags, point);
}

参考:http://download.csdn.net/detail/zhao_wei2003zj/2370544

http://download.csdn.net/detail/a136328960/1464551

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值