用不同方法在不同視窗中繪製線條
void CMyView::OnLButtonUp(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default //MessageBox("WM_LBUTTONUP"); // // 1:利用SDK全域函數實現畫線功能 // HDC hdc; hdc = ::GetDC(m_hWnd); ::MoveToEx(hdc,m_ptOld.x,m_ptOld.y,NULL); ::LineTo(hdc,point.x,point.y); ::ReleaseDC(m_hWnd,hdc); // 2:利用MFC的CDC類實現畫線功能 // CDC *pDC = GetDC(); pDC->MoveTo(m_ptOld); pDC->LineTo(point); ReleaseDC(pDC); // 3:利用MFC的CClientDC類實現畫線功能 // CClientDC dc(this); dc.MoveTo(m_ptOld); dc.LineTo(point); // 4:利用MFC的CWindowDC類實現畫線功能 // CWindowDC dc_2(this); dc_2.MoveTo(m_ptOld); dc_2.LineTo(point); // 5:利用MFC的CWindowDC類在父視窗中實現畫線功能 // CWindowDC dc_3(GetParent()); dc_3.MoveTo(m_ptOld); dc_3.LineTo(point); // 6:利用MFC的CWindowDC類在桌面視窗中實現畫線功能 // CWindowDC dc_4(GetDesktopWindow()); dc_4.MoveTo(m_ptOld); dc_4.LineTo(point); CView::OnLButtonUp(nFlags, point);}
現在來分析上面的代碼。
1:首先想想要完成畫線這樣一個功能該怎麼做呢?
從按下滑鼠左鍵開始,移動滑鼠至另一位置,鬆開滑鼠左鍵,整個操作過程就是要PC實現畫線的充分條件;PC處理完成後通過顯示屏展現結果。到此為止,我們接觸的全是硬體(操作的滑鼠、看到的螢幕)。難道我們直接和硬體打交道嗎?NO!和硬體打交道的是OS,我們只要和OS打交道就行了,OS就是人與機器之間的翻譯員。
2:上面代碼就是跟OS交流的語言,告訴OS我要幹什麼,怎麼幹。然後OS翻譯我們的意思給機器,之後機器就把事情幹好了。
3:我要作業系統這麼做。
// 1:利用SDK全域函數實現畫線功能 // HDC hdc;//裝置上下文控制代碼 hdc = ::GetDC(m_hWnd);//把視窗和裝置上下文控制代碼關聯起來 ::MoveToEx(hdc,m_ptOld.x,m_ptOld.y,NULL);//初始化點的位置 ::LineTo(hdc,point.x,point.y);//移動到這個點 ::ReleaseDC(m_hWnd,hdc);//釋放控制代碼資源
OS把上面的代碼翻譯成機器代碼給機器看,機器一看,哦,這樣哦。
4:上面代碼中2到6的方法都是依據方法1為基礎的。MFC把API函數封裝到類中,就造出了CDC,CClientDC...等等這樣的類。它們工作原理都差不多,如下:在建構函式中完成視窗與裝置上下文控制代碼的關聯工作,在MoveTo中調用API函數MoveTo,在LineTo函數中調用API函數LineTo,具體情況請看原始碼。
void CMyView::OnLButtonUp(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default // 裝置描述表(Device Context,DC)是一個資訊結構體,包含物理輸出裝置及其驅動程式。 // 在Windows平台下,所有的的圖形操作都是通過它完成。 //MessageBox("WM_LBUTTONUP"); // // 繪製彩色線條 // //CPen pen(PS_SOLID,10,RGB(255,0,0));// PS_SOLID實心 CPen pen(PS_DASH,1,RGB(255,0,0));// PS_DASH虛線,寬度<=1時才有效。 CClientDC dc(this); CPen *pOldPen = dc.SelectObject(&pen); dc.MoveTo(m_ptOld); dc.LineTo(point); dc.SelectObject(pOldPen); // 使用畫刷繪圖 // CBrush brush(RGB(0,255,0));// 共有4個建構函式 CBrush *oldBrush; oldBrush = dc.SelectObject(&brush);// 先把自己定義的畫刷選到裝置描述表 dc.FillRect(CRect(m_ptOld,point),NULL);// 用自己定義的畫刷 //dc.FillRect(CRect(m_ptOld,point),&brush);// 指定畫刷 //dc.FillRect(CRect(m_ptOld,point),NULL);// 系統最初預設的畫刷顏色是白色 // 位元影像畫刷 // CBitmap bitmap; bitmap.LoadBitmap(IDB_BITMAP1); CBrush brush_2(&bitmap); dc.FillRect(CRect(m_ptOld,point),&brush_2); // 透明畫刷 // dc.Rectangle(CRect(m_ptOld,point)); // 畫刷控制代碼轉換為畫刷對象 // CBrush *pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH)); oldBrush = dc.SelectObject(pBrush); dc.Rectangle(CRect(m_ptOld,point)); m_bDraw = FALSE; CView::OnLButtonUp(nFlags, point);}
void CMyView::OnMouseMove(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default //MessageBox("WM_MOUSEMOVE"); // 繪製連續線條 CClientDC dc(this); if (TRUE == m_bDraw) { dc.MoveTo(m_ptOld); dc.LineTo(point); m_ptOld = point; } CView::OnMouseMove(nFlags, point);}
void CMyView::OnLButtonUp(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default // 裝置描述表(Device Context,DC)是一個資訊結構體,包含物理輸出裝置及其驅動程式。 // 在Windows平台下,所有的的圖形操作都是通過它完成。 //MessageBox("WM_LBUTTONUP"); // // 繪製彩色線條 // //CPen pen(PS_SOLID,10,RGB(255,0,0));// PS_SOLID實心 CPen pen(PS_DASH,1,RGB(255,0,0));// PS_DASH虛線,寬度<=1時才有效。 CClientDC dc(this); CPen *pOldPen = dc.SelectObject(&pen); dc.MoveTo(m_ptOld); dc.LineTo(point); dc.SelectObject(pOldPen); // 使用畫刷繪圖 // CBrush brush(RGB(0,255,0));// 共有4個建構函式 CBrush *oldBrush; oldBrush = dc.SelectObject(&brush);// 先把自己定義的畫刷選到裝置描述表 dc.FillRect(CRect(m_ptOld,point),NULL);// 用自己定義的畫刷 //dc.FillRect(CRect(m_ptOld,point),&brush);// 指定畫刷 //dc.FillRect(CRect(m_ptOld,point),NULL);// 系統最初預設的畫刷顏色是白色 // 位元影像畫刷 // CBitmap bitmap; bitmap.LoadBitmap(IDB_BITMAP1); CBrush brush_2(&bitmap); dc.FillRect(CRect(m_ptOld,point),&brush_2); // 透明畫刷 // dc.Rectangle(CRect(m_ptOld,point)); // 畫刷控制代碼轉換為畫刷對象 // CBrush *pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH)); oldBrush = dc.SelectObject(pBrush); dc.Rectangle(CRect(m_ptOld,point)); m_bDraw = FALSE; CView::OnLButtonUp(nFlags, point);}
void CMyView::OnMouseMove(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default //MessageBox("WM_MOUSEMOVE"); // 繪製連續線條 CClientDC dc(this); if (TRUE == m_bDraw) { dc.MoveTo(m_ptOld); dc.LineTo(point); m_ptOld = point; } CView::OnMouseMove(nFlags, point);}