A simple Class for calling V1's libs in V2

Post your working scripts, libraries and tools.
viv
Posts: 217
Joined: 09 Dec 2020, 17:48

A simple Class for calling V1's libs in V2

Post by viv » 16 Oct 2021, 04:48

Write the following via online translation
I don't know much about Class, so I hope it's not too much of a problem

Test in AutoHotkey v2 2.0-beta.1
Copy the DLL to your script directory or set dllPath
Test in this dll ahkdll-v1-release-master\x64w\AutoHotkey.dll
Thanks to HotKeyIt for their help! viewtopic.php?f=67&t=95612#p425193
Supports up to 10 params

Code: Select all

; Test in AutoHotkey v2 2.0-beta.1
; Copy the DLL to your script directory or set dllPath
; Test in this dll                                             ahkdll-v1-release-master\x64w\AutoHotkey.dll
; Need V1 AutoHotkey.dll                                       https://hotkeyit.github.io/v1/
; Download dll                                                 https://github.com/HotKeyIt/ahkdll-v1-release/archive/master.zip
; Sample need copy func and save in  D:\OSDTIP.ahk             https://www.autohotkey.com/boards/viewtopic.php?f=6&t=76881
; Thanks to HotKeyIt for their help!                           https://www.autohotkey.com/boards/viewtopic.php?f=67&t=95612#p425193
; Supports up to 10 params

; Persistent
; test := IncludeLib("D:\OSDTIP.ahk")  ;(v1 libs path, AutoHotkey.dll path)
; test.do("OSDTIP_Pop","Notification","Message", "-2000")
; Sleep(2000)
; test.do("OSDTIP_Pop","Notification","Message",  "0", "C11 zh7 w160 CW101010 CTD3D3D3 U1 U2",,,"0x00FFFF", "0x808080", "30")
; Sleep(2000)
; test.do("OSDTIP_KBLeds","CapsLock", "", "-2000")
; Sleep(2000)
; test.do("OSDTIP_Volume","+1", "", "-2000")
; Sleep(2000)
; test.do("OSDTIP_Desktop",A_UserName,A_Hour ":" A_Min ":" A_Sec ,"-2000") ;Variables dont need ""
; Sleep(2000)
; test.do("OSDTIP_Alert","MainText","SubText")
; Sleep(2000)
; test := ""
; ExitApp

Class IncludeLib
{

    __New(libPath, dllPath := "")
    {
        if !FileExist(dllPath := dllPath ? dllPath : A_ScriptDir "\AutoHotkey.dll")
            MsgBox("Miss AutoHotkey.dll file"), ExitApp()
        This.hDll := DllCall("LoadLibrary", "Str", dllPath, "Ptr")
        DllCall("AutoHotkey.dll\ahktextdll", "Str", "#Persistent `n#NoTrayIcon `n#include " libPath, "Str", "", "Str", "")
        This.hahkFunction := DllCall("GetProcAddress", "Ptr", This.hDll, "AStr", "ahkFunction", "PTR")
    }

    __Delete()
    {
        DllCall("AutoHotkey.dll\ahkExec", "Str", "ExitApp", "CDecl")
        DllCall("FreeLibrary", "Ptr", This.hDll)
    }

    do(FuncNmae, v*)
    {
        p := []
        Loop 10
            p.Push(v.Has(A_Index) ? v[A_Index] : "")
        ahkFunction := DllCall.Bind(this.hahkFunction, "Str", , "Str", p[1], "Str", p[2], "Str", p[3], "Str", p[4], "Str", p[5], "Str", p[6], "Str", p[7], "Str", p[8], "Str", p[9], "Str", p[10], "CDecl Str")
        return ahkFunction(FuncNmae)
    }
}

viv
Posts: 217
Joined: 09 Dec 2020, 17:48

Re: A simple Class for calling V1's libs in V2

Post by viv » 16 Oct 2021, 05:55

Having a bit of trouble working with ACC and not sure what to do about it

use this in chrome will stuck
viewtopic.php?p=347959#p347959

Stuck on this line

Code: Select all

if DllCall("oleacc\AccessibleChildren", "Ptr",ComObjValue(Acc), "Int",0, "Int",cChildren, "Ptr",VarSetCapacity(varChildren,cChildren*(8+2*A_PtrSize),0)*0+&varChildren, "Int*",cChildren)=0
https://github.com/sancarn/ACC.AHK/blob/795d10646f9b90a05d2cc3d7f505b7950ff9db21/AccV2.ahk#L583
or this
https://github.com/sancarn/ACC.AHK/blob/795d10646f9b90a05d2cc3d7f505b7950ff9db21/AccV2.ahk#L614
Last edited by viv on 20 Oct 2021, 08:14, edited 1 time in total.

