VC image drag and drop and animation examples
- 2020-04-02 01:27:08
- OfStack
Basic knowledge of
1. Use of PictureBox control
Load the bitmap file
1. Get the bitmap handle from the file path
//Gets the bitmap handle & NBSP;
void CMovePictureDlg::GetHandleFromPath(CString path)
{
hBitmap= (HBITMAP)::LoadImage(AfxGetInstanceHandle(),path,IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION|LR_LOADFROMFILE);//Create bitmap handle & NBSP;
}
2. Create bitmap objects and obtain bitmap information through the bitmap handle
//Getting a bitmap object & NBSP;
void CMovePictureDlg::GetBitMap(HBITMAP hBitmap)
{
m_BitMap.Attach(hBitmap);//Creates a bitmap object & NBSP; through a bitmap handle;
//Getting image information & NBSP;
BITMAPINFOHEADER bminfo;
m_BitMap.GetObject(sizeof(bminfo),&bminfo);
//Get bitmap width and height & NBSP;
m_nBmpWidth=bminfo.biWidth;
m_nBmpHeight=bminfo.biHeight;
}
Implementation steps:
1. Create a dialog project named MovePicture
2. Open the dialog box and drag in a PictureBox control, set the ID as: IDC_PICTUREBOX, set the type as: bitmap
3. Drag in two static text controls and two edit box controls. The static text control titles are: input momentum coefficient:, input resistance coefficient:, edit box ids are: IDC_EDITDV, IDC_EDITF, IDC_EDITDV, IDC_EDITDV, m_editDV, IDC_EDITF, m_editF
4. Implementation code
The header file
// 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;//Save system path & NBSP;
CString bmpPath;//Bitmap path & NBSP;
HBITMAP hBitmap;//Bitmap handle & NBSP;
CBitmap m_BitMap;//Bitmap object & NBSP;
int m_nBmpWidth;//Bitmap width & NBSP;
int m_nBmpHeight;//Bitmap height & NBSP;
CPictureBox* pictureBox;//Picture control & NBSP;
CRect picRect;//Control occupied area & NBSP;
BOOL isSelect;//Determines whether the control is selected & NBSP;
BOOL isDown;//Judge whether the mouse is pressed & NBSP;
CPoint oldPoint;//Original mouse position & NBSP;
CPoint startPoint;//Move the starting position & noon;
SYSTEMTIME startTime;//Start time & NBSP;
SYSTEMTIME endTime;//End time & NBSP;
double vx;//Velocity in the x direction & NBSP;
double vy;//Velocity in the y direction & NBSP;
double f;//Resistance & have spent
double dv;//Dynamic increment & NBSP;
CRect clientRect;//Client area & NBSP;
};
//{{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_)
Implementation file
// 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
//Calculate the time difference & noon; & have spent
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;//If calculating the date is tricky, let the MFC do it & NBSP; & have spent
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 )
: 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;//Initializing the mouse pressed state & NBSP;
isSelect = FALSE;//Initializing the checked state & NBSP;
f = 0.05;//Initialization resistance & NBSP;
dv = 5;//Initializing dynamic increment & NBSP;
}
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
//Dialog initializing & NBSP;
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);//Get a picture frame pointer & NBSP;
SetSysPath();//Set system path & NBSP;
bmpPath = sysPath+"//image.bmp";// Set the bitmap path
GetHandleFromPath(bmpPath);//Create bitmap handle & NBSP;
GetBitMap(hBitmap);//Getting a bitmap & NBSP;
//Set the bitmap control area & PI;
SetPicRect(0,0);
pictureBox->MoveWindow(picRect);//Set the control position & NBSP;
//Sets the value of the text box & NBSP;
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.
//Redraw function & NBSP;
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);//Obtain client area size & NBSP;
pictureBox->SetBitmap(hBitmap);//Display bitmap & NBSP;
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;
}
//Press the left mouse button & NBSP;
void CMovePictureDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
isDown=TRUE;//Mouse down & NBSP;
if(PtInRect(picRect,point))//Press the button in the picture area.
{
isSelect=TRUE;//Picture checked & NBSP;
oldPoint = point;//Record the mouse position & NBSP;
startPoint = point;//Record the starting position of the mouse & PI;
GetSystemTime(&startTime);//Get the current time & NBSP;
}
CDialog::OnLButtonDown(nFlags, point);
}
//Left mouse button up & NBSP;
void CMovePictureDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
isDown=FALSE;//Mouse snap & NBSP;
if(isSelect)
{
CString strDV,strF;
m_editDV.GetWindowText(strDV);
m_editF.GetWindowText(strF);
dv = atof(strDV);
f = atof(strF);
isSelect=FALSE;//Release picture & NBSP;
GetSystemTime(&endTime);//Get the current time & NBSP;
double dx = point.x-startPoint.x;//Calculate the X-axis displacement & PI;
double dy = point.y-startPoint.y;//Calculate y axis displacement & PI;
int s = TimeDiff(endTime,startTime);//Calculate the time difference & noon;
//double r = sqrt(dx*dx+dy*dy);// Calculate the mouse displacement length
//double v=r/s;// Average velocity
vx=dv*dx/s;//Average X-axis velocity & NBSP;
vy=dv*dy/s;//Y axis average speed & NBSP;
SetTimer(1,1,NULL);//Set a timer & NBSP;
}
CDialog::OnLButtonUp(nFlags, point);
}
//Mouse movement & NBSP;
void CMovePictureDlg::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if(isDown&&isSelect)//Move in mouse down mode & NBSP;
{
int dx = point.x-oldPoint.x;//Calculate the relative change of x value & PI;
int dy = point.y-oldPoint.y;//Calculate the relative change in y value & PI;
//Reset PictureBox location & NBSP;
picRect.left=picRect.left+dx;
picRect.top=picRect.top+dy;
SetPicRect(picRect.left,picRect.top);//Reset image position & NBSP;
pictureBox->MoveWindow(picRect.left,picRect.top,m_nBmpWidth,m_nBmpHeight);//Changing the size of the picture frame & NBSP;
oldPoint=point;//Reset the original coordinates & NBSP;
}
CDialog::OnMouseMove(nFlags, point);
}
//Set system path & NBSP;
void CMovePictureDlg::SetSysPath()
{
//Gets the current path and stores it in the character array strBuff & PI.
char strBuff[256];
GetCurrentDirectory(256,strBuff);
sysPath.Format("%s",strBuff);//Saves the path to the global variable & PI;
}
//Set control area & NBSP;
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;
}
//Gets the bitmap handle & NBSP;
void CMovePictureDlg::GetHandleFromPath(CString path)
{
hBitmap= (HBITMAP)::LoadImage(AfxGetInstanceHandle(),path,IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION|LR_LOADFROMFILE);//Create bitmap handle & NBSP;
}
//Getting a bitmap object & NBSP;
void CMovePictureDlg::GetBitMap(HBITMAP hBitmap)
{
m_BitMap.Attach(hBitmap);//Creates a bitmap object & NBSP; through a bitmap handle;
//Getting image information & NBSP;
BITMAPINFOHEADER bminfo;
m_BitMap.GetObject(sizeof(bminfo),&bminfo);
//Get bitmap width and height & NBSP;
m_nBmpWidth=bminfo.biWidth;
m_nBmpHeight=bminfo.biHeight;
}
//Timer event & NBSP;
void CMovePictureDlg::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
if(abs(vx)>abs(vy))//When the horizontal velocity is greater than the vertical velocity, only the increment of the horizontal direction is changed.
{
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))//When the horizontal velocity is less than the vertical velocity, only the vertical increment & NBSP; is changed.
{
if(picRect.top==clientRect.top)
{
vy=-vy;
}
if(picRect.top==clientRect.bottom-m_nBmpHeight)
{
vy=-vy;
}
picRect.top+=vy;
}
//Border judgment & NBSP;
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);//Changing the size of the picture frame & NBSP;
//Incremental decline, uniform deceleration movement & NBSP;
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);//Reset image position & NBSP;
CDialog::OnTimer(nIDEvent);
}
void CMovePictureDlg::OnDestroy()
{
CDialog::OnDestroy();
// TODO: Add your message handler code here
this->KillTimer(1);//Destruction timer & NBSP;
}
1. Add a PictureBox control in the dialog box, set the ID as IDC_PICTUREBOX, type as bitmap
2. Create CPictureBox class inherited from CStatic
Declare in the dialog class
CPictureBox * pictureBox; // picture control
4. Get the control pointer in the OnInitDialog method of the dialog class
PictureBox = (CPictureBox *) GetDlgItem (IDC_PICTUREBOX); // get the picture box pointer
5. Display bitmaps
PictureBox - > SetBitmap (hBitmap); // display bitmap
6. Set the control location
PictureBox - > MoveWindow (picRect); // sets the control location