2012-06-26 27 views
1

我是新來的Windows編程,並開始在幾個月前的文字遊戲工作。我決定重寫我的代碼的WM_PAINT部分,我通常會重新繪製整個客戶區,但我認爲我會嘗試重繪特定區域,以減少閃爍。我注意到在我的代碼的一個特定部分,InvalidateRect/UpdateWindow似乎不想工作,但如果我用RedrawWindow替換2個函數,它將完美顯示。應該有一個InvalidateRect/UpdateWindow無法工作的實例,但RedrawWindow可以正常工作嗎?InvalidateRect/UpdateWindow失敗,但RedrawWindow正常工作,爲什麼?

用RedrawWindow代替我的代碼中的所有InvalidateRect/UpdateWindow調用會有什麼缺點嗎?

感謝您的信息!

.if uMsg==WM_PAINT 
    invoke BeginPaint,hWnd,ADDR ps 
    mov hdc,eax 

    .if (PAINT_DMGMSG>0) ;contains ->to a char's DMGMSG  
    invoke CreateFont,16,12,0,0,400,0,0,0,OEM_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH,NULL 
    invoke SelectObject,hdc,eax 
    mov hfont,eax 
    invoke SetTextColor,hdc,COLOR_SNOWWHITE 

    mov esi,TS_MSG2 
    mov edi,TS_MSG1 
    mov ecx,len(TS_MSG2) 
    rep movsb 
    mov BYTE ptr [edi],0 
    mov esi,TS_MSG3 
    mov edi,TS_MSG2 
    mov ecx,len(TS_MSG3) 
    rep movsb 
    mov BYTE ptr [edi],0 
    mov esi,PAINT_DMGMSG 
    mov edi,TS_MSG3 
    mov ecx,len(esi) 
    rep movsb 
    mov BYTE ptr [edi],0 

    invoke TextOut,hdc,0,500,TS_MSG1,len(TS_MSG1) 
    invoke TextOut,hdc,0,518,TS_MSG2,len(TS_MSG2) 
    invoke TextOut,hdc,0,536,TS_MSG3,len(TS_MSG3) 
    mov PAINT_DMGMSG,0 
    .endif 

    invoke EndPaint,hWnd,ADDR ps 

.elseif uMsg==WM_CHAR   ;used to handle keyboard input 
    push wParam 
    pop char 

      .if(SDWORD ptr [ebx+OFFSET_ALLEGIANCE]<0)&&(DWORD ptr [ebx+OFFSET_STATUS]!=STAT_DEAD) 
       invoke Combat,[esi+12],ebx 
       mov ebx,[edi+4] 
       mov eax,[human.color] 
       mov [ebx+OFFSET_CHARCOLOR],eax 

       mov ebx,pChar 
       mov ebx,[ebx+OFFSET_MOBMEM] 
       .if (DWORD ptr [ebx+OFFSET_MOBMEM_DMGMSG]>0) 
        mov ebx,[ebx+OFFSET_MOBMEM_DMGMSG] 
        mov XYrc.left,0 
        mov XYrc.top,500 
        push wWin 
        pop XYrc.right 
        mov XYrc.bottom,560  ;+font height 

        mov PAINT_DMGMSG,ebx 
;     invoke InvalidateRect,hWnd,ADDR XYrc,TRUE 
;     invoke UpdateWindow,hWnd 
        invoke RedrawWindow,hWnd,ADDR XYrc,NULL,NULL ;<- WORKS FINE! 
       .endif        
      .endif 

回答

0

假設你使用0作爲RedrawWindow()的最後一個參數(如你這樣做),確實有一個重要的區別:

  • UpdateWindow()將立即WM_PAINT,在函數返回之前。
  • RedrawWindow()(除非使用了標記RDW_UPDATENOW)只是將WM_PAINT放入消息隊列中,以便稍後再進行繪製。

這可以使區別,如果你無效矩形,但改變窗口狀態,然後後。在情況(1)中,使用「舊」數據繪製控件,但是(2)「有效」。

如果你的問題是由這種差異造成的,您可以嘗試使用InvalidateRect()只(不叫UpdateWindow(),也不RedrawWindow()該矩形失效會導致隨後WM_PAINT,當隊列中沒有任何其它事件會來的。(原文UpdateWindow()防止因爲立即WM_PAINT驗證窗口作爲繪畫的副作用)。

相關問題