User avatar
Delta Pythagorean
Posts: 627
Joined: 13 Feb 2017, 13:44
Location: Somewhere in the US
Contact:

Re: A simple Class for calling V1's libs in V2

Post by Delta Pythagorean » 18 Oct 2021, 12:09

Wouldn't it be better to use the __Call method instead of using the do method?

[AHK]......: v2.0.12 | 64-bit
[OS].......: Windows 11 | 23H2 (OS Build: 22621.3296)
[GITHUB]...: github.com/DelPyth
[PAYPAL]...: paypal.me/DelPyth
[DISCORD]..: tophatcat


viv
Posts: 217
Joined: 09 Dec 2020, 17:48

Re: A simple Class for calling V1's libs in V2

Post by viv » 19 Oct 2021, 00:48

@Delta Pythagorean
I am not a programmer and find calss very difficult to use
and the documentation does not have any examples
so I don't really understand what it is used for.

User avatar
Delta Pythagorean
Posts: 627
Joined: 13 Feb 2017, 13:44
Location: Somewhere in the US
Contact:

Re: A simple Class for calling V1's libs in V2

Post by Delta Pythagorean » 20 Oct 2021, 06:28

The best way to do it is through the __Call meta-method. I've provided some documentation to go along with my version of this class:

Code: Select all

/**
 * Include an AutoHotkey v1 library into an AutoHotkey v2 script/program.
 *
 * @example
 * Persistent(true)
 * test := IncludeLib("<OSDTIP>")
 * test.OSDTIP_Pop("Notification", "Message", "-2000")
 * Sleep(2000)
 * test.OSDTIP_Pop("Notification", "Message", "0", "C11 zh7 w160 CW101010 CTD3D3D3 U1 U2",,, "0x00FFFF", "0x808080", "30")
 * Sleep(2000)
 * test.OSDTIP_KBLeds("CapsLock", "", "-2000")
 * Sleep(2000)
 * test.OSDTIP_Volume("+1", "", "-2000")
 * Sleep(2000)
 * test.OSDTIP_Desktop(A_UserName, Format("{1}:{2}:{3}", A_Hour, A_Min, A_Sec), "-2000") ; Variables dont need ""
 * Sleep(2000)
 * test.OSDTIP_Alert("MainText","SubText")
 * Sleep(2000)
 * test := ""
 * ExitApp(0)
*/
class IncludeLib
{
	/** @type {number} */
	handle_dll := 0

	/** @type {number} */
	handle_ahk_func := 0

	/** @type {string}  */
	lib_path := ""
	
	/** @type {string}  */
	dll_path := ""


	__New(lib_path, dll_path := "")
	{
		this.lib_path := lib_path
		this.dll_path := dll_path ? (dll_path) : (A_ScriptDir . "\AutoHotkey.dll")

		if (!FileExist(this.dll_path))
		{
			throw Error("Invalid or missing dynamic link library file", -1, dll_path)
		}

		try
		{
			this.handle_dll := DllCall("LoadLibrary", "Str", this.dll_path, "Ptr")
		}
		catch Any
		{
			throw Error("Could not load dynamic link library", -1, this.dll_path)
		}
		DllCall(dll_path . "\ahktextdll", "Str", "#Persistent `n#NoTrayIcon `n#include " . this.lib_path, "Str", "", "Str", "")
		this.handle_ahk_func := DllCall("GetProcAddress", "Ptr", this.handle_dll, "AStr", "ahkFunction", "PTR")
	}

	__Delete()
	{
		DllCall(this.dll_path . "\ahkExec", "Str", "ExitApp", "CDecl")
		DllCall("FreeLibrary", "Ptr", this.handle_dll)
	}

	__Call(func_name, args*)
	{
		params := []
		params.Push("Str", "")
		for index, value in args
		{
			if (value == "") || (!value)
			{
				params.Push("Str", "")
				continue
			}

			if (this._TypeOf(value) !== "String")
			{
				type_of := this._TypeOf(value)
				throw Error("Expected a string, got a" . (type_of == "Array" ? "n") . " " . type_of, -1, "args[" . index . "]")
			}

			params.Push("Str", value)
		}
		params.Push("CDel Str")

		ahk_func := DllCall.Bind(this.handle_ahk_func, params*)		; Should look like: DllCall(this.handle_ahk_func, "Str", "", ("Str", params) ... , "CDel Str")

		try
		{
			return ahk_func(func_name)
		}
		catch Any as err
		{
			throw err
		}
	}

