2015-12-21 6 views
-1

Я делаю процедуру, которая перемещает белый элип в центр окна. Я делаю это, используя процедуры BeginPaint, EndPaint, Ellipse. Когда нет цикла, он работает нормально, показывая elipse внизу, но когда я использую цикл, он перемещает elipse, где мне нужно, и чем перестает отвечать (я полагаю, процедура не возвращает управление). Как исправить эту проблему? Я даже начал делать копии значений registegrs.Приложение перестает отвечать после длительной обработки WM_PAINT

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 
+0

Похоже, вы не отпуская кисть с 'DeleteObject' –

+0

К сожалению, это не помогло – Henry1996

+0

Узнать, как это сделать это сначала на C++. Затем код в asm. Хотя этот последний шаг кажется бессмысленным. –

ответ

4

Ваш код перестает отвечать, потому что вы зацикливание внутри вашей процедуры рисования, проверки изменений в ESI регистр, но вы не обновляя ESI с новое значение для каждой итерации цикла. Вы оказываетесь в бесконечном цикле.

Вы не должны перемещать эллипс, перемещая его окраску или даже спать во время процедуры рисования. Предполагается, что вы будете рисовать текущее состояние эллипса. Извлеките свой цикл полностью и сохраните текущие атрибуты эллипса (положение, цвет и т. Д.) В отдельных переменных вне процедуры рисования. Каждый раз, когда принимается WM_PAINT, процедура должна нарисовать эллипс один раз с использованием текущих значений, а затем выйти (и не забудьте позвонить по номеру EndPaint() перед выходом из WM_PAINT).

Чтобы реализовать анимацию (перемещая эллипс вокруг, перемещая его цвета и т. Д.), Вы можете использовать таймер (см. SetTimer()) для обновления значений атрибутов по мере необходимости. Каждый раз, когда изменяется значение атрибута, звоните InvalidateRect(), чтобы сообщить ОС, что для окна эллипса требуется новое сообщение WM_PAINT. Пусть ваш цикл сообщений вашего окна решит, когда нужно доставить вам новое сообщение WM_PAINT. Остановите таймер, когда достигнут желаемый конечный результат.

0

информация отсутствует у вас EndPaint();

Я не знаю, как много раз выбирать один и тот же объект gdi, но это хорошая практика, если не рекомендуется восстанавливать исходный объект по завершении текущего.

я не код на ассемблере, но я думаю, что это должно быть, как это

invoke SelectObject, hdc, initialBrush 
push eax 
... 
pop eax 
invoke SelectObject, hdc, eax 
Смежные вопросы