作者purpose (purpose)
看板C_and_CPP
標題Re: [問題] 所謂在MemDC裡畫(更新)
時間Sat Nov 27 19:17:33 2010
※ 引述《steven70101 (老人)》之銘言:
: 遇到的問題: (題意請描述清楚)
: 最近再要時間內製作俄羅斯方塊
: 目前已經大致弄好
: 但是卻卡在一個多重貼圖閃爍的問題
: 由於是完全不懂的新手 上網查資料大至知道是要使用雙緩衝
: 或是先畫在memDC裡
: 目前已經修正到閃爍問題改善許多
: 但是方塊本身以及旁邊的計量表有時還是會閃爍
: 還找不到原因改善...
: 問題是 何謂畫在memdc裡呢
: 網路上講的整個都很抽象 偏偏又都沒實際例子
: 唯一有的也都是MFC 偏偏我是用WIN32 API
: 希望得到的正確結果:
: 希望有大大能提出具體例子好讓我了解
: 程式跑出來的錯誤結果:
: 開發平台: (例: VC++ or gcc/g++ or Dev-C++, Windows or Linux)
: 有問題的code: (請善用置底文標色功能)
: http://codepad.org/ACZcWR5v
: 補充說明:
假設你想要 Resize 視窗,則會導致視窗重新繪圖,會出現以下流程
進入 WM_PAINT 訊息 -> 裡面的 BeginPaint() 函數觸發 WM_ERASEBKGND 訊息
-> 此訊息預設的處理動作: 用白色把視窗內容填滿 -> 執行你指定的繪圖動作
又假設你的繪圖動作是,在對話方塊內畫一個矩形,且使用預設的黑色。
則螢幕畫面會不斷地,先是整個視窗變白,再畫黑矩形,因為「白黑白黑白黑」速度太快
,畫面就感覺很閃了。
版友說的,跟你提的雙緩衝,就是改變上面的流程
重繪發生 -> 禁止顯示器上的對話方塊變白 -> 在記憶體內建立跟對話方塊同大
的矩形 -> 把該記憶體清除為白色 -> 畫好黑色矩形 -> 將該記憶體內容貼到
顯示器 (BitBlt)
首先就是這樣:
case WM_ERASEBKGND:
return 0;
break;
直接 return 就可以禁止。
接著當然就是處理 WM_PAINT,在裡面建立一塊記憶體,把東西畫好,再用 BitBlt 讓
顯示器反應新畫面。
大致的函數調用順序如下
hdc = BeginPaint(...);
HDC
hdcMem = CreateCompatibleDC(h
hdc);
HBITMAP
bmpMem = CreateCompatibleBitmap(
hdc, 客戶區寬度, 客戶區高度);
SelectObject(
hdcMem,
bmpMem);
FillRect(
hdcMem, &rectClient, (HBRUSH) GetStockObject(BLACK_BRUSH));
Rectangle(
hdcMem, 0, 20, 客戶區寬度, 120);
BitBlt(
hdc, 0, 0, 客戶區寬度, 客戶區高度,
hdcMem, 0, 0, SRCCOPY);
原本 Rectangle(...) 繪圖函數,只要傳 hdc 就能把圖畫好,
但現在要畫在記憶體,所以用 hdcMem 取代。
而 hdcMem 被畫完後,結果會存在記憶體,直到你明確調用 BitBlt() 時,才會把結果
反應到螢幕上的對話方塊。
那 FillRect(...) 的目的,就是不管原本 hdcMem 存了什麼內容,都先用黑色塗滿,
也就是對應原本的 WM_ERASEBKGND 觸發的動作。
hdcMem 在使用 CreateCompatibleDC(hdc) 建立出來時,不會跟客戶區一樣大,而是
只有 1x1 大小。因此用 CreateCompatibleBitmap(...) 做出跟客戶區一樣大的
bmpMem,再用 SelectObject(hdcMem, bmpMem); 讓 hdcMem 的大小可以放大。
完整原理我是不懂,背起來就對,反正 GDI 本來就是很龐大的機制。
程式碼。用 VC 2008 的 Win32 視窗程式範本改寫,修改了 WndProc() 內容,跟增加一個
叫 CBrush 的類別。完整程式碼在網址:
http://codepad.org/RyUazucp
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 124.8.140.25
→ tropical72:p大好強!! 11/27 19:20
推 aecho:p大好強!! 11/27 19:33
推 VictorTom:p大好強!! 11/27 20:00
推 loveme00835:Orz ... 11/27 20:01
推 Yshuan:推 最近有碰到相同問題 11/27 20:15
→ purpose:哪裡,版上其他大大沒空回這些而已 11/27 20:39
推 nowar100:幫你m 11/27 20:49
推 elfkiller:PUSH 11/28 00:15
推 james732:有看有推 11/28 00:21
→ yoco315:p大好強!! 11/28 12:44
推 xatier:p大好強!! 11/29 13:06