遇到的問題:
- 鼠標點擊會截斷鼠標雙擊的事件,無法保存橢圓的數據。也就是說雙擊執行的過程是OnLButtonDown,OnLButtonUp,OnLButtonDblClk,OnLButtonUp。並不是想象中的直接執行OnLButtonDblClk,那么如果在OnLButtonDown中定義起始點,OnLButtonUp中定義終點,橢圓可以直接畫出,但是雙擊時,會先執行OnLButtonDown,OnLButtonUp那么起點和終點就會被重新覆蓋,且覆蓋后的點的坐標都一樣,然后才執行OnLButtonDblClk,此時,起點和終點相同,就沒法再畫橢圓,而且最后還會再執行一次OnLButtonUp。
那么如何解決問題?
剛開始百度發現他們是通過判斷鼠標兩次點擊的時間差是否小於系統定義的時間差500,鼠標雙擊會先執行一次OnLButtonDown然后在第二次的OnLButtonDown來判斷是不是鼠標在雙擊,然而這種方法還是會將原始數據覆蓋,無法保存那條線的數據。
后來我在睡覺前突然想到可以通過數組來保存原始數據,通過數組的下標來控制鼠標雙擊時的數據保存到另一個數組中,以避免數據的覆蓋,於是寫出上面的程序。
- MFC中數據的查看
MFC中如何查看數據,剛開始打算直接使用TextOut來直接輸出執行過程中的數據,但是,它只支持CString類型,遇到int型還要sprintf轉格式,太麻煩,而且也不能實時刷新,顯示的范圍還有限。
使用控制台輸出,可是MFC執行時 ,連控制台的界面都沒見。
只能使用文件流來輸出信息。
實現思路:
1通過兩點畫橢圓
2.以這將這兩點組合到一起,也就是可以看做一條線決定了一個橢圓。每畫一個橢圓就往線的數組里記錄一次。
3.獲取鼠標雙擊的坐標,並判斷這點是否在橢圓內部,如果在內部,則重畫橢圓(帶填充)並將線的數組清空,如果不在,則繼續雙擊時,線的數組的下標不增加,重新覆蓋數據,然后再判斷這個點是否在橢圓內。
程序:
全局變量
1 CPoint start_p,end_p; 2 bool flag=true;//雙擊時的點是否在橢圓內 3 ofstream myfile; 4 int i=0;//用來計數線的數組 5 6 class Line{ 7 public : 8 CPoint p1,p2; 9 Line(){ 10 p1.SetPoint(0,0); 11 p2.SetPoint(0,0); 12 } 13 void set_p1( CPoint a1){ 14 p1.SetPoint(a1.x,a1.y); 15 } 16 void set_p2( CPoint a2){ 17 p2.SetPoint(a2.x,a2.y); 18 } 19 20 }; 21 22 Line l[30];
1 // CMy91View 消息處理程序
2 3 4 void CMy91View::OnLButtonDown(UINT nFlags, CPoint point) 5 { 6 // TODO: ÔÚ´ËÌí¼ÓÏûÏ¢´¦Àí³ÌÐò´úÂëºÍ/»òµ÷ÓÃĬÈÏÖµ 7 8 CView::OnLButtonDown(nFlags, point); 9 10 11 //單擊 12 start_p=point; 13 l[i].set_p1(point); 14 15 myfile.open("1.txt",ios::app); 16 myfile<<"單擊OnLButtonDown:"<<endl; 17 myfile<<"l:"<<i<<endl; 18 myfile<<"p1:("<<l[i].p1.x<<","<<l[i].p1.y<<")"<<endl; 19 myfile<<"p2:("<<l[i].p2.x<<","<<l[i].p2.y<<")"<<endl; 20 myfile<<endl<<endl; 21 myfile.close(); 22 23 } 24 25 26 void CMy91View::OnLButtonUp(UINT nFlags, CPoint point) 27 { 28 // TODO: ÔÚ´ËÌí¼ÓÏûÏ¢´¦Àí³ÌÐò´úÂëºÍ/»òµ÷ÓÃĬÈÏÖµ 29 30 CView::OnLButtonUp(nFlags, point); 31 32 if(1){ 33 end_p=point; 34 l[i].set_p2(point); 35 36 CClientDC dc(this); 37 dc.Ellipse(start_p.x,start_p.y,end_p.x,end_p.y); 38 39 myfile.open("1.txt",ios::app); 40 myfile<<"單擊OnLButtonUp:"<<endl; 41 myfile<<"l:"<<i<<endl; 42 myfile<<"p1:("<<l[i].p1.x<<","<<l[i].p1.y<<")"<<endl; 43 myfile<<"p2:("<<l[i].p2.x<<","<<l[i].p2.y<<")"<<endl; 44 myfile<<endl<<endl; 45 myfile.close(); 46 47 //判斷是不是雙擊,雙擊后會讓下一個坐標的p2點不為0,但p1點為0; 48 if(l[i].p1.x!=0&&l[i].p1.y!=0){ 49 i++;//增加橢圓 50 }else{ 51 if(i>0&&!flag){ 52 i--;//不在圓內雙擊,計數減1,,重新計數 53 } 54 55 } 56 57 } 58 } 59 60 //判斷一個點是否在橢圓內部 61 bool in_Elliplse(CPoint p1,CPoint p2,CPoint p3){ 62 CPoint center((p1.x+p2.x)/2,(p1.y+p2.y)/2); 63 CPoint r(abs(p1.x-p2.x)/2,abs(p1.y-p2.y)); 64 CPoint p3_0(p3.x-center.x,p3.y-center.y); 65 66 if(r.x>r.y){ 67 double x=pow((double)p3_0.x,2)/pow((double)r.x,2); 68 double y=pow((double)p3_0.y,2)/pow((double)r.y,2); 69 if(x+y<=1){ 70 return true; 71 }else{ 72 return false; 73 } 74 }else{ 75 double x=pow((double)p3_0.y,2)/pow((double)r.x,2); 76 double y=pow((double)p3_0.x,2)/pow((double)r.y,2); 77 if(x+y<=1){ 78 return true; 79 }else{ 80 return false; 81 } 82 } 83 84 } 85 86 void CMy91View::OnLButtonDblClk(UINT nFlags, CPoint point) 87 { 88 // TODO: ÔÚ´ËÌí¼ÓÏûÏ¢´¦Àí³ÌÐò´úÂëºÍ/»òµ÷ÓÃĬÈÏÖµ 89 90 CView::OnLButtonDblClk(nFlags, point); 91 92 myfile.open("1.txt",ios::app); 93 myfile<<"雙擊"<<endl<<"OnLButtonDblClk:"<<endl; 94 myfile<<"l:"<<i<<endl; 95 myfile<<"p1:("<<l[i].p1.x<<","<<l[i].p1.y<<")"<<endl; 96 myfile<<"p2:("<<l[i].p2.x<<","<<l[i].p2.y<<")"<<endl; 97 myfile<<"l-1:"<<i-1<<endl; 98 myfile<<"p1:("<<l[i-1].p1.x<<","<<l[i-1].p1.y<<")"<<endl; 99 myfile<<"p2:("<<l[i-1].p2.x<<","<<l[i-1].p2.y<<")"<<endl; 100 myfile<<"l-2:"<<i-2<<endl; 101 myfile<<"p1:("<<l[i-2].p1.x<<","<<l[i-2].p1.y<<")"<<endl; 102 myfile<<"p2:("<<l[i-2].p2.x<<","<<l[i-2].p2.y<<")"<<endl; 103 myfile<<endl<<endl; 104 myfile.close(); 105 106 //填充 107 if(in_Elliplse(l[i-2].p1,l[i-2].p2,l[i-1].p1)){ 108 CBrush brush(RGB(0,255,0)); 109 CClientDC dc(this); 110 dc.SelectObject(&brush); 111 dc.Ellipse(l[i-2].p1.x,l[i-2].p1.y,l[i-2].p2.x,l[i-2].p2.y); 112 113 //重新計數 114 i=0; 115 116 //清空橢圓 117 for(int a=0;a<30;a++){ 118 CPoint p(0,0); 119 l[i].set_p1(p); 120 l[i].set_p2(p); 121 } 122 flag=true; 123 }else{ 124 flag=false; 125 } 126 127 128 }
數據分析:
使用文件流來輸出信息,如下:
在第一次鼠標按下再抬起時畫橢圓,然后橢圓內雙擊填充時的數據信息:
單擊OnLButtonDown:
l:0
p1:(270,94)
p2:(0,0)
單擊OnLButtonUp:
l:0
p1:(270,94)
p2:(488,222)
單擊OnLButtonDown:
l:1
p1:(391,176)
p2:(0,0)
單擊OnLButtonUp:
l:1
p1:(391,176)
p2:(391,176)
雙擊
OnLButtonDblClk:
l:2
p1:(0,0)
p2:(0,0)
l-1:1
p1:(391,176)
p2:(391,176)
l-2:0
p1:(270,94)
p2:(488,222)
單擊OnLButtonUp:
l:0
p1:(0,0)
p2:(391,176)
在第一次鼠標按下再抬起時畫橢圓,然后橢圓外雙擊(可以任意次)這里就一次,然后在橢圓內雙擊填充時的數據信息:
單擊OnLButtonDown:
l:0
p1:(335,85)
p2:(0,0)
單擊OnLButtonUp:
l:0
p1:(335,85)
p2:(601,197)
單擊OnLButtonDown:
l:1
p1:(397,284)
p2:(0,0)
單擊OnLButtonUp:
l:1
p1:(397,284)
p2:(397,284)
雙擊
OnLButtonDblClk:
l:2
p1:(0,0)
p2:(0,0)
l-1:1
p1:(397,284)
p2:(397,284)
l-2:0
p1:(335,85)
p2:(601,197)
單擊OnLButtonUp:
l:2
p1:(0,0)
p2:(397,284)
單擊OnLButtonDown:
l:1
p1:(423,141)
p2:(397,284)
單擊OnLButtonUp:
l:1
p1:(423,141)
p2:(423,140)
雙擊
OnLButtonDblClk:
l:2
p1:(0,0)
p2:(397,284)
l-1:1
p1:(423,141)
p2:(423,140)
l-2:0
p1:(335,85)
p2:(601,197)
單擊OnLButtonUp:
l:0
p1:(0,0)
p2:(423,140)
實驗結果:
程序的不足:
在程序只有雙擊填充時,線的數組才會清空,下標再次重0開始,如果用戶不雙擊,一直在畫橢圓,那么最多畫30個橢圓(這個數值可以任意修改),但這個數值不是無窮的。或許可以通過動態建立數組或者使用線性列表來解決。(如果有誰解決了,@我,大家一起進步)