-1

I'm making a procedure that would move the white elipse to the center of the window. i'm doing this using BeginPaint, EndPaint, Ellipse procedures. When there is no cycle, it works Ok, showing the elipse on the bottom, but when i'm using a cycle it moves the elipse where i need and than stops responding (I suppose procedure doesn't return control). How to fix this issue? I have even started to do the copies of registegrs values.

WM_Paint:

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

invoke DrawInitialElipse

Procedure:

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
rkhb
  • 14,159
  • 7
  • 32
  • 60
Henry1996
  • 25
  • 5

2 Answers2

4

Your code stops responding because you are looping inside your drawing procedure, checking for changes to the ESI register, but you are not updating ESI with a new value on each loop iteration. You end up in an endless loop.

You are not supposed to be moving the ellipse, shifting its coloring, or even sleeping while inside your drawing procedure to begin with. You are supposed to be drawing the current state of the ellipse. Get rid of your loop completely and keep the ellipse's current attributes (position, color, etc) in separate variables outside of the drawing procedure. Each time WM_PAINT is received, the procedure needs to draw the ellipse one time using the current attribute values and then exit (and don't forget to call EndPaint() before exiting from WM_PAINT).

To implement animation (moving the ellipse around, shifting its colors, etc), you can use a timer (see SetTimer()) to update the attribute values as needed. Each time an attribute value changes, call InvalidateRect() to let the OS know that a new WM_PAINT message is needed for the ellipse's window. Let your window's message loop decide when to actually deliver the new WM_PAINT message to you. Stop the timer when the desired end result has been reached.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
0

you are missing EndPaint();

i don't know the behavior of selecting the same gdi object multiple times, but it is good practice if not recommended to restore the original object when done with the current.

i do not code in asm, but i think it should be like this

invoke SelectObject, hdc, initialBrush
push eax
...
pop eax
invoke SelectObject, hdc, eax
milevyo
  • 2,165
  • 1
  • 13
  • 18