GDI+ standard library 1.45 by tic

Post your working scripts, libraries and tools for AHK v1.1 and older
Bode

Re: GDI+ standard library 1.45 by tic

19 Aug 2016, 06:35

Yes, its ridiculously fast :D Just wanted to see if there was a way to do it other than the default search which probably will slow down on Win 10. Maybe multiple scripts which take turns capturing and processing image. Have a basic idea as to how to go about it. Dont know if that will work out and the default Built-in search is good enough for me right now.
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: GDI+ standard library 1.45 by tic

20 Aug 2016, 12:42

OK, so I have been tinkering with the OOP version of GDI some more, and here is where I am at so far.

You will need the class wrapped version of GDip_all from this post and call it CGdip.ahk

The new class - CGDipHelper.ahk:
Note: This class is in no way complete. It is just a proof-of-concept
I really like how it simplifies working with GDI - the function chaining is really handy, and having the destructors do the garbage collection for you is nice too.
The problem is, I don't really know GDI, so I am kind of stabbing in the dark as to what a lot of things are and whether or not to wrap them in classes (or which class to wrap them in). I have to return to working on UCR at some point, but this is an interesting distraction for now.

Code: Select all

#Include, CGdip.ahk
Class CGDipHelper {
	__New(){
		; Start gdi+
		If !pToken := CGDip.Gdip_Startup()
		{
			;MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
			OutputDebug % "AHK| gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system"
			return 0
		}
		this.ptr := pToken
		OutputDebug % "AHK| GDI+ started."
	}
	
	__Delete(){
		OutputDebug % "AHK| Shutting down GDI+"
		CGDip.Gdip_Shutdown(this.ptr)
	}
	
	SetImage(hwnd, HBitmap){
		return CGDip.SetImage(hwnd, HBitmap.ptr)
	}
	
	CreateBitmap(Width, Height, Format=0x26200A){
		return new this.Bitmap(Width, Height, Format)
	}
	
	CreateBrush(){
		return new this.Brush()
	}
	
	CreateCompatibleDC(hdc=0){
		return new this.CompatibleDC(hdc)
	}
	
	CreateDIBSection(w, h, hdc="", bpp=32, ByRef ppvBits=0){
		hBitmap := CGDip.CreateDIBSection(w, h, hdc, bpp, ppvBits)
		return new this.HBitmap(hBitmap)
	}
	
	CreatePen(ARGB, w){
		return new this.Pen(ARGB, w)
	}
	
	DrawEllipse(Graphics, Pen, x, y, w, h){
		return CGDip.Gdip_DrawEllipse(Graphics.ptr, Pen.ptr, x, y, w, h)
	}
	
	DrawRectangle(Graphics, Pen, x, y, w, h){
		return CGDip.Gdip_DrawRectangle(Graphics.ptr, Pen.ptr, x, y, w, h)
	}
	
	SelectObject(DC, hgdiobj){
		return CGDip.SelectObject(DC.ptr, hgdiobj)
	}
	
	Class Bitmap {
		__New(Width, Height, Format=0x26200A){
			OutputDebug % "AHK| Creating Bitmap"
			this.ptr := CGDip.Gdip_CreateBitmap(Width, Height, Format)
		}
		
		__Delete(){
			OutputDebug % "AHK| Deleting Bitmap"
			CGDip.Gdip_DisposeImage(this.ptr)
		}
		
		GetGraphics(){
			pGraphics := CGDip.Gdip_GraphicsFromImage(this.ptr)
			return new CGDipHelper.Graphics(pGraphics)
		}
		
		CreateHBITMAP(Background=0xffffffff){
			hBitmap := CGDip.Gdip_CreateHBITMAPFromBitmap(this.ptr, Background)
			return new CGDipHelper.HBitmap(hBitmap)
		}
	}
	
	Class HBitmap {
		__New(hBitmap){
			OutputDebug % "AHK| Creating HBitmap"
			this.ptr := hBitmap
		}
		
		__Delete(){
			OutputDebug % "AHK| Deleting HBitmap"
			CGDip.DeleteObject(this.ptr)
		}
	}
	
	Class Graphics {
		__New(pGraphics){
			OutputDebug % "AHK| Creating Graphics"
			this.ptr := pGraphics
		}
		
		__Delete(){
			OutputDebug % "AHK| Deleting Graphics"
			CGDip.Gdip_DeleteGraphics(this.ptr)
		}
		
		SetSmoothingMode(SmoothingMode)
		{
			ret := CGDip.Gdip_SetSmoothingMode(this.ptr, SmoothingMode)
			return this
		}
		
		FillRectangle(Brush, x, y, w, h){
			CGDip.Gdip_FillRectangle(this.ptr, Brush.ptr, x, y, w, h)
			return this
		}
		
		FillEllipse(Brush, x, y, w, h){
			CGDip.Gdip_FillEllipse(this.ptr, Brush.ptr, x, y, w, h)
			return this
		}
	}
	
	Class Brush {
		ptr := 0
		__New(){
		}

		__Delete(){
			this.Delete()
		}
		
		Delete(){
			if (this.ptr){
				OutputDebug % "AHK| Deleting Brush"
				CGDip.Gdip_DeleteBrush(this.ptr)
				return 1
			}
			return 0
		}
		
		CreateSolid(ARGB=0xff000000){
			this.Delete()
			this.ptr := CGDip.Gdip_BrushCreateSolid(ARGB)
			OutputDebug % "AHK| Creating Brush"
			return this
		}
		
		FillRectangle(Graphics, x, y, w, h){
			if (this.ptr){
				CGDip.Gdip_FillRectangle(Graphics.ptr, this.ptr, x, y, w, h)
				return this
			}
			return 0
		}
		
		FillEllipse(Graphics, x, y, w, h){
			if (this.ptr){
				CGDip.Gdip_FillEllipse(Graphics.ptr, this.ptr, x, y, w, h)
				return this
			}
			return 0
		}

	}
	
	Class Pen {
		__New(ARGB, w){
			this.Create(ARGB, w)
		}
		
		Create(ARGB, w){
			this.Delete()
			OutputDebug % "AHK| Creating Pen"
			this.ptr := CGDip.Gdip_CreatePen(ARGB, w)
			return this
		}
		
		__Delete(){
			this.Delete()
		}
		
		Delete(){
			if (this.ptr){
				OutputDebug % "AHK| Deleting Pen"
				CGDip.Gdip_DeletePen(this.ptr)
			}
		}
	}
	
	class CompatibleDC {
		__New(hdc){
			OutputDebug % "AHK| Creating Compatible DC"
			hDC := CGDip.CreateCompatibleDC(hdc)
			this.ptr := hDC
		}
		
		__Delete(){
			OutputDebug % "AHK| Deleting Compatible DC"
			CGDip.DeleteDC(this.ptr)
		}
		
		GetGraphics(){
			pGraphics := CGDip.Gdip_GraphicsFromHDC(this.ptr)
			return new CGDipHelper.Graphics(pGraphics)
		}
		
		UpdateLayeredWindow(hwnd, x="", y="", w="", h="", Alpha=255){
			CGDip.UpdateLayeredWindow(hwnd, this.ptr, x, y, w, h, Alpha)
		}
	}
}
Example #1 from the tutorial re-written to use this class:

