Detect when a word appears in a specific area of the screen

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Elixium
Posts: 4
Joined: 26 Oct 2018, 12:49

Detect when a word appears in a specific area of the screen

26 Oct 2018, 12:58

Hi. I'm looking for a script/app that will take a rasterized/screenshot scan of an area of the screen e.g. once per minute to check if a new piece of text has appeared. The text is always the same word & the only thing that changes is the color & location of the text within this area of the screen.

Image
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Detect when a word appears in a specific area of the screen

26 Oct 2018, 15:26

Is the canvas always gonna be grey? Do the words disappear? Do they overlap? Is there ever only a single word visible at any given moment?
Elixium
Posts: 4
Joined: 26 Oct 2018, 12:49

Re: Detect when a word appears in a specific area of the screen

26 Oct 2018, 16:04

The canvas color doesn't change.
Once an instance of the word appears, it does not disappear.
The words do not overlap.
There will always be a few instances of this word visible.
User avatar
Xtra
Posts: 2750
Joined: 02 Oct 2015, 12:15

Re: Detect when a word appears in a specific area of the screen

26 Oct 2018, 16:52

Note: CaptureScreen() is 32bit only

Code: Select all

#NoEnv
#Persistent
SetWorkingDir, %A_ScriptDir%
CoordMode, Pixel, Screen
SetTimer, Checking, 60000
gosub, Checking
return

Checking:
    status := CheckForChange(0,0,200,200)
    if (status)
        MsgBox There was a change!
return

CheckForChange(x1,y1,x2,y2,reset:=0)
{
    static filename := A_ScriptDir . "\__waitforstartdrawing.png" , LastCheckImage := 0
    if (!LastCheckImage || reset)
    {
        CaptureScreen(x1 . "," . y1 . "," . x2 . "," . y2, 0, A_ScriptDir . "\__checkdrawing.png")
        LastCheckImage := 1
    }
    change := false
    ImageSearch,,,x1,y1,x2,y2, % A_ScriptDir . "\__checkdrawing.png"
    if (ErrorLevel=1)
    {
        change := true		
        CaptureScreen(x1 . "," . y1 . "," . x2 . "," . y2, 0, A_ScriptDir . "\__checkdrawing.png")
    }
    return change
}

