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.
Detect when a word appears in a specific area of the screen
Re: Detect when a word appears in a specific area of the screen
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?
Re: Detect when a word appears in a specific area of the screen
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.
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.
Re: Detect when a word appears in a specific area of the screen
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")
}
Re: Detect when a word appears in a specific area of the screen
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 . . . .
Who is online
Users browsing this forum: bobstoner289, Google [Bot], peter_ahk and 323 guests