📄 huibiantuxinchaozuo.txt
字号:
源程序 - 汇编源文件
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Programmed by 罗云彬, bigluo@telekbird.com.cn
; Website: http://asm.yeah.net
; LuoYunBin's Win32 ASM page (罗云彬的编程乐园)
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 版本信息
; 汇编教程附带源程序 - 屏幕放大器
; V1.0 ------ 2000年7月1日
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat, stdcall
option casemap :none ; case sensitive
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 数据
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include user32.inc
include kernel32.inc
include comctl32.inc
include comdlg32.inc
include gdi32.inc
includelib user32.lib
includelib kernel32.lib
includelib comctl32.lib
includelib comdlg32.lib
includelib gdi32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Equ 数据
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
DLG_MAIN equ 1000
ID_BITMAP equ 1001
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hWinPic dd ?
hDcMem dd ?
hBitmap dd ?
hWinDesktop dd ?
hInstance dd ?
szBuffer db 256 dup (?)
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 子程序声明
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcDlgMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
.data
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
include Win.asm
;********************************************************************
_ProcDlgMain proc uses ebx edi esi, \
hWnd:DWORD,wMsg:DWORD,wParam:DWORD,lParam:DWORD
local @stPoint:POINT
local @hDcDesktop,@hDcPic
mov eax,wMsg
.if eax == WM_CLOSE
invoke EndDialog,hWnd,NULL
invoke KillTimer,hWnd,1
invoke DeleteDC,hDcMem
invoke DeleteObject,hBitmap
; *******************************************************************
.elseif eax == WM_INITDIALOG
invoke GetDlgItem,hWnd,ID_BITMAP
mov hWinPic,eax
invoke GetDesktopWindow
mov hWinDesktop,eax
invoke SetWindowPos,hWnd,HWND_TOPMOST,0,0,0,0,\
SWP_NOMOVE or SWP_NOSIZE
; *******************************************************************
invoke GetDC,hWinDesktop
mov @hDcDesktop,eax
invoke CreateCompatibleDC,@hDcDesktop
mov hDcMem,eax
invoke CreateCompatibleBitmap,@hDcDesktop,80,80
mov hBitmap,eax
invoke SelectObject,hDcMem,hBitmap
invoke ReleaseDC,hWinDesktop,@hDcDesktop
invoke SetTimer,hWnd,1,100,NULL
; *******************************************************************
.elseif eax == WM_TIMER
invoke GetCursorPos,addr @stPoint
sub @stPoint.x,20
sub @stPoint.y,20
.if @stPoint.x < 0
mov @stPoint.x,0
.endif
.if @stPoint.y < 0
mov @stPoint.y,0
.endif
invoke GetDC,hWinDesktop
mov @hDcDesktop,eax
invoke GetDC,hWinPic
mov @hDcPic,eax
invoke PatBlt,hDcMem,0,0,80,80,BLACKNESS
invoke StretchBlt,hDcMem,0,0,80,80,\
@hDcDesktop,@stPoint.x,@stPoint.y,40,40,SRCCOPY
invoke BitBlt,@hDcPic,0,0,80,80,\
hDcMem,0,0,SRCCOPY
invoke ReleaseDC,hWinDesktop,@hDcDesktop
invoke ReleaseDC,hWinPic,@hDcPic
.else
;********************************************************************
; 注意:对话框的消息处理后,要返回 TRUE,对没有处理的消息
; 要返回 FALSE
;********************************************************************
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
_ProcDlgMain endp
;********************************************************************
start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcDlgMain,0
invoke ExitProcess,NULL
end start
程序的分析和要点
在程序的初始化中,我们用GetDc 取的桌面的屏幕的 DC,再用 CreateCompatibleDC 建立一个内存DC做缓冲区,建立一个位图再用 SelectObject 把 hDcMem 设置为这个位图是为了是 hDcMem 的大小变为 80x80。
invoke GetDC,hWinDesktop
mov @hDcDesktop,eax
invoke CreateCompatibleDC,@hDcDesktop
mov hDcMem,eax
invoke CreateCompatibleBitmap,@hDcDesktop,80,80
mov hBitmap,eax
invoke SelectObject,hDcMem,hBitmap
invoke ReleaseDC,hWinDesktop,@hDcDesktop
然后在程序的每 0.1 秒一次的 WM_TIMER 定时器消息中,我们先用 GetDC 取得桌面和对话框中文本框的句柄,然后用 PatBlt 把内存DC清除为黑色,再用 StretchBlt 从桌面DC中拷贝 40x40的区域到内存 DC 中,新的大小是 80x80(放大功能就是这样实现的),拷贝的位置是用 GetCursorPos 取得的,也就是鼠标的当前位置,最后用 BitBlt 把内存DC 拷贝到对话框中。如果直接把桌面DC 拷贝到对话框中也可以,但是当鼠标移动到屏幕边缘上时,由于屏幕外的点是无效的,所以对话框中的一部分会花屏,大家可以改动程序试试。
invoke GetCursorPos,addr @stPoint
invoke GetDC,hWinDesktop
mov @hDcDesktop,eax
invoke GetDC,hWinPic
mov @hDcPic,eax
invoke PatBlt,hDcMem,0,0,80,80,BLACKNESS
invoke StretchBlt,hDcMem,0,0,80,80,\
@hDcDesktop,@stPoint.x,@stPoint.y,40,40,SRCCOPY
invoke BitBlt,@hDcPic,0,0,80,80,\
hDcMem,0,0,SRCCOPY
invoke ReleaseDC,hWinDesktop,@hDcDesktop
invoke ReleaseDC,hWinPic,@hDcPic
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -