Форум: "Прочее";
Текущий архив: 2011.10.23;
Скачать: [xml.tar.bz2];
ВнизКак сделать чтобы при WM_PAINT нарисованное оставалось на форме Найти похожие ветки
← →
trololo (2011-06-26 13:44) [0]Есть прога на асме, рисует линии, квадраты и круги.
В нижеследующем коде при событии WM_PAINT перерисовывается только
текущая фигура, при этом все нарисованные раннее потеряются.
Каким образом можно этого избежать?
Я плохо шарю в асме и винапи... Но может можно рисовать на каком-нибудь канвасе, а потом его прорисовку вызывать при WM_PAINT и WM_SIZE?
WndProc proc uses ebx, hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL ps:PAINTSTRUCT
LOCAL cc:CHOOSECOLOR
mov eax,uMsg
.IF eax==WM_MOUSEMOVE
jmp fallthr ; Fall through
.ELSEIF eax==WM_LBUTTONDOWN
fallthr:
.IF wParam & MK_LBUTTON ; If LH Button down
.IF figureset ; Do we have the figure yet ?
invoke GetDC, hWnd
mov hdc,eax
invoke GetStockObject, WHITE_PEN
invoke SelectObject, hdc, eax
call drawfigure ; erase old figure <---------------------
LOWORD lParam
mov coords.corn2.x,eax ; coords of point on figure
HIWORD lParam
mov coords.corn2.y,ebx ;
invoke SelectObject, hdc, colorpen
call drawfigure ; make new figure visible <---------------------
invoke ReleaseDC, hWnd, hdc
.ELSE
LOWORD lParam
mov coords.corn1.x,eax ; Set figure first coords
HIWORD lParam
mov coords.corn1.y,ebx ;
mov figureset,TRUE ; We have the figure
.ENDIF
.ENDIF
.ELSEIF eax==WM_RBUTTONDOWN
mov figureset, FALSE
; inc figure
;
.ELSEIF eax==WM_CREATE
finit ; Initialise coprocessor
invoke CreatePen, PS_SOLID, 1, 0FF0000h ; Solid, thin & blue
mov colorpen,eax
invoke CreateWindowEx,NULL, ADDR ButtonClassName,ADDR ButtonLineText,\
WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON,\
1,1,70,30,hWnd,ButtonLineID,hInstance,NULL
invoke CreateWindowEx,NULL, ADDR ButtonClassName,ADDR ButtonCircleText,\
WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON,\
80,1,70,30,hWnd,ButtonCircleID,hInstance,NULL
invoke CreateWindowEx,NULL, ADDR ButtonClassName,ADDR ButtonSquareText,\
WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON,\
160,1,120,30,hWnd,ButtonSquareID,hInstance,NULL
invoke CreateWindowEx,NULL, ADDR ButtonClassName,ADDR ButtonColorText,\
WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON,\
290,1,70,30,hWnd,ButtonColorID,hInstance,NULL
.ELSEIF eax==WM_COMMAND
.IF wParam==ButtonLineID
mov figure, 1
.ELSEIF wParam==ButtonCircleID
mov figure, 2
.ELSEIF wParam==ButtonSquareID
mov figure, 3
.ELSEIF wParam==ButtonColorID
mov cc.lStructSize,sizeof cc ;size of the struct
push hWnd ;our window is the owner of the color dialog
pop cc.hwndOwner
mov cc.rgbResult,255 ;start the box of in red
mov cc.Flags,CC_FULLOPEN+CC_RGBINIT ;dialog is open all the way and starts with our predefined start
mov cc.lpCustColors,offset rgb ;holder for the rgb declared in the color dialog box
invoke ChooseColor, addr cc ;we only filled a little of the stuct but it is ebough to where we can call it
.if eax == TRUE ;return true means they chose a color and did not hit cancel or alt+f4
push cc.rgbResult ;get our color and save it
pop color
invoke DeleteObject, colorpen
invoke CreatePen, PS_SOLID, 1, color ; Solid, thin & blue
mov colorpen,eax
;invoke SetDCPenColor, hdc, color
;mov colorpen,eax
.endif
.ENDIF
.ELSEIF eax==WM_SIZE
LOWORD lParam
mov cxClient,eax
HIWORD lParam
mov cyClient,ebx
.ELSEIF eax==WM_PAINT
invoke InvalidateRect, hWnd, NULL, TRUE
invoke BeginPaint,hWnd, ADDR ps
mov hdc,eax
invoke SelectObject, hdc, colorpen
call drawfigure ; Repaint if resized <---------------------
invoke EndPaint,hWnd, ADDR ps
.ELSEIF eax==WM_DESTROY
invoke DeleteObject, colorpen
invoke PostQuitMessage,NULL
.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.ENDIF
xor eax,eax
ret
WndProc endp
← →
trololo (2011-06-26 13:48) [1]Оставшаяся часть кода
;...
WinMain PROTO :DWORD, :DWORD, :DWORD, :SDWORD
.data
ClassName db "SimpleWinClass",0
AppName db "Paint 0.001a",0
ButtonClassName db "button",0
ButtonLineText db "Линия",0
ButtonCircleText db "Круг",0
ButtonSquareText db "Прямоугольник",0
ButtonColorText db "Цвет",0
FigureCoords STRUCT ; 2 pairs of DWORD coordinates (x,y), (8 bytes/pair)
corn1 POINT {} ; First diagonal figure
corn2 POINT {} ; Second "
FigureCoords ENDS
coords FigureCoords {}
figure db 1 ;Flag for figure (0 - point; 1 - line; 2 - circle; 3 - square)
radius DD ? ; computed value
hdc HDC ?
cxClient DD ?
cyClient DD ?
colorpen DD ? ; Pen handle
color DD ? ; color of pen
rgb dd 16 dup(?) ;value for cc struct
figureset db ? ; Flag for first figure
.data?
hInstance HINSTANCE ?
CommandLine LPSTR ?
.const
ButtonLineID equ 1
ButtonCircleID equ 2
ButtonSquareID equ 3
ButtonColorID equ 4
LOWORD MACRO bigword ;; Retrieves the low word from double word argument
mov eax,bigword
and eax,0FFFFh ;; Set to low word
ENDM
HIWORD MACRO bigword ;; Retrieves the high word from double word argument
mov ebx,bigword
shr ebx,16 ;; Shift 16 for high word to set to high word
ENDM
;----------------------------------------------------------------------------
.code
start:
invoke GetModuleHandle, NULL
mov hInstance,eax
invoke GetCommandLine
invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
invoke ExitProcess,eax
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:SDWORD
;...
WinMain endp
WndProc proc uses ebx, hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
;...
WndProc endp
drawfigure PROC
.IF figure==1
call drawline
.ELSEIF figure==2
call drawcircle
.ELSEIF figure==3
call drawrectangle
.ENDIF
ret
drawfigure ENDP
drawline PROC ; Use to erase/show the rubber-band line
invoke MoveToEx, hdc, coords.corn1.x, coords.corn1.y, NULL ; Set start point
invoke LineTo, hdc, coords.corn2.x, coords.corn2.y ; Draw line to end point
ret
drawline ENDP
drawrectangle PROC ; Use to erase/show the rubber-band rectangle
invoke MoveToEx, hdc, coords.corn1.x, coords.corn1.y, NULL ; Set 1st figure
invoke LineTo, hdc, coords.corn2.x, coords.corn1.y ; Draw line to 2nd
invoke LineTo, hdc, coords.corn2.x, coords.corn2.y ; Draw line to 3rd
invoke LineTo, hdc, coords.corn1.x, coords.corn2.y ; Draw line to 4th
invoke LineTo, hdc, coords.corn1.x, coords.corn1.y ; Draw line to 1st
ret
drawrectangle ENDP
drawcircle PROC ; Use to erase/show the rubber-band circle
fild coords.corn1.x
fisub coords.corn2.x
fld st ; take copy
fmul ; base squared
fild coords.corn1.y
fisub coords.corn2.y
fld st
fmul ; vertical side squared
fadd
fsqrt ; Get hypotenuse
fistp radius
mov eax,coords.corn1.x ; Set the bounding coordinates
sub eax,radius ;
mov ebx,coords.corn1.y ;
sub ebx,radius ;
mov ecx,coords.corn1.x ;
add ecx,radius ;
mov edx,coords.corn1.y ;
add edx,radius ;
invoke Ellipse, hdc, eax,ebx,ecx,edx ; draw the circle
ret
drawcircle ENDP
end start
← →
Плохиш © (2011-06-26 14:01) [2]
> Каким образом можно этого избежать?
По событию отрисовывать все требуемые фигуры, а не только текущую.
← →
trololo (2011-06-26 14:03) [3]Это получается нужно их каждую отдельно хранить...
Есть ли еще какие-нибудь пути?
← →
trololo (2011-06-26 14:06) [4]В этом случае количество фигур будет ограничено...
← →
Плохиш © (2011-06-26 14:09) [5]
> можно рисовать
> на каком-нибудь канвасе, а потом его прорисовку вызывать
> при WM_PAINT и WM_SIZE?
>
>
Тебе разрешение надо? Я не против.
← →
trololo (2011-06-26 14:14) [6]Можешь подсказать функции для работы с этим канвасом и его перерисовкой?
← →
Kerk © (2011-06-26 14:19) [7]http://msdn.microsoft.com/en-us/library/dd183377%28v=vs.85%29.aspx
← →
Юрий Зотов © (2011-06-26 14:21) [8]
> trololo (26.06.11 14:14) [6]
> Можешь подсказать функции для работы с этим канвасом и его
> перерисовкой?
См. справку по TCanvas, там все эти функции есть.
← →
trololo (2011-06-26 14:26) [9]Kerk, Юрий Зотов, спасибо
← →
trololo (2011-06-26 14:54) [10]правда TCanvas это класс делфи.
А на мсдн я так и не нашел как рисовать на битмапе...
Функции рисования принимают как аргумент Device Context (HDC)
← →
Юрий Зотов © (2011-06-26 15:25) [11]Если обязательно на WinAPI (правда, непонятно, зачем - средствами VCL все это делается намного проще), то см. в MSDN раздел GDI Functions.
А DC можно получить функцей GetDC.
← →
trololo (2011-06-26 15:37) [12]Я не против VCL, даже за, непонятно как рисовать на этом битмапе и как его отрисовывать на форме.
Сейчас на dc и рисуется, но этого способа минусы нарисованное стирается после WM_PAINT.
Другое дело если нарисованное хранилось в битмапе и после WM_PAINT отрисовывалось
← →
Юрий Зотов © (2011-06-26 15:43) [13]> trololo (26.06.11 15:37) [12]
> Я не против VCL, даже за
Тогда зачем все эти навороты? Берете форму, у нее есть Cavas и событие OnPaint. В обработчике этого события рисуете на этой канве что угодно - и все будет сохраняться.
← →
Плохиш © (2011-06-26 20:57) [14]
> Юрий Зотов © (26.06.11 15:43) [13]
Так он хочет только последнюю фигуру отрисовывать, а остальные должны на канвасе каким-то волшебным способом сохраняться.
Страницы: 1 вся ветка
Форум: "Прочее";
Текущий архив: 2011.10.23;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.003 c