/* CaptureScreen(aRect, bCursor, sFileTo, nQuality)
1) If the optional parameter bCursor is True, captures the cursor too.
2) If the optional parameter sFileTo is 0, set the image to Clipboard.
   If it is omitted or "", saves to screen.bmp in the script folder,
   otherwise to sFileTo which can be BMP/JPG/PNG/GIF/TIF.
3) The optional parameter nQuality is applicable only when sFileTo is JPG. Set it to the desired quality level of the resulting JPG, an integer between 0 - 100.
4) If aRect is 0/1/2/3, captures the entire desktop/active window/active client area/active monitor.
5) aRect can be comma delimited sequence of coordinates, e.g., "Left, Top, Right, Bottom" or "Left, Top, Right, Bottom, Width_Zoomed, Height_Zoomed".
   In this case, only that portion of the rectangle will be captured. Additionally, in the latter case, zoomed to the new width/height, Width_Zoomed/Height_Zoomed.

Example:
CaptureScreen(0)
CaptureScreen(1)
CaptureScreen(2)
CaptureScreen(3)
CaptureScreen("100, 100, 200, 200")
CaptureScreen("100, 100, 200, 200, 400, 400")   ; Zoomed
*/
/* Convert(sFileFr, sFileTo, nQuality)
Convert("C:\image.bmp", "C:\image.jpg")
Convert("C:\image.bmp", "C:\image.jpg", 95)
Convert(0, "C:\clip.png")   ; Save the bitmap in the clipboard to sFileTo if sFileFr is "" or 0.
*/
CaptureScreen(aRect = 0, bCursor = False, sFile = "", nQuality = "")
{
    If !aRect
    {
        SysGet, nL, 76  ; virtual screen left & top
        SysGet, nT, 77
        SysGet, nW, 78	; virtual screen width and height
        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" , "ptr", hWnd, "ptr", &rt)
        DllCall("ClientToScreen", "ptr", hWnd, "ptr", &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), NumPut(40,mi,0,"uint")
        DllCall("GetMonitorInfo", "ptr", DllCall("MonitorFromPoint", "int64", pt, "Uint", 2, "ptr"), "ptr", &mi)
        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	; convert the Left,top, right, bottom into left, top, width, height
        nT := rt2
        nW := rt3 - rt1
        nH := rt4 - rt2
        znW := rt5
        znH := rt6
    }

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

CaptureCursor(hDC, nL, nT)
{
    VarSetCapacity(mi, 32, 0), Numput(16+A_PtrSize, mi, 0, "uint")
    DllCall("GetCursorInfo", "ptr", &mi)
    bShow   := NumGet(mi, 4, "uint")
    hCursor := NumGet(mi, 8)
    xCursor := NumGet(mi,8+A_PtrSize, "int")
    yCursor := NumGet(mi,12+A_PtrSize, "int")

    DllCall("GetIconInfo", "ptr", hCursor, "ptr", &mi)
    xHotspot := NumGet(mi, 4, "uint")
    yHotspot := NumGet(mi, 8, "uint")
    hBMMask  := NumGet(mi,8+A_PtrSize)
    hBMColor := NumGet(mi,16+A_PtrSize)

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

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

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

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

    If !sFileFr
    {
        DllCall("OpenClipboard", "ptr", 0)
        If	(DllCall("IsClipboardFormatAvailable", "Uint", 2) && (hBM:=DllCall("GetClipboardData", "Uint", 2, "ptr")))
            DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "ptr", hBM, "ptr", 0, "ptr*", pImage)
        DllCall("CloseClipboard")
    }
    Else If	sFileFr Is Integer
        DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "ptr", sFileFr, "ptr", 0, "ptr*", pImage)
    Else	DllCall("gdiplus\GdipLoadImageFromFile", "wstr", sFileFr, "ptr*", pImage)
    DllCall("gdiplus\GdipGetImageEncodersSize", "UintP", nCount, "UintP", nSize)
    VarSetCapacity(ci,nSize,0)
    DllCall("gdiplus\GdipGetImageEncoders", "Uint", nCount, "Uint", nSize, "ptr", &ci)
    struct_size := 48+7*A_PtrSize, offset := 32 + 3*A_PtrSize, pCodec := &ci - struct_size
    Loop, %	nCount
        If InStr(StrGet(Numget(offset + (pCodec+=struct_size)), "utf-16") , "." . sExtTo)
            break

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

    If pImage
        pCodec < &ci + nSize	? DllCall("gdiplus\GdipSaveImageToFile", "ptr", pImage, "wstr", sFileTo, "ptr", pCodec, "ptr", pParam) : DllCall("gdiplus\GdipCreateHBITMAPFromBitmap", "ptr", pImage, "ptr*", hBitmap, "Uint", 0) . SetClipboardData(hBitmap), DllCall("gdiplus\GdipDisposeImage", "ptr", pImage)

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

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

SaveHBITMAPToFile(hBitmap, sFile)
{
    VarSetCapacity(oi,104,0)
    DllCall("GetObject", "ptr", hBitmap, "int", 64+5*A_PtrSize, "ptr", &oi)
    fObj := FileOpen(sFile, "w")
    fObj.WriteShort(0x4D42)
    fObj.WriteInt(54+NumGet(oi,36+2*A_PtrSize,"uint"))
    fObj.WriteInt64(54<<32)
    fObj.RawWrite(&oi + 16 + 2*A_PtrSize, 40)
    fObj.RawWrite(NumGet(oi, 16+A_PtrSize), NumGet(oi,36+2*A_PtrSize,"uint"))
    fObj.Close()
}

