;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ; 功能: 把屏幕内容拷贝到剪贴板并显示在程序窗口上 ; 作者: Purple Endurer ; 环境: Windows 2000 PRO + MASM32 V8 ; ; 日志 ; --------------------- ; 2005.12.24 创建! ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< .386 .model flat, stdcall option casemap:none include /masm32/include/windows.inc include /masm32/include/gdi32.inc include /masm32/include/kernel32.inc include /masm32/include/user32.incincludelib /masm32/lib/gdi32.lib includelib /masm32/lib/kernel32.lib includelib /masm32/lib/user32.libDlgProc PROTO :DWORD, :DWORD, :DWORD, :DWORD CopyScreenToBitmap PROTO :DWORD CopyBMPtoClipboard PROTO :HANDLE, :HWND DrawBMP PROTO :HWND, :HANDLEm_m2m MACRO d1, d2 push d2 pop d1 ENDMIDD_dlgCopyScr equ 8000 IDC_btnCopyScr equ 1008.data? g_hInstance HINSTANCE ? g_ScrRect RECT <>.code start: invoke GetModuleHandle, NULL mov g_hInstance, eax ;m_m2m g_ScrRect.top, 0 ;m_m2m g_ScrRect.left, 0 ;m_m2m g_ScrRect.bottom, 200 ;m_m2m g_ScrRect.right, 100 invoke DialogBoxParam, g_hInstance, IDD_dlgCopyScr, NULL, OFFSET DlgProc, NULL invoke ExitProcess, eaxDlgProc proc hWnd: HWND, uMsg: UINT, wParam: WPARAM, lParam: LPARAM .IF uMsg == WM_CLOSE invoke EndDialog, hWnd, NULL ;.ELSEIF uMsg == WM_INITDIALOG .ELSEIF (uMsg == WM_COMMAND) mov eax, wParam mov edx, eax shr edx, 16 .if (dx == BN_CLICKED) ;If button is clicked .IF (eax == IDC_btnCopyScr) invoke GetDesktopWindow invoke GetWindowRect, eax, ADDR g_ScrRect invoke CopyScreenToBitmap, ADDR g_ScrRect push eax invoke CopyBMPtoClipboard, eax, hWnd pop eax invoke DrawBMP, hWnd, eax .ENDIF .endif .ELSE mov eax, FALSE ret .ENDIF mov eax, TRUE ret DlgProc endp; lpRect 为指向要拷贝的屏幕区域的坐标结构的指针 CopyScreenToBitmap proc lpRect: DWORD LOCAL hScrDC, hMemDC: HDC ;屏幕和内存设备描述表 LOCAL hBitmap, hOldBitmap: HBITMAP ;位图句柄 LOCAL nX, nY, nX2, nY2: DWORD ;选定区域坐标 LOCAL nWidth, nHeight: DWORD ;位图宽度和高度 LOCAL xScrn, yScrn: DWORD ;屏幕分辨率 ;判断选定区域是否为空矩形 invoke IsRectEmpty, lpRect or eax, eax jz @F ;m_m2m eax, 1 ;是空矩形 ret @@: ;为屏幕创建设备描述表 xor eax, eax jz @F szDisplay db "DISPLAY", 0 @@: invoke CreateDC, ADDR szDisplay, NULL, NULL, NULL cmp eax, NULL jne @F ;m_m2m eax, 2 ;不能创建DC ret @@: mov hScrDC, eax ;为屏幕设备描述表创建兼容的内存设备描述表 invoke CreateCompatibleDC, hScrDC cmp eax, NULL jne @F ;m_m2m eax, 3 ;不能创建兼容的内存设备描述表 ret @@: mov hMemDC, eax ;获得选定区域坐标 mov eax, lpRect assume eax: ptr RECT m_m2m nX, [eax].left m_m2m nY, [eax].top m_m2m nX2, [eax].right m_m2m nY2, [eax].bottom assume eax: nothing ;获得屏幕分辨率 invoke GetDeviceCaps, hScrDC, HORZRES mov xScrn, eax invoke GetDeviceCaps, hScrDC, VERTRES mov yScrn, eax ;确保选定区域是可见的 .if (nX < 0) m_m2m nX, 0 .endif .if (nY < 0) m_m2m nY, 0 .endif mov eax, nX2 .if (eax > xScrn) m_m2m nX2, xScrn .endif mov eax, nY2 .if (eax > yScrn) m_m2m nY2, yScrn .endif mov eax, nX2 sub eax, nX mov nWidth, eax mov eax, nY2 sub eax, nY mov nHeight, eax ;创建一个与屏幕设备描述表兼容的位图 invoke CreateCompatibleBitmap, hScrDC, nWidth, nHeight cmp eax, NULL jne @F ;m_m2m eax, 4 ;不能创建屏幕设备描述表兼容的位图 ret @@: mov hBitmap, eax ;把新位图选到内存设备描述表中 invoke SelectObject, hMemDC, hBitmap cmp eax, NULL jne @F ;m_m2m eax, 5 ;an error occurs and the selected object is not a region ret @@: cmp eax, GDI_ERROR jne @F ;m_m2m eax, 6 ret @@: mov hOldBitmap, eax ;把屏幕设备描述表拷贝到内存设备描述表中 invoke BitBlt, hMemDC, 0, 0, nWidth, nHeight, hScrDC, nX, nY, SRCCOPY ;得到屏幕位图的句柄 invoke SelectObject, hMemDC, hOldBitmap push eax ;mov hBitmap, eax ;清除 invoke DeleteDC, hScrDC invoke DeleteDC, hMemDC ;返回位图句柄 pop eax ;mov eax, hBitmap ret CopyScreenToBitmap endp;得到屏幕位图句柄以后,我们可以把屏幕内容粘贴到剪贴板上 ;hBitmap: 位图句柄 ;hWnd: 程序窗口句柄 CopyBMPtoClipboard proc hBitmap: HANDLE, hWnd: HWND invoke OpenClipboard, hWnd ; or eax, eax jnz @F m_m2m eax, 1 ret @@: ;清空剪贴板 invoke EmptyClipboard or eax, eax jnz @F m_m2m eax, 2 ret @@: ;把位图内容粘贴到剪贴板上 invoke SetClipboardData, CF_BITMAP, hBitmap or eax, eax jnz @F m_m2m eax, 3 ret @@: ;关闭剪贴板 invoke CloseClipboard or eax, eax jnz @F m_m2m eax, 4 ret @@: xor eax, eax ret CopyBMPtoClipboard endp;在指定窗口上绘制位图 DrawBMP proc hWnd: HWND, hBmp: HANDLE LOCAL hDC: HDC LOCAL hOld: DWORD LOCAL memDC :DWORD invoke GetDC, hWnd mov hDC, eax invoke CreateCompatibleDC, eax mov memDC, eax invoke SelectObject, memDC, hBmp mov hOld, eax invoke BitBlt, hDC, 120, 0, 1000, 1000, memDC, 0, 0, SRCCOPY invoke SelectObject, hDC, hOld invoke DeleteDC, memDC invoke DeleteDC, hDC ;xor eax, eax ret DrawBMP endpend start ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ;资源文件rsrc.rc ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< #include "/masm32/include/resource.h"#define IDD_dlgcopyScr 8000 #define IDC_btnCopyScr 1008IDD_dlgcopyScr DIALOG 20, 20, 295, 165 STYLE 0x0004 | DS_CENTER | WS_CAPTION | DS_SYSMODAL | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE | WS_OVERLAPPED | DS_MODALFRAME | DS_3DLOOK CAPTION "拷贝屏幕" { PUSHBUTTON "&C 拷贝屏幕", IDC_btnCopyScr, 5, 5, 52, 52, WS_BORDER }