环境: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