SetClipboardData(hBitmap)
{
    VarSetCapacity(oi,104,0)
    DllCall("GetObject", "ptr", hBitmap, "int", 64+5*A_PtrSize, "ptr", &oi)
    sz := NumGet(oi,36+2*A_PtrSize,"uint")
    hDIB :=	DllCall("GlobalAlloc", "Uint", 2, "Uptr", 40+sz, "ptr")
    pDIB := DllCall("GlobalLock", "ptr", hDIB, "ptr")
    DllCall("RtlMoveMemory", "ptr", pDIB, "ptr", &oi + 16 + 2*A_PtrSize, "Uptr", 40)
    DllCall("RtlMoveMemory", "ptr", pDIB+40, "ptr", NumGet(oi, 16+A_PtrSize), "Uptr", sz)
    DllCall("GlobalUnlock", "ptr", hDIB)
    DllCall("DeleteObject", "ptr", hBitmap)
    DllCall("OpenClipboard", "ptr", 0)
    DllCall("EmptyClipboard")
    DllCall("SetClipboardData", "Uint", 8, "ptr", hDIB)
    DllCall("CloseClipboard")
}
User avatar
gwarble
Posts: 525
Joined: 30 Sep 2013, 15:01

Re: Detect when a word appears in a specific area of the screen

21 Nov 2018, 17:01

Xtra wrote:
26 Oct 2018, 16:52
Note: CaptureScreen() is 32bit only
Thanks to user LinearSpoon, here is an Ansi/Unicode/32bit/64bit compatible version of CaptureScreen():
https://autohotkey.com/board/topic/1216 ... in-81-x64/

Code: Select all

/* CaptureScreen(aRect, bCursor, sFileTo, nQuality)
* Screen Capture with Transparent Windows and Mouse Cursor - by SEAN
* made compatible with Unicode or ANSI, 32 or 64bit - by Linear Spoon
1) If the optional parameter bCursor is True, captures the cursor too.
2) If the optional parameter sFileTo is 0, set the image to Clipboard.
   If it is omitted or "", saves to screen.bmp in the script folder,
   otherwise to sFileTo which can be BMP/JPG/PNG/GIF/TIF.
3) The optional parameter nQuality is applicable only when sFileTo is JPG. Set it to the desired quality level of the resulting JPG, an integer between 0 - 100.
4) If aRect is 0/1/2/3, captures the entire desktop/active window/active client area/active monitor.
5) aRect can be comma delimited sequence of coordinates, e.g., "Left, Top, Right, Bottom" or "Left, Top, Right, Bottom, Width_Zoomed, Height_Zoomed".
   In this case, only that portion of the rectangle will be captured. Additionally, in the latter case, zoomed to the new width/height, Width_Zoomed/Height_Zoomed.
*/

CaptureScreen(aRect = 0, bCursor = False, sFile = "", nQuality = "")
{
	If !aRect
	{
		SysGet, nL, 76  ; virtual screen left & top
		SysGet, nT, 77
		SysGet, nW, 78	; virtual screen width and height
		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" , "ptr", hWnd, "ptr", &rt)
		DllCall("ClientToScreen", "ptr", hWnd, "ptr", &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), NumPut(40,mi,0,"uint")
		DllCall("GetMonitorInfo", "ptr", DllCall("MonitorFromPoint", "int64", pt, "Uint", 2, "ptr"), "ptr", &mi)
		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	; convert the Left,top, right, bottom into left, top, width, height
		nT := rt2
		nW := rt3 - rt1
		nH := rt4 - rt2
		znW := rt5
		znH := rt6
	}

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

CaptureCursor(hDC, nL, nT)
{
	VarSetCapacity(mi, 32, 0), Numput(16+A_PtrSize, mi, 0, "uint")
	DllCall("GetCursorInfo", "ptr", &mi)
	bShow   := NumGet(mi, 4, "uint")
	hCursor := NumGet(mi, 8)
	xCursor := NumGet(mi,8+A_PtrSize, "int")
	yCursor := NumGet(mi,12+A_PtrSize, "int")

	DllCall("GetIconInfo", "ptr", hCursor, "ptr", &mi)
	xHotspot := NumGet(mi, 4, "uint")
	yHotspot := NumGet(mi, 8, "uint")
	hBMMask  := NumGet(mi,8+A_PtrSize)
	hBMColor := NumGet(mi,16+A_PtrSize)

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

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

Convert(sFileFr = "", sFileTo = "", nQuality = "")
{
	If (sFileTo = "")
		sFileTo := A_ScriptDir . "\screen.bmp"
	SplitPath, sFileTo, , sDirTo, sExtTo, sNameTo
	
	If Not hGdiPlus := DllCall("LoadLibrary", "str", "gdiplus.dll", "ptr")
		Return	sFileFr+0 ? SaveHBITMAPToFile(sFileFr, sDirTo (sDirTo = "" ? "" : "\") sNameTo ".bmp") : ""
	VarSetCapacity(si, 16, 0), si := Chr(1)
	DllCall("gdiplus\GdiplusStartup", "UintP", pToken, "ptr", &si, "ptr", 0)

	If !sFileFr
	{
		DllCall("OpenClipboard", "ptr", 0)
		If	(DllCall("IsClipboardFormatAvailable", "Uint", 2) && (hBM:=DllCall("GetClipboardData", "Uint", 2, "ptr")))
			DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "ptr", hBM, "ptr", 0, "ptr*", pImage)
		DllCall("CloseClipboard")
	}
	Else If	sFileFr Is Integer
		DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "ptr", sFileFr, "ptr", 0, "ptr*", pImage)
	Else	DllCall("gdiplus\GdipLoadImageFromFile", "wstr", sFileFr, "ptr*", pImage)
	DllCall("gdiplus\GdipGetImageEncodersSize", "UintP", nCount, "UintP", nSize)
	VarSetCapacity(ci,nSize,0)
	DllCall("gdiplus\GdipGetImageEncoders", "Uint", nCount, "Uint", nSize, "ptr", &ci)
	struct_size := 48+7*A_PtrSize, offset := 32 + 3*A_PtrSize, pCodec := &ci - struct_size
	Loop, %	nCount
		If InStr(StrGet(Numget(offset + (pCodec+=struct_size)), "utf-16") , "." . sExtTo)
			break

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

	If pImage
		pCodec < &ci + nSize	? DllCall("gdiplus\GdipSaveImageToFile", "ptr", pImage, "wstr", sFileTo, "ptr", pCodec, "ptr", pParam) : DllCall("gdiplus\GdipCreateHBITMAPFromBitmap", "ptr", pImage, "ptr*", hBitmap, "Uint", 0) . SetClipboardData(hBitmap), DllCall("gdiplus\GdipDisposeImage", "ptr", pImage)

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


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

SaveHBITMAPToFile(hBitmap, sFile)
{
	VarSetCapacity(oi,104,0)
	DllCall("GetObject", "ptr", hBitmap, "int", 64+5*A_PtrSize, "ptr", &oi)
	fObj := FileOpen(sFile, "w")
	fObj.WriteShort(0x4D42)
	fObj.WriteInt(54+NumGet(oi,36+2*A_PtrSize,"uint"))
	fObj.WriteInt64(54<<32)
	fObj.RawWrite(&oi + 16 + 2*A_PtrSize, 40)
	fObj.RawWrite(NumGet(oi, 16+A_PtrSize), NumGet(oi,36+2*A_PtrSize,"uint"))
	fObj.Close()
}

SetClipboardData(hBitmap)
{
	VarSetCapacity(oi,104,0)
	DllCall("GetObject", "ptr", hBitmap, "int", 64+5*A_PtrSize, "ptr", &oi)
	sz := NumGet(oi,36+2*A_PtrSize,"uint")
	hDIB :=	DllCall("GlobalAlloc", "Uint", 2, "Uptr", 40+sz, "ptr")
	pDIB := DllCall("GlobalLock", "ptr", hDIB, "ptr")
	DllCall("RtlMoveMemory", "ptr", pDIB, "ptr", &oi + 16 + 2*A_PtrSize, "Uptr", 40)
	DllCall("RtlMoveMemory", "ptr", pDIB+40, "ptr", NumGet(oi, 16+A_PtrSize), "Uptr", sz)
	DllCall("GlobalUnlock", "ptr", hDIB)
	DllCall("DeleteObject", "ptr", hBitmap)
	DllCall("OpenClipboard", "ptr", 0)
	DllCall("EmptyClipboard")
	DllCall("SetClipboardData", "Uint", 8, "ptr", hDIB)
	DllCall("CloseClipboard")
}
EitherMouse - Multiple mice, individual settings . . . . www.EitherMouse.com . . . . forum . . . .

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Marium0505 and 342 guests