	_TypeOf(Value)
	{
		if ((comClass := ComObjType(Value, "Class")) != "")
		{
			return comClass
		}

		try ; `Value is Object` is not checked because it can be false for prototypes.
		{
			if (ObjHasOwnProp(Value, "__Class"))
			{
				return "Prototype"
			}
		}

		while (Value := ObjGetBase(Value))
		{
			if (ObjHasOwnProp(Value, "__Class"))
			{
				return Value.__Class
			}
		}

		return "Object"
	}
}
EDIT: Fixed a few things such as where the AHK.DLL file resides not being used and allowing more than 10 parameters for the DllCall to the function residing in the library.
As for the codeblock highlighting the rest of the code into a comment because multi-line comments aren't implemented with v2's style, I refuse to change my ways :P
Last edited by Delta Pythagorean on 22 Oct 2021, 01:55, edited 1 time in total.

[AHK]......: v2.0.12 | 64-bit
[OS].......: Windows 11 | 23H2 (OS Build: 22621.3296)
[GITHUB]...: github.com/DelPyth
[PAYPAL]...: paypal.me/DelPyth
[DISCORD]..: tophatcat


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

Re: A simple Class for calling V1's libs in V2

Post by jNizM » 20 Oct 2021, 06:36

OT @Delta Pythagorean
The multi-line comments (/* */) as one-line comment breaks the forum codbox highlighter. Use ; for one-line comments

Or @joedf can you push a fix for this?
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile

User avatar
kczx3
Posts: 1640
Joined: 06 Oct 2015, 21:39

Re: A simple Class for calling V1's libs in V2

Post by kczx3 » 20 Oct 2021, 07:52

Multi line comments are used because some editors highlight words that start with @ differently within those comments. Typically called Comment Docs, I think.

viv
Posts: 217
Joined: 09 Dec 2020, 17:48

Re: A simple Class for calling V1's libs in V2

Post by viv » 20 Oct 2021, 07:57

@Delta Pythagorean

Thank you very much
As a non-programmer, I don’t pay much attention to throwing mistakes

But the example fails to run...
TIPs : Error: Expected a String but got an Array.
I guess there is a problem with the incoming parameters
I tested it with reference to
args is not passed in

Code: Select all

i := test()
i.do("1","2","3")
class test
{
	__Call(test1,args*)
	{
		MsgBox test1 ;has test1
		MsgBox args.length ;have length 1
		for i in args ;but nothing in array?
			MsgBox i
	}
}

Tre4shunter
Posts: 139
Joined: 26 Jan 2016, 16:05

Re: A simple Class for calling V1's libs in V2

Post by Tre4shunter » 20 Oct 2021, 10:18

[EDIT] disregard, apparently i was using not latest beta version.

Im unable to get either example with OSDTIP to work?

failing here for some reason?

Code: Select all

        DllCall("AutoHotkey.dll\ahktextdll", "Str", "#Persistent `n#NoTrayIcon `n#include " libPath, "Str", "", "Str", "")
i have the autohotkey.dll in my main script dir. It's a 'Failed to load dll' Error.

ideas?

HotKeyIt
Posts: 2364
Joined: 29 Sep 2013, 18:35
Contact:

Re: A simple Class for calling V1's libs in V2

Post by HotKeyIt » 20 Oct 2021, 11:20

It should be DllCall(dll_path "\ahktextdll", "Str", "#Persistent `n#NoTrayIcon `n#include " . lib_path, "Str", "", "Str", "")

Tre4shunter
Posts: 139
Joined: 26 Jan 2016, 16:05

Re: A simple Class for calling V1's libs in V2

Post by Tre4shunter » 21 Oct 2021, 18:17

Im really struggling to understand why @Delta Pythagorean's version of the OPs script does not work.

it states "Expected a String but got an Array." I've tried my best to understand this one, but cant seem to make it work....if anyone could perhaps shed some light id be very grateful.

Thanks!

-Tr4

Tre4shunter
Posts: 139
Joined: 26 Jan 2016, 16:05

Re: A simple Class for calling V1's libs in V2

Post by Tre4shunter » 22 Oct 2021, 09:17

