Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 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
15-1309369259
Dimka Maslov
2011-06-29 21:40
2011.10.23
Вот до чего техника дошла


1-1263286244
sann-x
2010-01-12 11:50
2011.10.23
Установка ActiveX компонента


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


6-1244462643
Zheksonz
2009-06-08 16:04
2011.10.23
проверка на наличие компьютера в сети


15-1309206592
Юрий
2011-06-28 00:29
2011.10.23
С днем рождения ! 28 июня 2011 вторник





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский