hi, please have a look at the source. this is a program which uses backbuffering and it is a clone of a game named "snake". BUT: when i compile the program it is automatically executed by my batchfile and it works fine. one time i started it directly through windows (with doubleclick) and it crashed. nothing worked anymore, even CTRL+Alt+Del. then i compiled the same source again, and tried the same thing once more. it worked. isn't that weird??? here is the source:
.................
snakebody STRUCT
sx dd ?
sy dd ?
direction dd ?
snakebody ENDS
.const
.data
szDisplayName db "-worm",0
szClassName db "Win_Class",0
TheText db "Do you really want to quit?",0
bodybit db "bodybit",0
snakeelements dd 6
snakeone snakebody {5,101,3},{5,85,3},{5,69,3},{5,53,3},{5,37,3},{5,21,3},{5,5,3},20 dup(,?,?>)
.data?
CommandLine dd ?
hWnd dd ?
hInstance dd ?
hIcon dd ?
backgroundbrush dd ?
backbuffer HDC ?
backbitmap HBITMAP ?
oldbit dd ?
screenrect RECT >
blackbrush dd ?
myDC dd ?
maxx dd ?
maxy dd ?
hpen dd ?
oldpen dd ?
olddir dd ?
bodybmp HBITMAP ?
bodybmpdc HDC ?
..............
invoke CreateSolidBrush,00000000h
mov backgroundbrush,eax
mov wc.hbrBackground, eax
mov wc.lpszMenuName, NULL
mov wc.lpszClassName, offset szClassName
m2m wc.hIcon, hIcon
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor, eax
m2m wc.hIconSm, hIcon
invoke RegisterClassEx, ADDR wc
;================================
; Centre window at following size
;================================
mov Wwd, 500
mov Wht, 350
invoke GetSystemMetrics,SM_CXSCREEN
mov maxx,eax
invoke TopXY,Wwd,eax
mov Wtx, eax
invoke GetSystemMetrics,SM_CYSCREEN
mov maxy,eax
invoke TopXY,Wht,eax
mov Wty, eax
invoke CreateWindowEx,WS_EX_LEFT,
ADDR szClassName,
ADDR szDisplayName,
WS_POPUP,
Wtx,Wty,Wwd,Wht,
NULL,NULL,
hInst,NULL
mov hWnd,eax
invoke LoadMenu,hInst,600 ; menu ID
invoke SetMenu,hWnd,eax
invoke ShowWindow,hWnd,SW_SHOWMAXIMIZED
invoke UpdateWindow,hWnd
invoke DeleteObject,backgroundbrush
StartLoop:
invoke GetMessage,ADDR msg,NULL,0,0
cmp eax, 0
je ExitLoop
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
invoke InvalidateRect,hWnd,NULL,FALSE
jmp StartLoop
ExitLoop:
.........................
.elseif uMsg == WM_CREATE
invoke GetDC,hWin
mov myDC,eax
mov screenrect.left,0
mov screenrect.top,0
mov eax,maxx
mov screenrect.right,eax
mov eax,maxy
mov screenrect.bottom,eax
invoke CreateSolidBrush,00000000h
mov blackbrush,eax
invoke CreateCompatibleDC,myDC
mov backbuffer,eax ;handle of the invisible Devicecontext
invoke CreateCompatibleBitmap,myDC,screenrect.right,screenrect.bottom
mov backbitmap,eax ;handle of the invis. Bitmap
invoke SelectObject,backbuffer,backbitmap
mov oldbit,eax
invoke FillRect, backbuffer, ADDR screenrect, blackbrush ;fill invis screen with black
invoke CreatePen,PS_SOLID,1,00FFFFFFh ;a white pen
mov hpen,eax
invoke SelectObject,backbuffer,hpen ;pen for the invis. screen
invoke LoadBitmap,hInstance,addr bodybit
mov bodybmp,eax
invoke CreateCompatibleDC,myDC
mov bodybmpdc,eax
invoke SelectObject,bodybmpdc,bodybmp
..........................
.elseif uMsg==WM_KEYDOWN
.if wParam==VK_DOWN
.if snakeone[0].direction!=1
mov snakeone[0].direction,3
.endif
.elseif wParam==VK_UP
.if snakeone[0].
Hi SaFc0n,
one thing I noticed is that you don't invoke PostQuitMessage,NULL in the Destroy-Message. I don't know if this is the problem and if this is needed but I am using it to tell the program that I exit.
Stefan
This message was edited by Stefan Krause, on 3/2/2001 2:09:08 PM
Seems you only pasted a fragment (I don't see a .code section, and a few other things that must be there).
What are you doing with the command line? How are you parsing it?
Windows isn't quite consistant in how it passes in CL params from a bat file or a shortcut.
See MASM32Lib GetCL.
stefan, i do use invoke PostQuitMessage,NULL. ernie, i do nothing with the commandline. here is the whole source:
.386
.model flat, stdcall
option casemap :none
include \MASM32\INCLUDE\windows.inc
include \MASM32\INCLUDE\masm32.inc
include \MASM32\INCLUDE\gdi32.inc
include \MASM32\INCLUDE\user32.inc
include \MASM32\INCLUDE\kernel32.inc
includelib \MASM32\LIB\masm32.lib
includelib \MASM32\LIB\gdi32.lib
includelib \MASM32\LIB\user32.lib
includelib \MASM32\LIB\kernel32.lib
WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
TopXY PROTO :DWORD,:DWORD
Paint_Proc PROTO :DWORD,:DWORD
wsprintfA PROTO C :DWORD,:VARARG
wsprintf equ
m2m MACRO M1, M2
push M2
pop M1
ENDM
return MACRO arg
mov eax, arg
ret
ENDM
snakebody STRUCT
sx dd ?
sy dd ?
direction dd ?
snakebody ENDS
.const
.data
szDisplayName db "-worm",0
szClassName db "Win_Class",0
TheText db "Do you really want to quit?",0
bodybit db "bodybit",0
snakeelements dd 6
snakeone snakebody {5,101,3},{5,85,3},{5,69,3},{5,53,3},{5,37,3},{5,21,3},{5,5,3},20 dup(,?,?>)
.data?
CommandLine dd ?
hWnd dd ?
hInstance dd ?
hIcon dd ?
backgroundbrush dd ?
backbuffer HDC ?
backbitmap HBITMAP ?
oldbit dd ?
screenrect RECT >
blackbrush dd ?
myDC dd ?
maxx dd ?
maxy dd ?
hpen dd ?
oldpen dd ?
olddir dd ?
bodybmp HBITMAP ?
bodybmpdc HDC ?
; #########################################################################
.code
start:
invoke GetModuleHandle, NULL
mov hInstance, eax
invoke GetCommandLine
mov CommandLine, eax
invoke WinMain,hInstance,NULL,CommandLine,SW_SHOWDEFAULT
invoke ExitProcess,eax
; #########################################################################
WinMain proc hInst :DWORD,
hPrevInst :DWORD,
CmdLine :DWORD,
CmdShow :DWORD
;====================
; Put LOCALs on stack
;====================
LOCAL wc :WNDCLASSEX
LOCAL msg :MSG
LOCAL Wwd :DWORD
LOCAL Wht :DWORD
LOCAL Wtx :DWORD
LOCAL Wty :DWORD
;==================================================
; Fill WNDCLASSEX structure with required variables
;==================================================
invoke LoadIcon,hInst,500 ; icon ID
mov hIcon, eax
mov wc.cbSize, sizeof WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW \
or CS_BYTEALIGNWINDOW
mov wc.lpfnWndProc, offset WndProc
mov wc.cbClsExtra, NULL
mov wc.cbWndExtra, NULL
m2m wc.hInstance, hInst
invoke CreateSolidBrush,00000000h
mov backgroundbrush,eax
mov wc.hbrBackground, eax
mov wc.lpszMenuName, NULL
mov wc.lpszClassName, offset szClassName
m2m wc.hIcon, hIcon
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor, eax
m2m wc.hIconSm, hIcon
invoke RegisterClassEx, ADDR wc
;================================
; Centre window at following size
;================================
mov Wwd, 500
mov Wht, 350
invoke GetSystemMetrics,SM_CXSCREEN
mov maxx,eax
invoke TopXY,Wwd,eax
mov Wtx, eax
invoke GetSystemMetrics,SM_CYSCREEN
mov maxy,eax
invoke TopXY,Wht,eax
mov Wty, eax
invoke CreateWindowEx,WS_EX_LEFT,
ADDR szClassName,
ADDR szDisplayName,
WS_OVERLAPPEDWINDOW,
Wtx,Wty,Wwd,Wht,
NULL,NULL,
hi,
ok, i found out myself. i just had to use InvalidateRect,hWnd,0,FALSE instead of InvalidateRect,hWnd,NULL,FALSE
don't ask me why.
Umm, I hate to break this to you:
NULL EQU 0
So your problem must be elsewhere.Safcon,
putting "invoke InvalidateRect,hWnd,NULL,FALSE" in the message
loop is an unusual thing to do, it means the application is
cycling this API at high speed which sniffs to me of a stack
problem.
I would be inclined to place it somewhere else where it is called
on a needs basis, can it be put in the WM_PAINT message processing ?
Regards,
hutch@pbq.com.au
hutch-- has a very good point
add GDIFlush to make sure that your queue doesn't get too long
or better yet put it in a timer routine since the invalidaterect and the gdiflush will trigger new messages== new invalidaterect + ........etc.
This message was edited by Hiroshimator, on 3/3/2001 6:38:14 PM