Code: Select all

; gdi+ ahk tutorial 1 written by tic (Tariq Porter)
; Requires Gdip.ahk either in your Lib folder as standard library or using #Include
;
; Tutorial to draw a single ellipse and rectangle to the screen

#SingleInstance, Force
#NoEnv
SetBatchLines, -1

; Uncomment if Gdip.ahk is not in your standard library
#Include, CGDipHelper.ahk

OutputDebug DBGVIEWCLEAR

global GDI := new CGDipHelper()

; Set the width and height we want as our drawing area, to draw everything in. This will be the dimensions of our bitmap
Width :=1400, Height := 1050

; Create a layered window (+E0x80000 : must be used for UpdateLayeredWindow to work!) that is always on top (+AlwaysOnTop), has no taskbar entry or caption
Gui, 1: -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs

; Show the window
Gui, 1: Show, NA

; Get a handle to this window we have created in order to update it later
hwnd1 := WinExist()

; Create a gdi bitmap with width and height of what we are going to draw into it. This is the entire drawing area for everything
;hbm := CreateDIBSection(Width, Height)
HBitmap := GDI.CreateDIBSection(Width, Height)

; Get a device context compatible with the screen
;hdc := CreateCompatibleDC()
DC := GDI.CreateCompatibleDC()

; Select the bitmap into the device context
obm := GDI.SelectObject(DC, HBitmap.ptr)

