VC实现图片拖拽及动画的实例
更新时间:2020年4月25日 17:45 点击:1882
基础知识
1.PictureBox控件的使用
2.加载位图文件
1.通过文件路径获得位图句柄
复制代码 代码如下:
//获得位图句柄
void CMovePictureDlg::GetHandleFromPath(CString path)
{
hBitmap= (HBITMAP)::LoadImage(AfxGetInstanceHandle(),path,IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION|LR_LOADFROMFILE);//创建位图句柄
}
2.通过位图句柄创建位图对象并获得位图信息
复制代码 代码如下:
//获取位图对象
void CMovePictureDlg::GetBitMap(HBITMAP hBitmap)
{
m_BitMap.Attach(hBitmap);//通过位图句柄创建位图对象
//获取图像信息
BITMAPINFOHEADER bminfo;
m_BitMap.GetObject(sizeof(bminfo),&bminfo);
//获取位图宽高
m_nBmpWidth=bminfo.biWidth;
m_nBmpHeight=bminfo.biHeight;
}
实现步骤:
1.创建一个对话框工程命名为MovePicture
2.打开对话框资源拖入一个PictureBox控件,设置ID为:IDC_PICTUREBOX,设置类型为:位图
3.拖入两个静态文本控件和两个编辑框控件,静态文本控件标题分别为:输入动量系数:、输入阻力系数:,编辑框ID分别为:IDC_EDITDV、IDC_EDITF,为IDC_EDITDV关联变量为:m_editDV,为IDC_EDITF关联变量为:m_editF
4.实现代码
头文件
复制代码 代码如下:
// MovePictureDlg.h : header file
//
#include "PictureBox.h"
#if !defined(AFX_MOVEPICTUREDLG_H__6FFC1DDF_478C_43D6_B854_4D51E98D5E50__INCLUDED_)
#define AFX_MOVEPICTUREDLG_H__6FFC1DDF_478C_43D6_B854_4D51E98D5E50__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
/////////////////////////////////////////////////////////////////////////////
// CMovePictureDlg dialog
class CMovePictureDlg : public CDialog
{
// Construction
public:
void GetBitMap(HBITMAP hBitmap);
void GetHandleFromPath(CString path);
void SetPicRect(int x,int y);
void SetSysPath();
CMovePictureDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CMovePictureDlg)
enum { IDD = IDD_MOVEPICTURE_DIALOG };
CEdit m_editF;
CEdit m_editDV;
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMovePictureDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
HICON m_hIcon;
// Generated message map functions
//{{AFX_MSG(CMovePictureDlg)
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnTimer(UINT nIDEvent);
afx_msg void OnDestroy();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
private:
CString sysPath;//保存系统路径
CString bmpPath;//位图路径
HBITMAP hBitmap;//位图句柄
CBitmap m_BitMap;//位图对象
int m_nBmpWidth;//位图宽度
int m_nBmpHeight;//位图高度
CPictureBox* pictureBox;//图片控件
CRect picRect;//控件所占区域
BOOL isSelect;//判断控件是否被选中
BOOL isDown;//判断鼠标是否按下
CPoint oldPoint;//鼠标原始位置
CPoint startPoint;//移动起始位置
SYSTEMTIME startTime;//开始时间
SYSTEMTIME endTime;//结束时间
double vx;//x方向速度
double vy;//y方向速度
double f;//阻力
double dv;//动力增量
CRect clientRect;//客户区域
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_MOVEPICTUREDLG_H__6FFC1DDF_478C_43D6_B854_4D51E98D5E50__INCLUDED_)
实现文件
复制代码 代码如下:
// MovePictureDlg.cpp : implementation file
//
#include "stdafx.h"
#include "MovePicture.h"
#include "MovePictureDlg.h"
#include <math.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
//计算时间差
inline __int64 TimeDiff(SYSTEMTIME left,SYSTEMTIME right)
{
CTime tmLeft(left.wYear,left.wMonth,left.wDay,0,0,0);
CTime tmRight(left.wYear,left.wMonth,left.wDay,0,0,0);
CTimeSpan sp;
sp = tmLeft - tmRight;//计算日期比较麻烦,就交给MFC去做吧
long lLMinllis = (left.wHour*3600 + left.wMinute*60 + left.wSecond)*1000 + left.wMilliseconds;
long lRMinllis = (right.wHour*3600 + right.wMinute*60 + right.wSecond)*1000 + right.wMilliseconds;
return (__int64)sp.GetDays()*86400000 + (lLMinllis - lRMinllis);
}
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMovePictureDlg dialog
CMovePictureDlg::CMovePictureDlg(CWnd* pParent /*=NULL*/)
: CDialog(CMovePictureDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CMovePictureDlg)
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
isDown = FALSE;//初始化鼠标按下状态
isSelect = FALSE;//初始化选中状态
f = 0.05;//初始化阻力
dv = 5;//初始化动力增量
}
void CMovePictureDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CMovePictureDlg)
DDX_Control(pDX, IDC_EDITF, m_editF);
DDX_Control(pDX, IDC_EDITDV, m_editDV);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CMovePictureDlg, CDialog)
//{{AFX_MSG_MAP(CMovePictureDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_LBUTTONDOWN()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONUP()
ON_WM_TIMER()
ON_WM_DESTROY()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMovePictureDlg message handlers
//对话框初始化
BOOL CMovePictureDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About…" menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
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);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
pictureBox = (CPictureBox*)GetDlgItem(IDC_PICTUREBOX);//获得图片框指针
SetSysPath();//设置系统路径
bmpPath = sysPath+"//image.bmp";//设置位图路径
GetHandleFromPath(bmpPath);//创建位图句柄
GetBitMap(hBitmap);//获得位图
//设置位图控件区域
SetPicRect(0,0);
pictureBox->MoveWindow(picRect);//设置控件位置
//设置文本框值
CString strDV,strF;
strDV.Format("%f",dv);
strF.Format("%f",f);
m_editDV.SetWindowText(strDV);
m_editF.SetWindowText(strF);
return TRUE; // return TRUE unless you set the focus to a control
}
void CMovePictureDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
//重绘函数
void CMovePictureDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
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;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
this->GetClientRect(&clientRect);//获得客户区域大小
pictureBox->SetBitmap(hBitmap);//显示位图
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CMovePictureDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
//鼠标左键按下
void CMovePictureDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
isDown=TRUE;//鼠标按下
if(PtInRect(picRect,point))//鼠标在图片区域按下
{
isSelect=TRUE;//图片选中
oldPoint = point;//记录下鼠标位置
startPoint = point;//记录下鼠标起始位置
GetSystemTime(&startTime);//得到当前时间
}
CDialog::OnLButtonDown(nFlags, point);
}
//鼠标左键弹起
void CMovePictureDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
isDown=FALSE;//鼠标弹起
if(isSelect)
{
CString strDV,strF;
m_editDV.GetWindowText(strDV);
m_editF.GetWindowText(strF);
dv = atof(strDV);
f = atof(strF);
isSelect=FALSE;//释放图片
GetSystemTime(&endTime);//得到当前时间
double dx = point.x-startPoint.x;//计算x轴位移
double dy = point.y-startPoint.y;//计算y轴位移
int s = TimeDiff(endTime,startTime);//计算时间差
//double r = sqrt(dx*dx+dy*dy);//计算鼠标位移长度
//double v=r/s;//求平均速度
vx=dv*dx/s;//x轴平均速度
vy=dv*dy/s;//y轴平均速度
SetTimer(1,1,NULL);//设置定时器
}
CDialog::OnLButtonUp(nFlags, point);
}
//鼠标移动
void CMovePictureDlg::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if(isDown&&isSelect)//在鼠标按下状态下移动
{
int dx = point.x-oldPoint.x;//计算x值的相对变化
int dy = point.y-oldPoint.y;//计算y值的相对变化
//重新设置PictureBox位置
picRect.left=picRect.left+dx;
picRect.top=picRect.top+dy;
SetPicRect(picRect.left,picRect.top);//重置图片位置
pictureBox->MoveWindow(picRect.left,picRect.top,m_nBmpWidth,m_nBmpHeight);//改变图片框大小
oldPoint=point;//重置原始坐标
}
CDialog::OnMouseMove(nFlags, point);
}
//设置系统路径
void CMovePictureDlg::SetSysPath()
{
//获取当前路径,保存到字符数组strBuff中
char strBuff[256];
GetCurrentDirectory(256,strBuff);
sysPath.Format("%s",strBuff);//将路径保存到全局变量中
}
//设置控件区域
void CMovePictureDlg::SetPicRect(int x, int y)
{
picRect.top=y;
picRect.bottom=picRect.top+m_nBmpHeight;
picRect.left=x;
picRect.right=picRect.left+m_nBmpWidth;
}
//获得位图句柄
void CMovePictureDlg::GetHandleFromPath(CString path)
{
hBitmap= (HBITMAP)::LoadImage(AfxGetInstanceHandle(),path,IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION|LR_LOADFROMFILE);//创建位图句柄
}
//获取位图对象
void CMovePictureDlg::GetBitMap(HBITMAP hBitmap)
{
m_BitMap.Attach(hBitmap);//通过位图句柄创建位图对象
//获取图像信息
BITMAPINFOHEADER bminfo;
m_BitMap.GetObject(sizeof(bminfo),&bminfo);
//获取位图宽高
m_nBmpWidth=bminfo.biWidth;
m_nBmpHeight=bminfo.biHeight;
}
//定时器事件
void CMovePictureDlg::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
if(abs(vx)>abs(vy))//当水平速度大于垂直速度时,只改变水平方向增量
{
if(picRect.left==clientRect.left)
{
vx=-vx;
}
if(picRect.left==clientRect.right-m_nBmpWidth)
{
vx=-vx;
}
picRect.left+=vx;
}
else if(abs(vx)<abs(vy))//当水平速度小于垂直速度时,只改变垂直方向增量
{
if(picRect.top==clientRect.top)
{
vy=-vy;
}
if(picRect.top==clientRect.bottom-m_nBmpHeight)
{
vy=-vy;
}
picRect.top+=vy;
}
//边界判断
if(picRect.left<clientRect.left)
{
picRect.left=clientRect.left;
}
if(picRect.left>clientRect.right-m_nBmpWidth)
{
picRect.left=clientRect.right-m_nBmpWidth;
}
if(picRect.top<clientRect.top)
{
picRect.top=clientRect.top;
}
if(picRect.top>clientRect.bottom-m_nBmpHeight)
{
picRect.top=clientRect.bottom-m_nBmpHeight;
}
pictureBox->MoveWindow(picRect.left,picRect.top,m_nBmpWidth,m_nBmpHeight);//改变图片框大小
//增量递减,匀减速运动
if(vx>0)
{
vx-=f;
if(vx<0)
{
vx=0;
}
}
else if(vx<0)
{
vx+=f;
if(vx>0)
{
vx=0;
}
}
if(vy>0)
{
vy-=f;
if(vy<0)
{
vy=0;
}
}
else if(vy<0)
{
vy+=f;
if(vy>0)
{
vy=0;
}
}
SetPicRect(picRect.left,picRect.top);//重置图片位置
CDialog::OnTimer(nIDEvent);
}
void CMovePictureDlg::OnDestroy()
{
CDialog::OnDestroy();
// TODO: Add your message handler code here
this->KillTimer(1);//销毁定时器
}
1.在对话框中添加一PictureBox控件,设置ID为IDC_PICTUREBOX,类型为位图
2.创建CPictureBox类继承于CStatic
3.在对话框类中声明
CPictureBox* pictureBox;//图片控件
4.在对话框类的OnInitDialog方法中获得控件指针
pictureBox = (CPictureBox*)GetDlgItem(IDC_PICTUREBOX);//获得图片框指针
5.显示位图
pictureBox->SetBitmap(hBitmap);//显示位图
6.设置控件位置
pictureBox->MoveWindow(picRect);//设置控件位置
上一篇: 深入解析C++中的引用类型
相关文章
- ps动态环绕动画效果是现在很多人都非常喜欢的,大多数人还不知道ps动态环绕动画效果怎么制作下面文章就给大家介绍下ps怎么制作科技感十足的动态环绕动画效果,一起来看看...2017-07-06
使用PHP+JavaScript将HTML页面转换为图片的实例分享
这篇文章主要介绍了使用PHP+JavaScript将HTML元素转换为图片的实例分享,文后结果的截图只能体现出替换的字体,也不能说将静态页面转为图片可以加快加载,只是这种做法比较interesting XD需要的朋友可以参考下...2016-04-19- 这篇文章主要介绍了C#从数据库读取图片并保存的方法,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下...2021-01-16
- 今天小编在这里就来给各位Photoshop的这一款软件的使用者们来说说把古装美女图片转为细腻的工笔画效果的制作教程,各位想知道方法的使用者们,那么下面就快来跟着小编一...2016-09-14
- 这篇文章主要介绍了Python 图片转数组,二进制互转操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-09
- php如何实现抓取网页图片,相较于手动的粘贴复制,使用小程序要方便快捷多了,喜欢编程的人总会喜欢制作一些简单有用的小软件,最近就参考了网上一个php抓取图片代码,封装了一个php远程抓取图片的类,测试了一下,效果还不错分享...2015-10-30
antdesign-vue结合sortablejs实现两个table相互拖拽排序功能
这篇文章主要介绍了antdesign-vue结合sortablejs实现两个table相互拖拽排序功能,本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-01-09jquery左右滚动焦点图banner图片鼠标经过显示上下页按钮
jquery左右滚动焦点图banner图片鼠标经过显示上下页按钮...2013-10-13- 下面小编就为大家带来一篇利用JS实现点击按钮后图片自动切换的简单方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2016-10-25
- Photoshop的这一款软件小编相信很多的人都已经是使用过了吧,那么今天小编在这里就给大家带来了用Photoshop软件制作枪战电影海报的教程,想知道制作步骤的玩家们,那么下面...2016-09-14
- 这篇文章主要为大家详细介绍了js实现上传图片及时预览的相关资料,具有一定的参考价值,感兴趣的朋友可以参考一下...2016-05-09
- 图片剪裁是常用的方法,那么如何通过4坐标剪裁图片,本文就详细的来介绍一下,感兴趣的小伙伴们可以参考一下...2021-06-04
- 共享一段使用PHP下载CSS文件中的图片的代码 复制代码 代码如下: <?php //note 设置PHP超时时间 set_time_limit(0); //note 取得样式文件内容 $styleFileContent = file_get_contents('images/style.css'); //not...2013-10-04
- PHP代码如下:复制代码 代码如下:if (isset($_FILES["Filedata"]) || !is_uploaded_file($_FILES["Filedata"]["tmp_name"]) || $_FILES["Filedata"]["error"] != 0) { $upload_file = $_FILES['Filedata']; $fil...2013-10-04
- 这篇文章主要给大家介绍了关于微信小程序如何获取图片宽度与高度的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-10
C#中图片旋转和翻转(RotateFlipType)用法分析
这篇文章主要介绍了C#中图片旋转和翻转(RotateFlipType)用法,实例分析了C#图片旋转及翻转Image.RotateFlip方法属性的常用设置技巧,需要的朋友可以参考下...2020-06-25- ps软件是现在很多人比较喜欢的,有着非常不错的使用效果,这次文章就给大家介绍下ps怎么制作图片阴影效果,还不知道制作方法的赶紧来看看。 ps图片阴影效果怎么做方法/...2017-07-06
- 这篇文章主要介绍了OpenCV如何去除图片中的阴影的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-29
- 本文主要介绍用C#实现图片转换成字节流,字节流转换成图片,并根据图片路径返回图片的字节流,有需要的朋友可以参考下...2020-06-25
- 这篇文章主要介绍了JavaScript 如何禁止用户保存图片,帮助大家完成需求,更好的理解和使用JavaScript,感兴趣的朋友可以了解下...2020-11-19