2013-04-05 98 views
1

我使用CPaintDC将三个对象绘制到一个窗口上,现在我试图通过使用OnMouseMove事件处理函数让其中的一个(椭圆)变为可拖动。我只是在玩MFC,并且失去了如何使这个工作。MFC拖动对象

这是我在OnMouseMove曾尝试:

// TODO: Add your message handler code here and/or call default 
CClientDC dc(this); 
CRect rect; 
GetClientRect(&rect); 
dc.SetMapMode(MM_ANISOTROPIC); 
dc.SetWindowExt(100, 100); 
CRect rectEllipse(ellipse.cx, ellipse.cy,(ellipse.cx) + 10, (ellipse.cy) + 10);//(10, 10, 20, 20);dc.Ellipse(ellipse.cx, ellipse.cy, (ellipse.cx) + 10, (ellipse.cy) + 10);//10, 10, 20, 20); 
//CPoint ellipseDest; 

//dc.SetViewportExt(rect.Width(), rect.Height()); 
if (mouseCaptured) 
    { 
     ellipse.cx = point.x; 
     ellipse.cy = point.y; 
     InvalidateRect(rectEllipse, TRUE); 
    } 
CDialogEx::OnMouseMove(nFlags, point); 

请找我的代码粘贴下面。

非常感谢您的帮助。

#include "stdafx.h" 
#include "CSIT861a3 Vasilkovskiy.h" 
#include "CSIT861a3 VasilkovskiyDlg.h" 
#include "afxdialogex.h" 

#ifdef _DEBUG 
#define new DEBUG_NEW 
#endif 


// CAboutDlg dialog used for App About 

class CAboutDlg : public CDialogEx 
{ 
public: 
    CAboutDlg(); 

// Dialog Data 
    enum { IDD = IDD_ABOUTBOX }; 

    protected: 
    virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support 

// Implementation 
protected: 
    DECLARE_MESSAGE_MAP() 
public: 
// afx_msg void OnLButtonDown(UINT nFlags, CPoint point); 
// afx_msg void OnLButtonUp(UINT nFlags, CPoint point); 
// afx_msg void OnMouseMove(UINT nFlags, CPoint point); 
}; 

CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD) 
{ 
} 

void CAboutDlg::DoDataExchange(CDataExchange* pDX) 
{ 
    CDialogEx::DoDataExchange(pDX); 
} 

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx) 
// ON_WM_LBUTTONDOWN() 
// ON_WM_LBUTTONUP() 
// ON_WM_MOUSEMOVE() 
END_MESSAGE_MAP() 


// CCSIT861a3VasilkovskiyDlg dialog 




CCSIT861a3VasilkovskiyDlg::CCSIT861a3VasilkovskiyDlg(CWnd* pParent /*=NULL*/) 
    : CDialogEx(CCSIT861a3VasilkovskiyDlg::IDD, pParent) 
{ 
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); 

    ellipseColor = RGB(255, 0, 0); 
    centerRectColor = RGB(0, 0, 0); 
    rightRectColor = RGB(255, 0, 0); 
    centerRect.left = 40; 
    centerRect.top = 20; 
    centerRect.right = 55; 
    centerRect.bottom = 80; 
    rightRect.left = 75; 
    rightRect.top = 35; 
    rightRect.right = 90; 
    rightRect.bottom = 50; 
    ellipse.cx = 10; 
    ellipse.cy = 10; 
    mouseCaptured = false; 
} 

void CCSIT861a3VasilkovskiyDlg::DoDataExchange(CDataExchange* pDX) 
{ 
    CDialogEx::DoDataExchange(pDX); 
} 

BEGIN_MESSAGE_MAP(CCSIT861a3VasilkovskiyDlg, CDialogEx) 
    ON_WM_SYSCOMMAND() 
    ON_WM_PAINT() 
    ON_WM_QUERYDRAGICON() 
    ON_WM_LBUTTONDOWN() 
    ON_WM_LBUTTONUP() 
    ON_WM_MOUSEMOVE() 
END_MESSAGE_MAP() 


// CCSIT861a3VasilkovskiyDlg message handlers 

BOOL CCSIT861a3VasilkovskiyDlg::OnInitDialog() 
{ 
    CDialogEx::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) 
    { 
     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); 
     } 
    } 

    // 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 

    return TRUE; // return TRUE unless you set the focus to a control 
} 

