我想做一个 一排动态按钮 效果是鼠标越近的按钮边框变的越大,倒是实现了,就是老闪屏,帮我看下
我是用的VS2005   单纯的一个对话框程序下面是新建的一个继承自CButton的类#pragma once
// CNbtnclass CNbtn : public CButton
{
DECLARE_DYNAMIC(CNbtn)public:
CNbtn();
virtual ~CNbtn();protected:
DECLARE_MESSAGE_MAP()
public:
// afx_msg BOOL OnEraseBkgnd(CDC* pDC);
public:
// afx_msg void OnPaint();
public:
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
public:
afx_msg void OnPaint();
};// Nbtn.cpp : 实现文件
//#include "stdafx.h"
#include "SimpDmm.h"
#include "Nbtn.h"
// CNbtnIMPLEMENT_DYNAMIC(CNbtn, CButton)CNbtn::CNbtn()
{}CNbtn::~CNbtn()
{
}
BEGIN_MESSAGE_MAP(CNbtn, CButton)
// ON_WM_ERASEBKGND()
// ON_WM_PAINT()
ON_WM_ERASEBKGND()
ON_WM_PAINT()
END_MESSAGE_MAP()
BOOL CNbtn::OnEraseBkgnd(CDC* pDC)
{
return true;
}void CNbtn::OnPaint()
{
__super::OnPaint(); //?
}
下面是主对话框的头文件及源文件 
// SimpDmmDlg.h : 头文件
//#pragma once
#include "Nbtn.h"
// CSimpDmmDlg 对话框
class CSimpDmmDlg : public CDialog
{
// 构造
public:
CSimpDmmDlg(CWnd* pParent = NULL); // 标准构造函数// 对话框数据
enum { IDD = IDD_SIMPDMM_DIALOG }; protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持public:
static const int btnCount = 5; //可以这么写  但不推荐
CPoint ptVeryOld; //鼠标未放上前最左按钮 的左上角起绘点坐标
SIZE sizeBase; //基础按钮的长宽(即鼠标未放上前的大小 所有按钮一致,未用数组) 在OnInitDlg中初始化 SIZE sizeAfter[btnCount]; //各按钮的长宽 在OnInitDlg中初始化// 实现
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()
private: CNbtn dmmbtn[btnCount]; //按钮数组
CPoint ptCenter; //中心点
CPoint ptLftp[btnCount]; //每按钮 左上的起绘点
SIZE AftSize[btnCount]; //各按钮边长数组
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
virtual BOOL PreTranslateMessage(MSG* pMsg);
};// SimpDmmDlg.cpp : 实现文件
//#include "stdafx.h"
#include "SimpDmm.h"
#include "SimpDmmDlg.h"#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框class CAboutDlg : public CDialog
{
public:
CAboutDlg();// 对话框数据
enum { IDD = IDD_ABOUTBOX }; protected:
virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持// 实现
protected:
DECLARE_MESSAGE_MAP()
};CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()
// CSimpDmmDlg 对话框
CSimpDmmDlg::CSimpDmmDlg(CWnd* pParent /*=NULL*/)
: CDialog(CSimpDmmDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}void CSimpDmmDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}BEGIN_MESSAGE_MAP(CSimpDmmDlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_WM_MOUSEMOVE()
ON_WM_ERASEBKGND()
END_MESSAGE_MAP()
// CSimpDmmDlg 消息处理程序BOOL CSimpDmmDlg::OnInitDialog()
{
CDialog::OnInitDialog(); // 将“关于...”菜单项添加到系统菜单中。 // IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
} // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
//  执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标 sizeBase.cx=60; //初始化   基本长宽
sizeBase.cy=60;
ptVeryOld.x = 150; //初始化   初始绘图基点
ptVeryOld.y = 150;
ptCenter.x = ptVeryOld.x+sizeBase.cx * btnCount/2;
ptCenter.y = ptVeryOld.y+sizeBase.cy/2;
for (int i=0;i<btnCount;i++) //一定要养成一个好的命名习惯阿   真操蛋
{
ptLftp[i].x=ptVeryOld.x + i*sizeBase.cx;
ptLftp[i].y=ptVeryOld.y;
CRect rttmp(ptVeryOld.x + i*sizeBase.cx ,ptVeryOld.y,ptVeryOld.x + (i+1)*sizeBase.cx,ptVeryOld.y+sizeBase.cy);
dmmbtn[i].Create(_T("躲狗狗."),WS_CHILD|WS_VISIBLE
,rttmp
,this,ID_MYBTN_START+i);
} return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}void CSimpDmmDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。void CSimpDmmDlg::OnPaint()
{
//  CDialog::OnPaint();
}//当用户拖动最小化窗口时系统调用此函数取得光标显示。
//
HCURSOR CSimpDmmDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CSimpDmmDlg::OnMouseMove(UINT nFlags, CPoint point)
{
CPoint ptNow(point); //取得现在的坐标,转成固定,防止有变,不知是否多余
int Kuan=0;
for (int i=0;i<btnCount;i++) //计算当前鼠标位置时  各按钮的大小 保存到 sizeAfter[]中
{
int l=abs(ptNow.x-ptLftp[i].x); //当前光标距 每按钮左上点的绝对距离
if (l<120)
{
sizeAfter[i].cx=120-l/2;
sizeAfter[i].cy=120-l/2;
}
else
{
sizeAfter[i].cx=60;
sizeAfter[i].cy=60;
}
Kuan += sizeAfter[i].cx;

} ptLftp[0].x = ptCenter.x-Kuan/2;
ptLftp[0].y = ptCenter.y-sizeAfter[0].cy/2;
int leftx=0;
for (int i=1;i<btnCount;i++) //据边长宽  来确定每个按钮的左上首位置坐标
{
leftx += sizeAfter[i-1].cx;
ptLftp[i].x = ptLftp[0].x + leftx;
ptLftp[i].y = ptCenter.y - sizeAfter[i].cy/2; } HDWP hDwp = BeginDeferWindowPos(5);
for (int i=0;i<btnCount;i++)
{
DeferWindowPos(hDwp
,dmmbtn[i]
,NULL
,ptLftp[i].x
,ptLftp[i].y
,sizeAfter[i].cx
,sizeAfter[i].cy
,SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOCOPYBITS |SWP_NOZORDER);
}
EndDeferWindowPos(hDwp); CDialog::OnMouseMove(nFlags, point);
}BOOL CSimpDmmDlg::OnEraseBkgnd(CDC* pDC)
{
CRect rctc;
GetClientRect(&rctc);
//ScreenToClient(&rctc); pDC->FillSolidRect(&rctc,RGB(168,152,129));
//  for (int i=0;i<btnCount;i++)
//  {
//  dmmbtn[i].RedrawWindow();
//  }
UpdateWindow();
return true;
//return CDialog::OnEraseBkgnd(pDC);
}
BOOL CSimpDmmDlg::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_MOUSEMOVE)
{
CPoint pttmp;
pttmp.x = pMsg->pt.x;
pttmp.y = pMsg->pt.y;
ScreenToClient(&pttmp);
OnMouseMove(0,pttmp);
} return CDialog::PreTranslateMessage(pMsg);
}