; Get a pointer to the graphics of the bitmap, for use with drawing functions
; Set the smoothing mode to antialias = 4 to make shapes appear smother (only used for vector drawing and filling)
G := DC.GetGraphics().SetSmoothingMode(4)

; Create a fully opaque red brush (ARGB = Transparency, red, green, blue) to draw a circle
Brush := GDI.CreateBrush()
; Fill the graphics of the bitmap with an ellipse using the brush created
; Filling from coordinates (100,50) an ellipse of 200x300
Brush.CreateSolid(0xffff0000).FillEllipse(G, 100, 500, 200, 300)

; Create a slightly transparent (66) blue brush (ARGB = Transparency, red, green, blue) to draw a rectangle
; Fill the graphics of the bitmap with a rectangle using the brush created
; Filling from coordinates (250,80) a rectangle of 300x200
Brush.CreateSolid(0x660000ff).FillRectangle(G, 250, 80, 300, 200)

; Update the specified window we have created (hwnd1) with a handle to our bitmap (hdc), specifying the x,y,w,h we want it positioned on our screen
; So this will position our gui at (0,0) with the Width and Height specified earlier
DC.UpdateLayeredWindow(hwnd1, 0, 0, Width, Height)

; Select the object back into the hdc
GDI.SelectObject(DC, obm)
Return

;#######################################################################

Esc::ExitApp
Some code I wrote to draw a circle with optional border - sort of based on example 9:

Code: Select all

#SingleInstance, Force
#NoEnv
SetBatchLines, -1

#Include, CGDipHelper.ahk

OutputDebug DBGVIEWCLEAR

global GDI := new CGDipHelper()

;Gui, 1: +ToolWindow -Caption +AlwaysOnTop
Gui, 1: +HwndhGui
Gui, 1: Margin, 0, 0
Gui, 1: Add, Picture, w400 h400 0xE hwndhImage
DrawCircle(hImage, 0xFF0000FF, 0xFFFFFFFF, 0xFF000000, 3)
Gui, 1: Show
;WinSet,TransColor, FFFFFF, % "ahk_id " hGUI
Return

DrawCircle(hwnd, Foreground, Background, Border := -1, BorderWidth := 0)
{
	; We also want to width and height (posw and Posh)
	GuiControlGet, Pos, Pos, % hwnd

	bm := GDI.CreateBitmap(PosW, PosH)
	G := bm.GetGraphics().SetSmoothingMode(4)
	
	x := 0, y := 0
	Brush := GDI.CreateBrush()
	G.FillRectangle(Brush.CreateSolid(Background), x, y, Posw, Posh)
	if (Border != -1){
		G.FillEllipse(Brush.CreateSolid(Border), x, y, PosW, PosH)
		PosW -= BorderWidth*2, PosH -= BorderWidth*2, x += BorderWidth, y += BorderWidth
	}
	G.FillEllipse(Brush.CreateSolid(Foreground), x, y, PosW, PosH)
	
	GDI.SetImage(hwnd, bm.CreateHBITMAP())
	
	Return, 0
}

;#######################################################################

Esc::
GuiClose:
ExitApp
Return
Example #2

Code: Select all

; gdi+ ahk tutorial 2 written by tic (Tariq Porter)
; Requires Gdip.ahk either in your Lib folder as standard library or using #Include
;
; Tutorial to draw a single ellipse and rectangle to the screen, but just the outlines of these shapes

#SingleInstance, Force
#NoEnv
SetBatchLines, -1

#Include, CGDipHelper.ahk

OutputDebug DBGVIEWCLEAR

global GDI := new CGDipHelper()

; Set the width and height we want as our drawing area, to draw everything in. This will be the dimensions of our bitmap
Width := 600, Height := 400

; Create a layered window (+E0x80000 : must be used for UpdateLayeredWindow to work!) that is always on top (+AlwaysOnTop), has no taskbar entry or caption
Gui, 1: -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs

; Show the window
Gui, 1: Show, NA

; Get a handle to this window we have created in order to update it later
hwnd1 := WinExist()

; Create a gdi bitmap with width and height of what we are going to draw into it. This is the entire drawing area for everything
;hbm := CreateDIBSection(Width, Height)
HBitmap := GDI.CreateDIBSection(Width, Height)

; Get a device context compatible with the screen
DC := GDI.CreateCompatibleDC()

; Select the bitmap into the device context
obm := GDI.SelectObject(DC, HBitmap.ptr)

; Get a pointer to the graphics of the bitmap, for use with drawing functions
; Set the smoothing mode to antialias = 4 to make shapes appear smother (only used for vector drawing and filling)
G := DC.GetGraphics().SetSmoothingMode(4)

; Create a fully opaque red pen (ARGB = Transparency, red, green, blue) of width 3 (the thickness the pen will draw at) to draw a circle
Pen := GDI.CreatePen(0xffff0000, 3)

; Draw an ellipse into the graphics of the bitmap (this being only the outline of the shape) using the pen created
; This pen has a width of 3, and is drawing from coordinates (100,50) an ellipse of 200x300
GDI.DrawEllipse(G, Pen, 100, 50, 200, 300)

; Create a slightly transparent (66) blue pen (ARGB = Transparency, red, green, blue) to draw a rectangle
; This pen is wider than the last one, with a thickness of 10
Pen.Create(0x660000ff, 10)

; Draw a rectangle onto the graphics of the bitmap using the pen just created
; Draws the rectangle from coordinates (250,80) a rectangle of 300x200 and outline width of 10 (specified when creating the pen)
GDI.DrawRectangle(G, Pen, 250, 80, 300, 200)

; Update the specified window we have created (hwnd1) with a handle to our bitmap (hdc), specifying the x,y,w,h we want it positioned on our screen
; So this will position our gui at (0,0) with the Width and Height specified earlier
DC.UpdateLayeredWindow(hwnd1, 0, 0, Width, Height)

; Select the object back into the hdc
GDI.SelectObject(DC, obm)

Return

;#######################################################################

Esc::
ExitApp
p3trus
Posts: 137
Joined: 02 Aug 2016, 03:20

Re: GDI+ standard library 1.45 by tic

25 Aug 2016, 22:20

tic wrote:.. as AHK does not have anonymous functions, which are absolutely necessary for a proper running library that controls a GUI...
Mmmm.. whenever I reached the point of needing an anonymous func, I found a workaround by using a BoundFunc Object.
Maybe that could work in your case too...?
tic
Posts: 92
Joined: 03 Nov 2014, 03:10

Re: GDI+ standard library 1.45 by tic

26 Aug 2016, 14:42

p3trus wrote:
tic wrote:.. as AHK does not have anonymous functions, which are absolutely necessary for a proper running library that controls a GUI...
Mmmm.. whenever I reached the point of needing an anonymous func, I found a workaround by using a BoundFunc Object.
Maybe that could work in your case too...?
You will still need to litter your application with many tiny functions that may do no more than one line.
Click one element to hide another:

Code: Select all

myElement.onClick = function(dom) {
    dom.find("#anotherElement").hide();
}
p3trus
Posts: 137
Joined: 02 Aug 2016, 03:20

Re: GDI+ standard library 1.45 by tic

26 Aug 2016, 15:27

...sure, but most of those tiny functions will be used multiple times; so it doesn't really matter if you write n anonymous functions, or one helper function and n instant one-use BoundFuncs;
It even has it advantages, if you ever need to change the mechanism of the function, you don't need to search & replace your whole script but only the 'prototype' function.

/edit: In fact, dom.find() and element.hide() are exaxtly that sort of littering functions, and by making that anonymous function you're binding the selector to the find() function, and sort-of-bind the hide() function to the found element...
I guess when writing a library or framework, you can't live without that litter ^^
zekerya

Re: GDI+ standard library 1.45 by tic

10 Oct 2016, 00:54

here is my simple imagesearch code,please someone write the final code within gdi to work on background.i'm not expert.

Code: Select all

#NoEnv
SetWorkingDir %A_ScriptDir%
CoordMode, Mouse, Window
SendMode Input
#SingleInstance Force
SetTitleMatchMode 2
#WinActivateForce


F5::
Macro1:
Loop, 500
{
    CoordMode, Pixel, Window
    ImageSearch, FoundX, FoundY, 660, 341, 696, 379, *90 C:\Users\KURD\AppData\Roaming\MacroCreator\Screenshots\Screen_20161010090916.png
    CenterImgSrchCoords("*90 C:\Users\KURD\AppData\Roaming\MacroCreator\Screenshots\Screen_20161010090916.png", FoundX, FoundY)
    If ErrorLevel = 0
    	Click, %FoundX%, %FoundY% Left, 1
    Sleep, 10
}
Until ErrorLevel = 0
If ErrorLevel = 0
{
}
Return


F8::ExitApp

CenterImgSrchCoords(File, ByRef CoordX, ByRef CoordY)
{
	static LoadedPic
	LastEL := ErrorLevel
	Gui, Pict:Add, Pic, vLoadedPic, %File%
	GuiControlGet, LoadedPic, Pict:Pos
	Gui, Pict:Destroy
	CoordX += LoadedPicW // 2
	CoordY += LoadedPicH // 2
	ErrorLevel := LastEL
}
guest3456
Posts: 3453
Joined: 09 Oct 2013, 10:31

Re: GDI+ standard library 1.45 by tic

15 Nov 2016, 22:31

I have updated Gdip_All.ahk to support AHK v2

This version is not backwards compatible with AHK v1. There are syntax changes and changed command names. The file works and can be run by the v2 interpreter without errors. I also gave it a look with my eyes for anything I thought needed changing. I may have missed some things.

It might be backwards compatible with AHK v1 if you could figure a way around some issues. I don't think checking A_AhkVersion will be sufficient
1. SysGet, Monitor being changed to MonitorGet
2. if var is type being changed to if var is "type"
3. expression parameters must be used for Loop Parse, % var, SplitPath and maybe others
4. ??

You can see the changes in the commit history

https://github.com/mmikeww/AHKv2-Gdip/
Last edited by guest3456 on 16 Nov 2016, 12:20, edited 2 times in total.

User avatar
jNizM
Posts: 3183
Joined: 30 Sep 2013, 01:33
Contact:

Re: GDI+ standard library 1.45 by tic

16 Nov 2016, 02:14

@guest3456
when you change the lib to support v2 and drop v1 support you should drop thinks like this too:

before:

Code: Select all

PrintWindow(hwnd, hdc, Flags:=0)
{
    Ptr := A_PtrSize ? "UPtr" : "UInt"
	
    return DllCall("PrintWindow", Ptr, hwnd, Ptr, hdc, "uint", Flags)
}
after:

Code: Select all

PrintWindow(hwnd, hdc, flags := 0)
{
    return DllCall("PrintWindow", "ptr", hwnd, "ptr", hdc, "uint", flags)
}
-> Windows Data Types for AHK
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: GDI+ standard library 1.45 by tic

16 Nov 2016, 03:37

if var is type being changed to if var is "type"
Just use RegEx
Recommends AHK Studio
guest3456
Posts: 3453
Joined: 09 Oct 2013, 10:31

Re: GDI+ standard library 1.45 by tic

16 Nov 2016, 08:34

jNizM wrote:@guest3456
when you change the lib to support v2 and drop v1 support you should drop thinks like this too:

before:

Code: Select all

PrintWindow(hwnd, hdc, Flags:=0)
{
    Ptr := A_PtrSize ? "UPtr" : "UInt"
	
    return DllCall("PrintWindow", Ptr, hwnd, Ptr, hdc, "uint", Flags)
}
after:

Code: Select all

PrintWindow(hwnd, hdc, flags := 0)
{
    return DllCall("PrintWindow", "ptr", hwnd, "ptr", hdc, "uint", flags)
}
-> Windows Data Types for AHK
sure. you're right. feel free to make the changes and submit a Pull Request

nnnik wrote:
if var is type being changed to if var is "type"
Just use RegEx
did you even try it? do you even use v2? you are misunderstanding. RegEx won't allow it to be backwards compatible.
in v1 if xx is type is a dedicated command.
in v2, is is an expression operator.

what do you expect this code to do in both v1 and v2?:

Code: Select all

MsgBox, % 123 is "number"
MsgBox, % "helloworld" is "alpha"
Last edited by guest3456 on 16 Nov 2016, 08:43, edited 1 time in total.

User avatar
jNizM
Posts: 3183
Joined: 30 Sep 2013, 01:33
Contact:

Re: GDI+ standard library 1.45 by tic

16 Nov 2016, 08:40

1. nope =)

2. whats with type.ahk from lexikos?

Code: Select all

MsgBox % type("")     ; String
MsgBox % type(1)      ; Integer
MsgBox % type(1/1)    ; Float
MsgBox % type("1")    ; String
MsgBox % type(2**42)  ; Integer


