用MASM32编程截取屏幕

    技术2022-05-11  136

    ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<; 功能: 把屏幕内容拷贝到剪贴板并显示在程序窗口上; 作者: Purple Endurer;  环境: Windows 2000 PRO + MASM32 V8;; 日志; ---------------------; 2005.12.24 创建!;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<.386.model flat, stdcalloption casemap:noneinclude /masm32/include/windows.incinclude /masm32/include/gdi32.incinclude /masm32/include/kernel32.incinclude /masm32/include/user32.inc

    includelib /masm32/lib/gdi32.libincludelib /masm32/lib/kernel32.libincludelib /masm32/lib/user32.lib

    DlgProc PROTO :DWORD, :DWORD, :DWORD, :DWORDCopyScreenToBitmap PROTO :DWORDCopyBMPtoClipboard PROTO :HANDLE, :HWNDDrawBMP PROTO :HWND, :HANDLE

    m_m2m MACRO d1, d2    push d2    pop d1ENDM

    IDD_dlgCopyScr  equ 8000IDC_btnCopyScr  equ 1008

    .data?g_hInstance HINSTANCE ?g_ScrRect   RECT    <>

    .codestart:    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, eax

    DlgProc 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    retDlgProc 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

        retCopyScreenToBitmap 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    retCopyBMPtoClipboard 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    retDrawBMP endp

    end start

    ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<;资源文件rsrc.rc;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<#include "/masm32/include/resource.h"

    #define IDD_dlgcopyScr              8000#define IDC_btnCopyScr              1008

    IDD_dlgcopyScr DIALOG 20, 20, 295, 165STYLE 0x0004 | DS_CENTER | WS_CAPTION | DS_SYSMODAL | WS_SYSMENU | WS_MINIMIZEBOX      | WS_VISIBLE | WS_OVERLAPPED | DS_MODALFRAME | DS_3DLOOKCAPTION "拷贝屏幕"{  PUSHBUTTON      "&C 拷贝屏幕", IDC_btnCopyScr, 5, 5, 52, 52, WS_BORDER}


    最新回复(0)