I'm currently working on some of the components of a larger project. As far as I can tell everything is working exactly as it should, but experience tells me that different versions of windows etc can play a role in how things work out. So I'm hoping that I can get a few people that can test the current functionality on a few different systems.
The main function of the current script is to simple allow the user to select a region of any monitor while showing the area selected with some simple lines running along the x and y axis for the starting corner and ending corner.
If the user switches monitors the window containing the lines should automatically follow and resize its self to the dimensions of the new monitor.
As far as I can tell it is working the way it should, but both of my two monitors have the exact same dimensions 1366x768 so I can't definitively same that it's working as expected.
A secondary function of the current script is to take a screenshot based on the dimensions selected. Once again everything is working fine, and I don't foresee there being any problems with this, but if for some reason the first function isn't working properly, there could be a issue here.
The last function of the current script is to run a image search on the screen shot taken by the second function. This isn't really a planned part of the larger project, but when I had the other two functions added in I could see that I was only a few lines of code from adding it in. So I just decided to add it in and see if there are any issues running it on other computers.
So here is what I need from you if you are so kind to help me out.
When you run the script, you will see a simple gui with 3 buttons on it. There are also 3 hotkeys that also execute the same functions as each of the 3 buttons. These hotkeys are Numpad1 - 2 and 3 and each corresponds to each of the buttons in the same order.
Once the script is running, press the "Take Screen Shot" button (or press numpad1). Once pressed, you should see two lines centered on your cursor going all the way across the full width and full height of your screen.
While the lines are there, move your cursor to any other monitor, the lines should be drawn on any screen.
Next press the left mouse button, this will lock the position of the first lines and create another set of them as well as a rectangle that fills the space between them.
If the second set of lines is to the left and below the center of the first set you should see a green translucent rectangle filling the space, else you should see a red rectangle. If the box is red you shouldn't be able to exit it, but if the box is green, clicking will remove the graphics from your screen. Next you will here a beep and the gui should now have a copy of the image you just took. It is set to max out at 300x300 depending on the ratio of width and height of the screenshot.
Next click the "Set Search Area" button, it works exactly the same way the first time did, this time it is just setting a area for the search. So if need be, redo the first button and get a small screenshot and then with the second button just set a area that contains the first.
Lastly, press "Search", if it finds the image it will beep once and move your cursor to where it found the image +20px x and y offset.
There is no loop so don't worry about it getting stuck.
Hopefully everything works exactly as expected regardless of computer/system etc.
If you are kind enough to help.
Please give the outcome of the tests, whether or not you have at least two different monitor sizes (optionally how many monitors and or resolutions). And your OS.
I am running a two monitor setup (both 1366x768) and am running Windows 8.1 64bit.
*** while setting the positions, you can press the hotkeys to restart ***
*** You can also right click the gui or press esc to exit the script ***
***The script creates a folder in the same directory that you create this script to hold the screen shot.
Once you are done running and want to do cleanup, just delete the script and the folder called "Temp Screen Shots"***
Here is the script. It contains everything needed to run.
Code: Select all
;Written By: Hellbent aka CivReborn
;Date: June 15th 2019
#SingleInstance,Force
SetBatchLines,-1
IfNotExist,%A_ScriptDir%\Recorded Shots
FileCreateDir, %A_ScriptDir%\Temp Screen Shots
SetWorkingDir,%A_ScriptDir%\Temp Screen Shots
Coordmode,Mouse,screen
CoordMode,Pixel,Screen
global CapActive:=0,SP,XCAP,YCAP,WCAP,HCAP,OB:=0,CAPIT:=0
global CapWin:={},Monitors := New MonitorClass()
Gdip_Startup()
global TXC,TYC,BB:=New_Brush("000000","88"),GB:=New_Brush("00ff00","55"),RB:=New_Brush("ff0000","55")
Gui,1:+AlwaysOnTop -DPIScale +HWNDGUI1HWND
Gui,1:Color,333333,444444
Gui,1:Font,cwhite s10 Bold ,Segoe UI
Gui,1:Add,Button,xm ym w300 h30 -Theme gSet_Capture_Area vSCAP,Take Screen Shot
Gui,1:Add,Button,xm w300 h30 -Theme gSet_Capture_Area vSSA,Set Search Area
Gui,1:Add,Button,xm w300 h30 -Theme gImageSearch,Search
Gui,1:Add,Picture,xm y+10 w300 h300 vPic gUpdatePic,% A_WorkingDir "\Test Screen Shot.png"
UpdatePic()
Gui,1:Show,AutoSize,HB Snap it
return
GuiClose:
GuiContextMenu:
2GuiContextMenu:
*ESC::
ExitApp
UpdatePic(){
static FakePic
Gui,Fake:Add,Picture,vFakePic,% A_WorkingDir "\Test Screen Shot.png"
GuiControlGet,Pos,Fake:Pos,FakePic
Gui,Fake:Destroy
if(PosW<=300&&PosH<=300){
NW:=PosW,NH:=PosH
}else if(PosW>PosH){
ratio:=PosH/PosW,NW:=300,NH:=300*Ratio
}else if(PosW<PosH){
ratio:=PosW/PosH,NH:=300,NW:=300*Ratio
}else {
NW:=300,NH:=300
}
GuiControl,1:Move,Pic,% "w" NW " h" NH
GuiControl,1:,Pic,% A_WorkingDir "\Test Screen Shot.png"
Gui,1:Show,AutoSize
}
Set_Capture_Area:
if(A_GuiControl="SCAP")
CAPIT:=1
Create_Capture_Size_Window()
return
Numpad3::
ImageSearch:
ImageSearch,foundx,foundy,XCAP,YCAP,XCAP+WCAP,YCAP+HCAP,%A_WorkingDir%\Test Screen Shot.png
if(ErrorLevel=0){
SoundBeep,500
MouseMove,FoundX+20,FoundY+20
}else if(ErrorLevel=1){
Loop 3
SoundBeep,600
}
return
Create_Capture_Size_Window(){
static ft
Gui,2:Destroy
CapWin:=Layered_Window_SetUp(3,0,0,A_ScreenWidth,A_ScreenHeight,"2","+AlwaysOnTop -DPIScale -Caption +Owner1")
Max:=Monitors.Get_Largest_Monitor_Size()
CapWin.hbm:=CreateDIBSection(Max.Width,Max.Height)
CapWin.hdc := CreateCompatibleDC()
CapWin.obm := SelectObject(CapWin.hdc,CapWin.hbm),CapWin.G := Gdip_GraphicsFromHDC(CapWin.hdc)
Gdip_SetSmoothingMode(CapWin.G,3)
;~ ToolTip,% Max.Width "`n" Max.Height
if(!ft){
Monitors.Set_Window_Move_Timer(GUINAME:=2,GUIHWND:=CapWin.hwnd,TCount:=300,xpOff:=0,ypOff:=0,xr:=1,yr:=1,Fill_Screen:=1)
ft:=1
}else {
Monitors.Window_Move_Obj.GUIHWND:=CapWin.hwnd
Monitors.Turn_On_Window_Move_Timer()
}
CapActive:=1,SP:=0,OB:=0
SetTimer,Set_Positions,10
}
Set_Positions(){
Coordmode,Mouse,Window
If(!WinActive("ahk_Id" CapWin.Hwnd)){
WinActivate,% "ahk_Id" CapWin.Hwnd
}
Gdip_GraphicsClear(CapWin.g)
MouseGetPos,tx,ty
if(SP=0){
Fill_Box(CapWin.G,BB,tx,0,1,Monitors.Monitor[Monitors.Window_Move_Obj.Current_Monitor].Bottom-Monitors.Monitor[Monitors.Window_Move_Obj.Current_Monitor].Top)
Fill_Box(CapWin.G,BB,0,ty,Monitors.Monitor[Monitors.Window_Move_Obj.Current_Monitor].Right-Monitors.Monitor[Monitors.Window_Move_Obj.Current_Monitor].Left,1)
TXC:=tx,TYC:=ty
}else if(SP=1){
Fill_Box(CapWin.G,BB,TXC,0,1,Monitors.Monitor[Monitors.Window_Move_Obj.Current_Monitor].Bottom-Monitors.Monitor[Monitors.Window_Move_Obj.Current_Monitor].Top)
Fill_Box(CapWin.G,BB,0,TYC,Monitors.Monitor[Monitors.Window_Move_Obj.Current_Monitor].Right-Monitors.Monitor[Monitors.Window_Move_Obj.Current_Monitor].Left,1)
Fill_Box(CapWin.G,BB,tx,0,1,Monitors.Monitor[Monitors.Window_Move_Obj.Current_Monitor].Bottom-Monitors.Monitor[Monitors.Window_Move_Obj.Current_Monitor].Top)
Fill_Box(CapWin.G,BB,0,ty,Monitors.Monitor[Monitors.Window_Move_Obj.Current_Monitor].Right-Monitors.Monitor[Monitors.Window_Move_Obj.Current_Monitor].Left,1)
if(TXC<tx&&TYC<ty){
Fill_Box(CapWin.G,GB,TXC,TYC,tx-TXC,ty-TYC)
WCAP:=tx-TXC,HCAP:=ty-TYC,OB:=0
XCAP:=TXC+Monitors.Monitor[Monitors.Window_Move_Obj.Current_Monitor].Left,YCAP:=TYC+Monitors.Monitor[Monitors.Window_Move_Obj.Current_Monitor].Top
}else if(TXC>tx&&TYC<ty){
Fill_Box(CapWin.G,RB,tx,TYC,TXC-tx,ty-TYC)
OB:=1
}else if(TXC>tx&&TYC>ty){
Fill_Box(CapWin.G,RB,tx,ty,TXC-tx,TYC-ty)
OB:=1
}else if(TXC<tx&&TYC>ty){
Fill_Box(CapWin.G,RB,TXC,ty,tx-TXC,TYC-ty)
OB:=1
}
}
UpdateLayeredWindow(CapWin.hwnd, CapWin.hdc,Monitors.Monitor[Monitors.Window_Move_Obj.Current_Monitor].Left,Monitors.Monitor[Monitors.Window_Move_Obj.Current_Monitor].Top,Monitors.Monitor[Monitors.Window_Move_Obj.Current_Monitor].Right-Monitors.Monitor[Monitors.Window_Move_Obj.Current_Monitor].Left, Monitors.Monitor[Monitors.Window_Move_Obj.Current_Monitor].Bottom-Monitors.Monitor[Monitors.Window_Move_Obj.Current_Monitor].Top)
}
#IF (CapActive=1)
LButton::
if(SP=0)
SP:=1
else if(SP=1&&OB=0){
Monitors.Turn_Off_Window_Move_Timer()
CapActive:=0
SelectObject(CapWin.hdc,CapWin.obm),DeleteObject(CapWin.hbm),DeleteDC(CapWin.hdc),gdip_deleteGraphics(CapWin.g)
CapWin:="",SP:=0
Gui,2:Destroy
SetTimer,Set_Positions,Off
if(CAPIT)
gosub,Take_ScreenShot
}
return
#IF
Numpad1::
SelectObject(CapWin.hdc,CapWin.obm),DeleteObject(CapWin.hbm),DeleteDC(CapWin.hdc),gdip_deleteGraphics(CapWin.g)
CapWin:="",SP:=0,CapActive:=0,CAPIT:=1
Create_Capture_Size_Window()
return
Numpad2::
SelectObject(CapWin.hdc,CapWin.obm),DeleteObject(CapWin.hbm),DeleteDC(CapWin.hdc),gdip_deleteGraphics(CapWin.g)
CapWin:="",SP:=0,CapActive:=0,CAPIT:=0
Create_Capture_Size_Window()
return
Take_ScreenShot:
CAPIT:=0
TempBitmap:=Gdip_BitmapFromScreen(XCAP "|" YCAP "|" WCAP "|" HCAP)
Gdip_SaveBitmapToFile(TempBitmap,A_WorkingDir "\Test Screen Shot.png", 100)
Gdip_DisposeImage(TempBitmap)
SoundBeep,400,300
SetPicToWindow()
return
SetPicToWindow(){
static FakePic
Gui,Fake:Add,Picture,vFakePic,% A_WorkingDir "\Test Screen Shot.png"
GuiControlGet,Pos,Fake:Pos,FakePic
Gui,Fake:Destroy
if(PosW<=300&&PosH<=300){
NW:=PosW
NH:=PosH
}else if(PosW>PosH){
ratio:=PosH/PosW
NW:=300
NH:=300*Ratio
}else if(PosW<PosH){
ratio:=PosW/PosH
NH:=300
NW:=300*Ratio
}else {
NW:=300
NH:=300
}
GuiControl,1:Move,Pic,% "w" NW " h" NH
GuiControl,1:,Pic,% A_WorkingDir "\Test Screen Shot.png"
Gui,1:Show,AutoSize
}
;-------------------------------------------------------------------------------------------------
;-------------------------------------------------------------------------------------------------
;-------------------------------------------------------------------------------------------------
class MonitorClass {
__New(){
This._SetMonCount()
This._SetPrimeMonitor()
This._Set_Bounds()
}
_SetMonCount(){
local MC
SysGet, MC, MonitorCount
This.MonitorCount := MC
}
_SetPrimeMonitor(){
local PM
SysGet, PM, MonitorPrimary
This.PrimeMonitor := PM
}
_Set_Bounds(){
local bmon,bmonLeft,bmonRight,bmonTop,bmonBottom
This.Monitors:=[]
Loop,% This.MonitorCount {
SysGet, bmon, Monitor, % A_Index
This.Monitor[A_Index]:= { Left : bmonLeft
, Top : bmonTop
, Right : bmonRight
, Bottom : bmonBottom }
}
}
Get_Current_Monitor(){
local x,y
CoordMode,Mouse,Screen
MouseGetPos,x,y
Loop,% This.MonitorCount {
if(x>=This.Monitor[A_Index].Left&&x<=This.Monitor[A_Index].Right&&y>=This.Monitor[A_Index].Top&&y<=This.Monitor[A_Index].Bottom){
return A_Index
}
}
}
Get_New_Window_Position(curMon,xpOff,ypOff,xr,yr){
local tposa:="",tposa:={}
if(xr=1) ; 1 xr = relative to the left side ; 2 xr = relative to the right side
tposa.x:=This.Monitor[curMon].Left+xpOff
else
tposa.x:=This.Monitor[curMon].Right-xpOff
if(yr=1) ; 1 yr = relative to the top ; 2 yr = relative to the bottom
tposa.y:=This.Monitor[curMon].Top+ypOff
else
tposa.y:=This.Monitor[curMon].Bottom-ypOff
return tposa
}
Set_Window_Move_Timer(GUINAME:=1,GUIHWND:="",TCount:=500,xpOff:=0,ypOff:=0,xr:=1,yr:=1,Fill_Screen:=0){
local Window_Timer
This.Window_Move_Obj:= { Interval : TCount
, GUINAME : GUINAME
, FILLSCREEN : Fill_Screen
, GUIHWND : GUIHWND
, XPOFF : xpOff
, YPOFF : ypOff
, XRelative : xr
, YRelative : yr
, Current_Monitor : This.Get_Current_Monitor()
, Old_Monitor : This.Get_Current_Monitor()
, NEW_GUI_POS : This.Get_New_Window_Position(This.Get_Current_Monitor(),xpOff,ypOff,xr,yr) }
This.Window_Timer := Window_Timer := ObjBindMethod(This, "_Window_Move_Timer")
This._Set_TFTime()
SetTimer,%Window_Timer%,%TCount%
}
Get_Largest_Monitor_Size(){
local tempMSW:="",tempMSH:=""
Loop,% This.MonitorCount {
if(This.Monitor[A_Index].Right-This.Monitor[A_Index].Left>=This.Monitor[A_Index+1].Right-This.Monitor[A_Index+1].Left&&This.Monitor[A_Index].Right-This.Monitor[A_Index].Left>=This.Monitor[tempMSW].Right-This.Monitor[tempMSW].Left)
tempMSW:=A_index
if(This.Monitor[A_Index].Bottom-This.Monitor[A_Index].Top>=This.Monitor[A_Index+1].Bottom-This.Monitor[A_Index+1].Top&&This.Monitor[A_Index].Bottom-This.Monitor[A_Index].Top>=This.Monitor[tempMSH].Bottom-This.Monitor[tempMSH].Top)
tempMSH:=A_index
}
This.Max_Monitor_Dimensions := {Width: This.Monitor[tempMSW].Right-This.Monitor[tempMSW].Left, Height: This.Monitor[tempMSH].Bottom-This.Monitor[tempMSH].Top}
return This.Max_Monitor_Dimensions
}
_Window_Move_Timer(){
This.Window_Move_Obj.Current_Monitor := This.Get_Current_Monitor()
if(This.Window_Move_Obj.Current_Monitor!=This.Window_Move_Obj.Old_Monitor&&!DllCall("IsIconic", "Ptr", This.Window_Move_Obj.GUIHWND, "UInt")){
This.Window_Move_Obj.NEW_GUI_POS:=This.Get_New_Window_Position(This.Window_Move_Obj.Current_Monitor,This.Window_Move_Obj.XPOFF,This.Window_Move_Obj.YPOFF,This.Window_Move_Obj.XRelative,This.Window_Move_Obj.YRelative)
This._Move_Window()
This.Window_Move_Obj.Old_Monitor := This.Window_Move_Obj.Current_Monitor
}
}
_Set_TFTime(){
This.Window_Move_Obj.Current_Monitor := This.Get_Current_Monitor()
This.Window_Move_Obj.NEW_GUI_POS:=This.Get_New_Window_Position(This.Window_Move_Obj.Current_Monitor,This.Window_Move_Obj.XPOFF,This.Window_Move_Obj.YPOFF,This.Window_Move_Obj.XRelative,This.Window_Move_Obj.YRelative)
This.Window_Move_Obj.Old_Monitor := This.Window_Move_Obj.Current_Monitor
This._Move_Window()
}
_Move_Window(){
if(!This.Window_Move_Obj.FILLSCREEN)
Gui,% This.Window_Move_Obj.GUINAME ":Show",% "x" This.Window_Move_Obj.NEW_GUI_POS.X " y" This.Window_Move_Obj.NEW_GUI_POS.Y " NA"
else
Gui,% This.Window_Move_Obj.GUINAME ":Show",% "x" This.Window_Move_Obj.NEW_GUI_POS.X " y" This.Window_Move_Obj.NEW_GUI_POS.Y " w" This.Monitor[This.Window_Move_Obj.Current_Monitor].Right " h" This.Monitor[This.Window_Move_Obj.Current_Monitor].Bottom " NA"
}
Turn_Off_Window_Move_Timer(){
local Window_Timer
Window_Timer := This.Window_Timer
SetTimer,%Window_Timer%,Off
}
Turn_On_Window_Move_Timer(){
local Window_Timer
Window_Timer := This.Window_Timer
This._Set_TFTime()
SetTimer,%Window_Timer%,On
}
GetGuiPos(){
local x,y
WinGetPos,x,y,,,% "ahk_id " This.Window_Move_Obj.GUIHWND
return x
}
}
;######################################################################################################################################
;##################################################### #######################################################
;##################################################### Gdip LITE #######################################################
;##################################################### #######################################################
;######################################################################################################################################
Layered_Window_SetUp(Smoothing,Window_X,Window_Y,Window_W,Window_H,Window_Name:=1,Window_Options:=""){
Layered:={}
Layered.W:=Window_W,Layered.H:=Window_H,Layered.X:=Window_X,Layered.Y:=Window_Y
Layered.Name:=Window_Name,Layered.Options:=Window_Options
;~ Layered.Token:=Gdip_Startup()
Create_Layered_GUI(Layered),Layered.hwnd:=winExist()
;~ Layered.hbm := CreateDIBSection(Window_W,Window_H),Layered.hdc := CreateCompatibleDC()
;~ Layered.obm := SelectObject(Layered.hdc,Layered.hbm),Layered.G := Gdip_GraphicsFromHDC(Layered.hdc)
;~ Gdip_SetSmoothingMode(Layered.G,Smoothing)
return Layered
}
Create_Layered_GUI(Layered){
Gui,% Layered.Name ": +E0x80000 +LastFound " Layered.Options
Gui,% Layered.Name ":Show",% "x" Layered.X " y" Layered.Y " w" Layered.W " h" Layered.H ;" NA"
}
Layered_Window_ShutDown(This){
SelectObject(This.hdc,This.obm),DeleteObject(This.hbm),DeleteDC(This.hdc)
gdip_deleteGraphics(This.g),Gdip_Shutdown(This.Token)
}
New_Brush(colour:="000000",Alpha:="FF"){
new_colour := "0x" Alpha colour
return Gdip_BrushCreateSolid(new_colour)
}
New_Pen(colour:="000000",Alpha:="FF",Width:= 5){
new_colour := "0x" Alpha colour
return Gdip_CreatePen(New_Colour,Width)
}
Fill_Box(pGraphics,pBrush,x,y,w,h) {
Ptr := A_PtrSize ? "UPtr" : "UInt"
return DllCall("gdiplus\GdipFillRectangle", Ptr, pGraphics, Ptr, pBrush, "float", x, "float", y, "float", w, "float", h)
}
; Gdip standard library v1.45 by tic (Tariq Porter) 07/09/11
; Modifed by Rseding91 using fincs 64 bit compatible Gdip library 5/1/2013
BitBlt(ddc, dx, dy, dw, dh, sdc, sx, sy, Raster=""){
Ptr := A_PtrSize ? "UPtr" : "UInt"
return DllCall("gdi32\BitBlt", Ptr, dDC, "int", dx, "int", dy, "int", dw, "int", dh, Ptr, sDC, "int", sx, "int", sy, "uint", Raster ? Raster : 0x00CC0020)
}
Gdip_SetImageAttributesColorMatrix(Matrix){
Ptr := A_PtrSize ? "UPtr" : "UInt"
VarSetCapacity(ColourMatrix, 100, 0)
Matrix := RegExReplace(RegExReplace(Matrix, "^[^\d-\.]+([\d\.])", "$1", "", 1), "[^\d-\.]+", "|")
StringSplit, Matrix, Matrix, |
Loop, 25
{
Matrix := (Matrix%A_Index% != "") ? Matrix%A_Index% : Mod(A_Index-1, 6) ? 0 : 1
NumPut(Matrix, ColourMatrix, (A_Index-1)*4, "float")
}
DllCall("gdiplus\GdipCreateImageAttributes", A_PtrSize ? "UPtr*" : "uint*", ImageAttr)
DllCall("gdiplus\GdipSetImageAttributesColorMatrix", Ptr, ImageAttr, "int", 1, "int", 1, Ptr, &ColourMatrix, Ptr, 0, "int", 0)
return ImageAttr
}
Gdip_GetImageWidth(pBitmap){
DllCall("gdiplus\GdipGetImageWidth", A_PtrSize ? "UPtr" : "UInt", pBitmap, "uint*", Width)
return Width
}
Gdip_GetImageHeight(pBitmap){
DllCall("gdiplus\GdipGetImageHeight", A_PtrSize ? "UPtr" : "UInt", pBitmap, "uint*", Height)
return Height
}
Gdip_DeletePen(pPen){
return DllCall("gdiplus\GdipDeletePen", A_PtrSize ? "UPtr" : "UInt", pPen)
}
Gdip_DeleteBrush(pBrush){
return DllCall("gdiplus\GdipDeleteBrush", A_PtrSize ? "UPtr" : "UInt", pBrush)
}
Gdip_DisposeImage(pBitmap){
return DllCall("gdiplus\GdipDisposeImage", A_PtrSize ? "UPtr" : "UInt", pBitmap)
}
Gdip_DeleteGraphics(pGraphics){
return DllCall("gdiplus\GdipDeleteGraphics", A_PtrSize ? "UPtr" : "UInt", pGraphics)
}
Gdip_DisposeImageAttributes(ImageAttr){
return DllCall("gdiplus\GdipDisposeImageAttributes", A_PtrSize ? "UPtr" : "UInt", ImageAttr)
}
CreateCompatibleDC(hdc=0){
return DllCall("CreateCompatibleDC", A_PtrSize ? "UPtr" : "UInt", hdc)
}
SelectObject(hdc, hgdiobj){
Ptr := A_PtrSize ? "UPtr" : "UInt"
return DllCall("SelectObject", Ptr, hdc, Ptr, hgdiobj)
}
DeleteObject(hObject){
return DllCall("DeleteObject", A_PtrSize ? "UPtr" : "UInt", hObject)
}
GetDC(hwnd=0){
return DllCall("GetDC", A_PtrSize ? "UPtr" : "UInt", hwnd)
}
GetDCEx(hwnd, flags=0, hrgnClip=0){
Ptr := A_PtrSize ? "UPtr" : "UInt"
return DllCall("GetDCEx", Ptr, hwnd, Ptr, hrgnClip, "int", flags)
}
ReleaseDC(hdc, hwnd=0){
Ptr := A_PtrSize ? "UPtr" : "UInt"
return DllCall("ReleaseDC", Ptr, hwnd, Ptr, hdc)
}
DeleteDC(hdc){
return DllCall("DeleteDC", A_PtrSize ? "UPtr" : "UInt", hdc)
}
Gdip_SetClipRegion(pGraphics, Region, CombineMode=0){
Ptr := A_PtrSize ? "UPtr" : "UInt"
return DllCall("gdiplus\GdipSetClipRegion", Ptr, pGraphics, Ptr, Region, "int", CombineMode)
}
CreateDIBSection(w, h, hdc="", bpp=32, ByRef ppvBits=0){
Ptr := A_PtrSize ? "UPtr" : "UInt"
hdc2 := hdc ? hdc : GetDC()
VarSetCapacity(bi, 40, 0)
NumPut(w, bi, 4, "uint"), NumPut(h, bi, 8, "uint"), NumPut(40, bi, 0, "uint"), NumPut(1, bi, 12, "ushort"), NumPut(0, bi, 16, "uInt"), NumPut(bpp, bi, 14, "ushort")
hbm := DllCall("CreateDIBSection", Ptr, hdc2, Ptr, &bi, "uint", 0, A_PtrSize ? "UPtr*" : "uint*", ppvBits, Ptr, 0, "uint", 0, Ptr)
if !hdc
ReleaseDC(hdc2)
return hbm
}
Gdip_GraphicsFromHDC(hdc){
DllCall("gdiplus\GdipCreateFromHDC", A_PtrSize ? "UPtr" : "UInt", hdc, A_PtrSize ? "UPtr*" : "UInt*", pGraphics)
return pGraphics
}
Gdip_GetDC(pGraphics){
DllCall("gdiplus\GdipGetDC", A_PtrSize ? "UPtr" : "UInt", pGraphics, A_PtrSize ? "UPtr*" : "UInt*", hdc)
return hdc
}
Gdip_Startup(){
Ptr := A_PtrSize ? "UPtr" : "UInt"
if !DllCall("GetModuleHandle", "str", "gdiplus", Ptr)
DllCall("LoadLibrary", "str", "gdiplus")
VarSetCapacity(si, A_PtrSize = 8 ? 24 : 16, 0), si := Chr(1)
DllCall("gdiplus\GdiplusStartup", A_PtrSize ? "UPtr*" : "uint*", pToken, Ptr, &si, Ptr, 0)
return pToken
}
Gdip_CreatePen(ARGB, w){
DllCall("gdiplus\GdipCreatePen1", "UInt", ARGB, "float", w, "int", 2, A_PtrSize ? "UPtr*" : "UInt*", pPen)
return pPen
}
Gdip_BrushCreateSolid(ARGB=0xff000000){
DllCall("gdiplus\GdipCreateSolidFill", "UInt", ARGB, A_PtrSize ? "UPtr*" : "UInt*", pBrush)
return pBrush
}
Gdip_BrushCreateHatch(ARGBfront, ARGBback, HatchStyle=0){
DllCall("gdiplus\GdipCreateHatchBrush", "int", HatchStyle, "UInt", ARGBfront, "UInt", ARGBback, A_PtrSize ? "UPtr*" : "UInt*", pBrush)
return pBrush
}
CreateRectF(ByRef RectF, x, y, w, h){
VarSetCapacity(RectF, 16)
NumPut(x, RectF, 0, "float"), NumPut(y, RectF, 4, "float"), NumPut(w, RectF, 8, "float"), NumPut(h, RectF, 12, "float")
}
CreatePointF(ByRef PointF, x, y){
VarSetCapacity(PointF, 8)
NumPut(x, PointF, 0, "float"), NumPut(y, PointF, 4, "float")
}
Gdip_FillRectangle(pGraphics, pBrush, x, y, w, h){
Ptr := A_PtrSize ? "UPtr" : "UInt"
return DllCall("gdiplus\GdipFillRectangle", Ptr, pGraphics, Ptr, pBrush, "float", x, "float", y, "float", w, "float", h)
}
Gdip_SetClipRect(pGraphics, x, y, w, h, CombineMode=0){
return DllCall("gdiplus\GdipSetClipRect", A_PtrSize ? "UPtr" : "UInt", pGraphics, "float", x, "float", y, "float", w, "float", h, "int", CombineMode)
}
Gdip_ResetClip(pGraphics){
return DllCall("gdiplus\GdipResetClip", A_PtrSize ? "UPtr" : "UInt", pGraphics)
}
Gdip_SetSmoothingMode(pGraphics, SmoothingMode){
return DllCall("gdiplus\GdipSetSmoothingMode", A_PtrSize ? "UPtr" : "UInt", pGraphics, "int", SmoothingMode)
}
Gdip_GraphicsClear(pGraphics, ARGB=0x00ffffff){
return DllCall("gdiplus\GdipGraphicsClear", A_PtrSize ? "UPtr" : "UInt", pGraphics, "int", ARGB)
}
UpdateLayeredWindow(hwnd, hdc, x="", y="", w="", h="", Alpha=255){
Ptr := A_PtrSize ? "UPtr" : "UInt"
if ((x != "") && (y != ""))
VarSetCapacity(pt, 8), NumPut(x, pt, 0, "UInt"), NumPut(y, pt, 4, "UInt")
if (w = "") ||(h = "")
WinGetPos,,, w, h, ahk_id %hwnd%
return DllCall("UpdateLayeredWindow", Ptr, hwnd, Ptr, 0, Ptr, ((x = "") && (y = "")) ? 0 : &pt, "int64*", w|h<<32, Ptr, hdc, "int64*", 0, "uint", 0, "UInt*", Alpha<<16|1<<24, "uint", 2)
}
Gdip_BitmapFromScreen(Screen=0, Raster=""){
if (Screen = 0){
Sysget, x, 76
Sysget, y, 77
Sysget, w, 78
Sysget, h, 79
}
else if (SubStr(Screen, 1, 5) = "hwnd:")
{
Screen := SubStr(Screen, 6)
if !WinExist( "ahk_id " Screen)
return -2
WinGetPos,,, w, h, ahk_id %Screen%
x := y := 0
hhdc := GetDCEx(Screen, 3)
}
else if (Screen&1 != "")
{
Sysget, M, Monitor, %Screen%
x := MLeft, y := MTop, w := MRight-MLeft, h := MBottom-MTop
}
else
{
StringSplit, S, Screen, |
x := S1, y := S2, w := S3, h := S4
}
if (x = "") || (y = "") || (w = "") || (h = "")
return -1
chdc := CreateCompatibleDC(), hbm := CreateDIBSection(w, h, chdc), obm := SelectObject(chdc, hbm), hhdc := hhdc ? hhdc : GetDC()
BitBlt(chdc, 0, 0, w, h, hhdc, x, y, Raster)
ReleaseDC(hhdc)
pBitmap := Gdip_CreateBitmapFromHBITMAP(hbm)
SelectObject(chdc, obm), DeleteObject(hbm), DeleteDC(hhdc), DeleteDC(chdc)
return pBitmap
}
Gdip_SaveBitmapToFile(pBitmap, sOutput, Quality=75){
Ptr := A_PtrSize ? "UPtr" : "UInt"
SplitPath, sOutput,,, Extension
if Extension not in BMP,DIB,RLE,JPG,JPEG,JPE,JFIF,GIF,TIF,TIFF,PNG
return -1
Extension := "." Extension
DllCall("gdiplus\GdipGetImageEncodersSize", "uint*", nCount, "uint*", nSize)
VarSetCapacity(ci, nSize)
DllCall("gdiplus\GdipGetImageEncoders", "uint", nCount, "uint", nSize, Ptr, &ci)
if !(nCount && nSize)
return -2
If (A_IsUnicode){
StrGet_Name := "StrGet"
Loop, %nCount%
{
sString := %StrGet_Name%(NumGet(ci, (idx := (48+7*A_PtrSize)*(A_Index-1))+32+3*A_PtrSize), "UTF-16")
if !InStr(sString, "*" Extension)
continue
pCodec := &ci+idx
break
}
} else {
Loop, %nCount%
{
Location := NumGet(ci, 76*(A_Index-1)+44)
nSize := DllCall("WideCharToMultiByte", "uint", 0, "uint", 0, "uint", Location, "int", -1, "uint", 0, "int", 0, "uint", 0, "uint", 0)
VarSetCapacity(sString, nSize)
DllCall("WideCharToMultiByte", "uint", 0, "uint", 0, "uint", Location, "int", -1, "str", sString, "int", nSize, "uint", 0, "uint", 0)
if !InStr(sString, "*" Extension)
continue
pCodec := &ci+76*(A_Index-1)
break
}
}
if !pCodec
return -3
if (Quality != 75)
{
Quality := (Quality < 0) ? 0 : (Quality > 100) ? 100 : Quality
if Extension in .JPG,.JPEG,.JPE,.JFIF
{
DllCall("gdiplus\GdipGetEncoderParameterListSize", Ptr, pBitmap, Ptr, pCodec, "uint*", nSize)
VarSetCapacity(EncoderParameters, nSize, 0)
DllCall("gdiplus\GdipGetEncoderParameterList", Ptr, pBitmap, Ptr, pCodec, "uint", nSize, Ptr, &EncoderParameters)
Loop, % NumGet(EncoderParameters, "UInt") ;%
{
elem := (24+(A_PtrSize ? A_PtrSize : 4))*(A_Index-1) + 4 + (pad := A_PtrSize = 8 ? 4 : 0)
if (NumGet(EncoderParameters, elem+16, "UInt") = 1) && (NumGet(EncoderParameters, elem+20, "UInt") = 6)
{
p := elem+&EncoderParameters-pad-4
NumPut(Quality, NumGet(NumPut(4, NumPut(1, p+0)+20, "UInt")), "UInt")
break
}
}
}
}
if (!A_IsUnicode)
{
nSize := DllCall("MultiByteToWideChar", "uint", 0, "uint", 0, Ptr, &sOutput, "int", -1, Ptr, 0, "int", 0)
VarSetCapacity(wOutput, nSize*2)
DllCall("MultiByteToWideChar", "uint", 0, "uint", 0, Ptr, &sOutput, "int", -1, Ptr, &wOutput, "int", nSize)
VarSetCapacity(wOutput, -1)
if !VarSetCapacity(wOutput)
return -4
E := DllCall("gdiplus\GdipSaveImageToFile", Ptr, pBitmap, Ptr, &wOutput, Ptr, pCodec, "uint", p ? p : 0)
}
else
E := DllCall("gdiplus\GdipSaveImageToFile", Ptr, pBitmap, Ptr, &sOutput, Ptr, pCodec, "uint", p ? p : 0)
return E ? -5 : 0
}
Gdip_Shutdown(pToken){
Ptr := A_PtrSize ? "UPtr" : "UInt"
DllCall("gdiplus\GdiplusShutdown", Ptr, pToken)
if hModule := DllCall("GetModuleHandle", "str", "gdiplus", Ptr)
DllCall("FreeLibrary", Ptr, hModule)
return 0
}
Gdip_CreateBitmapFromHBITMAP(hBitmap, Palette=0){
Ptr := A_PtrSize ? "UPtr" : "UInt"
DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", Ptr, hBitmap, Ptr, Palette, A_PtrSize ? "UPtr*" : "uint*", pBitmap)
return pBitmap
}
Thank you for your time.