MFC动态画矩形(响应WM_MOUSEMOVE)

来源:互联网 发布:c语言模块化编程视频 编辑:程序博客网 时间:2024/05/16 06:39

VS2010,基于对话框工程MFC示例


GDI版:


1、DrawRectDlg.h

// DrawRectDlg.h : 头文件//#pragma once// CDrawRectDlg 对话框class CDrawRectDlg : public CDialogEx{// 构造public:CDrawRectDlg(CWnd* pParent = NULL);// 标准构造函数// 对话框数据enum { IDD = IDD_DRAWRECT_DIALOG };protected:virtual void DoDataExchange(CDataExchange* pDX);// DDX/DDV 支持// 实现protected:HICON m_hIcon;CPoint m_ptbegin;CPoint m_ptEnd;BOOL m_blBtnDown;CDC m_dcMemory;// 生成的消息映射函数virtual BOOL OnInitDialog();afx_msg void OnSysCommand(UINT nID, LPARAM lParam);afx_msg void OnPaint();afx_msg HCURSOR OnQueryDragIcon();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);};

2、DrawRectDlg.cpp

// DrawRectDlg.cpp : 实现文件//#include "stdafx.h"#include "DrawRect.h"#include "DrawRectDlg.h"#include "afxdialogex.h"#ifdef _DEBUG#define new DEBUG_NEW#endif// 用于应用程序“关于”菜单项的 CAboutDlg 对话框class CAboutDlg : public CDialogEx{public:CAboutDlg();// 对话框数据enum { IDD = IDD_ABOUTBOX };protected:virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持// 实现protected:DECLARE_MESSAGE_MAP()};CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD){}void CAboutDlg::DoDataExchange(CDataExchange* pDX){CDialogEx::DoDataExchange(pDX);}BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)END_MESSAGE_MAP()// CDrawRectDlg 对话框CDrawRectDlg::CDrawRectDlg(CWnd* pParent /*=NULL*/): CDialogEx(CDrawRectDlg::IDD, pParent), m_ptbegin(0, 0), m_ptEnd(0, 0), m_blBtnDown(FALSE){m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);}void CDrawRectDlg::DoDataExchange(CDataExchange* pDX){CDialogEx::DoDataExchange(pDX);}BEGIN_MESSAGE_MAP(CDrawRectDlg, CDialogEx)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_WM_LBUTTONDOWN()ON_WM_LBUTTONUP()ON_WM_MOUSEMOVE()END_MESSAGE_MAP()// CDrawRectDlg 消息处理程序BOOL CDrawRectDlg::OnInitDialog(){CDialogEx::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: 在此添加额外的初始化代码return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE}void CDrawRectDlg::OnSysCommand(UINT nID, LPARAM lParam){if ((nID & 0xFFF0) == IDM_ABOUTBOX){CAboutDlg dlgAbout;dlgAbout.DoModal();}else{CDialogEx::OnSysCommand(nID, lParam);}}// 如果向对话框添加最小化按钮,则需要下面的代码//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,//  这将由框架自动完成。void CDrawRectDlg::OnPaint(){if (IsIconic()){CPaintDC dc(this); // 用于绘制的设备上下文SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);// 使图标在工作区矩形中居中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;// 绘制图标dc.DrawIcon(x, y, m_hIcon);}else{CPaintDC dc(this);CRect rc(m_ptbegin, m_ptEnd);rc.NormalizeRect();dc.Rectangle(&rc);CDialogEx::OnPaint();}}//当用户拖动最小化窗口时系统调用此函数取得光标//显示。HCURSOR CDrawRectDlg::OnQueryDragIcon(){return static_cast<HCURSOR>(m_hIcon);}void CDrawRectDlg::OnLButtonDown(UINT nFlags, CPoint point){// TODO: 在此添加消息处理程序代码和/或调用默认值m_ptbegin = point;m_blBtnDown = TRUE;CDC* pDC = GetDC();CRect rcClient;GetClientRect(&rcClient);CBitmap oBitmap;oBitmap.CreateCompatibleBitmap(pDC, rcClient.Width(), rcClient.Height());if (m_dcMemory.m_hDC != NULL){m_dcMemory.DeleteDC();}m_dcMemory.CreateCompatibleDC(pDC);m_dcMemory.SelectObject(&oBitmap);m_dcMemory.BitBlt(0, 0, rcClient.Width(), rcClient.Height(), pDC, 0, 0, SRCCOPY);oBitmap.DeleteObject();ReleaseDC(pDC);CDialogEx::OnLButtonDown(nFlags, point);}void CDrawRectDlg::OnLButtonUp(UINT nFlags, CPoint point){// TODO: 在此添加消息处理程序代码和/或调用默认值m_ptEnd = point;m_blBtnDown = FALSE;m_dcMemory.DeleteDC();Invalidate();CDialogEx::OnLButtonUp(nFlags, point);}void CDrawRectDlg::OnMouseMove(UINT nFlags, CPoint point){// TODO: 在此添加消息处理程序代码和/或调用默认值if (m_blBtnDown){CDC* pDC = GetDC();CRect rcClient;GetClientRect(&rcClient);pDC->BitBlt(0, 0, rcClient.Width(), rcClient.Height(), &m_dcMemory, 0, 0, SRCCOPY);CRect rc(m_ptbegin, point);rc.NormalizeRect();pDC->Rectangle(&rc);ReleaseDC(pDC);}CDialogEx::OnMouseMove(nFlags, point);}

3、源码:http://download.csdn.net/detail/wwkaven/8097101


GDI+版:


4、GDI_Plus_DrawRectDlg.h

// GDI_Plus_DrawRectDlg.h : 头文件//#pragma once#include "gdiplus.h"  #pragma comment(lib, "gdiplus.lib")  using namespace Gdiplus;  // CGDI_Plus_DrawRectDlg 对话框class CGDI_Plus_DrawRectDlg : public CDialogEx{// 构造public:CGDI_Plus_DrawRectDlg(CWnd* pParent = NULL);// 标准构造函数// 对话框数据enum { IDD = IDD_GDI_PLUS_DRAWRECT_DIALOG };protected:virtual void DoDataExchange(CDataExchange* pDX);// DDX/DDV 支持// 实现protected:HICON m_hIcon;ULONG_PTR m_gdiplusToken; Point m_ptBegin;Point m_ptEnd;BOOL m_bLBtnDown;CDC m_dcMemory;// 生成的消息映射函数virtual BOOL OnInitDialog();afx_msg void OnSysCommand(UINT nID, LPARAM lParam);afx_msg void OnPaint();afx_msg HCURSOR OnQueryDragIcon();DECLARE_MESSAGE_MAP()public:afx_msg void OnDestroy();afx_msg void OnLButtonDown(UINT nFlags, CPoint point);afx_msg void OnLButtonUp(UINT nFlags, CPoint point);afx_msg BOOL OnEraseBkgnd(CDC* pDC);afx_msg void OnMouseMove(UINT nFlags, CPoint point);};

5、GDI_Plus_DrawRectDlg.cpp

