Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2011.10.23;
Скачать: CL | DM;

Вниз

Как сделать чтобы при 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;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.007 c
1-1269838322
Jamix
2010-03-29 08:52
2011.10.23
голосовой модем


2-1309850310
Scott Storch
2011-07-05 11:18
2011.10.23
array of char to string and back


15-1309267786
eXAAAXe
2011-06-28 17:29
2011.10.23
Что за функция OpenRaw?


15-1309292992
Юрий
2011-06-29 00:29
2011.10.23
С днем рождения ! 29 июня 2011 среда


15-1308947395
Юрий
2011-06-25 00:29
2011.10.23
С днем рождения ! 25 июня 2011 суббота