[系统辅助]AutoHotkey调用内置函数截图

AutoHotkey调用内置函数截图 使用windows内置的函数实现任意区域截图

rect=%win_xx%, %win_yy%, %win_w%, %win_h%  ;目标位置信息
path = %A_ScriptDir%\配置\%win_exe%\%Edit%.bmp  ;存储位置信息
CaptureScreen(rect, False, path)
return
CaptureScreen(aRect = 0, bCursor = False, sFile = "", nQuality = "")
{
    If    !aRect
    {
        SysGet, nL, 76
        SysGet, nT, 77
        SysGet, nW, 78
        SysGet, nH, 79
    }
    Else If    aRect = 1
        WinGetPos, nL, nT, nW, nH, A
    Else If    aRect = 2
    {
        WinGet, hWnd, ID, A
        VarSetCapacity(rt, 16, 0)
        DllCall("GetClientRect" , "Uint", hWnd, "Uint", &rt)
        DllCall("ClientToScreen", "Uint", hWnd, "Uint", &rt)
        nL := NumGet(rt, 0, "int")
        nT := NumGet(rt, 4, "int")
        nW := NumGet(rt, 8)
        nH := NumGet(rt,12)
    }
    Else If    aRect = 3
    {
        VarSetCapacity(mi, 40, 0)
        DllCall("GetCursorPos", "int64P", pt)
        DllCall("GetMonitorInfoW", "Uint", DllCall("MonitorFromPoint", "int64", pt, "Uint", 2), "Uint", NumPut(40,mi)-4)
        nL := NumGet(mi, 4, "int")
        nT := NumGet(mi, 8, "int")
        nW := NumGet(mi,12, "int") - nL
        nH := NumGet(mi,16, "int") - nT
    }
    Else
    {
        StringSplit, rt, aRect, `,, %A_Space%%A_Tab%
        nL := rt1
        nT := rt2
        nW := rt3 - rt1
        nH := rt4 - rt2
        znW := rt5
        znH := rt6
    }


    mDC := DllCall("CreateCompatibleDC", "Uint", 0)
    hBM := CreateDIBSection(mDC, nW, nH)
    oBM := DllCall("SelectObject", "Uint", mDC, "Uint", hBM)
    hDC := DllCall("GetDC", "Uint", 0)
    DllCall("BitBlt", "Uint", mDC, "int", 0, "int", 0, "int", nW, "int", nH, "Uint", hDC, "int", nL, "int", nT, "Uint", 0x40000000 | 0x00CC0020)
    DllCall("ReleaseDC", "Uint", 0, "Uint", hDC)
    If    bCursor
        CaptureCursor(mDC, nL, nT)
    DllCall("SelectObject", "Uint", mDC, "Uint", oBM)
    DllCall("DeleteDC", "Uint", mDC)
    If    znW && znH
        hBM := Zoomer(hBM, nW, nH, znW, znH)
    If    sFile = 0
        SetClipboardData(hBM)
    Else    Convert(hBM, sFile, nQuality), DllCall("DeleteObject", "Uint", hBM)
}


CaptureCursor(hDC, nL, nT)
{
    VarSetCapacity(mi, 20, 0), mi := Chr(20)
    DllCall("GetCursorInfo", "Uint", &mi)
    bShow   := NumGet(mi, 4)
    hCursor := NumGet(mi, 8)
    xCursor := NumGet(mi,12)
    yCursor := NumGet(mi,16)


    If    bShow && hCursor:=DllCall("CopyIcon", "Uint", hCursor)
    {
    VarSetCapacity(ni, 20, 0)
    DllCall("GetIconInfo", "Uint", hCursor, "Uint", &ni)
    bIcon    := NumGet(ni, 0)
    xHotspot := NumGet(ni, 4)
    yHotspot := NumGet(ni, 8)
    hBMMask  := NumGet(ni,12)
    hBMColor := NumGet(ni,16)


    DllCall("DrawIcon", "Uint", hDC, "int", xCursor - xHotspot - nL, "int", yCursor - yHotspot - nT, "Uint", hCursor)
    DllCall("DestroyIcon", "Uint", hCursor)
    If    hBMMask
    DllCall("DeleteObject", "Uint", hBMMask)
    If    hBMColor
    DllCall("DeleteObject", "Uint", hBMColor)
    }
}


Zoomer(hBM, nW, nH, znW, znH)
{
    mDC1 := DllCall("CreateCompatibleDC", "Uint", 0)
    mDC2 := DllCall("CreateCompatibleDC", "Uint", 0)
    zhBM := CreateDIBSection(mDC2, znW, znH)
    oBM1 := DllCall("SelectObject", "Uint", mDC1, "Uint",  hBM)
    oBM2 := DllCall("SelectObject", "Uint", mDC2, "Uint", zhBM)
    DllCall("SetStretchBltMode", "Uint", mDC2, "int", 4)
    DllCall("StretchBlt", "Uint", mDC2, "int", 0, "int", 0, "int", znW, "int", znH, "Uint", mDC1, "int", 0, "int", 0, "int", nW, "int", nH, "Uint", 0x00CC0020)
    DllCall("SelectObject", "Uint", mDC1, "Uint", oBM1)
    DllCall("SelectObject", "Uint", mDC2, "Uint", oBM2)
    DllCall("DeleteDC", "Uint", mDC1)
    DllCall("DeleteDC", "Uint", mDC2)
    DllCall("DeleteObject", "Uint", hBM)
    Return    zhBM
}


Convert(sFileFr = "", sFileTo = "", nQuality = "")
{
    If    sFileTo  =
        sFileTo := A_ScriptDir . "\screen.bmp"
    SplitPath, sFileTo, , sDirTo, sExtTo, sNameTo


    IfNot    hGdiPlus := DllCall("LoadLibraryW", "str", "gdiplus.dll")
        Return    sFileFr+0 ? SaveHBITMAPToFile(sFileFr, sDirTo . "\" . sNameTo . ".bmp") : ""
    VarSetCapacity(si, 16, 0), si := Chr(1)
    DllCall("gdiplus\GdiplusStartup", "UintP", pToken, "Uint", &si, "Uint", 0)


    If    !sFileFr
    {
        DllCall("OpenClipboard", "Uint", 0)
        If     DllCall("IsClipboardFormatAvailable", "Uint", 2) && (hBM:=DllCall("GetClipboardData", "Uint", 2))
        DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "Uint", hBM, "Uint", 0, "UintP", pImage)
        DllCall("CloseClipboard")
    }
    Else If    sFileFr Is Integer
        DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "Uint", sFileFr, "Uint", 0, "UintP", pImage)
    Else    DllCall("gdiplus\GdipLoadImageFromFile", "WStr", sFileFr, "UintP", pImage)


    DllCall("gdiplus\GdipGetImageEncodersSize", "UintP", nCount, "UintP", nSize)
    VarSetCapacity(ci,nSize,0)
    DllCall("gdiplus\GdipGetImageEncoders", "Uint", nCount, "Uint", nSize, "Uint", &ci)


    Loop, %    nCount
        If    InStr(StrGet(NumGet(ci,76*(A_Index-1)+44) , "UTF-16"), "." . sExtTo)
        {
            pCodec := &ci+76*(A_Index-1)
            Break
        }
    If    InStr(".JPG.JPEG.JPE.JFIF", "." . sExtTo) && nQuality<>"" && pImage && pCodec
    {
    DllCall("gdiplus\GdipGetEncoderParameterListSize", "Uint", pImage, "Uint", pCodec, "UintP", nSize)
    VarSetCapacity(pi,nSize,0)
    DllCall("gdiplus\GdipGetEncoderParameterList", "Uint", pImage, "Uint", pCodec, "Uint", nSize, "Uint", &pi)
    Loop, %    NumGet(pi)
        If    NumGet(pi,28*(A_Index-1)+20)=1 && NumGet(pi,28*(A_Index-1)+24)=6
        {
            pParam := &pi+28*(A_Index-1)
            NumPut(nQuality,NumGet(NumPut(4,NumPut(1,pParam+0)+20)))
            Break
        }
    }


    If    pImage
        pCodec    ? DllCall("gdiplus\GdipSaveImageToFile", "Uint", pImage, "WStr", sFileTo, "Uint", pCodec, "Uint", pParam) : DllCall("gdiplus\GdipCreateHBITMAPFromBitmap", "Uint", pImage, "UintP", hBitmap, "Uint", 0) . SetClipboardData(hBitmap), DllCall("gdiplus\GdipDisposeImage", "Uint", pImage)


    DllCall("gdiplus\GdiplusShutdown" , "Uint", pToken)
    DllCall("FreeLibrary", "Uint", hGdiPlus)
}


CreateDIBSection(hDC, nW, nH, bpp = 32, ByRef pBits = "")
{
    NumPut(VarSetCapacity(bi, 40, 0), bi)
    NumPut(nW, bi, 4)
    NumPut(nH, bi, 8)
    NumPut(bpp, NumPut(1, bi, 12, "UShort"), 0, "Ushort")
    NumPut(0,  bi,16)
    Return    DllCall("gdi32\CreateDIBSection", "Uint", hDC, "Uint", &bi, "Uint", 0, "UintP", pBits, "Uint", 0, "Uint", 0)
}


SaveHBITMAPToFile(hBitmap, sFile)
{
    DllCall("GetObject", "Uint", hBitmap, "int", VarSetCapacity(oi,84,0), "Uint", &oi)
    hFile:=    DllCall("CreateFileW", "Uint", &sFile, "Uint", 0x40000000, "Uint", 0, "Uint", 0, "Uint", 2, "Uint", 0, "Uint", 0)
    DllCall("WriteFile", "Uint", hFile, "int64P", 0x4D42|14+40+NumGet(oi,44)<<16, "Uint", 6, "UintP", 0, "Uint", 0)
    DllCall("WriteFile", "Uint", hFile, "int64P", 54<<32, "Uint", 8, "UintP", 0, "Uint", 0)
    DllCall("WriteFile", "Uint", hFile, "Uint", &oi+24, "Uint", 40, "UintP", 0, "Uint", 0)
    DllCall("WriteFile", "Uint", hFile, "Uint", NumGet(oi,20), "Uint", NumGet(oi,44), "UintP", 0, "Uint", 0)
    DllCall("CloseHandle", "Uint", hFile)
}


SetClipboardData(hBitmap)
{
    DllCall("GetObject", "Uint", hBitmap, "int", VarSetCapacity(oi,84,0), "Uint", &oi)
    hDIB :=    DllCall("GlobalAlloc", "Uint", 2, "Uint", 40+NumGet(oi,44))
    pDIB :=    DllCall("GlobalLock", "Uint", hDIB)
    DllCall("RtlMoveMemory", "Uint", pDIB, "Uint", &oi+24, "Uint", 40)
    DllCall("RtlMoveMemory", "Uint", pDIB+40, "Uint", NumGet(oi,20), "Uint", NumGet(oi,44))
    DllCall("GlobalUnlock", "Uint", hDIB)
    DllCall("DeleteObject", "Uint", hBitmap)
    DllCall("OpenClipboard", "Uint", 0)
    DllCall("EmptyClipboard")
    DllCall("SetClipboardData", "Uint", 8, "Uint", hDIB)
    DllCall("CloseClipboard")
}


Unicode4Ansi(ByRef wString, sString)
{
    nSize := DllCall("MultiByteToWideChar", "Uint", "932", "Uint", 0, "Uint", &sString, "int", -1, "Uint", 0, "int", 0)
    VarSetCapacity(wString, nSize * 2)
    DllCall("MultiByteToWideChar", "Uint", "932", "Uint", 0, "Uint", &sString, "int", -1, "Uint", &wString, "int", nSize)
    Return    &wString
}


Ansi4Unicode(pString)
{
    nSize := DllCall("WideCharToMultiByte", "UINT", "932", "Uint", 0, "Uint", pString, "int", -1, "Uint", 0, "int",  0, "Uint", 0, "Uint", 0)
    VarSetCapacity(sString, nSize)
    DllCall("WideCharToMultiByte", "UINT", "932", "Uint", 0, "Uint", pString, "int", -1, "str", sString, "int", nSize, "Uint", 0, "Uint", 0)
;msgbox, %sString%
;FileAppend, %sString%`n, Test.txt


sString := "*.BMP"
    Return    sString
}

给TA捐赠
共{{data.count}}人
人已捐赠
其他教程

(5)承影剑之Gui事件及控制回调函数

2016-8-9 11:22:49

其他教程

[教程]AutoHotkey字符串索引窗口标题激活窗口

2016-8-9 13:27:44

5 条回复 A文章作者 M管理员
  1. YanYan

    C:\Users\wcc\Desktop\??.ahk (123) : ==> This line does not contain a recognized action.
    Specifically: IfNot hGdiPlus := DllCall(“LoadLibraryW”, “str”, “gdiplus.dll”)

    用不了,报错。

  2. 龙之心谁懂

    向大神学习了,不明觉厉?

  3. AHKiller

    ?

  4. wld

    学习了,谢谢

  5. 万能蜗牛

    为啥这个只能用 ANSI 版本的 EXE 执行, Unicode 版本的 EXE 就不能执行? 好像是 Ansi4Unicode 和 Unicode4Ansi 这两个函数会出问题.

个人中心
购物车
优惠劵
有新私信 私信列表
搜索