// GDI_Plus_DrawRectDlg.cpp : 实现文件//#include "stdafx.h"#include "GDI_Plus_DrawRect.h"#include "GDI_Plus_DrawRectDlg.h"#include "afxdialogex.h"#ifdef _DEBUG#define new DEBUG_NEW#endif// 用于应用程序“关于”菜单项的 CAboutDlg 对话框class CAboutDlg : public CDialogEx{public:CAboutDlg();// 对话框数据enum { IDD = IDD_ABOUTBOX };protected:virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持// 实现protected:DECLARE_MESSAGE_MAP()};CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD){}void CAboutDlg::DoDataExchange(CDataExchange* pDX){CDialogEx::DoDataExchange(pDX);}BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)END_MESSAGE_MAP()// CGDI_Plus_DrawRectDlg 对话框CGDI_Plus_DrawRectDlg::CGDI_Plus_DrawRectDlg(CWnd* pParent /*=NULL*/): CDialogEx(CGDI_Plus_DrawRectDlg::IDD, pParent), m_bLBtnDown(FALSE){m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);// init gdi+GdiplusStartupInput input;  GdiplusStartup(&m_gdiplusToken, &input, NULL);m_ptBegin = Point(0, 0);m_ptEnd = Point(0, 0);}void CGDI_Plus_DrawRectDlg::DoDataExchange(CDataExchange* pDX){CDialogEx::DoDataExchange(pDX);}BEGIN_MESSAGE_MAP(CGDI_Plus_DrawRectDlg, CDialogEx)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_WM_DESTROY()ON_WM_LBUTTONDOWN()ON_WM_LBUTTONUP()ON_WM_ERASEBKGND()ON_WM_MOUSEMOVE()END_MESSAGE_MAP()// CGDI_Plus_DrawRectDlg 消息处理程序BOOL CGDI_Plus_DrawRectDlg::OnInitDialog(){CDialogEx::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: 在此添加额外的初始化代码return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE}void CGDI_Plus_DrawRectDlg::OnSysCommand(UINT nID, LPARAM lParam){if ((nID & 0xFFF0) == IDM_ABOUTBOX){CAboutDlg dlgAbout;dlgAbout.DoModal();}else{CDialogEx::OnSysCommand(nID, lParam);}}// 如果向对话框添加最小化按钮,则需要下面的代码//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,//  这将由框架自动完成。void CGDI_Plus_DrawRectDlg::OnPaint(){if (IsIconic()){CPaintDC dc(this); // 用于绘制的设备上下文SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);// 使图标在工作区矩形中居中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;// 绘制图标dc.DrawIcon(x, y, m_hIcon);}else{CPaintDC dc(this);CRect rc(m_ptBegin.X, m_ptBegin.Y, m_ptEnd.X, m_ptEnd.Y);rc.NormalizeRect();Pen pen(Color::Red, 2);Graphics graphics(dc.m_hDC);graphics.DrawRectangle(&pen, Rect(rc.left, rc.top, rc.Width(), rc.Height()));CDialogEx::OnPaint();}}//当用户拖动最小化窗口时系统调用此函数取得光标//显示。HCURSOR CGDI_Plus_DrawRectDlg::OnQueryDragIcon(){return static_cast<HCURSOR>(m_hIcon);}void CGDI_Plus_DrawRectDlg::OnDestroy(){CDialogEx::OnDestroy();// TODO: 在此处添加消息处理程序代码GdiplusShutdown(m_gdiplusToken);  }void CGDI_Plus_DrawRectDlg::OnLButtonDown(UINT nFlags, CPoint point){// TODO: 在此添加消息处理程序代码和/或调用默认值m_ptBegin = Point(point.x, point.y);m_bLBtnDown = TRUE;CDC* pDC = GetDC();CRect rcClient;GetClientRect(&rcClient);CBitmap oBitmap;oBitmap.CreateCompatibleBitmap(pDC, rcClient.Width(), rcClient.Height());m_dcMemory.CreateCompatibleDC(pDC);m_dcMemory.SelectObject(&oBitmap);m_dcMemory.BitBlt(0, 0, rcClient.Width(), rcClient.Height(), pDC, 0, 0, SRCCOPY);oBitmap.DeleteObject();ReleaseDC(pDC);CDialogEx::OnLButtonDown(nFlags, point);}void CGDI_Plus_DrawRectDlg::OnLButtonUp(UINT nFlags, CPoint point){// TODO: 在此添加消息处理程序代码和/或调用默认值m_ptEnd = Point(point.x, point.y);m_bLBtnDown = FALSE;m_dcMemory.DeleteDC();Invalidate();CDialogEx::OnLButtonUp(nFlags, point);}BOOL CGDI_Plus_DrawRectDlg::OnEraseBkgnd(CDC* pDC){// TODO: 在此添加消息处理程序代码和/或调用默认值return TRUE;//return CDialogEx::OnEraseBkgnd(pDC);}void CGDI_Plus_DrawRectDlg::OnMouseMove(UINT nFlags, CPoint point){// TODO: 在此添加消息处理程序代码和/或调用默认值if (m_bLBtnDown){CDC* pDC = GetDC();CRect rcClient;GetClientRect(&rcClient);pDC->BitBlt(0, 0, rcClient.Width(), rcClient.Height(), &m_dcMemory, 0, 0, SRCCOPY);CRect rc(m_ptBegin.X, m_ptBegin.Y, point.x, point.y);rc.NormalizeRect();Pen pen(Color::Red, 2);Graphics graphics(pDC->m_hDC);graphics.DrawRectangle(&pen, Rect(rc.left, rc.top, rc.Width(), rc.Height()));ReleaseDC(pDC);}CDialogEx::OnMouseMove(nFlags, point);}

6、源码:http://download.csdn.net/detail/wwkaven/8097445



0 0