轉VC繪製位元影像–BeginPaint()與GetDC()的區別

來源:互聯網
上載者:User
//========================================================================
//TITLE:
//    EVC繪製位元影像--BeginPaint()與GetDC()的區別
//AUTHOR:
//    norains
//DATE:
//    Tuesday  29-August-2006
//========================================================================
1.BeginPaint()和GetDC()
        在EVC中繪製位元影像比較方便,有不少現成的函數可供調用,我們所要注意的只是BeginPaint()或GetDC()的使用即可.
        因為代碼比較簡單,所以不做更多解釋.

        這是訊息迴圈函數:
        LRESULT CALLBACK MainWndProc(HWND hWnd,UINT wMsg,WPARAM wParam,LPARAM lParam)
        {
            ......
            
            switch(wMsg)
            {
                case WM_PAINT:
                        OnPaintMainWnd(hWnd,wMsg,wParam,lParam);
                        break;
                
                ......                
            
            }
            return DefWindowProc(hWnd,wMsg,wParam,lParam);
            
            ......
            
        }
        
        響應WM_PAINT訊息的函數,在這裡進行位元影像的繪製:
        LRESULT OnPaintMainWnd(HWND hWnd,UINT wMsg,WPARAM wParam,LPARAM lParam)
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd,&ps);
            //Create a DC that matches the device
            HDC hdcMem = CreateCompatibleDC(hdc);
            //Load the bitmap
            HANDLE hBmp= LoadImage(g_hInst_MainWnd,MAKEINTRESOURCE(IDB_MAINWND),IMAGE_BITMAP,0,0,0);
            //Select the bitmap into to the compatible device context
            HGDIOBJ hOldSel = SelectObject(hdcMem,hBmp);
            //Get the bitmap dimensions from the bitmap
            BITMAP bmp;
            GetObject(hBmp,sizeof(BITMAP),&bmp);
            //Get the window area
            RECT rc;
            GetClientRect(hWnd,&rc);
            //Copy the bitmap image from the memory DC to the screen DC
            BitBlt(hdc,rc.left,rc.top,bmp.bmWidth,bmp.bmHeight,hdcMem,0,0,SRCCOPY);
            //Restore original bitmap selection and destroy the memory DC
            SelectObject(hdcMem,hOldSel);    
            DeleteDC(hdcMem);
            EndPaint(hWnd,&ps);
            return 0;
        }

        我們都知道BeginPaint()和EndPaint()需要配套使用,並且這兩個函數也只能用在WM_PAINT訊息的相應函數當中.如果我們在WM_PAINT的響應函數中將以上兩個繪製函數相應替換為GetDC()和ReleaseDC()會有什麼結果呢?
        即:
        HDC hdc = BeginPaint(hWnd,&ps);    -->   HDC hdc = GetDC(hWnd);
        EndPaint(hWnd,&ps);                -->   ReleaseDC(hWnd,hdc);
        
        編譯並運行程式,我們發現視窗一片空白,好像沒有繪製位元影像.但其實不盡然,我們採用單步調試,可以發現其實位元影像已經繪製出來,只不過又被背景顏色抹掉了.由此可知,如果需要使用GetDC(),我們對訊息迴圈函數必須要加上對WM_ERASEBKGND的處理:
        LRESULT CALLBACK MainWndProc(HWND hWnd,UINT wMsg,WPARAM wParam,LPARAM lParam)
        {
            switch(wMsg)
            {
                case WM_PAINT:
                        OnPaintMainWnd(hWnd,wMsg,wParam,lParam);
                        break;
                case WM_ERASEBKGND    
                        return 0;            
            }
            return DefWindowProc(hWnd,wMsg,wParam,lParam);
        }
        只要系統不對WM_ERASEBKGND進行預設處理,我們用GetDC()替代BeginPaint()就可以正常使用.
        
        至此我們可以看出BeginPaint(),EndPaint()和GetDC(),ReleaseDC()的區別.前一對只能用在WM_PAINT響應函數中,並且繪製背景時不會被抹掉;後一對隨處可用,但如果用在WM_PAINT響應函數中,那麼接下來將會被WM_ERASEBKGND訊息的響應函數的背景繪製給抹掉.
        
        
        
        
2.繪圖閃爍問題        
    有時候我們大量繪製螢幕時,可能會出現螢幕閃爍問題,這時候可以採用雙緩衝的做法.步驟首先是建立一個記憶體DC,然後往記憶體DC中繪圖,最後把記憶體DC的內容複寫到顯示DC中,完成繪製.具體過程並不複雜,結合代碼來說明一下.
    PS:這段代碼也是相應WM_PAINT 訊息的.
    
    PAINTSTRUCT ps;
    HDC hdc;
    //擷取螢幕顯示DC        
    hdc = BeginPaint (hWnd, &ps);
    
    //建立記憶體DC
    HDC hdcMem = CreateCompatibleDC(hdc);
    //建立一個bmp記憶體空間
    HBITMAP hBmp = CreateCompatibleBitmap(hdc,SCREEN_WIDTH,SCREEN_HEIGHT);
    //將bmp記憶體空間分配給記憶體DC
    HGDIOBJ hOldSel = SelectObject(hdcMem,hBmp);
    
    //這是使用者需要繪製的畫面,全部往記憶體DC繪製
    Rectangle(hdcMem,0,0,SCREEN_WIDTH,SCREEN_HEIGHT);
    DrawMenuButton(hdcMem);
    
    //將記憶體DC的內容複寫到螢幕顯示DC中,完成顯示
    BitBlt(hdc,0,0,SCREEN_WIDTH,SCREEN_HEIGHT,hdcMem,0,0,SRCCOPY);
    //清除資源
    SelectObject(hdcMem,hOldSel);    
    DeleteDC(hdcMem);    
    EndPaint(hWnd,&ps);
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.