1. View类总是覆盖在CMainFrm框架窗口之上的.所以框架窗口无法对WM_LBUTTONDOWN消息做出响应.
2. 添加WM_LBUTONDOWN后:
1) 在DrawView.h中就申明了消息响应函数 OnLButtonDown
afx_msg是一个宏,指明后面的函数是消息响应函数
protected:
//{{AFX_MSG(CDrawView) //注释宏
afx_msg void OnLButtonDown(UINT nFlags, CPoint point); //消息响应函数原型的声明.
//}}AFX_MSG
2)在DrawView.cpp中,自动加入了消息映射宏ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONDOWN()在Message map tables for Windows messages消息映射表中定义的宏,
关联消息响应函数 CDrawView::OnLButtonDown(UINT nFlags, CPoint point)
BEGIN_MESSAGE_MAP(CDrawView, CView)
//{{AFX_MSG_MAP(CDrawView)
ON_WM_LBUTTONDOWN()
//}}AFX_MSG_MAP
------
// DrawView.cpp : implementation of the CDrawView class
//
#include "stdafx.h"
#include "Draw.h"
#include "DrawDoc.h"
#include "DrawView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// CDrawView
IMPLEMENT_DYNCREATE(CDrawView, CView)
BEGIN_MESSAGE_MAP(CDrawView, CView)
//{{AFX_MSG_MAP(CDrawView)
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()
/
// CDrawView construction/destruction
CDrawView::CDrawView()
{
// TODO: add construction code here
m_ptOriginal =0;
m_bDraw = false; //实时连续画线鼠标左键按下状态
m_ptOld =0; // 画扇形
}
CDrawView::~CDrawView()
{
}
BOOL CDrawView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
/
// CDrawView drawing
void CDrawView::OnDraw(CDC* pDC)
{
CDrawDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
}
/
// CDrawView printing
BOOL CDrawView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CDrawView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CDrawView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/
// CDrawView diagnostics
#ifdef _DEBUG
void CDrawView::AssertValid() const
{
CView::AssertValid();
}
void CDrawView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CDrawDoc* CDrawView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDrawDoc)));
return (CDrawDoc*)m_pDocument;
}
#endif //_DEBUG
/
// CDrawView message handlers
void CDrawView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
// MessageBox("View clicked");
m_ptOriginal = point;
m_bDraw = true;
m_ptOld = point; //鼠标左键摁下是获得当前鼠标的point,画鼠标轨迹时用
CView::OnLButtonDown(nFlags, point);
}
void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
/*
HDC hdc;
hdc = ::GetDC(m_hWnd);
MoveToEx(hdc,m_ptOriginal.x,m_ptOriginal.y,NULL);
LineTo(hdc,point.x,point.y);
::ReleaseDC(m_hWnd,hdc);
*/
/*
CDC* PDC = GetDC();
PDC->MoveTo(m_ptOriginal);
PDC->LineTo(point);
ReleaseDC(PDC);
*/
// CClientDC dc(this);
// CClientDC dc(GetParent());
//CWindowDC dc(this);
// CWindowDC dc(GetParent());
// CWindowDC dc(GetDesktopWindow());
// dc.MoveTo(m_ptOriginal);
// dc.LineTo(point);
/*
CPen pen(0,1,RGB(255,0,0));
CClientDC dc(this);
CPen* pPen=dc.SelectObject(&pen); //保存原有的笔
dc.MoveTo(m_ptOriginal);
dc.LineTo(point);
dc.SelectObject(pPen); //恢复原有的笔
*/
/* CBrush brush(RGB(0,255,0));
CBitmap bitmap;
bitmap.LoadBitmap(IDB_BITMAP1);
CClientDC dc(this);
CBrush brush(&bitmap);
dc.FillRect(CRect(m_ptOriginal,point),&brush);
*/
/* 画透明的矩形,矩形不会彼此覆盖
CClientDC dc(this);
// static CBrush* PASCAL FromHandle( HBRUSH hBrush ); 静态成员函数的直接用类来调用
CBrush *pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));//创建透明brush:空画刷
CBrush *pOldBursh = dc.SelectObject(pBrush); // 返回值是原有的画刷,把它保存原有的画刷到pOldBrush
dc.Rectangle(CRect(m_ptOriginal,point));//画矩形
dc.SelectObject(pOldBursh); // 画完矩形后恢复原有的画刷
*/
m_bDraw = false;
// ---
CView::OnLButtonUp(nFlags, point);
}
// 响应鼠标移动消息来连续线实时画线
/*
只要鼠标左键按一直按住的状态, 就一直画; 鼠标左键松开 就不画线
在CDrawView中增加一个成员变量bool类型的:m_bDraw
在CDrawView类的构造函数CDrawView()中初始化为false
在 OnLButtonDown消息响应函数中把m_bDraw置为true
在 OnLButtonUp消息响应函数中把m_bDraw置为false
*/
void CDrawView::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
//-----------------连续线实时画线
/*
CClientDC dc(this);
CPen pen(PS_SOLID,1,RGB(0,0,255));
CPen *pOldPen=dc.SelectObject(&pen); //把pen选入到dc中,并把dc的原有的pen保存到pOldPen中
if(m_bDraw==true)
{
dc.MoveTo(m_ptOriginal);
dc.LineTo(point);
m_ptOriginal = point; // 把当前位置作为新的起始点
}
dc.SelectObject(pOldPen);//从pOldPen中恢复dc原本的pen属性.
*/
// ------------- 画扇形
/*
在鼠标左键摁下是记录鼠标的当下位置point,也就是在OnLButtonDown消息响应函数中m_ptOriginal = point
画扇形必定是有个点是圆心,不动的,思路就是把鼠标点击左键时的点作为圆心,且不更新它的值(除非鼠标再次点击左键)
每次moveto(圆心) ---> lineto(当下point),这样就形成了扇形
*/
/*
CClientDC dc(this);
CPen pen(PS_SOLID,1,RGB(0,0,255));
CPen *pOldPen=dc.SelectObject(&pen);
if(m_bDraw==true)
{
//第一次响应OnMouseMove消息时: 按下了鼠标左键,取得圆心,实际上是画了一个点,因为m_ptOriginal = point
dc.MoveTo(m_ptOriginal);
dc.LineTo(point);
}
dc.SelectObject(pOldPen);
*/
// ------------- 画扇形,并把鼠标的轨迹连起来
/*
增加一个CDrawView类的私有成员变量m_ptOld 并在构造函数中CDrawView()中初始化为0
鼠标的轨迹其实就是 m_ptOld到鼠标的当下的point
*/
CClientDC dc(this);
CPen pen(PS_SOLID,1,RGB(0,0,255));
CPen *pOldPen=dc.SelectObject(&pen);
if(m_bDraw==true)
{
//画扇形
dc.MoveTo(m_ptOriginal);
dc.LineTo(point);
// 画鼠标轨迹
dc.MoveTo(m_ptOld);
dc.LineTo(point);
m_ptOld = point; //更新m_ptOld 为当下鼠标的位置
}
dc.SelectObject(pOldPen);
// 最后一个知识点 设置绘画模式:用函数SetROP2
/*
dc.SetROP2(R2_BLACK)
dc.MoveTo(m_ptOriginal);
dc.LineTo(point);
*/
// ---
CView::OnMouseMove(nFlags, point);
}
-----
-----