開始學習VC++MFC程式了!了解了一些如何在視窗上面繪畫的功能,突然聯想到平時在使用一些繪圖軟體或其它涉及到畫線的程式的一個小功能:需要畫一條直線時,總是在滑鼠左鍵按下時,開始畫線;滑鼠拖動時,始終顯示滑鼠左鍵按下時的起點與滑鼠最新位置之間的連線。這樣,使用者可以清楚地看到自己準備要畫的線的位置,直到連線剛好是自己想要的位置時,滑鼠左鍵釋放,連線完成。
我想這個功能還是比較容易實作的,唯一的難點在于如何擦除滑鼠拖動時之前繪制的連線,隻保留最後的連線即可。至于如何找到之前連線的位置(起點與終點),這個非常容易:增加一個變量,在滑鼠移動時用它始終儲存滑鼠目前位置即可。
步驟:
1、設定三個私有變量(在要繪畫的視窗類中添加)
private:
CPoint m_originCPoint;//儲存滑鼠左鍵按下時的滑鼠位置
CPoint m_preCPoint;//儲存滑鼠拖動(即滑鼠左鍵按下并移動)時的位置并不斷更新。
bool MouseDownFlag;//滑鼠左鍵按下的标志。
2、初始化變量:
在要繪畫的視窗類的構造函數中初始化變量:
m_originCPoint.x =m_originCPoint.y= 0;
m_preCPoint.x = m_preCPoint.y = 0;
MouseDownFlag = false;
3、建立滑鼠左鍵按下消息處理函數,并添加以下代碼:
void CfirstMAppView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息處理程式代碼和/或調用預設值
m_originCPoint =m_preCPoint= point;//把滑鼠左鍵按下時的位置賦給兩個變量
MouseDownFlag = true;//更新滑鼠按下标志
CView::OnLButtonDown(nFlags, point);
}
4、添加滑鼠左鍵釋放消息處理函數,并添加如下代碼:
void CfirstMAppView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息處理程式代碼和/或調用預設值
MouseDownFlag = false;//恢複标志為滑鼠釋放狀态
CView::OnLButtonUp(nFlags, point);
}
5、添加滑鼠移動消息處理函數,并添加以下代碼:
void CfirstMAppView::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息處理程式代碼和/或調用預設值
if (MouseDownFlag) {
//擷取DC
CClientDC dc(this);
//設定畫筆及其參數(線型,寬度,顔色)
CPen pen(PS_SOLID, 1, RGB(255, 0, 0));
CPen *oldpen=dc.SelectObject(&pen);
//改變畫圖模式并在該模式下把之前已經畫的線重新畫一遍,實作“擦除”的效果。
//此處應為R2_NOT,原文為R2_MERGEPENNOT是錯誤的!
int oldmode=SetROP2(dc, R2_NOT);
dc.MoveTo(m_originCPoint);
dc.LineTo(m_preCPoint);
//恢複原來的模式
SetROP2(dc,oldmode);
————————————————————————————————————————
//經檢查,下面這樣畫線是有問題的:這是在MouseMove狀态下,不應該把非螢幕顔色畫線。
//因為一旦螢幕顔色與視窗背景色(不一定是視窗預定的畫刷顔色)不一緻的話,它的反色就
//不是螢幕背景色了,是别外一個顔色。
//解決方法:在MouseMove狀态,始終用螢幕的反色畫線。最終顯示的線應該放在MouseUp
//狀态下按照指定的畫筆顔色畫線就可以了。研究以下圖檔主明白了:
//上面圖檔中的畫線才是正确的。把滑鼠移動時的畫線與最終線要分開。移動時的畫線始終用螢幕顔色的反色來畫線,最終線根據程式的需要自己設定。
//在正常的模式下,畫出目前滑鼠位置與初始點(滑鼠左鍵按下的位置)之間的連線
dc.MoveTo(m_originCPoint);
dc.LineTo(point);
//恢複畫筆
dc.SelectObject(oldpen);
//更新前一個點的位置為目前滑鼠位置
m_preCPoint = point;
——————————————————————————————————————————
}
CView::OnMouseMove(nFlags, point);
}