I am trying to write a program with two windows. One should be the drawing surface (line and circles only). The other must have all the data that will be generated from the line drawings that will be changed with the mouse. This program is already working but at the moment both the drawings and the data are in the same window and that does'nt look good.
Now both windows are up and the main window has a circle and a line on it. Unfortunately when I minimize the second window the line and circle dissapear. Even if I restrore the window it does not get drawn back. (Only when the window get moved the drawings are back)
.ELSEIF uMsg==WM_PAINT
;mov eax,hParent ;hWindow can be the Parent or the Child
;.IF hWindow==eax
invoke DrawVectors, hParentDC
;.ELSE
;.ENDIF
If I comment out the checking for the parent window (as above) in the WM_PAINT part it does not happen but the window gets to be updated continiously. To me it looks as if there are more WM_PAINT messages coming in than I bargained for.
After I restore the window I want to redraw the line and circle, but what message must I respond to? or what am I missing?
Below is a working example of the program. It needs to be assembled and linked.
.486
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\gdi32.inc
include \masm32\include\Fpu.inc
include \masm32\include\masm32.inc
include \masm32\include\debug.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib\masm32\lib\gdi32.lib
includelib \masm32\lib\Fpu.lib
includelib\masm32\lib\masm32.lib
includelib \masm32\lib\debug.lib
WinMain proto :DWORD,:DWORD,:DWORD,:DWORD
DrawVectors proto :HDC
EraseVectors proto :HDC
Vector STRUCT 4 ;X and Y as well as the polar coordinates
X1 real8 0.0
Y1 real8 0.0
X2 real8 0.0
Y2 real8 0.0
Amplitude real8 0.0
Angle real8 0.0
Vector ENDS
Bullet STRUCT 4 ;Used for the circle at the end of vector no 2
TopX DWORD 0
TopY DWORD 0
BotX DWORD 0
BotY DWORD 0
Bullet ENDS
.data
VectorClass db "VectorMoveClass",0
ParentName db "Parent",0
ChildName db "Child",0
V2P1 Vector <0.0,0.0,30.0,40.0> ;Initialized the first four members the last two will take the default of 0.0
OldV1P1 Vector <> ;After drawing the line in color it needs to be erased with white before drawing it again
BlueBullet Bullet <>
.data?
hInstance HINSTANCE ?
CommandLine LPSTR ?
hParent dd ?
hChild dd ?
hParentDC dd ?
hChildDC dd ?
WindowWidth dd ?
WindowHeight dd ?
hBluePen dd ?
hGreenPen dd ?
hRedPen dd ?
hPurplePen dd ?
hLightBluePen dd ?
hLightGreenPen dd ?
hLightRedPen dd ?
hLightPurplePen dd ?
hWhitePen dd ?
hWhiteBrush dd ?
hLightBlueBrush dd ?
hLightGreenBrush dd ?
hLightRedBrush dd ?
hLightPurpleBrush dd ?
Rect RECT <>
ClientWidth dd ?
ClientHeight dd ?
HalfWidth dd ?
HalfHeight dd ?
.const
ColorBlue dword 00ff0000h
ColorGreen dword 0000ff00h
ColorRed dword 000000ffh
ColorPurple dword 00ff00ffh
ColorLightBlue dword 00ffeeeeh
ColorLightGreen dword 00eeffeeh
ColorLightRed dword 00eeeeffh
ColorLightPurple dword 00ffeeffh
ColorWhite dword 00ffffffh
.code
start:
invoke GetModuleHandle, NULL
mov hInstance,eax
invoke GetCommandLine
mov CommandLine,eax
invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWNORMAL
invoke ExitProcess,eax
; -------------------------------------------------------------------------
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
LOCAL wc:WNDCLASSEX ;Dit is n Structure. LOCAL beteken spasie op die stack seblief
LOCAL msg:MSG ;Dit is n Structure
LOCAL hwnd:HWND
mov wc.cbSize,SIZEOF WNDCLASSEX ; fill values in members of wc
mov wc.style, CS_HREDRAW or CS_VREDRAW or CS_OWNDC ;meaning the DC's will be private
mov wc.lpfnWndProc, OFFSET ParentProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,NULL
push hInstance
pop wc.hInstance
mov wc.hbrBackground,COLOR_WINDOW+6
mov wc.lpszMenuName,NULL
mov wc.lpszClassName,OFFSET VectorClass
invoke LoadIcon,NULL,IDI_APPLICATION
mov wc.hIcon,eax
mov wc.hIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax
invoke RegisterClassEx, addr wc ; register our window Class
invoke GetSystemMetrics, SM_CXSCREEN
mov WindowWidth,eax
invoke GetSystemMetrics, SM_CYSCREEN
mov WindowHeight,eax
;Draw parent window
invoke CreateWindowEx, NULL,\
ADDR VectorClass,\ ;Pointer to the Class naam
ADDR ParentName,\ ;Pointer to what must be written in the title bar
WS_OVERLAPPED or WS_CAPTION or WS_MINIMIZEBOX or WS_SYSMENU,\
0,0,WindowWidth,WindowHeight,\
NULL,\
NULL,\
hInstance,\
NULL
mov hParent,eax
invoke GetClientRect,hParent,addr Rect
mov eax,Rect.right
mov ecx,Rect.bottom
mov ClientWidth,eax
mov ClientHeight,ecx
shr eax,1
shr ecx,1
mov HalfWidth,eax
mov HalfHeight,ecx
Invoke GetDC, hParent
mov hParentDC,eax
;Draw child window
invoke CreateWindowEx, NULL,\
ADDR VectorClass,\ ;Pointer to the Class naam
ADDR ChildName,\ ;Pointer to what must be written in the title bar
WS_MINIMIZEBOX or WS_SYSMENU or WS_SIZEBOX, \
200,200,200,200,\
hParent,\
NULL,\
hInstance,\
NULL
mov hChild,eax
invoke GetDC, hChild
mov hChildDC,eax
call CreatePens
invoke ShowWindow, hParent, SW_SHOWNORMAL
invoke ShowWindow, hChild, SW_SHOWNORMAL
invoke UpdateWindow, hParent
.WHILE TRUE
invoke GetMessage, ADDR msg,NULL,0,0
.BREAK .IF (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.ENDW
mov eax,msg.wParam
ret
WinMain endp
; -------------------------------------------------------------------------
ParentProc proc hWindow:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.IF uMsg==WM_DESTROY
mov eax,hParent ;hWindow can be the Parent or the child
.IF hWindow==eax
invoke DeleteObject, hBluePen
invoke DeleteObject, hGreenPen
invoke DeleteObject, hRedPen
invoke DeleteObject, hPurplePen
invoke DeleteObject, hLightBluePen
invoke DeleteObject, hLightGreenPen
invoke DeleteObject, hLightRedPen
invoke DeleteObject, hLightPurplePen
invoke DeleteObject, hWhitePen
invoke DeleteObject, hLightRedBrush
invoke DeleteObject, hLightGreenBrush
invoke DeleteObject, hLightBlueBrush
invoke DeleteObject, hLightPurpleBrush
.ENDIF
invoke PostQuitMessage, NULL
.ELSEIF uMsg==WM_CREATE
.ELSEIF uMsg==WM_COMMAND ;Menu's, Controls and others send WM_COMMAND messages.
mov eax,wParam ;Menu's en Controls het ID's hier.
;The lower 16 bits has the ID of the control that jou have given it
;The upper 16 bits has the command. ( BN_CLICKED vir Button Clicked )
.IF lParam==0 ;Zero means it is a Menu sending the message. (File, Edit ...)
.ELSE ;lParam has a handle of a control. (Button, CheckBox, EditBox ...)
.ENDIF
;.ELSEIF uMsg==WM_ERASEBKGND
;invoke EraseVectors, hParent
;mov eax,10
.ELSEIF uMsg==WM_PAINT
mov eax,hParent ;hWindow can be the Parent or the Child
.IF hWindow==eax
invoke DrawVectors, hParentDC
.ELSE
.ENDIF
.ELSE
invoke DefWindowProc,hWindow,uMsg,wParam,lParam ;You do not handle the message
ret
.ENDIF
xor eax,eax
ret
ParentProc endp
; -------------------------------------------------------------------------
CreatePens proc
invoke CreatePen, PS_SOLID, 2, ColorLightBlue
mov hLightBluePen,eax
invoke CreatePen, PS_SOLID, 2, ColorLightGreen
mov hLightGreenPen,eax
invoke CreatePen, PS_SOLID, 2, ColorLightRed
mov hLightRedPen,eax
invoke CreatePen, PS_SOLID, 2, ColorLightPurple
mov hLightPurplePen,eax
invoke CreatePen, PS_SOLID, 2, ColorBlue
mov hBluePen,eax
invoke CreatePen, PS_SOLID, 2, ColorGreen
mov hGreenPen,eax
invoke CreatePen, PS_SOLID, 2, ColorRed
mov hRedPen,eax
invoke CreatePen, PS_SOLID, 2, ColorPurple
mov hPurplePen,eax
invoke CreatePen, PS_SOLID, 2, ColorWhite
mov hWhitePen,eax
invoke CreateSolidBrush,ColorLightBlue
mov hLightBlueBrush,eax
invoke CreateSolidBrush,ColorLightGreen
mov hLightGreenBrush,eax
invoke CreateSolidBrush,ColorLightRed
mov hLightRedBrush,eax
invoke CreateSolidBrush,ColorLightPurple
mov hLightPurpleBrush,eax
invoke CreateSolidBrush,ColorWhite
mov hWhiteBrush,eax
ret
CreatePens endp
; -------------------------------------------------------------------------
DrawVectors proc hDC:HDC
invoke SelectObject, hDC, hLightBlueBrush
;mov OldBrushHandle,eax
invoke SelectObject, hDC, hBluePen
;mov OldPenHandle,eax
fld V2P1.X2
fld V2P1.Y2
fist BlueBullet.TopY
fistp BlueBullet.BotY
fist BlueBullet.TopX
fistp BlueBullet.BotX
mov ebx,BlueBullet.TopY
mov edx,BlueBullet.BotY
mov eax,BlueBullet.TopX
mov ecx,BlueBullet.BotX
add ebx,7
sub edx,7
sub eax,7
add ecx,7
neg ebx
neg edx
add ebx,HalfHeight
add edx,HalfHeight
add eax,HalfWidth
add ecx,HalfWidth
mov BlueBullet.TopY,ebx
mov BlueBullet.BotY,edx
mov BlueBullet.TopX,eax
mov BlueBullet.BotX,ecx
invoke Ellipse,hDC,eax,ebx,ecx,edx
invoke MoveToEx, hDC, 0, 0, 0
invoke LineTo, hDC, BlueBullet.TopX, BlueBullet.TopY
ret
DrawVectors endp
; -------------------------------------------------------------------------
EraseVectors proc hDC:HDC
invoke SelectObject, hDC, hWhiteBrush
invoke SelectObject, hDC, hWhitePen
fld V2P1.X2
fld V2P1.Y2
fist BlueBullet.TopY
fistp BlueBullet.BotY
fist BlueBullet.TopX
fistp BlueBullet.BotX
mov ebx,BlueBullet.TopY
mov edx,BlueBullet.BotY
mov eax,BlueBullet.TopX
mov ecx,BlueBullet.BotX
add ebx,7
sub edx,7
sub eax,7
add ecx,7
neg ebx
neg edx
add ebx,HalfHeight
add edx,HalfHeight
add eax,HalfWidth
add ecx,HalfWidth
mov BlueBullet.TopY,ebx
mov BlueBullet.BotY,edx
mov BlueBullet.TopX,eax
mov BlueBullet.BotX,ecx
invoke Ellipse,hDC,eax,ebx,ecx,edx
invoke MoveToEx, hDC, 0, 0, 0
invoke LineTo, hDC, BlueBullet.TopX, BlueBullet.TopY
ret
EraseVectors endp
; -------------------------------------------------------------------------
end start
Thanks to all
Sarel
Sarel,
Can you tell me why you want the parent to occupy the entire screen, including the task bar? And why the resizing ability is not being allowed? You should make the parent resizable and smallerso you can test it better. I, also, will try that. It probably has nothing to do with the problem but everything to do with testing.
Paul
You should provide default message processing for all cases, including WM_PAINT message as in your case:
.ELSEIF uMsg==WM_PAINT
mov eax,hParent ;hWindow can be the Parent or the Child
; .IF hWindow==eax
invoke DrawVectors, hParentDC
; .ELSE
; .ENDIF
; .ELSE
; invoke DefWindowProc,hWindow,uMsg,wParam,lParam ;You do not handle the message
; ret
.ENDIF
invoke DefWindowProc,hWindow,uMsg,wParam,lParam ;You do not handle the message
ret
; xor eax,eax
;ret
ParentProc endp
Quote from: arafel on March 08, 2006, 09:28:28 PM
You should provide default message processing for all cases, including WM_PAINT message as in your case:
.ELSEIF uMsg==WM_PAINT
mov eax,hParent ;hWindow can be the Parent or the Child
; .IF hWindow==eax
invoke DrawVectors, hParentDC
; .ELSE
; .ENDIF
; .ELSE
; invoke DefWindowProc,hWindow,uMsg,wParam,lParam ;You do not handle the message
; ret
.ENDIF
invoke DefWindowProc,hWindow,uMsg,wParam,lParam ;You do not handle the message
ret
; xor eax,eax
;ret
ParentProc endp
I am greatfull for your answer arafel. The answer is very easy, but I would never have done it. I didnt even think about it.
Thank you very much.
Sarel
Quote from: PBrennick on March 08, 2006, 09:18:58 PM
Sarel,
Can you tell me why you want the parent to occupy the entire screen, including the task bar? And why the resizing ability is not being allowed? You should make the parent resizable and smallerso you can test it better. I, also, will try that. It probably has nothing to do with the problem but everything to do with testing.
Paul
I need to manipulate vectors with the mouse. All vectors will originate from the ceter of the client area and can be in any direction from there. As I will be manipulating one vector the others will respond in their own manner, and can be positioned where they will suit me the best. The program will scale the vectors so that they will fit at least half the client area's height. I need to use the maximum area for the most accurate positioning of the vectors.