純SDK實現雙緩衝繪圖與普通繪圖差別示範

來源:互聯網
上載者:User

先大致介紹一下WINDOWS下的繪圖原理:

我們在 Windows 環境下看到各種元素,如菜單、按鈕、視窗、映像,從根本上說,都是“畫”出來的。這時的螢幕,就相當於一塊黑板,而 Windows 下的各種 GDI 要素,如畫筆、畫刷等,就相當於彩色粉筆了。我們在黑板上手工畫圖時,是一筆一划的,電腦亦然。只不過電腦的速度比手工快的太多,所以在我們看起來好像所有的圖形文字都是同時出現的。

普通繪圖方式的局限
上述繪圖方式我們暫且稱之為普通繪圖方式吧。雖然這種方式能滿足相當一部分的繪圖需要,但是當要繪製的對象太複雜,尤其是含有位元影像時,電腦便力不從心了。這時的畫面會顯示的很慢,對於運動的畫面,會給人“卡”住了的感覺,總之一個字:不爽。
解決之道:雙緩衝

 雙緩衝的原理可以這樣形象的理解:把電腦螢幕看作一塊黑板。首先我們在記憶體環境中建立一個“虛擬“的黑板,然後在這塊黑板上繪製複雜的圖形,等圖形全部繪製完畢的時候,再一次性的把記憶體中繪製好的圖形“拷貝”到另一塊黑板(螢幕)上。採取這種方法可以提高繪圖速度,極大的改善繪圖效果。下面是原理圖:

                                                        雙緩衝原理

下面貼出代碼吧

#include <windows.h><br />#include "resource.h"<br />LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;<br />void PThanshu(HWND);//普通畫圖函數<br />void DHChanshu(HWND);//雙緩衝畫圖函數</p><p>int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,<br /> PSTR szCmdLine, int iCmdShow)<br />{<br /> static TCHAR szAppName [] = TEXT ("GDI") ;<br /> HWND hwnd ;<br /> MSG msg ;<br /> WNDCLASS wndclass ;</p><p> wndclass.style = CS_HREDRAW | CS_VREDRAW ;<br /> wndclass.lpfnWndProc = WndProc ;<br /> wndclass.cbClsExtra = 0 ;<br /> wndclass.cbWndExtra = 0 ;<br /> wndclass.hInstance = hInstance ;<br /> wndclass.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE(IDI_ICON1)) ;<br /> wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;<br /> wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;<br /> wndclass.lpszMenuName = szAppName;<br /> wndclass.lpszClassName = szAppName ;</p><p> if (!RegisterClass (&wndclass))<br /> {<br /> MessageBox (NULL, TEXT ("This program requires Windows NT!"),<br /> szAppName, MB_ICONERROR) ;<br /> return 0 ;<br /> }</p><p> hwnd = CreateWindow (szAppName, TEXT ("GDI TEST"),<br /> WS_OVERLAPPEDWINDOW,<br /> CW_USEDEFAULT, CW_USEDEFAULT,<br /> CW_USEDEFAULT, CW_USEDEFAULT,<br /> NULL, NULL, hInstance, NULL) ;</p><p> ShowWindow (hwnd, iCmdShow) ;<br /> UpdateWindow (hwnd) ;</p><p> while (GetMessage (&msg, NULL, 0, 0))<br /> {<br /> TranslateMessage (&msg) ;<br /> DispatchMessage (&msg) ;<br /> }<br /> return msg.wParam ;<br />}<br /> static int cxClient, cyClient;<br /> static int radius=1;<br />LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)<br />{</p><p> HDC hdc;<br /> HINSTANCE hInstance ;<br /> static int pt,gdi;//PT--普通畫圖,GDI--雙緩衝畫圖<br /> PAINTSTRUCT ps ;<br /> RECT rect;</p><p> TCHAR szAppName[]="GDI";</p><p> switch (message)<br /> {<br /> case WM_CREATE:<br /> SetTimer(hwnd,1,1000,NULL);<br /> hInstance = ((LPCREATESTRUCT) lParam)->hInstance ;</p><p> return 0 ;<br /> case WM_TIMER:<br /> //GetClientRect(hwnd,&rect);//本打算在這裡觸發WM_PAINT訊息的<br />// InvalidateRect(hwnd,&rect,TRUE);<br /> if(radius<16)<br /> {radius++;}<br /> else<br /> {radius=0;}</p><p> if(pt)<br /> {<br /> PThanshu(hwnd);//普通畫圖<br /> }<br /> else if(gdi)<br /> {<br />DHChanshu(hwnd);//雙緩衝畫圖<br /> }<br /> else<br /> return 0;</p><p> case WM_SIZE:<br /> //cxClient = LOWORD (lParam) ;<br /> //cyClient = HIWORD (lParam) ;<br /> return 0 ;</p><p> case WM_PAINT:<br /> /*if(pt==1)<br /> {<br /> hdc = BeginPaint (hwnd, &ps) ;<br /> for(int x=0;x<cxClient;x+=16)<br /> for(int y=0;y<cyClient;y=+16)<br /> {<br /> Ellipse(hdc,x,y,x+radius,y+radius);</p><p> }<br /> EndPaint (hwnd, &ps) ;<br /> }<br /> else<br />{<br />hdc=BeginPaint (hwnd, &ps) ;<br />DrawText(hdc,szAppName,-1,&rect,DT_CENTER);<br />EndPaint(hwnd,&ps);</p><p>}*/<br /> hdc=BeginPaint(hwnd,&ps);<br /> GetClientRect(hwnd,&rect);<br /> DrawText(hdc,szAppName,-1,&rect,DT_CENTER);<br /> EndPaint(hwnd,&ps);</p><p> return 0 ;<br /> case WM_COMMAND:<br /> if(lParam==0)<br /> {<br /> switch(wParam)<br /> {</p><p> case IDM_PT://普通畫圖功能表項目ID<br /> pt=1;<br /> gdi=0;<br /> return 0;<br /> case IDM_DHC://雙緩衝畫圖功能表項目ID<br /> gdi=1;<br /> pt=0;<br /> return 0;<br /> default:<br /> return 0;</p><p> }<br /> }</p><p> case WM_DESTROY:<br /> PostQuitMessage (0) ;<br /> return 0 ;<br /> }<br /> return DefWindowProc (hwnd, message, wParam, lParam) ;<br />}<br />void PThanshu(HWND hwnd)<br />{</p><p>HDC hdc=GetDC(hwnd);<br />RECT rect;<br />GetClientRect(hwnd,&rect);<br />cxClient=rect.right;<br />cyClient=rect.bottom;<br />FillRect(hdc,&rect,NULL);</p><p>for(int x=0;x<cxClient;x+=16)<br /> for(int y=0;y<cyClient;y+=16)<br /> {<br /> Ellipse(hdc,x,y,x+radius,y+radius);</p><p> }<br /> ReleaseDC(hwnd,hdc);<br />}<br />void DHChanshu(HWND hwnd)//暫且沒實現<br />{<br />//MessageBox(hwnd,TEXT("zhaoxujing"),TEXT("yiruirui"),MB_OK);<br />HDC hdc=GetDC(hwnd);<br />RECT rect;<br />GetClientRect(hwnd,&rect);<br />cxClient=rect.right;<br />cyClient=rect.bottom;</p><p>HDC hdcmem=CreateCompatibleDC(hdc);<br />HBITMAP hbitmap=CreateCompatibleBitmap(hdc,cxClient,cyClient);<br />SelectObject(hdcmem,hbitmap);<br /> FillRect(hdcmem,&rect,NULL);<br />for(int x=0;x<cxClient;x+=16)<br /> for(int y=0;y<cyClient;y+=16)<br /> {<br /> Ellipse(hdcmem,x,y,x+radius,y+radius);</p><p> }<br /> BitBlt(hdc,0,0,cxClient,cyClient,hdcmem,0,0,SRCCOPY);<br /> DeleteObject(hdcmem);<br /> ReleaseDC(hwnd,hdc);</p><p>}<br />

 

完整的工程放在了CSDN上,地址:http://download.csdn.net/source/2992685

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.