以下是代码片段: ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; 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
|