; Object version - depends on current float format including a decimal point.
type(v)
{
    if IsObject(v)
        return "Object"
    return v = "" || [v].GetCapacity(1) ? "String" : InStr(v, ".") ? "Float" : "Integer"
}

; COM version - reports the wrong type for integers outside 32-bit range.
type_com(ByRef v)
{
    if IsObject(v)
        return "Object"
    a := ComObjArray(0xC, 1)
    a[0] := v
    DllCall("oleaut32\SafeArrayAccessData", "ptr", ComObjValue(a), "ptr*", ap)
    type := NumGet(ap+0, "ushort")
    DllCall("oleaut32\SafeArrayUnaccessData", "ptr", ComObjValue(a))
    return type = 3 ? "Integer" : type = 8 ? "String" : type = 5 ? "Float" : type
}
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
guest3456
Posts: 3453
Joined: 09 Oct 2013, 10:31

Re: GDI+ standard library 1.45 by tic

16 Nov 2016, 08:49

jNizM wrote: 2. whats with type.ahk from lexikos?

Code: Select all

MsgBox % type("")     ; String
MsgBox % type(1)      ; Integer
MsgBox % type(1/1)    ; Float
MsgBox % type("1")    ; String
MsgBox % type(2**42)  ; Integer


; Object version - depends on current float format including a decimal point.
type(v)
{
    if IsObject(v)
        return "Object"
    return v = "" || [v].GetCapacity(1) ? "String" : InStr(v, ".") ? "Float" : "Integer"
}
that should work. other types such as "upper/lower" wouldn't work. but the Gdip lib only checks for the type "integer" from what i see. and would need to rename it to Type2() since Type() is built-into AHKv2 and you wouldn't want to override it.

but pointless unless we can also get around the SysGet/MonitorGet thing

User avatar
jNizM
Posts: 3183
Joined: 30 Sep 2013, 01:33
Contact:

Re: GDI+ standard library 1.45 by tic

16 Nov 2016, 09:01

[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
guest3456
Posts: 3453
Joined: 09 Oct 2013, 10:31

Re: GDI+ standard library 1.45 by tic

16 Nov 2016, 09:03

looks good. you seem ready to take on the job of making it backwards compatible with AHK v1.1 :)

unfortunately AHK Basic v1.0 support would still be dropped :(
Last edited by guest3456 on 16 Nov 2016, 09:05, edited 1 time in total.

User avatar
jNizM
Posts: 3183
Joined: 30 Sep 2013, 01:33
Contact:

Re: GDI+ standard library 1.45 by tic

16 Nov 2016, 09:05

Since I use gdip call directly when needed - without this big lib... no =)
I just give you the hints to the right direction :P
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
User avatar
jNizM
Posts: 3183
Joined: 30 Sep 2013, 01:33
Contact:

Re: GDI+ standard library 1.45 by tic

16 Nov 2016, 10:37

Your lucky... did a small rewrite from ahk_v2 source... not bug tested

Code: Select all

for k, v in EnumDisplayMonitors()
    MsgBox % "Monitor #" k "`n`n"
           . "LEFT:`t`t"   GetMonitorInfo(v).LEFT  "`n"
           . "TOP:`t`t"    GetMonitorInfo(v).TOP   "`n"
           . "RIGHT:`t`t"  GetMonitorInfo(v).RIGHT "`n"
           . "BOTTOM:`t`t" GetMonitorInfo(v).BOTTOM

; ===============================================================================================================================

EnumDisplayMonitors()                                                             ; http://msdn.com/library/dd162610(vs.85,en-us)
{
    static addr := RegisterCallback("MonitorEnumProc", "", 4), mip := {}
    if !(DllCall("user32.dll\EnumDisplayMonitors", "ptr", 0, "ptr", 0, "ptr", addr, "ptr", &mip))
        return false
    return mip
}

; ===============================================================================================================================

MonitorEnumProc(hMonitor, hdcMonitor, lprcMonitor, lParam)                        ; http://msdn.com/library/dd145061(vs.85,en-us)
{
    Object(lParam).push(hMonitor)
    return true
}

; ===============================================================================================================================

