1

私は Windows プログラミングが初めてで、数か月前にテキスト ゲームに取り組み始めました。コードの WM_PAINT セクションを書き直すことにしました。通常はクライアント領域全体を継続的に再描画していましたが、ちらつきを減らす代わりに特定の領域を再描画しようと考えました。コードの特定のセクションで、InvalidateRect/UpdateWindow が機能しないように見えますが、2 つの関数を RedrawWindow に置き換えると、完全に表示されることに気付きました。InvalidateRect/UpdateWindow が機能しないが、RedrawWindow が代わりに正常に機能するインスタンスが存在する必要がありますか?

コード内のすべての InvalidateRect/UpdateWindow 呼び出しを RedrawWindow に置き換えるだけの欠点はありますか?

情報をありがとう!

.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
4

1 に答える 1

0

0(あなたがそうするように)の最後の引数として使用すると仮定するとRedrawWindow()、確かに1つの重要な違いがあります:

  • UpdateWindow()WM_PAINT関数が戻る前に、すぐに送信します。
  • RedrawWindow()(フラグRDW_UPDATENOWが使用されていない限り)WM_PAINTメッセージキューに配置するだけなので、実際には後でペイントが行われます。

長方形を無効にした場合、これは違いを生む可能性がありますが、その後ウィンドウの状態を変更します。(1)の場合、コントロールは「古い」データを使用してペイントされますが、(2)「機能」します。

問題の原因がこの違いである場合は、使用を試みることができますInvalidateRect()(を呼び出さUpdateWindow()ないでください。また、キューに他のイベントがない場合に、rectRedrawWindow()の無効化が発生します。絵の副作用として)。WM_PAINTUpdateWindow()WM_PAINT

于 2012-06-26T08:24:00.567 に答える