commit
c4d7284ad4
8 changed files with 593 additions and 0 deletions
@ -0,0 +1,2 @@ |
|||
* |
|||
!.gitignore |
@ -0,0 +1,60 @@ |
|||
; Set default location and name convention for compiled scripts to use |
|||
;@Ahk2Exe-ExeName %A_MyDocuments%\AutoHotkey\bin\AHK-%A_ScriptName% |
|||
|
|||
; Install hooks to make sure script can get physical state of keys instead of logical state. |
|||
#InstallKeybdHook |
|||
#InstallMouseHook |
|||
|
|||
; Settings |
|||
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. |
|||
SendMode Input ; Recommended for new scripts due to its superior speed and reliability. |
|||
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory. |
|||
#UseHook ; All hotkeys are implemented through keyboard hook to avoid script activating itself. |
|||
#MenuMaskKey vkFF |
|||
|
|||
; |
|||
; Function definitions |
|||
; |
|||
|
|||
Hold(Primary, Secondary) { |
|||
Send {%Primary% down} |
|||
if ( Secondary.Length() != 0 ) { |
|||
ThisLoop := Func("HoldLoop").bind(Primary,Secondary) |
|||
SetTimer, %ThisLoop%, 50 |
|||
} |
|||
} |
|||
|
|||
HoldLoop(Primary, Secondary) { |
|||
if GetKeyState(Primary,"P") { |
|||
SetTimer, , Delete |
|||
} |
|||
for index,key in Secondary { |
|||
if GetKeyState(key,"P") { |
|||
Send {%Primary% up} |
|||
SetTimer, , Delete |
|||
} |
|||
} |
|||
} |
|||
|
|||
Repeat(Primary, Secondary) { |
|||
Send {%Primary% up} |
|||
Sleep 100 |
|||
RepeatVar := 0 |
|||
Loop { |
|||
if GetKeyState(Primary,"P") { |
|||
return |
|||
} |
|||
for index,key in Secondary { |
|||
if GetKeyState(key,"P") { |
|||
return |
|||
} |
|||
} |
|||
if (RepeatVar == 2) { |
|||
SendEvent, {%Primary%} |
|||
RepeatVar := 1 |
|||
} else { |
|||
RepeatVar++ |
|||
} |
|||
Sleep 50 |
|||
} |
|||
} |
@ -0,0 +1,72 @@ |
|||
; Script can be directly run by or compiled into an .exe by the open-source software AutoHotkey |
|||
; https://www.autohotkey.com |
|||
|
|||
; |
|||
; Front Matter |
|||
; |
|||
|
|||
; Include general library |
|||
#Include ../lib/General.ahk |
|||
|
|||
; Only do hotkeys if relevant window is active |
|||
#IfWinActive, Minecraft |
|||
|
|||
; |
|||
; Hotkeys |
|||
; |
|||
|
|||
; Tab will be the hotkey |
|||
~Tab::return |
|||
|
|||
; Hold/Autoclick mouse buttons |
|||
; Holds if single click, autoclicks if double click |
|||
Tab & LButton UP:: |
|||
KeyWait, LButton, D, T0.2 |
|||
if (ErrorLevel = 0) { |
|||
Repeat("LButton",["RButton","MButton"]) |
|||
} else { |
|||
Hold("LButton",["RButton","MButton"]) |
|||
} |
|||
return |
|||
Tab & RButton UP:: |
|||
KeyWait, RButton, D, T0.2 |
|||
if (ErrorLevel = 0) { |
|||
Repeat("RButton",["LButton","MButton"]) |
|||
} else { |
|||
Hold("RButton",["LButton","MButton"]) |
|||
} |
|||
return |
|||
|
|||
; Autorun |
|||
Tab & w UP::Hold("w",["s"]) |
|||
Tab & s UP::Hold("s",["w"]) |
|||
Tab & a UP::Hold("a",["d","w","s"]) |
|||
Tab & d UP::Hold("d",["a","w","s"]) |
|||
|
|||
; Hold crouch |
|||
Tab & Shift UP:: |
|||
if GetKeyState("Alt","P") { |
|||
Hold("Shift",["Ctrl"]) |
|||
} else { |
|||
Hold("Shift",["Ctrl","Space"]) |
|||
} |
|||
return |
|||
|
|||
; Autojump/auto-ascend |
|||
Tab & Space UP::Hold("Space",["Shift"]) |
|||
|
|||
; Mouse button 4: auto-takeoff |
|||
; Macro assumes you have your fireworks in the first hotbar slot |
|||
XButton1:: |
|||
Loop, 5 { |
|||
Send {Space down} |
|||
Sleep 10 |
|||
} |
|||
Send {Space up}1 |
|||
Sleep 225 |
|||
Loop, 5 { |
|||
Send {Space down} |
|||
Sleep 10 |
|||
} |
|||
Send {Space up}{RButton} |
|||
return |
@ -0,0 +1,101 @@ |
|||
; Script can be directly run by or compiled into an .exe by the open-source software AutoHotkey |
|||
; https://www.autohotkey.com |
|||
|
|||
; |
|||
; Front Matter |
|||
; |
|||
|
|||
; Include general library |
|||
#Include ../lib/General.ahk |
|||
|
|||
; Include ViGEm library |
|||
#Include ../thirdparty/AHK-ViGEm-Bus/AHK-ViGEm-Bus.ahk |
|||
; Create a new Xbox 360 controller |
|||
MyXbox := new ViGEmXb360() |
|||
|
|||
; Settings |
|||
SetTitleMatchMode,2 |
|||
DetectHiddenWindows,On |
|||
|
|||
; Set percent to deflect by for fine controls |
|||
Defl := 30 |
|||
|
|||
; Create Gui to show deflection percent |
|||
MyGuiTime = 1 |
|||
Gui, +AlwaysOnTop -Caption +ToolWindow |
|||
Gui, Margin, 0, 0 |
|||
Gui, Font, s20 CWhite |
|||
Gui, Color, Black |
|||
Gui, Add, Text, vMyGuiText +Center, Fine Controls: 100`% |
|||
Gui, Show, NoActivate, OuterWildsAhkGui |
|||
WinSet, TransColor, Black, OuterWildsAhkGui |
|||
|
|||
UpdateGui: |
|||
If (MyGuiTime != 0) { |
|||
Gui, Show, NoActivate |
|||
GuiControl, Text, MyGuiText, Fine Controls: %Defl%`% |
|||
MyGuiTime-- |
|||
If (MyGuiTime == 0) { |
|||
Gui, Hide |
|||
SetTimer, UpdateGui, Off |
|||
} |
|||
} |
|||
return |
|||
|
|||
; Only do hotkeys if relevant window is active |
|||
#IfWinActive, Outer Wilds |
|||
|
|||
; |
|||
; Hotkeys |
|||
; |
|||
|
|||
; Hold keys |
|||
*!w UP::Hold("w",["s"]) |
|||
*!s UP::Hold("s",["w"]) |
|||
*!a UP::Hold("a",["d","w","s"]) |
|||
*!d UP::Hold("d",["a","w","s"]) |
|||
*!Space UP::Hold("Space",["Shift"]) |
|||
*!Shift UP::Hold("Shift",["Space"]) |
|||
|
|||
; Alt+Scroll changes deflect percent |
|||
*!WheelUp:: |
|||
Defl := Min(Defl + 5,100) |
|||
MyGuiTime = 10 |
|||
SetTimer, UpdateGui, 100 |
|||
Goto UpdateGui |
|||
return |
|||
*!WheelDown:: |
|||
Defl := Max(Defl - 5,0) |
|||
MyGuiTime = 10 |
|||
SetTimer, UpdateGui, 100 |
|||
Goto UpdateGui |
|||
return |
|||
|
|||
; Reset all axes when capslock is pressed |
|||
~CapsLock:: |
|||
MyXbox.Axes.LY.SetState(50) |
|||
MyXbox.Axes.LX.SetState(50) |
|||
MyXbox.Axes.RT.SetState(0) |
|||
MyXbox.Axes.LT.SetState(0) |
|||
return |
|||
|
|||
; Fine control is active when caps lock is on |
|||
#If GetKeyState("CapsLock","T") |
|||
|
|||
W::MyXbox.Axes.LY.SetState(50+Defl*.5) |
|||
W UP::MyXbox.Axes.LY.SetState(50) |
|||
|
|||
S::MyXbox.Axes.LY.SetState(50-Defl*.5) |
|||
S UP::MyXbox.Axes.LY.SetState(50) |
|||
|
|||
D::MyXbox.Axes.LX.SetState(50+Defl*.5) |
|||
D UP::MyXbox.Axes.LX.SetState(50) |
|||
|
|||
A::MyXbox.Axes.LX.SetState(50-Defl*.5) |
|||
A UP::MyXbox.Axes.LX.SetState(50) |
|||
|
|||
Space::MyXbox.Axes.RT.SetState(Defl*.16) |
|||
Space UP::MyXbox.Axes.RT.SetState(0) |
|||
|
|||
Shift::MyXbox.Axes.LT.SetState(Defl*.16) |
|||
Shift UP::MyXbox.Axes.LT.SetState(0) |
@ -0,0 +1,207 @@ |
|||
#include %A_LineFile%\..\CLR.ahk |
|||
|
|||
; Static class, holds ViGEm Client instance |
|||
class ViGEmWrapper { |
|||
static asm := 0 |
|||
static client := 0 |
|||
|
|||
Init(){ |
|||
if (this.client == 0){ |
|||
this.asm := CLR_LoadLibrary(A_LineFile "\..\ViGEmWrapper.dll") |
|||
} |
|||
} |
|||
|
|||
CreateInstance(cls){ |
|||
return this.asm.CreateInstance(cls) |
|||
} |
|||
|
|||
} |
|||
|
|||
; Base class for ViGEm "Targets" (Controller types - eg xb360 / ds4) to inherit from |
|||
class ViGEmTarget { |
|||
target := 0 |
|||
helperClass := "" |
|||
controllerClass := "" |
|||
|
|||
__New(){ |
|||
;~ this.asm := CLR_LoadLibrary(A_LineFile "\..\ViGEmWrapper.dll") |
|||
ViGEmWrapper.Init() |
|||
this.Instance := ViGEmWrapper.CreateInstance(this.helperClass) |
|||
|
|||
if (this.Instance.OkCheck() != "OK"){ |
|||
msgbox ViGEmWrapper.dll failed to load! |
|||
ExitApp |
|||
} |
|||
} |
|||
|
|||
SendReport(){ |
|||
this.Instance.SendReport() |
|||
} |
|||
} |
|||
|
|||
; DS4 (DualShock 4 for Playstation 4) |
|||
class ViGEmDS4 extends ViGEmTarget { |
|||
helperClass := "ViGEmWrapper.Ds4" |
|||
__New(){ |
|||
static buttons := {Square: 16, Cross: 32, Circle: 64, Triangle: 128, L1: 256, R1: 512, L2: 1024, R2: 2048 |
|||
, Share: 4096, Options: 8192, LS: 16384, RS: 32768 } |
|||
static specialButtons := {Ps: 1, TouchPad: 2} |
|||
static axes := {LX: 2, LY: 3, RX: 4, RY: 5, LT: 0, RT: 1} |
|||
|
|||
this.Buttons := {} |
|||
for name, id in buttons { |
|||
this.Buttons[name] := new this._ButtonHelper(this, id) |
|||
} |
|||
for name, id in specialButtons { |
|||
this.Buttons[name] := new this._SpecialButtonHelper(this, id) |
|||
} |
|||
|
|||
this.Axes := {} |
|||
for name, id in axes { |
|||
this.Axes[name] := new this._AxisHelper(this, id) |
|||
} |
|||
|
|||
this.Dpad := new this._DpadHelper(this) |
|||
base.__New() |
|||
} |
|||
|
|||
class _ButtonHelper { |
|||
__New(parent, id){ |
|||
this._Parent := parent |
|||
this._Id := id |
|||
} |
|||
|
|||
SetState(state){ |
|||
this._Parent.Instance.SetButtonState(this._Id, state) |
|||
this._Parent.Instance.SendReport() |
|||
return this._Parent |
|||
} |
|||
} |
|||
|
|||
class _SpecialButtonHelper { |
|||
__New(parent, id){ |
|||
this._Parent := parent |
|||
this._Id := id |
|||
} |
|||
|
|||
SetState(state){ |
|||
this._Parent.Instance.SetSpecialButtonState(this._Id, state) |
|||
this._Parent.Instance.SendReport() |
|||
return this._Parent |
|||
} |
|||
} |
|||
|
|||
class _AxisHelper { |
|||
__New(parent, id){ |
|||
this._Parent := parent |
|||
this._Id := id |
|||
} |
|||
|
|||
SetState(state){ |
|||
this._Parent.Instance.SetAxisState(this._Id, this.ConvertAxis(state)) |
|||
this._Parent.Instance.SendReport() |
|||
return this._Parent |
|||
} |
|||
|
|||
ConvertAxis(state){ |
|||
return round(state * 2.55) |
|||
} |
|||
} |
|||
|
|||
class _DpadHelper { |
|||
__New(parent){ |
|||
this._Parent := parent |
|||
this._Id := id |
|||
} |
|||
|
|||
SetState(state){ |
|||
static dPadDirections := {Up: 0, UpRight: 1, Right: 2, DownRight: 3, Down: 4, DownLeft: 5, Left: 6, UpLeft: 7, None: 8} |
|||
this._Parent.Instance.SetDpadState(dPadDirections[state]) |
|||
this._Parent.Instance.SendReport() |
|||
return this._Parent |
|||
} |
|||
} |
|||
} |
|||
|
|||
; Xb360 |
|||
class ViGEmXb360 extends ViGEmTarget { |
|||
helperClass := "ViGEmWrapper.Xb360" |
|||
__New(){ |
|||
static buttons := {A: 4096, B: 8192, X: 16384, Y: 32768, LB: 256, RB: 512, LS: 64, RS: 128, Back: 32, Start: 16, Xbox: 1024} |
|||
static axes := {LX: 2, LY: 3, RX: 4, RY: 5, LT: 0, RT: 1} |
|||
|
|||
this.Buttons := {} |
|||
for name, id in buttons { |
|||
this.Buttons[name] := new this._ButtonHelper(this, id) |
|||
} |
|||
|
|||
this.Axes := {} |
|||
for name, id in axes { |
|||
this.Axes[name] := new this._AxisHelper(this, id) |
|||
} |
|||
|
|||
this.Dpad := new this._DpadHelper(this) |
|||
|
|||
base.__New() |
|||
} |
|||
|
|||
class _ButtonHelper { |
|||
__New(parent, id){ |
|||
this._Parent := parent |
|||
this._Id := id |
|||
} |
|||
|
|||
SetState(state){ |
|||
this._Parent.Instance.SetButtonState(this._Id, state) |
|||
this._Parent.Instance.SendReport() |
|||
return this._Parent |
|||
} |
|||
} |
|||
|
|||
class _AxisHelper { |
|||
__New(parent, id){ |
|||
this._Parent := parent |
|||
this._id := id |
|||
} |
|||
|
|||
SetState(state){ |
|||
this._Parent.Instance.SetAxisState(this._Id, this.ConvertAxis(state)) |
|||
this._Parent.Instance.SendReport() |
|||
} |
|||
|
|||
ConvertAxis(state){ |
|||
value := round((state * 655.36) - 32768) |
|||
if (value == 32768) |
|||
return 32767 |
|||
return value |
|||
} |
|||
} |
|||
|
|||
class _DpadHelper { |
|||
_DpadStates := {1:0, 8:0, 2:0, 4:0} ; Up, Right, Down, Left |
|||
__New(parent){ |
|||
this._Parent := parent |
|||
} |
|||
|
|||
SetState(state){ |
|||
static dpadDirections := { None: {1:0, 8:0, 2:0, 4:0} |
|||
, Up: {1:1, 8:0, 2:0, 4:0} |
|||
, UpRight: {1:1, 8:1, 2:0, 4:0} |
|||
, Right: {1:0, 8:1, 2:0, 4:0} |
|||
, DownRight: {1:0, 8:1, 2:1, 4:0} |
|||
, Down: {1:0, 8:0, 2:1, 4:0} |
|||
, DownLeft: {1:0, 8:0, 2:1, 4:1} |
|||
, Left: {1:0, 8:0, 2:0, 4:1} |
|||
, UpLeft: {1:1, 8:0, 2:0, 4:1}} |
|||
newStates := dpadDirections[state] |
|||
for id, newState in newStates { |
|||
oldState := this._DpadStates[id] |
|||
if (oldState != newState){ |
|||
this._DpadStates[id] := newState |
|||
this._Parent.Instance.SetButtonState(id, newState) |
|||
} |
|||
this._Parent.SendReport() |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,151 @@ |
|||
; ========================================================== |
|||
; .NET Framework Interop |
|||
; https://autohotkey.com/boards/viewtopic.php?t=4633 |
|||
; ========================================================== |
|||
; |
|||
; Author: Lexikos |
|||
; Version: 1.2 |
|||
; Requires: AutoHotkey_L v1.0.96+ |
|||
; |
|||
|
|||
CLR_LoadLibrary(AssemblyName, AppDomain=0) |
|||
{ |
|||
if !AppDomain |
|||
AppDomain := CLR_GetDefaultDomain() |
|||
e := ComObjError(0) |
|||
Loop 1 { |
|||
if assembly := AppDomain.Load_2(AssemblyName) |
|||
break |
|||
static null := ComObject(13,0) |
|||
args := ComObjArray(0xC, 1), args[0] := AssemblyName |
|||
typeofAssembly := AppDomain.GetType().Assembly.GetType() |
|||
if assembly := typeofAssembly.InvokeMember_3("LoadWithPartialName", 0x158, null, null, args) |
|||
break |
|||
if assembly := typeofAssembly.InvokeMember_3("LoadFrom", 0x158, null, null, args) |
|||
break |
|||
} |
|||
ComObjError(e) |
|||
return assembly |
|||
} |
|||
|
|||
CLR_CreateObject(Assembly, TypeName, Args*) |
|||
{ |
|||
if !(argCount := Args.MaxIndex()) |
|||
return Assembly.CreateInstance_2(TypeName, true) |
|||
|
|||
vargs := ComObjArray(0xC, argCount) |
|||
Loop % argCount |
|||
vargs[A_Index-1] := Args[A_Index] |
|||
|
|||
static Array_Empty := ComObjArray(0xC,0), null := ComObject(13,0) |
|||
|
|||
return Assembly.CreateInstance_3(TypeName, true, 0, null, vargs, null, Array_Empty) |
|||
} |
|||
|
|||
CLR_CompileC#(Code, References="", AppDomain=0, FileName="", CompilerOptions="") |
|||
{ |
|||
return CLR_CompileAssembly(Code, References, "System", "Microsoft.CSharp.CSharpCodeProvider", AppDomain, FileName, CompilerOptions) |
|||
} |
|||
|
|||
CLR_CompileVB(Code, References="", AppDomain=0, FileName="", CompilerOptions="") |
|||
{ |
|||
return CLR_CompileAssembly(Code, References, "System", "Microsoft.VisualBasic.VBCodeProvider", AppDomain, FileName, CompilerOptions) |
|||
} |
|||
|
|||
CLR_StartDomain(ByRef AppDomain, BaseDirectory="") |
|||
{ |
|||
static null := ComObject(13,0) |
|||
args := ComObjArray(0xC, 5), args[0] := "", args[2] := BaseDirectory, args[4] := ComObject(0xB,false) |
|||
AppDomain := CLR_GetDefaultDomain().GetType().InvokeMember_3("CreateDomain", 0x158, null, null, args) |
|||
return A_LastError >= 0 |
|||
} |
|||
|
|||
CLR_StopDomain(ByRef AppDomain) |
|||
{ ; ICorRuntimeHost::UnloadDomain |
|||
DllCall("SetLastError", "uint", hr := DllCall(NumGet(NumGet(0+RtHst:=CLR_Start())+20*A_PtrSize), "ptr", RtHst, "ptr", ComObjValue(AppDomain))), AppDomain := "" |
|||
return hr >= 0 |
|||
} |
|||
|
|||
; NOTE: IT IS NOT NECESSARY TO CALL THIS FUNCTION unless you need to load a specific version. |
|||
CLR_Start(Version="") ; returns ICorRuntimeHost* |
|||
{ |
|||
static RtHst := 0 |
|||
; The simple method gives no control over versioning, and seems to load .NET v2 even when v4 is present: |
|||
; return RtHst ? RtHst : (RtHst:=COM_CreateObject("CLRMetaData.CorRuntimeHost","{CB2F6722-AB3A-11D2-9C40-00C04FA30A3E}"), DllCall(NumGet(NumGet(RtHst+0)+40),"uint",RtHst)) |
|||
if RtHst |
|||
return RtHst |
|||
EnvGet SystemRoot, SystemRoot |
|||
if Version = |
|||
Loop % SystemRoot "\Microsoft.NET\Framework" (A_PtrSize=8?"64":"") "\*", 2 |
|||
if (FileExist(A_LoopFileFullPath "\mscorlib.dll") && A_LoopFileName > Version) |
|||
Version := A_LoopFileName |
|||
if DllCall("mscoree\CorBindToRuntimeEx", "wstr", Version, "ptr", 0, "uint", 0 |
|||
, "ptr", CLR_GUID(CLSID_CorRuntimeHost, "{CB2F6723-AB3A-11D2-9C40-00C04FA30A3E}") |
|||
, "ptr", CLR_GUID(IID_ICorRuntimeHost, "{CB2F6722-AB3A-11D2-9C40-00C04FA30A3E}") |
|||
, "ptr*", RtHst) >= 0 |
|||
DllCall(NumGet(NumGet(RtHst+0)+10*A_PtrSize), "ptr", RtHst) ; Start |
|||
return RtHst |
|||
} |
|||
|
|||
; |
|||
; INTERNAL FUNCTIONS |
|||
; |
|||
|
|||
CLR_GetDefaultDomain() |
|||
{ |
|||
static defaultDomain := 0 |
|||
if !defaultDomain |
|||
{ ; ICorRuntimeHost::GetDefaultDomain |
|||
if DllCall(NumGet(NumGet(0+RtHst:=CLR_Start())+13*A_PtrSize), "ptr", RtHst, "ptr*", p:=0) >= 0 |
|||
defaultDomain := ComObject(p), ObjRelease(p) |
|||
} |
|||
return defaultDomain |
|||
} |
|||
|
|||
CLR_CompileAssembly(Code, References, ProviderAssembly, ProviderType, AppDomain=0, FileName="", CompilerOptions="") |
|||
{ |
|||
if !AppDomain |
|||
AppDomain := CLR_GetDefaultDomain() |
|||
|
|||
if !(asmProvider := CLR_LoadLibrary(ProviderAssembly, AppDomain)) |
|||
|| !(codeProvider := asmProvider.CreateInstance(ProviderType)) |
|||
|| !(codeCompiler := codeProvider.CreateCompiler()) |
|||
return 0 |
|||
|
|||
if !(asmSystem := (ProviderAssembly="System") ? asmProvider : CLR_LoadLibrary("System", AppDomain)) |
|||
return 0 |
|||
|
|||
; Convert | delimited list of references into an array. |
|||
StringSplit, Refs, References, |, %A_Space%%A_Tab% |
|||
aRefs := ComObjArray(8, Refs0) |
|||
Loop % Refs0 |
|||
aRefs[A_Index-1] := Refs%A_Index% |
|||
|
|||
; Set parameters for compiler. |
|||
prms := CLR_CreateObject(asmSystem, "System.CodeDom.Compiler.CompilerParameters", aRefs) |
|||
, prms.OutputAssembly := FileName |
|||
, prms.GenerateInMemory := FileName="" |
|||
, prms.GenerateExecutable := SubStr(FileName,-3)=".exe" |
|||
, prms.CompilerOptions := CompilerOptions |
|||
, prms.IncludeDebugInformation := true |
|||
|
|||
; Compile! |
|||
compilerRes := codeCompiler.CompileAssemblyFromSource(prms, Code) |
|||
|
|||
if error_count := (errors := compilerRes.Errors).Count |
|||
{ |
|||
error_text := "" |
|||
Loop % error_count |
|||
error_text .= ((e := errors.Item[A_Index-1]).IsWarning ? "Warning " : "Error ") . e.ErrorNumber " on line " e.Line ": " e.ErrorText "`n`n" |
|||
MsgBox, 16, Compilation Failed, %error_text% |
|||
return 0 |
|||
} |
|||
; Success. Return Assembly object or path. |
|||
return compilerRes[FileName="" ? "CompiledAssembly" : "PathToAssembly"] |
|||
} |
|||
|
|||
CLR_GUID(ByRef GUID, sGUID) |
|||
{ |
|||
VarSetCapacity(GUID, 16, 0) |
|||
return DllCall("ole32\CLSIDFromString", "wstr", sGUID, "ptr", &GUID) >= 0 ? &GUID : "" |
|||
} |
Binary file not shown.
Binary file not shown.
Loading…
Reference in new issue