GetMonitorInfo(hMonitor)                                                          ; http://msdn.com/library/dd144901(vs.85,en-us)
{
    static rcMonitor := {}
    NumPut(VarSetCapacity(MONITORINFOEX, 104, 0), MONITORINFOEX, 0, "uint")
    if !(DllCall("user32.dll\GetMonitorInfo", "ptr", hMonitor, "ptr", &MONITORINFOEX))
        return false
    rcMonitor.LEFT   := NumGet(MONITORINFOEX,  4, "int")    ; rcWork.LEFT   -> 20
    rcMonitor.TOP    := NumGet(MONITORINFOEX,  8, "int")    ; rcWork.TOP    -> 24
    rcMonitor.RIGHT  := NumGet(MONITORINFOEX, 12, "int")    ; rcWork.RIGHT  -> 28
    rcMonitor.BOTTOM := NumGet(MONITORINFOEX, 16, "int")    ; rcWork.BOTTOM -> 32
    return rcMonitor
}

; ===============================================================================================================================
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
just me
Posts: 9407
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: GDI+ standard library 1.45 by tic

16 Nov 2016, 11:05

Code: Select all

IsInteger(Var) {
   Static Integer := "Integer"
   If Var Is %Integer%
      Return True
   Return False
}
guest3456
Posts: 3453
Joined: 09 Oct 2013, 10:31

Re: GDI+ standard library 1.45 by tic

16 Nov 2016, 12:12

just me wrote:

Code: Select all

IsInteger(Var) {
   Static Integer := "Integer"
   If Var Is %Integer%
      Return True
   Return False
}
how does this work?

if i change it to this, it fails on v2. why?

Code: Select all

IsInteger(Var) {
   Static Int := "Integer"
   If Var Is %Int%
      Return True
   Return False
}
Last edited by guest3456 on 16 Nov 2016, 12:31, edited 3 times in total.

guest3456
Posts: 3453
Joined: 09 Oct 2013, 10:31

Re: GDI+ standard library 1.45 by tic

16 Nov 2016, 12:15

jNizM wrote:Your lucky... did a small rewrite from ahk_v2 source... not bug tested

Code: Select all

for k, v in EnumDisplayMonitors()
    MsgBox % "Monitor #" k "`n`n"
           . "LEFT:`t`t"   GetMonitorInfo(v).LEFT  "`n"
           . "TOP:`t`t"    GetMonitorInfo(v).TOP   "`n"
           . "RIGHT:`t`t"  GetMonitorInfo(v).RIGHT "`n"
           . "BOTTOM:`t`t" GetMonitorInfo(v).BOTTOM

; ===============================================================================================================================

EnumDisplayMonitors()                                                             ; http://msdn.com/library/dd162610(vs.85,en-us)
{
    static addr := RegisterCallback("MonitorEnumProc", "", 4), mip := {}
    if !(DllCall("user32.dll\EnumDisplayMonitors", "ptr", 0, "ptr", 0, "ptr", addr, "ptr", &mip))
        return false
    return mip
}

; ===============================================================================================================================

MonitorEnumProc(hMonitor, hdcMonitor, lprcMonitor, lParam)                        ; http://msdn.com/library/dd145061(vs.85,en-us)
{
    Object(lParam).push(hMonitor)
    return true
}

; ===============================================================================================================================

GetMonitorInfo(hMonitor)                                                          ; http://msdn.com/library/dd144901(vs.85,en-us)
{
    static rcMonitor := {}
    NumPut(VarSetCapacity(MONITORINFOEX, 104, 0), MONITORINFOEX, 0, "uint")
    if !(DllCall("user32.dll\GetMonitorInfo", "ptr", hMonitor, "ptr", &MONITORINFOEX))
        return false
    rcMonitor.LEFT   := NumGet(MONITORINFOEX,  4, "int")    ; rcWork.LEFT   -> 20
    rcMonitor.TOP    := NumGet(MONITORINFOEX,  8, "int")    ; rcWork.TOP    -> 24
    rcMonitor.RIGHT  := NumGet(MONITORINFOEX, 12, "int")    ; rcWork.RIGHT  -> 28
    rcMonitor.BOTTOM := NumGet(MONITORINFOEX, 16, "int")    ; rcWork.BOTTOM -> 32
    return rcMonitor
}

; ===============================================================================================================================
submit a PR and i'll add it

just me
Posts: 9407
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: GDI+ standard library 1.45 by tic

16 Nov 2016, 16:19

Code: Select all

If Var Is %Integer%
  • v1:
    variable reference: Integer -> "Integer"
  • v2:
    double variable reference: Integer -> "Integer" -> "Integer"

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: No registered users and 69 guests