📄 32asmswitchwindow.asm
字号:
;---------------------------------------;
; DDRAW Demo ;
; 本人初学win32汇编不久,对其并不是太熟,当然学习汇编仅是为了学破解,
;学破解原来的目的是想自己做外挂,当然我也正在跨出这一步,只是基础太差,不知
;要到何能马月才有所成。
; 本程序主要是用汇编实现了DirectDraw的窗口化。在写这个程序时在网上查了
;很久似乎并没有用WIN32写的窗口模式的DirectDraw程序,所以只有边学习,边摸索,
;大家都知道很多游戏是全屏的。并没有提供窗口化,为了对游戏进行一些辅助性的修改
;实现窗口化是很有必要的,那么如果有人想用WIN32对游戏进行修改,那么可以共同探讨
;一下,本程序还存在一些不足之处,请指正,不过总体方向没错。
; 下一篇我将用WIN32实现全屏和窗口化之间的切换。请大家鼓力一下小弟。
; Author : Jacksheng ;
;---------------------------------------;
; View with TAB size 8
TITLE WIN32ASM EXAMPLE
.486
.MODEL FLAT, STDCALL
option casemap :none
;-----------------------------------------------------------;
; WIN32ASM / DDRAW DEMO ;
;-----------------------------------------------------------;
INCLUDE windows.inc
INCLUDE gdi32.inc
INCLUDE kernel32.inc
INCLUDE user32.inc
INCLUDE ddraw.inc
INCLUDELIB gdi32.lib
INCLUDELIB kernel32.lib
INCLUDELIB user32.lib
INCLUDELIB ddraw.lib
ICO_MAIN equ 1000h
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ;对MESSAGEBOX进行宏定义
FATAL MACRO msg
LOCAL @@msg
.DATA
@@msg db msg, 0
.CODE
INVOKE MessageBox, hWinMain, ADDR @@msg, ADDR szDisplayName, MB_OK
INVOKE ExitProcess, 0
ENDM
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ;对色进行宏定义
RGB macro red,green,blue
xor eax,eax
mov ah,blue
shl eax,8
mov ah,green
mov al,red
endm
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hInstance dd ?
hWinMain dd ?
stRt RECT <?>
stPoint POINT <?>
stPoint2 POINT <?>
lpDD LPDIRECTDRAW ? ; DDraw object
lpDDSPrimary LPDIRECTDRAWSURFACE ? ; DDraw primary surface
lpDDSStore LPDIRECTDRAWSURFACE ?
ddsd DDSURFACEDESC <?> ; DDraw surface descriptor
ddscaps DDSCAPS <?> ; DDraw capabilities
pcClipper LPDIRECTDRAWCLIPPER ?
@hDc HDC ?
stFx DDBLTFX <?>
.const
szCaptionMain db 'My first Window !',0
szText db 'Win32 Assembly, Simple and powerful !',0
szClassName db "DDRAW Plasma Demo", 0 ; class name
szDisplayName EQU <szClassName> ; window name
szTest db "This is a stinky App",0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; // old DirectDraw Initialization stuff.
;// Set a window mode DirectDraw Display.
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_Init proc
invoke DirectDrawCreate,NULL,ADDR lpDD,NULL ;建对象
.if eax !=DD_OK
FATAL "Failed to create directdraw object!"
.endif
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
DDINVOKE SetCooperativeLevel, lpDD, NULL, DDSCL_NORMAL ;建控制级非独占模式
.IF eax != DD_OK
FATAL "Couldn't set DirectDraw cooperative level"
.ENDIF
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
invoke RtlZeroMemory,addr ddsd,sizeof ddsd
mov [ddsd.dwSize], sizeof DDSURFACEDESC
mov [ddsd.dwFlags], DDSD_CAPS
mov [ddsd.ddsCaps.dwCaps], DDSCAPS_PRIMARYSURFACE
DDINVOKE CreateSurface, lpDD, ADDR ddsd, ADDR lpDDSPrimary, NULL ;建主表面
.IF eax != DD_OK
FATAL "Couldn't create primary surface"
.ENDIF
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
mov [ddsd.dwSize], sizeof DDSURFACEDESC
mov [ddsd.dwFlags], DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT
mov [ddsd.ddsCaps.dwCaps], DDSCAPS_OFFSCREENPLAIN OR DDSCAPS_3DDEVICE
mov [ddsd.dwWidth],800
mov [ddsd.dwHeight],600
DDINVOKE CreateSurface, lpDD, ADDR ddsd, ADDR lpDDSStore, NULL ;建后台表面
.IF eax != DD_OK
FATAL "Couldn't create store surface"
.ENDIF
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
DDINVOKE CreateClipper, lpDD, 0, ADDR pcClipper, NULL ;设裁剪器
.IF eax != DD_OK
FATAL "Couldn't create Clipper "
.ENDIF
DDCINVOKE SetHWnd,pcClipper, 0, hWinMain
.IF eax != DD_OK
DDCINVOKE Release,pcClipper
FATAL "Failed to create primary surface"
.ENDIF
DDSINVOKE SetClipper,lpDDSPrimary,pcClipper
.IF eax != DD_OK
DDCINVOKE Release,pcClipper
FATAL "Failed to create SetClipper primary surface"
.ENDIF
ret
_Init endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; // Load images from offscteen buffer to primary buffer
; // and for display.
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_DisPlay proc
push 0
pop stPoint.x
push 0
pop stPoint.y
invoke ClientToScreen,hWinMain,addr stPoint ;get the client area on the desktop by using this line.
xor eax,eax
mov eax,stPoint.x
mov stRt.left,eax
add eax,800
mov stRt.right,eax
mov eax,stPoint.y
mov stRt.top,eax
add eax,600
mov stRt.bottom,eax
.while TRUE
DDSINVOKE Blt,lpDDSPrimary,addr stRt, lpDDSStore,NULL,DDBLT_WAIT,NULL
.if eax == DD_OK
;ret
.BREAK
.elseif eax == DDERR_SURFACELOST
DDSINVOKE Restore, lpDDSPrimary
DDSINVOKE Restore, lpDDSStore
.elseif eax !=DDERR_WASSTILLDRAWING
ret
;FATAL "Couldn't lock surface"
.endif
.endw
ret
_DisPlay endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; a test:// The conclusion is: Under no circumstance, draw directly to
; primary Surface!// It doesn't work that way.// ...// ...
; This is just a simple test function. It has shit use in this
; project.
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_TestDraw proc pointx,pointy
;local @hDc:HDC //要设为全局变量才行.
local @Point:POINT
local @Rect:RECT
mov eax,pointx
mov @Point.x,eax
sub eax,50
mov @Rect.left,eax
add eax,100
mov @Rect.right,eax
mov eax,pointy
mov @Point.y,eax
sub eax,50
mov @Rect.top,eax
add eax,100
mov @Rect.bottom,eax
DDSINVOKE GetDC,lpDDSStore,addr @hDc
.if eax!=DD_OK
ret
.else
invoke ClientToScreen,hWinMain,addr @Point ;坐标转换即相对转为绝对因DIRECTXDRAW需要
RGB 255,0,0
invoke SetTextColor,@hDc,eax
invoke TextOut,@hDc, 20, 20,addr szText, sizeof szText
invoke Ellipse,@hDc,@Rect.left,@Rect.top,@Rect.right,@Rect.bottom
DDSINVOKE ReleaseDC,lpDDSStore,@hDc
.endif
ret
_TestDraw endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; clear both off csreen buffer and primary buffer.
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_Clear proc
mov eax,sizeof stFx
mov stFx.dwSize,eax
mov stFx.dwFillColor,0
.while TRUE
DDSINVOKE Blt,lpDDSPrimary,NULL,NULL,NULL,DDBLT_COLORFILL,addr stFx
.if eax == DD_OK
.BREAK
.elseif eax == DDERR_SURFACELOST
DDSINVOKE Restore, lpDDSPrimary
.elseif eax !=DDERR_WASSTILLDRAWING
.BREAK
.endif
.endw
.while TRUE
DDSINVOKE Blt,lpDDSStore,NULL,NULL,NULL,DDBLT_COLORFILL,addr stFx
.if eax == DD_OK
.BREAK
.elseif eax == DDERR_SURFACELOST
DDSINVOKE Restore, lpDDSStore
.elseif eax !=DDERR_WASSTILLDRAWING
.BREAK
.endif
.endw
ret
_Clear endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; // make sure all things are terminated and set to NULL
;// when application ends.
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_Terminate proc
_Terminate endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 窗口过程
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcWinMain proc uses ebx edi esi,hWnd,uMsg,wParam,lParam
local @stPs:PAINTSTRUCT
local @stRect:RECT
mov eax,uMsg
;********************************************************************
.if eax== WM_LBUTTONDOWN
mov eax,lParam
and eax,0FFFFh
mov stPoint2.x,eax
mov eax,lParam
shr eax,16
mov stPoint2.y,eax
;invoke GetCursorPos,addr stPoint2
invoke _Clear
invoke _TestDraw,stPoint2.x,stPoint2.y
invoke _DisPlay
;********************************************************************
.elseif eax == WM_CLOSE
FATAL "Please accept Quit!"
invoke DestroyWindow,hWinMain
invoke PostQuitMessage,NULL
;********************************************************************
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
;********************************************************************
xor eax,eax
ret
_ProcWinMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_WinMain proc
local @stWndClass:WNDCLASSEX
local @stMsg:MSG
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke RtlZeroMemory,addr @stWndClass,sizeof @stWndClass
;********************************************************************
; 注册窗口类
;********************************************************************
invoke LoadIcon,NULL,IDI_INFORMATION
mov @stWndClass.hIcon,eax
invoke LoadCursor,0,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
INVOKE GetStockObject, BLACK_BRUSH
;mov [wc.hbrBackground], eax
mov @stWndClass.hbrBackground,eax;COLOR_WINDOW + 1
mov @stWndClass.lpszClassName,offset szClassName
invoke RegisterClassEx,addr @stWndClass
;********************************************************************
; 建立并显示窗口
;********************************************************************
invoke CreateWindowEx,WS_EX_CLIENTEDGE,\
offset szClassName,offset szCaptionMain,\
WS_OVERLAPPEDWINDOW,\
100,100,800,600,\
NULL,NULL,hInstance,NULL
mov hWinMain,eax
invoke _Init
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:
call _WinMain
invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -