最近<<windows环境下32位汇编语言程序设计>> 这本书看了一些章节了.
自从讲完GDI那章,往下就是通用对话框了.
通用对话框那章看起来很没意思,就跳着看了看.下一章是讲控件的,也没啥兴趣.
但是控件那章的窗口子类化,和窗口超类化倒是非常重要,给了我不少启发,
才知道原来各种各样的的漂亮的控件,窗口,无非也就是子类化,超类化,再加上资源作出来的.
再后面,讲的是内存和文件,再再后面,是DLL和HOOK.
各个章节都扫了一些,总感觉应该做点什么自己的东西,有点自己Debug的经验,心里才踏实.
于是,为了巩固以下,就做个贪食蛇吧.
以前用J2ME作过贪食蛇,也用C语言 WIN32 SDK 作过贪食蛇.
算法和思想都很简单.WIN32 API上也没有什么难点.
本来想做一个界面复杂的,但是发现手头没有好看的位图资源,也就懒得弄了.
本来还想用上一些控件,但是自己就是这样虎头蛇尾,做到后来就懒得往上加控件了.
由于对WIN32 SDK比以前用C语言作这个东西的时候理解深刻了一些,
程序模块化比以前好一点了.
解决了以前那个贪食蛇按键的一个BUG.
刚做的时候,其实是想先做个链表的,然后想把这个链表封装到 DLL里.
可是一想到这个链表的节点也没有啥通用性,又不会弄成CPP里面那种范型,也是弄一半旧懒得弄了.
就在.asm文件里巴,dll懒得弄了...
本以为学习了以前的东西,做一个贪食蛇已经没有任何技术难点了.
但是一想到如何动态分配内存空间,我就发现自己还有个重大的问题不会解决.
C语言里可以malloc,free.C++里可以new delete,Java也可以new ,汇编用什么呢?
最后发现,汇编没有这种直接的东西可以分配内存,只能用API .
这里用的是VirtualAlloc和VirtualFree。这样,总算可以给链表动态加节点了。
过程中还发现不知道在汇编中如何操作结构体,而这个程序当然要频繁地操作结构体的节点。
后来看了一眼术上前面介绍的,assume esi:ptr XXXX,配合 assume esi:nothing
就可以[esi].XXXX这样操作结构体了。通过这个程序,算是把这块熟悉了一遍。
在学习16位汇编的时候,就发现jmp的标签不好起名字,尤其做王爽<<汇编语言>>课程设计2的时候,
一个标签的名字真的让自己较劲脑汁想啊想。
还记得在大一的时候,程序设计的思想还不成熟,总觉得有些地方循环不好实现,就非要用个goto.
这次好了,WIN32 汇编里面 @@和 @B @F 很好地解决了问题。
时隔N年,倒不是觉得不goto就没办法,只是觉得 jmp这东西简化了我不少代码。用起来很爽的感觉。
对了,还有一点很重要
在单位的win7上调试程序,遇到用了不该用的内存,P反映都没有
在XP上就会蹦出来个震撼的对话框。
怎么也不明白到底哪里弄错了,无奈之下,用自己的XP笔记本的VC6.0,搭配了个DEBUG环境,
才找到了问题所在------堆栈不平衡,导致 ret语句 跳转的地方不正确。
这种问题在高级语言里是不可能出现的。
DEBUG 还是没有用OllyDbg,这个东西以后再学习吧!WIN7 这东西,把错误提示都给屏蔽掉了,
给用户了一个“更好”的体验,却给我调试程序增加了麻烦。。。
VC6.0 调试汇编还是很好用的,IDE也熟悉,快捷键也熟悉,KUAKUA两下,就找到问题所在了。
还是那句话,WIN32 ASM 没有个 好的IDE,真坑人!
以前用C语言,WIN32 SDK,VC6.0 作出来的贪食蛇,exe文件大小200K
这次用WIN32汇编语言,WIN32 SDK作出来的贪食蛇,exe文件大小只有17K,嘿嘿
废话了一大堆,上个代码,贴个图吧。
没啥技术含量,就是纪念自己第一次用win32 汇编写了个几百行的小东西
.386
.model flat,stdcall
option casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include kernel32.inc
includelib kernel32.lib
include user32.inc
includelib user32.lib
include gdi32.inc
includelib gdi32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;IDB_TOOLBAR equ 100
ID_TIMER equ 1
SIZE_WND_WIDTH equ 800
SIZE_WND_HEIGHT equ 600
POS_CANVAS_X equ 100
POS_CANVAS_Y equ 100
SIZE_CANVAS_WIDTH equ 400
SIZE_CANVAS_HEIGHT equ 300
SIZE_UNIT_WIDTH equ 20
SIZE_UNIT_HEIGHT equ 20
DIR_MOVE_UP equ 3
DIR_MOVE_DOWN equ 1
DIR_MOVE_LEFT equ 2
DIR_MOVE_RIGHT equ 0 ; default direction
WM_GAME_START equ WM_USER+1 ; OWNER DEFINE
WM_GAME_OVER equ WM_USER+2
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data
;**********************************************************************************
.data?
MIAOSTRUCT struct ; struct def
xPos dd ?
yPos dd ?
pNext dd ?
MIAOSTRUCT ends
pHead dd ?
stHead MIAOSTRUCT <>
pCur dd ?
szTemp db 256 dup(?)
dwDirection dd ?
wHasFood dw ?
wTickHasChangeDir dw ?
dwFoodPosX dd ?
dwFoodPosY dd ?
hInstance dd ?
hWinMain dd ?
hDcBuffer dd ?
hBmpBuffer dd ?
;hBmpTest dd ?
wGameScore dw ?
;**********************************************************************************
.const
szDebug1 db 'szDebug1',0
szDebug2 db 'szDebug2',0
szLinkNull db 'Null linklist',0
szShowNode db 'sn (%d,%d)',0
szFreeNode db 'delete node (%d,%d)',0
szFreeFinish db 'Finish free,total %d node(s)',0
szKeyDir db 'Current key dir is %d',0
szMainClassName db 'miaoclass',0
szMainCaption db 'gj1111myl',0
szGameOver db 'GameOver',0
szGameStart db 'GameStart',0
szGameScore db 'score: %d',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Insert value to link list.Link list will create a node and add it.
_InsertMiao proc uses ebx esi,xPos,yPos
LOCAL @pStNode
mov eax,pHead
.if eax==NULL ; insert head
;invoke MessageBox,NULL,addr szDebug1,addr szDebug1,MB_OK
invoke RtlZeroMemory,addr stHead,sizeof stHead
mov eax,xPos
mov stHead.xPos,eax
mov eax,yPos
mov stHead.yPos,eax
mov eax,0
mov stHead.pNext,eax
mov eax,offset stHead
mov pHead,eax
.else ; insert normal
;nvoke MessageBox,NULL,addr szDebug2,addr szDebug2,MB_OK
; Creat a new node
invoke VirtualAlloc,NULL,sizeof MIAOSTRUCT,MEM_RESERVE or MEM_COMMIT,PAGE_READWRITE
.if eax
mov @pStNode,eax
.endif
invoke RtlZeroMemory,@pStNode,sizeof MIAOSTRUCT
mov esi,@pStNode
assume esi:ptr MIAOSTRUCT
mov eax,xPos
mov [esi].xPos,eax
mov eax,yPos
mov [esi].yPos,eax
mov eax,0
mov [esi].pNext,eax
assume esi:nothing
; find tail of linklist
mov eax,pHead
mov pCur,eax
.while TRUE
mov esi,pCur
assume esi:ptr MIAOSTRUCT
.break .if [esi].pNext==NULL
mov eax,[esi].pNext
mov pCur,eax
assume esi:nothing
.endw
assume esi:nothing
; attach new node to tail
mov esi,pCur
assume esi:ptr MIAOSTRUCT
mov eax,@pStNode
mov [esi].pNext,eax
assume esi:nothing
.endif
ret
_InsertMiao endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Show each node of link list.Test if link list is correct.
_ShowMiao proc uses esi
mov eax,pHead
mov pCur,eax
.if eax==NULL ; head is NULL
invoke MessageBox,NULL,addr szLinkNull,addr szLinkNull,MB_OK
ret
.endif
; Show each node
.while TRUE
.break .if pCur==NULL
mov esi,pCur
assume esi:ptr MIAOSTRUCT
; szTemp can't local,it will not stead stack!
invoke wsprintf,addr szTemp,addr szShowNode,[esi].xPos,[esi].yPos
invoke MessageBox,NULL,addr szTemp,addr szTemp,MB_OK
mov eax,[esi].pNext
mov pCur,eax
assume esi:nothing
.endw
ret
_ShowMiao endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Get tail node of Linklist
_GetTailNodeMiao proc uses ebx esi edi
.if pHead==NULL ; if pHead==NULL,means linklist is NULL
xor eax,eax
ret
.endif
mov eax,pHead
mov pCur,eax
.while TRUE
mov esi,pCur
assume esi:ptr MIAOSTRUCT
.break .if [esi].pNext==NULL
mov eax,[esi].pNext
mov pCur,eax
assume esi:nothing
.endw
assume esi:nothing
mov eax,pCur
ret
_GetTailNodeMiao endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Destroy linklist
_DestroyMiao proc uses ebx ecx edx esi edi
LOCAL @pCur2
mov edx,0
.while TRUE
invoke _GetTailNodeMiao
mov pCur,eax
.break .if pCur==NULL
; free head
mov eax,pHead
.if pCur==eax
invoke VirtualFree,pCur,sizeof MIAOSTRUCT,MEM_DECOMMIT
mov pHead,NULL
ret
.endif
; Get the node before tail node
push pHead
pop @pCur2
.while TRUE
mov esi,@pCur2
assume esi:ptr MIAOSTRUCT
mov eax,pCur
.break .if [esi].pNext==eax
push [esi].pNext
pop @pCur2
assume esi:nothing
.endw
; Free normal node
invoke VirtualFree,pCur,sizeof MIAOSTRUCT,MEM_DECOMMIT
; Set the node before tail's pNext = NULL
mov esi,@pCur2
assume esi:ptr MIAOSTRUCT
mov [esi].pNext,NULL
assume esi:nothing
.endw
ret
_DestroyMiao endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Check if (xPos,yPos) is member of linklist
_CheckPosOnLink proc uses ebx ecx,xPos,yPos
push pHead
pop pCur
.while TRUE
.break .if pCur==NULL
mov esi,pCur
assume esi:ptr MIAOSTRUCT
mov ebx,[esi].xPos
mov ecx,[esi].yPos
.if ebx==xPos
.if ecx==yPos
mov eax,1
ret
.endif
.endif
mov eax,[esi].pNext
mov pCur,eax
assume esi:nothing
.endw
xor eax,eax ; not found
ret
_CheckPosOnLink endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; add new node to pHead
_GrowUpOnLinkHead proc xPos,yPos
.if pHead==NULL
ret
.endif
invoke VirtualAlloc,NULL,sizeof MIAOSTRUCT,MEM_RESERVE or MEM_COMMIT,PAGE_READWRITE
.if eax
mov pCur,eax
Invoke RtlZeroMemory,pCur,sizeof MIAOSTRUCT
mov esi,pCur
assume esi:ptr MIAOSTRUCT
push xPos
pop [esi].xPos
push yPos
pop [esi].yPos
push pHead
pop [esi].pNext
push pCur
pop pHead
assume esi:nothing
.endif
ret
_GrowUpOnLinkHead endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; calc mod
_Mod proc uses ecx edx _dwNumber1,_dwNumber2
xor edx,edx
mov eax,_dwNumber1
mov ecx,_dwNumber2
.if ecx
div ecx
mov eax,edx
.endif
ret
_Mod endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; WinMain message proc
_ProcWinMain proc uses ebx ecx esi edi,hWnd,uMsg,wParam,lParam
LOCAL @hDc
LOCAL @stPs:PAINTSTRUCT
LOCAL @stRect:RECT
LOCAL @BufX,@BufY,@DestX,@DestY
LOCAL @dwFoodX,@dwFoodY
LOCAL @stTime:SYSTEMTIME
LOCAL @wTimeBit:WORD
mov eax,uMsg
.if eax==WM_TIMER
;*********************************************************
; If no food,generate one
;************************************************************
.if wHasFood==0 ; has no food on screen,generate one
@@:
; random a num
mov eax,0
invoke GetLocalTime,addr @stTime
mov ax,@stTime.wSecond
mov @wTimeBit,ax
mov @BufX,eax
mov eax,0
invoke GetLocalTime,addr @stTime
mov ax,@stTime.wSecond
mov @wTimeBit,ax
mov @BufY,eax
; set real pos
invoke _Mod,@BufX,20
mov @BufX,eax
invoke _Mod,@BufY,15
mov @BufY,eax
invoke _CheckPosOnLink,@BufX,@BufY ; make sure food not on snake
.if eax!=0
jmp @B
.endif
push @BufX
pop dwFoodPosX
push @BufY
pop dwFoodPosY
; fill food rect
mov eax,SIZE_UNIT_WIDTH
mul @BufX
mov @stRect.left,eax
mov @stRect.right,eax
add @stRect.right,SIZE_UNIT_WIDTH
mov eax,SIZE_UNIT_HEIGHT
mul @BufY
mov @stRect.top,eax
mov @stRect.bottom,eax
add @stRect.bottom,SIZE_UNIT_HEIGHT
invoke GetStockObject,LTGRAY_BRUSH
invoke FillRect,hDcBuffer,addr @stRect,eax
mov ax,1
mov wHasFood,ax
.endif
;*********************************************************
; Update node's value by DIR_MOVE
;************************************************************
mov wTickHasChangeDir,0 ; set flag of control per frame
.if pHead!=NULL
mov esi,pHead
assume esi:ptr MIAOSTRUCT
mov ebx,[esi].xPos
mov @DestX,ebx
mov ebx,[esi].yPos
mov @DestY,ebx
assume esi:nothing
.if dwDirection==DIR_MOVE_UP
mov eax,@DestY
dec eax
mov @DestY,eax
.elseif dwDirection==DIR_MOVE_DOWN
mov eax,@DestY
inc eax
mov @DestY,eax
.elseif dwDirection==DIR_MOVE_LEFT
mov eax,@DestX
dec eax
mov @DestX,eax
.elseif dwDirection==DIR_MOVE_RIGHT
mov eax,@DestX
inc eax
mov @DestX,eax
.endif
.else
invoke MessageBox,NULL,addr szLinkNull,addr szLinkNull,MB_OK
invoke SendMessage,hWnd,WM_CLOSE,0,0
ret
.endif
;*********************************************************
; Check collision
;************************************************************
; check border
.if @DestX>=20
invoke SendMessage,hWnd,WM_GAME_OVER,0,0
ret
.elseif @DestX<0
invoke SendMessage,hWnd,WM_GAME_OVER,0,0
ret
.elseif @DestY>=15
invoke SendMessage,hWnd,WM_GAME_OVER,0,0
ret
.elseif @DestY<0
invoke SendMessage,hWnd,WM_GAME_OVER,0,0
ret
.endif
; check self
invoke _CheckPosOnLink,@DestX,@DestY
.if eax!=0
invoke SendMessage,hWnd,WM_GAME_OVER,0,0
.endif
; check food
mov eax,dwFoodPosX
.if @DestX==eax
mov eax,dwFoodPosY
.if @DestY==eax
;invoke MessageBox,NULL,addr szDebug2,addr szDebug2,MB_OK
; set generate food flag
mov wHasFood,0
; inc wGameScore
inc wGameScore
; snake grows up
invoke _GrowUpOnLinkHead,dwFoodPosX,dwFoodPosY
jmp @F
.endif
.endif
;*********************************************************
; Snake move
;************************************************************
push pHead
pop pCur
.while TRUE
.break .if pCur==NULL
mov esi,pCur
assume esi:ptr MIAOSTRUCT
push [esi].xPos
pop @BufX
push [esi].yPos
pop @BufY
mov eax,SIZE_UNIT_WIDTH ; erase history
mul @BufX
mov @stRect.left,eax
mov @stRect.right,eax
add @stRect.right,SIZE_UNIT_WIDTH
mov eax,SIZE_UNIT_HEIGHT
mul @BufY
mov @stRect.top,eax
mov @stRect.bottom,eax
add @stRect.bottom,SIZE_UNIT_HEIGHT
invoke GetStockObject,BLACK_BRUSH
invoke FillRect,hDcBuffer,addr @stRect,eax
push @DestX ; real move
pop [esi].xPos
push @DestY
pop [esi].yPos
push @BufX ; record pos for next node move
pop @DestX
push @BufY
pop @DestY
push [esi].pNext
pop pCur
assume esi:nothing
.endw
@@:
;*********************************************************
; Draw each node of linklist
;************************************************************
mov eax,pHead
mov pCur,eax
.while TRUE
.break .if pCur==NULL
mov esi,pCur
assume esi:ptr MIAOSTRUCT
; ebx=real xPos of current node
mov eax,SIZE_UNIT_WIDTH
mul [esi].xPos
mov ebx,eax
; ecx=real yPos of current node
mov eax,SIZE_UNIT_HEIGHT
mul [esi].yPos
mov ecx,eax
assume esi:nothing
; current rect
mov @stRect.left,ebx
mov @stRect.right,SIZE_UNIT_WIDTH
add @stRect.right,ebx
mov @stRect.top,ecx
mov @stRect.bottom,SIZE_UNIT_HEIGHT
add @stRect.bottom,ecx
invoke GetStockObject,WHITE_BRUSH
invoke FillRect,hDcBuffer,addr @stRect,eax
assume esi:ptr MIAOSTRUCT
mov eax,[esi].pNext
mov pCur,eax
assume esi:nothing
.endw
invoke InvalidateRect,hWnd,NULL,FALSE
.elseif eax==WM_PAINT
mov @stRect.left,0
mov @stRect.right,100
mov @stRect.top,0
mov @stRect.bottom,100
invoke BeginPaint,hWnd,addr @stPs
mov @hDc,eax
; Draw game canvas
invoke BitBlt,@hDc,POS_CANVAS_X,POS_CANVAS_Y,SIZE_WND_WIDTH,SIZE_WND_HEIGHT,hDcBuffer,0,0,SRCCOPY
; Draw score
mov eax,0
mov ax,wGameScore
invoke wsprintf,addr szTemp,addr szGameScore,eax
invoke DrawText,@hDc,addr szTemp,-1,addr @stRect,DT_LEFT
invoke EndPaint,hWnd,addr @stPs
.elseif eax==WM_KEYDOWN
mov eax,wParam
.if eax==VK_UP && wTickHasChangeDir==0
.if dwDirection!=DIR_MOVE_DOWN && dwDirection!=DIR_MOVE_UP
mov eax,DIR_MOVE_UP
mov dwDirection,eax
mov wTickHasChangeDir,1 ; set flag ,could only change dir once per frame
.endif
.elseif eax==VK_DOWN && wTickHasChangeDir==0
.if dwDirection!=DIR_MOVE_DOWN && dwDirection!=DIR_MOVE_UP
mov eax,DIR_MOVE_DOWN
mov dwDirection,eax
mov wTickHasChangeDir,1
.endif
.elseif eax==VK_LEFT && wTickHasChangeDir==0
.if dwDirection!=DIR_MOVE_LEFT && dwDirection!=DIR_MOVE_RIGHT
mov eax,DIR_MOVE_LEFT
mov dwDirection,eax
mov wTickHasChangeDir,1
.endif
.elseif eax==VK_RIGHT && wTickHasChangeDir==0
.if dwDirection!=DIR_MOVE_LEFT && dwDirection!=DIR_MOVE_RIGHT
mov eax,DIR_MOVE_RIGHT
mov dwDirection,eax
mov wTickHasChangeDir,1
.endif
.endif
.elseif eax==WM_GAME_START
invoke MessageBox,NULL,addr szGameStart,addr szGameStart,MB_OK
.if pHead!=NULL
invoke _DestroyMiao
.endif
;************************************************************
; Init linklist
;************************************************************
invoke _InsertMiao,10,6
invoke _InsertMiao,9,6
invoke _InsertMiao,8,6
invoke _InsertMiao,7,6
invoke _InsertMiao,6,6
invoke _InsertMiao,5,6
; Set proc timer
invoke SetTimer,hWnd,ID_TIMER,200,NULL
.elseif eax==WM_GAME_OVER
;************************************************************
; Destroy linklist
;************************************************************
invoke _DestroyMiao
invoke KillTimer,hWnd,ID_TIMER
;invoke InvalidateRect,hWnd,NULL,TRUE
; set 0 to wGameScore
mov wGameScore,0
invoke MessageBox,NULL,addr szGameOver,addr szGameOver,MB_OK
.elseif eax==WM_CLOSE
;************************************************************
; delete buffer dc & bitmap
;************************************************************
invoke DeleteObject,hBmpBuffer
invoke DeleteDC,hDcBuffer
invoke SendMessage,NULL,WM_GAME_OVER,0,0
invoke DestroyWindow,hWnd
invoke PostQuitMessage,NULL
.elseif eax==WM_CREATE
;************************************************************
; Create buffer dc & bitmap
;************************************************************
invoke GetDC,hWnd
mov @hDc,eax
invoke CreateCompatibleDC,@hDc
mov hDcBuffer,eax
invoke CreateCompatibleBitmap,hDcBuffer,SIZE_CANVAS_WIDTH,SIZE_CANVAS_HEIGHT
mov hBmpBuffer,eax
invoke SelectObject,hDcBuffer,hBmpBuffer
invoke ReleaseDC,hWnd,@hDc
; for game start
invoke SendMessage,hWnd,WM_GAME_START,0,0
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
xor eax,eax
ret
_ProcWinMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Create window
_WinMain proc
LOCAL @stWndClass:WNDCLASSEX
LOCAL @stMsg:MSG
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke RtlZeroMemory,addr @stWndClass,sizeof @stWndClass
invoke LoadCursor,NULL,IDC_ARROW
mov @stWndClass.hCursor,eax
push hInstance
pop @stWndClass.hInstance
mov @stWndClass.cbSize,sizeof WNDCLASSEX
mov @stWndClass.style,CS_HREDRAW or CS_VREDRAW
mov @stWndClass.lpfnWndProc,offset _ProcWinMain
mov @stWndClass.hbrBackground,COLOR_WINDOW+1
mov @stWndClass.lpszClassName,offset szMainClassName
invoke RegisterClassEx,addr @stWndClass
invoke CreateWindowEx,WS_EX_CLIENTEDGE,\
offset szMainClassName,offset szMainCaption,\
WS_OVERLAPPEDWINDOW,\
100,100,SIZE_WND_WIDTH,SIZE_WND_HEIGHT,\
NULL,NULL,hInstance,NULL
mov hWinMain,eax
invoke ShowWindow,hWinMain,SW_SHOWNORMAL
invoke UpdateWindow,hWinMain
.while TRUE
invoke GetMessage,addr @stMsg,NULL,0,0
.break .if eax==0
invoke TranslateMessage,addr @stMsg
invoke DispatchMessage,addr @stMsg
.endw
ret
_WinMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
;invoke _InsertMiao,0,0
;invoke _InsertMiao,1,1
;invoke _CheckPosOnLink,1,2
;.if eax==0
; invoke MessageBox,NULL,addr szDebug1,addr szDebug1,MB_OK
;.else
; invoke MessageBox,NULL,addr szDebug2,addr szDebug2,MB_OK
;.endif
;invoke _InsertMiao,2,2
;invoke _ShowMiao
;invoke _DestroyMiao
invoke _WinMain
invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start
图:
PS :
最近小静静一直在加班,通常要到12点多,这个周末也一天都没有休息。
镇是辛苦 小静静了!
我呢,作为陪加班的,就踏踏实实调试了几天程序。
小静静现在胃也不舒服,脖子也不舒服,后背也难受,整了一身的职业病。
我应该尽我的义务,监督小静静注意身体,不能乱吃,不能休息不好了。
小静静呢,也应该配合我,听话,千万别累坏了~
等小静静的游戏GOLD了,我一定拷贝一个,只玩小静静设计的任务,一天玩10遍,嘿嘿~