void CCSIT861a3VasilkovskiyDlg::OnSysCommand(UINT nID, LPARAM lParam) 
{ 
    if ((nID & 0xFFF0) == IDM_ABOUTBOX) 
    { 
     CAboutDlg dlgAbout; 
     dlgAbout.DoModal(); 
    } 
    else 
    { 
     CDialogEx::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 CCSIT861a3VasilkovskiyDlg::OnPaint() 
{ 
    //Create pen and pointer to the old pen 
    CPen blackPen; 
    blackPen.CreatePen(PS_SOLID, 1, RGB (0, 0, 0)); 

    //Create a bursh 
    CBrush blackBrush(centerRectColor); 
    CBrush redBrush(rightRectColor); 
    CBrush hatchRedBrush(HS_CROSS, ellipseColor); 

    //Set up object for painting 
    CPaintDC dc (this); 
    CRect rect; 
    GetClientRect (&rect); 
    dc.SetMapMode (MM_ANISOTROPIC); 
    dc.SetWindowExt (100, 100); 
    dc.SetViewportExt (rect.Width(), rect.Height()); 


    //select pen 
    dc.SelectObject(&blackPen); 

    //Rectangle red interior color 
    dc.SelectObject(&redBrush); 
    dc.Rectangle(rightRect); //(75, 35, 90, 50); 

    //Rectangel black interior 
    dc.SelectObject(&blackBrush);//Select Brush 
    dc.Rectangle(centerRect);//(40, 20, 55, 80); 

    //Ellipse 
    dc.SelectObject(&hatchRedBrush);//Select Brush 
    dc.Ellipse(ellipse.cx, ellipse.cy, (ellipse.cx) + 10, (ellipse.cy) + 10);//10, 10, 20, 20); 

    if (IsIconic()) 
    { 
     CPaintDC dc(this); // device context for painting 

     SendMessage(WM_ICONERASEBKGND, reinterpret_cast<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 
    { 
     CDialogEx::OnPaint(); 
    } 
} 

// The system calls this function to obtain the cursor to display while the user drags 
// the minimized window. 
HCURSOR CCSIT861a3VasilkovskiyDlg::OnQueryDragIcon() 
{ 
    return static_cast<HCURSOR>(m_hIcon); 
} 



//void CAboutDlg::OnLButtonDown(UINT nFlags, CPoint point) 
//{ 
// // TODO: Add your message handler code here and/or call default 
// //SetCapture(); 
// CClientDC dc(this); 
// CRect rect; 
// GetClientRect(&rect); 
// dc.SetMapMode(MM_ANISOTROPIC); 
// dc.SetWindowExt(100, 100); 
// dc.SetViewportExt(rect.Width(), rect.Height()); 
// CRect rectEllipse(10, 10, 20, 20); 
// 
// ellipseColor = RGB(0,0,0); 
// 
// CDialogEx::OnLButtonDown(nFlags, point); 
//} 


//void CAboutDlg::OnLButtonUp(UINT nFlags, CPoint point) 
//{ 
// // TODO: Add your message handler code here and/or call default 
// ReleaseCapture(); 
// CDialogEx::OnLButtonUp(nFlags, point); 
//} 


//void CAboutDlg::OnMouseMove(UINT nFlags, CPoint point) 
//{ 
// // TODO: Add your message handler code here and/or call default 
// 
// CDialogEx::OnMouseMove(nFlags, point); 
//} 


void CCSIT861a3VasilkovskiyDlg::OnLButtonDown(UINT nFlags, CPoint point) 
{ 
    // TODO: Add your message handler code here and/or call default 


    CClientDC dc(this); 
    CRect rect; 
    GetClientRect(&rect); 
    dc.SetMapMode(MM_ANISOTROPIC); 
    dc.SetWindowExt(100, 100); 
    dc.SetViewportExt(rect.Width(), rect.Height()); 

    CRect rectEllipse(ellipse.cx, ellipse.cy, 20, 20);//(10, 10, 20, 20); 
    CRgn circle; 
    dc.LPtoDP(rectEllipse); 
    circle.CreateEllipticRgnIndirect(rectEllipse); 

    if (circle.PtInRegion(point)) 
    { 
     SetCapture(); 
      mouseCaptured = true; 
     ellipseColor = RGB(0,0,255); 
     InvalidateRect(rectEllipse, FALSE); 
    } 

    CDialogEx::OnLButtonDown(nFlags, point); 
} 


void CCSIT861a3VasilkovskiyDlg::OnLButtonUp(UINT nFlags, CPoint point) 
{ 
    // TODO: Add your message handler code here and/or call default 
    ReleaseCapture(); 
    mouseCaptured = false; 
    CDialogEx::OnLButtonUp(nFlags, point); 
} 


void CCSIT861a3VasilkovskiyDlg::OnMouseMove(UINT nFlags, CPoint point) 
{ 

    // TODO: Add your message handler code here and/or call default 

    if (mouseCaptured) 
     { 
       /* 
       Code to drag and drop and redraw ellipse 
        */ 
       InvalidateRect(rectEllipse, TRUE); 
     } 
    CDialogEx::OnMouseMove(nFlags, point); 
} 
+0

您需要作废两个矩形,一个在老位置,一个在新的位置。或者制作一个足够大的矩形以包含两者。 – 2013-04-05 22:29:50

+0

只需要注意MFC。当然它有效,但如果可以的话,看看其他地方。 – 2013-04-05 22:39:01

+0

@MarkRansom目前,当我尝试拖动椭圆时,只是简单地删除它的一部分。如果这是问题,它不应该打印多个新的不擦除旧的。谢谢。 – Zzz 2013-04-05 22:45:35

回答

1

我认为Mark Ransom的评论是正确的,您需要使MouseMove上的两个矩形无效。

CRect rectEllipse(ellipse.cx, ellipse.cy,(ellipse.cx) + 10, (ellipse.cy) + 10); 
if (mouseCaptured) 
{ InvalidateRect(rectEllipse, TRUE); 
    ellipse.cx = point.x; 
    ellipse.cy = point.y; 
    CRect rectNew(ellipse.cx, ellipse.cy,(ellipse.cx) + 10, (ellipse.cy) + 10); 
    InvalidateRect(rectNew, TRUE); 

}

此外,在OnLButtonUp()

if (mouseCaptured) 
{ ellipseColor = RGB(255, 0, 0); 
    CRect rectEllipse(ellipse.cx, ellipse.cy,(ellipse.cx) + 10, (ellipse.cy) + 10); 
    InvalidateRect(rectEllipse, TRUE); 
} 
+0

我试过了你的建议,但问题是一样的。将鼠标左键按在椭圆上时发生的所有事情是在按下鼠标的位置删除椭圆。 – Zzz 2013-04-07 04:14:05

+0

你可以尝试在调用'CDialogEx :: OnPaint()'后将'OnPaint()'中的自定义绘制逻辑移至? – 2013-04-07 17:37:09