Delta Pythagorean wrote:
20 Oct 2021, 06:28
The best way to do it is through the __Call meta-method. I've provided some documentation to go along with my version of this class:

Code: Select all

/**
 * Include an AutoHotkey v1 library into an AutoHotkey v2 script/program.
 *
 * @example
 * Persistent(true)
 * test := IncludeLib("<OSDTIP>")
 * test.OSDTIP_Pop("Notification", "Message", "-2000")
 * Sleep(2000)
 * test.OSDTIP_Pop("Notification", "Message", "0", "C11 zh7 w160 CW101010 CTD3D3D3 U1 U2",,, "0x00FFFF", "0x808080", "30")
 * Sleep(2000)
 * test.OSDTIP_KBLeds("CapsLock", "", "-2000")
 * Sleep(2000)
 * test.OSDTIP_Volume("+1", "", "-2000")
 * Sleep(2000)
 * test.OSDTIP_Desktop(A_UserName, Format("{1}:{2}:{3}", A_Hour, A_Min, A_Sec), "-2000") ; Variables dont need ""
 * Sleep(2000)
 * test.OSDTIP_Alert("MainText","SubText")
 * Sleep(2000)
 * test := ""
 * ExitApp(0)
*/
class IncludeLib
{
	/** @type {number} */
	handle_dll := 0

	/** @type {number} */
	handle_ahk_func := 0

	/** @type {string}  */
	lib_path := ""
	
	/** @type {string}  */
	dll_path := ""


	__New(lib_path, dll_path := "")
	{
		this.lib_path := lib_path
		this.dll_path := dll_path ? (dll_path) : (A_ScriptDir . "\AutoHotkey.dll")

		if (!FileExist(this.dll_path))
		{
			throw Error("Invalid or missing dynamic link library file", -1, dll_path)
		}

		try
		{
			this.handle_dll := DllCall("LoadLibrary", "Str", this.dll_path, "Ptr")
		}
		catch Any
		{
			throw Error("Could not load dynamic link library", -1, this.dll_path)
		}
		DllCall(dll_path . "\ahktextdll", "Str", "#Persistent `n#NoTrayIcon `n#include " . this.lib_path, "Str", "", "Str", "")
		this.handle_ahk_func := DllCall("GetProcAddress", "Ptr", this.handle_dll, "AStr", "ahkFunction", "PTR")
	}

	__Delete()
	{
		DllCall(this.dll_path . "\ahkExec", "Str", "ExitApp", "CDecl")
		DllCall("FreeLibrary", "Ptr", this.handle_dll)
	}

	__Call(func_name, args*)
	{
		params := []
		params.Push("Str", "")
		for index, value in args
		{
			if (value == "") || (!value)
			{
				params.Push("Str", "")
				continue
			}

			if (this._TypeOf(value) !== "String")
			{
				type_of := this._TypeOf(value)
				throw Error("Expected a string, got a" . (type_of == "Array" ? "n") . " " . type_of, -1, "args[" . index . "]")
			}

			params.Push("Str", value)
		}
		params.Push("CDel Str")

		ahk_func := DllCall.Bind(this.handle_ahk_func, params*)		; Should look like: DllCall(this.handle_ahk_func, "Str", "", ("Str", params) ... , "CDel Str")

		try
		{
			return ahk_func(func_name)
		}
		catch Any as err
		{
			throw err
		}
	}

	_TypeOf(Value)
	{
		if ((comClass := ComObjType(Value, "Class")) != "")
		{
			return comClass
		}

		try ; `Value is Object` is not checked because it can be false for prototypes.
		{
			if (ObjHasOwnProp(Value, "__Class"))
			{
				return "Prototype"
			}
		}

		while (Value := ObjGetBase(Value))
		{
			if (ObjHasOwnProp(Value, "__Class"))
			{
				return Value.__Class
			}
		}

		return "Object"
	}
}
EDIT: Fixed a few things such as where the AHK.DLL file resides not being used and allowing more than 10 parameters for the DllCall to the function residing in the library.
As for the codeblock highlighting the rest of the code into a comment because multi-line comments aren't implemented with v2's style, I refuse to change my ways :P
Appreciate the updates, im learning lots....but i still cant get your version of this class to work, no matter what i try? Also - are you missing something here?

Code: Select all

params.Push("CDel Str")..shoudnt it be "Cdecl Str"
Sorry to be such a bother with this..

Thanks again

Post Reply

Return to “Scripts and Functions (v2)”