[問題] 直接對程式發送SendMessage(WM_PAINT)新

看板C_and_CPP (C/C++)作者 (yolling)時間14年前 (2012/05/03 22:01), 編輯推噓5(5019)
留言24則, 4人參與, 最新討論串1/4 (看更多)
我最近在研究人物在程式移動的樣子 我軟體用Visual Studio 然後是用WINDOWS API寫的 當我人物移動之後我就調用了InvalidateRect()來將整個視窗無效化 可是我程式在重繪的時候,畫面會有閃爍的問題 所以我想說改程式來試試看就直接發送SendMessage(WM_PAINT) 結果當人物一移動的時候就當了 我上網查原因,查到的都只有說不可以這樣做 可是都沒有人說為什麼不能這樣做@@ 因此想請問一下為何這樣做不行呢? 然後人物移動的程式碼如下: case WM_KEYDOWN: switch (wParam){ case VK_UP: y--;break; case VK_DOWN:y++;break; case VK_LEFT:x--;break; case VK_RIGHT:x++;break; default: break; } InvalidateRect(hwnd,NULL,true) ; UpdateWindow(hwnd); break; 我在想會閃爍的原因是不是因為我按下按鍵不放, 導致重畫的頻率太快太高了,所以會閃爍@@ 麻煩請高手指導一下,謝謝 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 114.34.32.47 ※ 編輯: yoll522 來自: 114.34.32.47 (05/03 22:04)

05/03 23:09, , 1F
閃爍不是都要用double buffer嗎
05/03 23:09, 1F

05/03 23:10, , 2F
大概就是你直接畫在DC上會閃 要先畫在一塊buffer 再一次
05/03 23:10, 2F

05/03 23:10, , 3F
swap到DC上 就不會閃了~細節要再google
05/03 23:10, 3F
意思是我應該先把WM_PAINT裡要貼的圖,改貼在一塊buffer 然後在呼叫貼圖,把要貼的圖從buffer取出嗎? 不過我個人不知道這樣要怎麼做,我先爬文看看在試試看 成功與否 謝謝 ※ 編輯: yoll522 來自: 114.34.32.47 (05/03 23:20)

05/03 23:48, , 4F
這問題很常見阿 關鍵字double buffer一定沒有錯
05/03 23:48, 4F

05/03 23:48, , 5F
但 我也是好幾年前寫過那麼一次 現在也忘光細節了
05/03 23:48, 5F

05/04 05:39, , 6F
double buffer是一點錯沒有,但是現在成熟的框架不
05/04 05:39, 6F

05/04 05:39, , 7F
少,可以嘗試下Qt之類……
05/04 05:39, 7F

05/04 09:20, , 8F
因為我是要拿來做專題的@@ 指導老師跟我討論之後決定用api
05/04 09:20, 8F

05/04 09:21, , 9F
來寫。今天放學之後我會查一下double buffer該如何做
05/04 09:21, 9F

05/04 23:13, , 10F
我用了double buffer 可是依然閃爍ˊˋ
05/04 23:13, 10F
Rect rect(x,y,250,550); Unit srcunit = UnitPixel; //像素大小 Image* image = new Image(L"peo.png"); Bitmap CacheImage( 1024, 768 ); //創建畫布,大小為1024*768 Graphics CacheGraphics( &CacheImage );//指定要畫創出來的畫布 CacheGraphics.DrawImage(image, rect,0,cy[i++],500,590,UnitPixel);//繪畫中 Graphics graphics(hdc); //指定要開始在視窗繪圖 graphics.DrawImage(&CacheImage, 0,0);//將畫布的圖整個貼上 ※ 編輯: yoll522 來自: 120.124.130.253 (05/04 23:16)

05/04 23:15, , 11F
程式碼呢
05/04 23:15, 11F
※ 編輯: yoll522 來自: 120.124.130.253 (05/04 23:17)

05/04 23:17, , 12F
剛剛 補上了,麻煩高手指證一下 謝謝
05/04 23:17, 12F

05/04 23:19, , 13F
那個cy[i++]是人物移動的時候走路的圖,每一步都不同座標
05/04 23:19, 13F
※ 編輯: yoll522 來自: 120.124.130.253 (05/04 23:20)

05/04 23:32, , 14F
給完整的吧,我編譯一次跑看看,不然搞不清楚你在講什麼
05/04 23:32, 14F

05/04 23:41, , 15F
05/04 23:41, 15F

05/04 23:42, , 16F
麻煩妳了@@
05/04 23:42, 16F

05/05 09:56, , 17F
http://ideone.com/rQk1q 我改的部份不多,沒有幾行,你
05/05 09:56, 17F

05/05 09:57, , 18F
用檔案比對軟體應該就可以找到那些部份。我不太懂你的移動
05/05 09:57, 18F

05/05 09:58, , 19F
邏輯,所以註解那行 DrawImage(image, rect,0,cy[i++],500
05/05 09:58, 19F

05/05 16:15, , 20F
已經不會閃爍了@@ 很感謝你,不過我有幾個問題想請問一下
05/05 16:15, 20F
InvalidateRect(hwnd,NULL,false) ; Bitmap CacheImage( 1024, 768, image->GetPixelFormat() ); Graphics CacheGraphics( &CacheImage ); SolidBrush sbr(Color(128, 128, 128)); CacheGraphics.FillRectangle(&sbr, 0, 0, 1024, 768); 第二行的那個第三個參數,請問那個是什麼意思@@? 第四行我沒猜錯的話應該是創一個變數叫sbr,它的背景顏色為參數所給的 然後第五行的第一個參數就是先把sbr的顏色填滿,填的大小為後面的四個參數大小嚕? 這樣做的意思是不是因為使用InvalidateRect第三個參數設定false 不要讓背景重置,而是改用把背景的顏色直接畫在畫布上 另外我人物的移動是因為我們角色移動一步有五張行走圖 而那五張都包含在peo.png的圖裡面,所以我才會弄一個 static int cy[]={0,600,1200,1800,2400} 這是那張圖裡面每個行走圖的素數位置,因為目前是測試階段 所以我程式是寫說按一下按鍵,就切換到下一個行走的圖 這是我自己想法,也不確定是不是這樣做@@ 然後再一次的感謝你,以及Q大,這double buffer讓我學到很多 ※ 編輯: yoll522 來自: 114.34.32.47 (05/05 16:25) ※ 編輯: yoll522 來自: 114.34.32.47 (05/05 16:33)

05/05 16:33, , 21F
可是為什麼背景重置,跟直接把背景畫在畫布上
05/05 16:33, 21F

05/05 16:34, , 22F
後者就不會閃爍呢?
05/05 16:34, 22F

05/05 18:35, , 23F
image->GetPixelFormat()我稍微查了一下,他是不是
05/05 18:35, 23F

05/05 18:35, , 24F
取得image的像素?
05/05 18:35, 24F
文章代碼(AID): #1Fee-lTk (C_and_CPP)
文章代碼(AID): #1Fee-lTk (C_and_CPP)