应用程序在长时间处理WM_PAINT后停止响应

时间:2015-12-21 22:43:45

标签: winapi assembly wm-paint

我正在制作一个将白色椭圆移动到窗口中心的程序。我是使用BeginPaint,EndPaint,Ellipse程序完成此操作的。当没有循环时,它工作正常,显示底部的椭圆,但是当我使用一个循环时,它会移动我需要的椭圆而不是停止响应(我想程序不会返回控制) 。如何解决这个问题?我甚至开始做registegrs值的副本。

WM_PAINT:

invoke   BeginPaint, hWnd, addr ps ;  
mov     hdc, eax        ; 
invoke GetClientRect, hWnd, addr rect; invoke DrawInitialElipse

invoke DrawInitialElipse

步骤:

DrawInitialElipse proc
LOCAL tempEAL:BYTE
LOCAL tempEAX:DWORD
LOCAL tempEDX:DWORD
LOCAL tempECX:DWORD

mov tempEAL, al
mov tempEAX, eax
mov tempEDX, edx
mov tempECX, ecx

finit
fld initialColorStep
fld currentColorDouble
fadd
fst currentColorDouble
fistp dword ptr currentColorInt

mov al, byte ptr [currentColorInt]
mov tempColor, al

mov esi, currentInitialCirclePositionY
.WHILE (esi != ydiv2)
.if stepNumber1==0
    mov edi, startY
    mov currentInitialCirclePositionY, edi
.else
    dec currentInitialCirclePositionY
.endif

inc stepNumber1

mov edi, currentInitialCirclePositionY
sub edi,cnst_10
mov topLeftY, edi


mov edi, startX
sub edi, cnst_5
mov topLeftX, edi

mov edi, currentInitialCirclePositionY
add edi, cnst_10
mov bottomRightY, edi

mov edi, startX
add edi, cnst_5
mov bottomRightX, edi


invoke CreateBrush, 240,240,240
mov initialBrush, edi
invoke SelectObject, hdc, initialBrush
invoke Ellipse, hdc, topLeftX,topLeftY,bottomRightX,bottomRightY; //рисуем другим перо
invoke Sleep, 10
.ENDW
mov al, tempEAL
mov eax,tempEAX
mov edx,tempEDX
mov ecx,tempECX
ret
DrawInitialElipse endp

2 个答案:

答案 0 :(得分:4)

您的代码停止响应,因为您在绘图过程中循环,检查ESI寄存器的更改,但是您没有在每次循环迭代时使用新值更新ESI。你最终会陷入无休止的循环中。

您不应该在绘图过程中移动椭圆,移动颜色,甚至睡觉。您应该绘制椭圆的当前状态。完全摆脱循环并将椭圆的当前属性(位置,颜色等)保留在绘图过程之外的单独变量中。每次收到WM_PAINT时,程序都需要使用当前属性值绘制椭圆一次,然后退出(并且不要忘记调用{在退出EndPaint()之前{1}}。

要实现动画(移动椭圆,移动颜色等),您可以使用计时器(请参阅SetTimer())根据需要更新属性值。每次属性值更改时,请调用InvalidateRect()让操作系统知道椭圆窗口需要新的WM_PAINT消息。让您的窗口的消息循环决定何时实际向您发送新的WM_PAINT消息。达到所需的最终结果时停止计时器。

答案 1 :(得分:0)

您遗失EndPaint();

我不知道多次选择同一个gdi对象的行为,但如果不建议在完成当前对象时恢复原始对象,这是一个好习惯。

我不在asm中编码,但我认为它应该像这样

invoke SelectObject, hdc, initialBrush
push eax
...
pop eax
invoke SelectObject, hdc, eax