I have updated/completed the functions, they have only been tested in AutoHotkey Basic (v1.0), although some may be usable as they are, or with some alterations in AutoHotkey v1.1 ANSI/Unicode versions.
The original aim was to create the functions that I felt were missing but needed in AutoHotkey Basic (one or two could still benefit AHK v1.1/v2). I wanted all of these functions in some form for AutoHotkey v1.1/v2 anyway, and it was an interesting challenge to try to bring them to AutoHotkey Basic.
Note: I have also recreated StrReplace and Trim/LTrim/RTrim for AutoHotkey Basic.
Note: The Winapi function wsprinf is useful for when AHK's Format function is not available.
AutoHotkey Basic was pretty good to work with, it did already have so many of the features that make AutoHotkey great. The one annoyance that sticks out is that I couldn't do things like
, I had to space it out to avoid causing a script error.
Code: Select all
;'AutoHotkey Basic Unicode' by jeeswg
;Unicode functions for AutoHotkey v1.0 'Basic' / AutoHotkey v1.1. x32 ANSI
;JEE_AhkBWinGetTitleUtf8(hWnd)
;JEE_AhkBClipboardGetTextUtf8()
;JEE_AhkBClipboardGetTextUtf8Alt()
;JEE_AhkBClipboardGetPathsUtf8(vSep="`n")
;JEE_AhkBClipboardSetTextUtf8(vText)
;JEE_AhkBClipboardSetTextUtf8Alt(vText)
;JEE_AhkBCtlGetTextUtf8(hCtl=0)
;JEE_AhkBCtlGetSelTextUtf8(hCtl=0)
;JEE_AhkBMsgBoxUtf8(vText, vWinTitle="", vType=0)
;JEE_AhkBChrUtf8(vNum)
;JEE_AhkBChrAUtf8(vNum)
;JEE_AhkBSendCharsUtf8(hWnd, vText)
;JEE_AhkBCtlSetTextUtf8(hCtl, vText)
;JEE_AhkBEditPasteUtf8(hCtl, vText, vCanUndo=1)
;JEE_AhkBAnsiToUtf8(vText)
;JEE_AhkBUtf8ToAnsi(vText, vBFC=0)
;JEE_AhkBAscUtf8(vText)
;JEE_AhkBAscAUtf8(vText)
;JEE_AhkBOrdUtf8(vText, vAscMode=0)
;JEE_AhkBOrdAUtf8(vText)
;JEE_AhkBStrLenUtf8(vText)
;JEE_AhkBSubStrUtf8(vText, vPos, vLen="")
;JEE_AhkBMemMove(vAddrDest, vAddrSource, vSize)
;JEE_AhkBHexGet(vAddr, vSize)
;JEE_AhkBHexPut(vHex, vAddr)
;JEE_AhkBHex2Dec(vHex)
;JEE_AhkBDec2Hex(vNum, vLen=0, vCase="U")
;JEE_AhkBDec2HexAlt(vNum, vLen=0, vCase="U")
;JEE_AhkBFileGetEnc(vPath, vOpt="", ByRef vIsEmpty="")
;JEE_AhkBFileEmpty(vPath)
;JEE_AhkBFileReadUtf8(vPath, vEnc="", vOffset=0, vSize=-1)
;JEE_AhkBFileAppendHex(vHex, vPath)
;JEE_AhkBFileReadHex(vPath, vOffset=0, vSize=-1)
;JEE_AhkBFileAppendUtf8(vText, vPath, vEnc="", vAddBOM=1)
;JEE_AhkBFileReadBin(ByRef vData, vPath, vOffset=0, vSize=-1, ByRef vBytesRead=0)
;JEE_AhkBFileReadBinAlt(ByRef vData, vPath, vOffset=0, vSize=-1, ByRef vBytesRead=0)
;JEE_AhkBFileAppendBin(vAddr, vPath, vSize=0)
;JEE_AhkBUtf16ToUtf8(vAddr16, vSize16, vAddr8=0, vSize8=-1)
;JEE_AhkBUtf8ToUtf16(vAddr8, vSize8=-1, vAddr16=0, vSize16=-1)
;JEE_AhkBUtf16ToAnsi(vAddr16, vSize16, vAddrA=0, vSizeA=-1, vBFC=1)
;JEE_AhkBAnsiToUtf16(vAddrA, vSizeA, vAddr16=0, vSize16=-1)
;StrReplace(vText, vNeedle, vReplaceText="", ByRef vCount="", vLimit=-1)
;Trim(vText, vOmitChars=" `t")
;LTrim(vText, vOmitChars=" `t")
;RTrim(vText, vOmitChars=" `t")
;==================================================
JEE_AhkBWinGetTitleUtf8(hWnd)
{
static Ptr := "Int", UPtr := "UInt"
vDHW := A_DetectHiddenWindows
DetectHiddenWindows, On
vChars := DllCall("user32\GetWindowTextLengthW", Ptr,hWnd)+1
VarSetCapacity(vTextUtf16, vChars*2, 0)
DllCall("user32\GetWindowTextW", Ptr,hWnd, Ptr,&vTextUtf16, Int,vChars)
vSize := DllCall("kernel32\WideCharToMultiByte", UInt,65001, UInt,0, Ptr,&vTextUtf16, Int,vChars, Ptr,0, Int,0, Ptr,0, Ptr,0)
VarSetCapacity(vWinTitle, vSize, 0)
DllCall("kernel32\WideCharToMultiByte", UInt,65001, UInt,0, Ptr,&vTextUtf16, Int,vChars, Str,vWinTitle, Int,vSize, Ptr,0, Ptr,0)
DetectHiddenWindows, % vDHW
return vWinTitle
}
;==================================================
JEE_AhkBClipboardGetTextUtf8()
{
static Ptr := "Int", UPtr := "UInt"
Transform, vText, Unicode
return vText
}
;==================================================
;alternative method (that does not retrieve file paths, see JEE_AhkBClipboardGetPathsUtf8 instead)
JEE_AhkBClipboardGetTextUtf8Alt()
{
static Ptr := "Int", UPtr := "UInt"
;CF_LOCALE := 0x10 ;CF_UNICODETEXT := 0xD
;CF_OEMTEXT := 0x7 ;CF_TEXT := 0x1
if !DllCall("user32\IsClipboardFormatAvailable", UInt,0xD)
if DllCall("user32\IsClipboardFormatAvailable", UInt,0x1)
return Clipboard
else
return ""
if !DllCall("user32\OpenClipboard", Ptr,0)
return ""
if !hBuf := DllCall("user32\GetClipboardData", UInt,0xD, Ptr)
{
DllCall("user32\CloseClipboard")
return ""
}
pBuf := DllCall("kernel32\GlobalLock", Ptr,hBuf, Ptr)
vSize := DllCall("kernel32\GlobalSize", Ptr,hBuf, UPtr)
VarSetCapacity(vOutputUtf16, vSize, 0)
DllCall("kernel32\RtlMoveMemory", Ptr,&vOutputUtf16, Ptr,pBuf, UPtr,vSize)
vChars := vSize/2
vSize := DllCall("kernel32\WideCharToMultiByte", UInt,65001, UInt,0, Ptr,&vOutputUtf16, Int,vChars, Ptr,0, Int,0, Ptr,0, Ptr,0)
VarSetCapacity(vOutput, vSize, 0)
DllCall("kernel32\WideCharToMultiByte", UInt,65001, UInt,0, Ptr,&vOutputUtf16, Int,vChars, Str,vOutput, Int,vSize, Ptr,0, Ptr,0)
DllCall("kernel32\GlobalUnlock", Ptr,hBuf)
DllCall("user32\CloseClipboard")
return vOutput
}
;==================================================
JEE_AhkBClipboardGetPathsUtf8(vSep="`n")
{
static Ptr := "Int", UPtr := "UInt"
;CF_HDROP := 0xF
if !DllCall("user32\IsClipboardFormatAvailable", UInt,0xF)
return ""
if !DllCall("user32\OpenClipboard", Ptr,0)
return ""
if !hDrop := DllCall("user32\GetClipboardData", UInt,0xF, Ptr)
{
DllCall("user32\CloseClipboard")
return ""
}
;==============================
;based on JEE_DropGetPaths:
vOutput := ""
vCount := DllCall("shell32\DragQueryFileW", Ptr,hDrop, UInt,-1, Ptr,0, UInt,0, UInt)
Loop, % vCount
{
vChars := DllCall("shell32\DragQueryFileW", Ptr,hDrop, UInt,A_Index-1, Ptr,0, UInt,0, UInt) + 1
VarSetCapacity(vPathUtf16, vChars*2, 0)
DllCall("shell32\DragQueryFileW", Ptr,hDrop, UInt,A_Index-1, Ptr,&vPathUtf16, UInt,vChars, UInt)
vSize := DllCall("kernel32\WideCharToMultiByte", UInt,65001, UInt,0, Ptr,&vPathUtf16, Int,vChars, Ptr,0, Int,0, Ptr,0, Ptr,0)
VarSetCapacity(vPath, vSize, 0)
DllCall("kernel32\WideCharToMultiByte", UInt,65001, UInt,0, Ptr,&vPathUtf16, Int,vChars, Str,vPath, Int,vSize, Ptr,0, Ptr,0)
vOutput .= vPath vSep
}
DllCall("shell32\DragFinish", Ptr,hDrop)
;==============================
DllCall("user32\CloseClipboard")
return SubStr(vOutput, 1, -StrLen(vSep))
}
;==================================================
JEE_AhkBClipboardSetTextUtf8(vText)
{
static Ptr := "Int", UPtr := "UInt"
Transform, Clipboard, Unicode, % vText
}
;==================================================
;alternative method
JEE_AhkBClipboardSetTextUtf8Alt(vText)
{
static Ptr := "Int", UPtr := "UInt"
;GMEM_ZEROINIT := 0x40, GMEM_MOVEABLE := 0x2
hBuf := DllCall("kernel32\GlobalAlloc", UInt,0x42, UPtr,(StrLen(vText)+2)*2, Ptr)
pBuf := DllCall("kernel32\GlobalLock", Ptr,hBuf, Ptr)
vChars := DllCall("kernel32\MultiByteToWideChar", UInt,65001, UInt,0, Str,vText, Int,-1, Ptr,0, Int,0)
VarSetCapacity(vTextUtf16, vChars*2, 0)
DllCall("kernel32\MultiByteToWideChar", UInt,65001, UInt,0, Str,vText, Int,-1, Ptr,&vTextUtf16, Int,vChars*2)
DllCall("kernel32\RtlMoveMemory", Ptr,pBuf, Ptr,&vTextUtf16, UPtr,vChars*2)
;CF_LOCALE := 0x10 ;CF_UNICODETEXT := 0xD
;CF_OEMTEXT := 0x7 ;CF_TEXT := 0x1
hWnd := A_ScriptHwnd ? A_ScriptHwnd : WinExist("ahk_pid " DllCall("kernel32\GetCurrentProcessId", UInt))
DllCall("kernel32\GlobalUnlock", Ptr,hBuf)
DllCall("user32\OpenClipboard", Ptr,hWnd)
DllCall("user32\EmptyClipboard")
DllCall("user32\SetClipboardData", UInt,0xD, Ptr,hBuf, Ptr)
DllCall("user32\CloseClipboard")
return
}
;==================================================
JEE_AhkBCtlGetTextUtf8(hCtl=0)
{
static Ptr := "Int", UPtr := "UInt"
if !hCtl
{
WinGet, hWnd, ID, A
ControlGetFocus, vCtlClassNN, % "ahk_id " hWnd
ControlGet, hCtl, Hwnd,, % vCtlClassNN, % "ahk_id " hWnd
}
SendMessage, 0xE, 0, 0,, % "ahk_id " hCtl ;WM_GETTEXTLENGTH := 0xE
vChars := ErrorLevel+1
VarSetCapacity(vTextUtf16, vChars*2, 0)
DllCall("user32\SendMessageW", Ptr,hCtl, UInt,0xD, UPtr,vChars, Ptr,&vTextUtf16, Ptr) ;WM_GETTEXT := 0xD
vSize := DllCall("kernel32\WideCharToMultiByte", UInt,65001, UInt,0, Ptr,&vTextUtf16, Int,vChars, Ptr,0, Int,0, Ptr,0, Ptr,0)
VarSetCapacity(vText, vSize, 0)
DllCall("kernel32\WideCharToMultiByte", UInt,65001, UInt,0, Ptr,&vTextUtf16, Int,vChars, Str,vText, Int,vSize, Ptr,0, Ptr,0)
return vText
}
;==================================================
JEE_AhkBCtlGetSelTextUtf8(hCtl=0)
{
static Ptr := "Int", UPtr := "UInt"
if !hCtl
{
WinGet, hWnd, ID, A
ControlGetFocus, vCtlClassNN, % "ahk_id " hWnd
ControlGet, hCtl, Hwnd,, % vCtlClassNN, % "ahk_id " hWnd
}
VarSetCapacity(vPos1, 4, 0), VarSetCapacity(vPos2, 4, 0)
SendMessage, 0xB0, % &vPos1, % &vPos2,, % "ahk_id " hCtl ;EM_GETSEL := 0xB0
vPos1 := NumGet(&vPos1, 0, "UInt"), vPos2 := NumGet(&vPos2, 0, "UInt")
if (vPos1 = vPos2)
return
vOffset := vPos1*2
vCharsSel := vPos2-vPos1
SendMessage, 0xE, 0, 0,, % "ahk_id " hCtl ;WM_GETTEXTLENGTH := 0xE
vChars := ErrorLevel+1
VarSetCapacity(vTextUtf16, vChars*2, 0)
DllCall("user32\SendMessageW", Ptr,hCtl, UInt,0xD, UPtr,vChars, Ptr,&vTextUtf16, Ptr) ;WM_GETTEXT := 0xD
vSize := DllCall("kernel32\WideCharToMultiByte", UInt,65001, UInt,0, Ptr,&vTextUtf16+vOffset, Int,vCharsSel, Ptr,0, Int,0, Ptr,0, Ptr,0)
VarSetCapacity(vText, vSize, 0)
DllCall("kernel32\WideCharToMultiByte", UInt,65001, UInt,0, Ptr,&vTextUtf16+vOffset, Int,vCharsSel, Str,vText, Int,vSize, Ptr,0, Ptr,0)
return vText
}
;==================================================
JEE_AhkBMsgBoxUtf8(vText, vWinTitle="", vType=0)
{
static Ptr := "Int", UPtr := "UInt"
vChars := DllCall("kernel32\MultiByteToWideChar", UInt,65001, UInt,0, Str,vText, Int,-1, Ptr,0, Int,0)
VarSetCapacity(vTextUtf16, vChars*2, 0)
DllCall("kernel32\MultiByteToWideChar", UInt,65001, UInt,0, Str,vText, Int,-1, Ptr,&vTextUtf16, Int,vChars*2)
if (vWinTitle = "")
vWinTitle := A_ScriptName
vChars := DllCall("kernel32\MultiByteToWideChar", UInt,65001, UInt,0, Str,vWinTitle, Int,-1, Ptr,0, Int,0)
VarSetCapacity(vWinTitleUtf16, vChars*2, 0)
DllCall("kernel32\MultiByteToWideChar", UInt,65001, UInt,0, Str,vWinTitle, Int,-1, Ptr,&vWinTitleUtf16, Int,vChars*2)
return DllCall("user32\MessageBoxW", Ptr,0, Ptr,&vTextUtf16, Ptr,&vWinTitleUtf16, UInt,vType)
}
;==================================================
;get nth Unicode character
JEE_AhkBChrUtf8(vNum)
{
static Ptr := "Int", UPtr := "UInt"
VarSetCapacity(vTextUtf16, 6, 0)
if (vNum <= 0) || (vNum + 0 = "")
return
else if (vNum <= 65535)
vChars := 2, NumPut(vNum, &vTextUtf16, 0, "UShort")
else
{
vChars := 3, vNum -= 65536
NumPut(55296+Floor(vNum/1024), &vTextUtf16, 0, "UShort")
NumPut(56320+Mod(vNum,1024), &vTextUtf16, 2, "UShort")
}
vSize := DllCall("kernel32\WideCharToMultiByte", UInt,65001, UInt,0, Ptr,&vTextUtf16, Int,vChars, Ptr,0, Int,0, Ptr,0, Ptr,0)
VarSetCapacity(vOutput, vSize, 0)
DllCall("kernel32\WideCharToMultiByte", UInt,65001, UInt,0, Ptr,&vTextUtf16, Int,vChars, Str,vOutput, Int,vSize, Ptr,0, Ptr,0)
return vOutput
}
;==================================================
;get nth ANSI character
JEE_AhkBChrAUtf8(vNum)
{
static Ptr := "Int", UPtr := "UInt"
VarSetCapacity(vText, 2, 0)
NumPut(vNum, &vText+0, 0, "UChar")
VarSetCapacity(vTextUtf16, 4, 0)
DllCall("kernel32\MultiByteToWideChar", UInt,0, UInt,0, Ptr,&vText, Int,-1, Ptr,&vTextUtf16, Int,4)
vSize := DllCall("kernel32\WideCharToMultiByte", UInt,65001, UInt,0, Ptr,&vTextUtf16, Int,2, Ptr,0, Int,0, Ptr,0, Ptr,0)
VarSetCapacity(vOutput, vSize, 0)
DllCall("kernel32\WideCharToMultiByte", UInt,65001, UInt,0, Ptr,&vTextUtf16, Int,2, Str,vOutput, Int,vSize, Ptr,0, Ptr,0)
return vOutput
}
;==================================================
JEE_AhkBSendCharsUtf8(hWnd, vText)
{
static Ptr := "Int", UPtr := "UInt"
if !hWnd
{
WinGet, hWnd, ID, A
ControlGetFocus, vCtlClassNN, % "ahk_id " hWnd
if !(vCtlClassNN = "")
ControlGet, hWnd, Hwnd,, % vCtlClassNN, % "ahk_id " hWnd
}
vChars := DllCall("kernel32\MultiByteToWideChar", UInt,65001, UInt,0, Str,vText, Int,-1, Ptr,0, Int,0)
VarSetCapacity(vTextUtf16, vChars*2, 0)
DllCall("kernel32\MultiByteToWideChar", UInt,65001, UInt,0, Str,vText, Int,-1, Ptr,&vTextUtf16, Int,vChars*2)
Loop, % vChars-1
{
vNum := NumGet(&vTextUtf16+0, A_Index*2-2, "UShort")
DllCall("user32\PostMessageW", Ptr,hWnd, UInt,0x102, UPtr,vNum, Ptr,1) ;WM_CHAR := 0x102
}
}
;==================================================
JEE_AhkBCtlSetTextUtf8(hCtl, vText)
{
static Ptr := "Int", UPtr := "UInt"
if !hCtl
{
WinGet, hWnd, ID, A
ControlGetFocus, vCtlClassNN, % "ahk_id " hWnd
ControlGet, hCtl, Hwnd,, % vCtlClassNN, % "ahk_id " hWnd
}
vChars := DllCall("kernel32\MultiByteToWideChar", UInt,65001, UInt,0, Str,vText, Int,-1, Ptr,0, Int,0)
VarSetCapacity(vTextUtf16, vChars*2, 0)
DllCall("kernel32\MultiByteToWideChar", UInt,65001, UInt,0, Str,vText, Int,-1, Ptr,&vTextUtf16, Int,vChars*2)
DllCall("user32\SendMessageW", Ptr,hCtl, UInt,0xC, UPtr,0, Ptr,&vTextUtf16, Ptr) ;WM_SETTEXT := 0xC
}
;==================================================
JEE_AhkBEditPasteUtf8(hCtl, vText, vCanUndo=1)
{
static Ptr := "Int", UPtr := "UInt"
if !hCtl
{
WinGet, hWnd, ID, A
ControlGetFocus, vCtlClassNN, % "ahk_id " hWnd
ControlGet, hCtl, Hwnd,, % vCtlClassNN, % "ahk_id " hWnd
}
vChars := DllCall("kernel32\MultiByteToWideChar", UInt,65001, UInt,0, Str,vText, Int,-1, Ptr,0, Int,0)
VarSetCapacity(vTextUtf16, vChars*2, 0)
DllCall("kernel32\MultiByteToWideChar", UInt,65001, UInt,0, Str,vText, Int,-1, Ptr,&vTextUtf16, Int,vChars*2)
DllCall("user32\SendMessageW", Ptr,hCtl, UInt,0xC2, UPtr,vCanUndo, Ptr,&vTextUtf16, Ptr) ;EM_REPLACESEL := 0xC2
}
;==================================================
JEE_AhkBAnsiToUtf8(vText)
{
static Ptr := "Int", UPtr := "UInt"
vChars := DllCall("kernel32\MultiByteToWideChar", UInt,0, UInt,0, Str,vText, Int,-1, Ptr,0, Int,0)
VarSetCapacity(vTextUtf16, vChars*2, 0)
DllCall("kernel32\MultiByteToWideChar", UInt,0, UInt,0, Str,vText, Int,-1, Ptr,&vTextUtf16, Int,vChars*2)
vSize := DllCall("kernel32\WideCharToMultiByte", UInt,65001, UInt,0, Ptr,&vTextUtf16, Int,vChars, Ptr,0, Int,0, Ptr,0, Ptr,0)
VarSetCapacity(vOutput, vSize, 0)
DllCall("kernel32\WideCharToMultiByte", UInt,65001, UInt,0, Ptr,&vTextUtf16, Int,vChars, Str,vOutput, Int,vSize, Ptr,0, Ptr,0)
return vOutput
}
;==================================================
;note: best-fit characters (replace Unicode chars with lookalike chars if available, otherwise '?')
JEE_AhkBUtf8ToAnsi(vText, vBFC=0)
{
static Ptr := "Int", UPtr := "UInt"
;WC_NO_BEST_FIT_CHARS := 0x400
vFlags := vBFC ? 0 : 0x400
vChars := DllCall("kernel32\MultiByteToWideChar", UInt,65001, UInt,0, Str,vText, Int,-1, Ptr,0, Int,0)
VarSetCapacity(vTextUtf16, vChars*2, 0)
DllCall("kernel32\MultiByteToWideChar", UInt,65001, UInt,0, Str,vText, Int,-1, Ptr,&vTextUtf16, Int,vChars*2)
vSize := DllCall("kernel32\WideCharToMultiByte", UInt,0, UInt,vFlags, Ptr,&vTextUtf16, Int,vChars, Ptr,0, Int,0, Ptr,0, Ptr,0)
VarSetCapacity(vOutput, vSize, 0)
DllCall("kernel32\WideCharToMultiByte", UInt,0, UInt,vFlags, Ptr,&vTextUtf16, Int,vChars, Str,vOutput, Int,vSize, Ptr,0, Ptr,0)
return vOutput
}
;==================================================
JEE_AhkBAscUtf8(vText)
{
static Ptr := "Int", UPtr := "UInt"
VarSetCapacity(vTextUtf16, 2, 0)
DllCall("kernel32\MultiByteToWideChar", UInt,65001, UInt,0, Str,vText, Int,-1, Ptr,&vTextUtf16, Int,2)
return NumGet(&vTextUtf16, 0, "UShort")
}
;==================================================
JEE_AhkBAscAUtf8(vText)
{
static Ptr := "Int", UPtr := "UInt"
vAnsi := JEE_AhkBUtf8ToAnsi(vText)
return NumGet(&vAnsi, 0, "UChar")
}
;==================================================
;AscMode, get the number of the first 2 bytes
JEE_AhkBOrdUtf8(vText, vAscMode=0)
{
static Ptr := "Int", UPtr := "UInt"
VarSetCapacity(vTextUtf16, 4, 0)
DllCall("kernel32\MultiByteToWideChar", UInt,65001, UInt,0, Str,vText, Int,-1, Ptr,&vTextUtf16, Int,4)
vNum := NumGet(&vTextUtf16, 0, "UShort")
if vAscMode || (vNum < 55296) || (vNum > 56319)
return vNum
else
{
vNum1 := NumGet(&vTextUtf16, 0, "UShort")
vNum2 := NumGet(&vTextUtf16, 2, "UShort")
return (vNum1-55296)*1024+(vNum2-56320)+65536
}
}
;==================================================
JEE_AhkBOrdAUtf8(vText)
{
static Ptr := "Int", UPtr := "UInt"
vAnsi := JEE_AhkBUtf8ToAnsi(vText)
return NumGet(&vAnsi, 0, "UChar")
}
;==================================================
JEE_AhkBStrLenUtf8(vText)
{
static Ptr := "Int", UPtr := "UInt"
vSize := StrLen(vText)
return DllCall("kernel32\MultiByteToWideChar", UInt,65001, UInt,0, Str,vText, Int,vSize, Ptr,0, Int,0)
}
;==================================================
;note: uses same parameters as AHK v2's SubStr
JEE_AhkBSubStrUtf8(vText, vPos, vLen="")
{
static Ptr := "Int", UPtr := "UInt"
if (vLen = 0)
return
vSize := StrLen(vText)
vChars := DllCall("kernel32\MultiByteToWideChar", UInt,65001, UInt,0, Str,vText, Int,vSize, Ptr,0, Int,0)
if (vLen = "")
vLen := vChars
VarSetCapacity(vTextUtf16, vChars*2, 0)
DllCall("kernel32\MultiByteToWideChar", UInt,65001, UInt,0, Str,vText, Int,vSize, Ptr,&vTextUtf16, Int,vChars*2)
if (vPos < 0)
vPos := vChars + 1 + vPos
if (vPos < 0) || (vPos > vChars)
return
if (vLen < 0)
vLen := vChars - vPos + 1 + vLen
if (vLen < 0)
return
if (vPos + vLen > vChars + 1)
vLen -= vPos + vLen - vChars - 1
if (vLen < 0)
return
vSize := vLen*2
VarSetCapacity(vOutput, vSize, 0)
DllCall("kernel32\WideCharToMultiByte", UInt,65001, UInt,0, Ptr,&vTextUtf16+vPos*2-2, Int,vLen, Str,vOutput, Int,vSize, Ptr,0, Ptr,0)
return vOutput
}
;==================================================
;note: unlike NumGet, vAddrDest/vAddrSource must be numbers
;note: RtlMoveMemory parameter order is: 'dest, source' [NOT 'source, destination']
JEE_AhkBMemMove(vAddrDest, vAddrSource, vSize)
{
static Ptr := "Int", UPtr := "UInt"
DllCall("kernel32\RtlMoveMemory", Ptr,vAddrDest, Ptr,vAddrSource, UPtr,vSize)
}
;==================================================
;note: unlike NumGet, vAddr must be a number
JEE_AhkBHexGet(vAddr, vSize)
{
static Ptr := "Int", UPtr := "UInt", UIntP := "UInt*"
;CRYPT_STRING_HEX := 0x4 ;to return space/CRLF-separated text
;CRYPT_STRING_HEXRAW := 0xC ;to return raw hex (not supported by Windows XP)
DllCall("crypt32\CryptBinaryToString" (A_IsUnicode ? "W" : "A"), Ptr,vAddr, UInt,vSize, UInt,0x4, Ptr,0, UIntP,vChars)
VarSetCapacity(vHex, vChars*(A_IsUnicode ? 2 : 1), 0)
DllCall("crypt32\CryptBinaryToString" (A_IsUnicode ? "W" : "A"), Ptr,vAddr, UInt,vSize, UInt,0x4, Str,vHex, UIntP,vChars)
vHex := StrReplace(vHex, "`r`n")
vHex := StrReplace(vHex, " ")
return vHex
}
;==================================================
;note: unlike NumPut, vAddr must be an address
JEE_AhkBHexPut(vHex, vAddr)
{
static Ptr := "Int", UPtr := "UInt"
vChars := StrLen(vHex)
;CRYPT_STRING_HEX := 0x4
;CRYPT_STRING_HEXRAW := 0xC ;(not supported by Windows XP)
DllCall("crypt32\CryptStringToBinary" (A_IsUnicode ? "W" : "A"), Ptr,&vHex, UInt,vChars, UInt,0x4, Ptr,0, UIntP,vSize, Ptr,0, Ptr,0)
DllCall("crypt32\CryptStringToBinary" (A_IsUnicode ? "W" : "A"), Ptr,&vHex, UInt,vChars, UInt,0x4, Ptr,vAddr, UIntP,vSize, Ptr,0, Ptr,0)
}
;==================================================
JEE_AhkBHex2Dec(vHex)
{
static Ptr := "Int", UPtr := "UInt"
if !(SubStr(vHex, 1, 2) = "0x")
vHex := "0x" vHex
return vHex + 0
}
;==================================================
;printf - C++ Reference
;http://www.cplusplus.com/reference/cstdio/printf/
;Format Specification Syntax: printf and wprintf Functions
;https://msdn.microsoft.com/en-us/library/56e442dc.aspx
JEE_AhkBDec2Hex(vNum, vLen=0, vCase="U")
{
static Ptr := "Int", UPtr := "UInt"
vLen := (vLen > 0) ? "0" vLen : ""
vFormat := "%" vLen "I64" (vCase = "U" ? "X" : "x") ;e.g. %I64X, %02I64X
VarSetCapacity(vNum2, A_IsUnicode ? 40 : 20, 0)
DllCall("user32\wsprintf" (A_IsUnicode ? "W" : "A"), Str,vNum2, Str,vFormat, Int64,vNum, "CDecl Int")
return vNum2
}
;==================================================
JEE_AhkBDec2HexAlt(vNum, vLen=0, vCase="U")
{
static Ptr := "Int", UPtr := "UInt"
if (vLen = "")
vLen := 0
SetFormat, Integer, H
vNum += 0
SetFormat, Integer, D
StringReplace, vNum, vNum, 0x,, 0
if (vCase = "U")
StringUpper, vNum, vNum
else
StringLower, vNum, vNum
if (StrLen(vNum) < vLen)
{
Loop, % vLen - StrLen(vNum)
vNum := "0" vNum
}
return vNum
}
;==================================================
JEE_AhkBFileGetEnc(vPath, vOpt="", ByRef vIsEmpty="")
{
static Ptr := "Int", UPtr := "UInt"
vIsEmpty := 0
vAttrib := FileExist(vPath)
if (vAttrib = "") || InStr(vAttrib, "D")
return
FileGetSize, vSize, % vPath
if (vSize <= 1)
{
if (vSize = 0)
vIsEmpty := 1
return "ANSI"
}
;GENERIC_READ := 0x80000000 ;OPEN_EXISTING := 3
;FILE_SHARE_WRITE := 0x2 ;FILE_SHARE_READ := 0x1
if !hFile := DllCall("kernel32\CreateFile", Str,vPath, UInt,0x80000000, UInt,0x3, Ptr,0, UInt,3, UInt,0, Ptr,0, Ptr)
return
VarSetCapacity(vData, 4, 0)
DllCall("kernel32\ReadFile", Ptr,hFile, Ptr,&vData, UInt,4, UIntP,vBytesActuallyRead, Ptr,0)
DllCall("kernel32\CloseHandle", Ptr,hFile)
if (NumGet(vData, 0, "UShort") "," NumGet(vData, 2, "UChar") = "48111,191") ;239,187,191
{
if (vSize = 3)
vIsEmpty := 1
return "UTF-8"
}
if (NumGet(vData, 0, "UShort") = 65279) ;255,254
{
if (vSize = 2)
vIsEmpty := 1
return "UTF-16"
}
if (NumGet(vData, 0, "UShort") = 65534) ;254,255
{
if (vSize = 2)
vIsEmpty := 1
return "UTF-16 BE"
}
}
;==================================================
JEE_AhkBFileEmpty(vPath)
{
static Ptr := "Int", UPtr := "UInt"
vIsEmpty := 0
vAttrib := FileExist(vPath)
if (vAttrib = "") || InStr(vAttrib, "D")
return 0
FileGetSize, vSize, % vPath
if (vSize = 0)
return 1
;GENERIC_WRITE := 0x40000000 ;OPEN_EXISTING := 3
;FILE_SHARE_WRITE := 0x2 ;FILE_SHARE_READ := 0x1
;TRUNCATE_EXISTING := 5 ;(if exists truncate to 0 bytes else do nothing)
hFile := DllCall("kernel32\CreateFile", Str,vPath, UInt,0x40000000, UInt,0x3, Ptr,0, UInt,5, UInt,0, Ptr,0, Ptr)
if (hFile <= 0)
{
MsgBox, % A_ThisFunc ": error: clearing file:`r`n" vPath
return 0
}
DllCall("kernel32\CloseHandle", Ptr,hFile)
return 1
}
;==================================================
;reads as UTF-8 unless otherwise specified
;from file: ANSI/UTF-8/UTF-16/UTF-16 BE/bin
;to var: ANSI/UTF-8/hex
JEE_AhkBFileReadUtf8(vPath, vEnc="", vOffset=0, vSize=-1)
{
static Ptr := "Int", UPtr := "UInt"
vBOM := Chr(239) Chr(187) Chr(191)
if !FileExist(vPath)
return
if (vEnc = "")
vEnc := JEE_AhkBFileGetEnc(vPath, "", vIsEmpty)
if (vEnc = "UTF-8")
FileRead, vUtf8, % vPath
else if (vEnc = "ANSI")
{
FileRead, vText, % vPath
vSize := JEE_AhkBAnsiToUtf16(&vText, StrLen(vText))
VarSetCapacity(vUtf16, vSize, 0)
JEE_AhkBAnsiToUtf16(&vText, StrLen(vText), &vUtf16, vSize)
vSize8 := JEE_AhkBUtf16ToUtf8(&vUtf16, vSize)
VarSetCapacity(vUtf8, vSize8, 0)
JEE_AhkBUtf16ToUtf8(&vUtf16, vSize, &vUtf8, vSize8)
return vText
}
else if (vEnc = "UTF-16")
{
JEE_AhkBFileReadBin(vUtf16, vPath, 0, -1, vSize)
vSize8 := JEE_AhkBUtf16ToUtf8(&vUtf16, vSize)
VarSetCapacity(vUtf8, vSize8, 0)
JEE_AhkBUtf16ToUtf8(&vUtf16, vSize, &vUtf8, vSize8)
}
else if (vEnc = "UTF-16 BE")
{
JEE_AhkBFileReadBin(vBE, vPath, 0, -1, vSize)
VarSetCapacity(vUtf16, vSize, 0)
;LCMAP_BYTEREV := 0x800
DllCall("kernel32\LCMapStringW", UInt,0, UInt,0x800, Str,vBE, Int,vSize/2, Str,vUtf16, Int,vSize/2)
vSize8 := JEE_AhkBUtf16ToUtf8(&vUtf16, vSize)
VarSetCapacity(vUtf8, vSize8, 0)
JEE_AhkBUtf16ToUtf8(&vUtf16, vSize, &vUtf8, vSize8)
}
VarSetCapacity(vUtf8, -1)
if (SubStr(vUtf8, 1, 3) = vBOM)
vUtf8 := SubStr(vUtf8, 4)
return vUtf8
}
;==================================================
JEE_AhkBFileAppendHex(vHex, vPath)
{
static Ptr := "Int", UPtr := "UInt"
VarSetCapacity(vData, vSize := StrLen(vHex)/(A_IsUnicode ? 1 : 2), 0)
JEE_AhkBHexPut(vHex, &vData)
JEE_AhkBFileAppendBin(&vData, vPath, vSize)
}
;==================================================
JEE_AhkBFileReadHex(vPath, vOffset=0, vSize=-1)
{
static Ptr := "Int", UPtr := "UInt"
if !JEE_AhkBFileReadBin(vData, vPath, vOffset, vSize, vBytesRead)
return
return JEE_AhkBHexGet(&vData, vBytesRead)
}
;==================================================
;if file doesn't exist, creates a UTF-8 file
;to file: ANSI/UTF-8/UTF-16/UTF-16 BE
JEE_AhkBFileAppendUtf8(vText, vPath, vEnc="", vAddBOM=1)
{
static Ptr := "Int", UPtr := "UInt"
vBOM := Chr(239) Chr(187) Chr(191)
if (vEnc = "")
vEnc := JEE_AhkBFileGetEnc(vPath, "", vIsEmpty)
if (vEnc = "")
vEnc := "UTF-8"
if (vIsEmpty || !FileExist(vPath)) && vAddBOM
vText := vBOM vText
if (vEnc = "ANSI") || (vEnc = "UTF-8")
FileAppend, % vText, % "*" vPath
else if (vEnc = "UTF-16")
{
vSize := JEE_AhkBUtf8ToUtf16(&vText, StrLen(vText))
VarSetCapacity(vUtf16, vSize, 0)
JEE_AhkBUtf8ToUtf16(&vText, StrLen(vText), &vUtf16, vSize)
JEE_AhkBFileAppendBin(&vUtf16, vPath, vSize)
}
else if (vEnc = "UTF-16 BE")
{
vSize := JEE_AhkBUtf8ToUtf16(&vText, StrLen(vText))
VarSetCapacity(vUtf16, vSize, 0)
JEE_AhkBUtf8ToUtf16(&vText, StrLen(vText), &vUtf16, vSize)
VarSetCapacity(vBE, vSize, 0)
;LCMAP_BYTEREV := 0x800
DllCall("kernel32\LCMapStringW", UInt,0, UInt,0x800, Str,vUtf16, Int,vSize/2, Str,vBE, Int,vSize/2)
JEE_AhkBFileAppendBin(&vBE, vPath, vSize)
}
}
;==================================================
JEE_AhkBFileReadBin(ByRef vData, vPath, vOffset=0, vSize=-1, ByRef vBytesRead=0)
{
static Ptr := "Int", UPtr := "UInt"
vBytesRead := 0
if !FileExist(vPath)
return 0
FileGetSize, vSize2, % vPath
if (vOffset > vSize2)
return 0
if (vSize = -1)
vSize := vSize2
if (vOffset + vSize > vSize2)
vSize -= (vOffset + vSize - vSize2)
;GENERIC_READ := 0x80000000 ;OPEN_EXISTING := 3
;FILE_SHARE_WRITE := 0x2 ;FILE_SHARE_READ := 0x1
hFile := DllCall("kernel32\CreateFile", Str,vPath, UInt,0x80000000, UInt,3, Ptr,0, UInt,3, UInt,0, Ptr,0, Ptr)
if !hFile
return 0
VarSetCapacity(vData, vSize, 0)
if vOffset
{
DllCall("kernel32\SetFilePointerEx", Ptr,hFile, Int64,vOffset, Int64P,vPointer, UInt,0) ;FILE_BEGIN := 0
if !vPointer
{
DllCall("kernel32\CloseHandle", Ptr,hFile)
return 0
}
}
DllCall("kernel32\ReadFile", Ptr,hFile, Ptr,&vData, UInt,vSize, UIntP,vBytesRead, Ptr,0)
DllCall("kernel32\CloseHandle", Ptr,hFile)
return 1
}
;==================================================
JEE_AhkBFileReadBinAlt(ByRef vData, vPath, vOffset=0, vSize=-1, ByRef vBytesRead=0)
{
static Ptr := "Int", UPtr := "UInt"
vBytesRead := 0
if !FileExist(vPath)
return 0
FileGetSize, vSize2, % vPath
if (vOffset > vSize2)
return 0
vRet := 0
if (vOffset = 0) && (vSize = -1)
{
FileRead, vData, % "*c " vPath
if !ErrorLevel
vBytesRead := vSize2, vRet := 1
}
else
{
if (vSize = -1)
vSize := vSize2
if (vOffset + vSize > vSize2)
vSize -= (vOffset + vSize - vSize2)
FileRead, vData2, % "*c " vPath
if !ErrorLevel
vBytesRead := vSize, vRet := 1
VarSetCapacity(vData, vSize, 1)
DllCall("kernel32\RtlMoveMemory", Ptr,&vData, Ptr,&vData2+vOffset, UPtr,vSize)
}
return vRet
}
;==================================================
;note: unlike NumPut, vAddr must be an address
JEE_AhkBFileAppendBin(vAddr, vPath, vSize=0)
{
static Ptr := "Int", UPtr := "UInt"
if (vSize <= 0)
return
SplitPath, vPath, vName, vDir, vExt, vNameNoExt, vDrive
if !FileExist(vDir)
FileCreateDir, % vDir
;GENERIC_WRITE := 0x40000000 ;OPEN_ALWAYS := 4
hFile := DllCall("kernel32\CreateFile", Str,vPath, UInt,0x40000000, UInt,0, Ptr,0, UInt,4, UInt,0, Ptr,0, Ptr)
if (hFile <= 0)
{
MsgBox, % A_ThisFunc ": error:`r`n" vPath
return 0
}
DllCall("kernel32\SetFilePointerEx", Ptr,hFile, Int64,0, Int64P,vPointer, UInt,2) ;FILE_END := 2
if !vPointer
{
DllCall("kernel32\CloseHandle", Ptr,hFile)
return 0
}
vRet := DllCall("kernel32\WriteFile", Ptr,hFile, Ptr,vAddr, UInt,vSize, UIntP,0, Ptr,0)
DllCall("kernel32\CloseHandle", Ptr,hFile)
return !!vRet
}
;==================================================
JEE_AhkBUtf16ToUtf8(vAddr16, vSize16, vAddr8=0, vSize8=-1)
{
static Ptr := "Int", UPtr := "UInt"
if (vAddr8 = 0)
return DllCall("kernel32\WideCharToMultiByte", UInt,65001, UInt,0, Ptr,vAddr16, Int,vSize16/2, Ptr,0, Int,0, Ptr,0, Ptr,0)
else
DllCall("kernel32\WideCharToMultiByte", UInt,65001, UInt,0, Ptr,vAddr16, Int,vSize16/2, Ptr,vAddr8, Int,vSize8, Ptr,0, Ptr,0)
}
;==================================================
JEE_AhkBUtf8ToUtf16(vAddr8, vSize8=-1, vAddr16=0, vSize16=-1)
{
static Ptr := "Int", UPtr := "UInt"
if (vAddr16 = 0)
return DllCall("kernel32\MultiByteToWideChar", UInt,65001, UInt,0, Ptr,vAddr8, Int,vSize8, Ptr,0, Int,0)*2 ;size of UTF-16 string in bytes
else
DllCall("kernel32\MultiByteToWideChar", UInt,65001, UInt,0, Ptr,vAddr8, Int,vSize8, Ptr,vAddr16, Int,vSize16)
}
;==================================================
JEE_AhkBUtf16ToAnsi(vAddr16, vSize16, vAddrA=0, vSizeA=-1, vBFC=1)
{
static Ptr := "Int", UPtr := "UInt"
;WC_NO_BEST_FIT_CHARS := 0x400
vFlags := vBFC ? 0 : 0x400
if (vAddrA = 0)
return DllCall("kernel32\WideCharToMultiByte", UInt,0, UInt,vFlags, Ptr,vAddr16, Int,vSize16/2, Ptr,0, Int,0, Ptr,0, Ptr,0)
else
DllCall("kernel32\WideCharToMultiByte", UInt,0, UInt,vFlags, Ptr,vAddr16, Int,vSize16/2, Ptr,vAddrA, Int,vSizeA, Ptr,0, Ptr,0)
}
;==================================================
JEE_AhkBAnsiToUtf16(vAddrA, vSizeA, vAddr16=0, vSize16=-1)
{
static Ptr := "Int", UPtr := "UInt"
if (vAddr16 = 0)
return DllCall("kernel32\MultiByteToWideChar", UInt,0, UInt,0, Ptr,vAddrA, Int,vSizeA, Ptr,0, Int,0)*2 ;size of UTF-16 string in bytes
else
DllCall("kernel32\MultiByteToWideChar", UInt,0, UInt,0, Ptr,vAddrA, Int,vSizeA, Ptr,vAddr16, Int,vSize16)
}
;==================================================
StrReplace(vText, vNeedle, vReplaceText="", ByRef vCount="", vLimit=-1)
{
if (vLimit > 0)
{
StringGetPos, vPos, vText, % vNeedle, % "L" (vLimit+1)
if vPos
vSfx := SubStr(vText, vPos), vText := SubStr(vText, 1, vPos-1)
}
StringReplace, vOutput, vText, % vNeedle, % vReplaceText, UseErrorLevel
vCount := ErrorLevel
return vOutput vSfx
}
;==================================================
Trim(vText, vOmitChars=" `t")
{
vOmitChars := RegExReplace(vOmitChars, "[\Q^-]\\E]", "\$0") ;make 4 chars literal: ^-]\
return RegExReplace(vText, "^[" vOmitChars "]*|[" vOmitChars "]*$")
}
;==================================================
LTrim(vText, vOmitChars=" `t")
{
vOmitChars := RegExReplace(vOmitChars, "[\Q^-]\\E]", "\$0") ;make 4 chars literal: ^-]\
return RegExReplace(vText, "^[" vOmitChars "]*")
}
;==================================================
RTrim(vText, vOmitChars=" `t")
{
vOmitChars := RegExReplace(vOmitChars, "[\Q^-]\\E]", "\$0") ;make 4 chars literal: ^-]\
return RegExReplace(vText, "[" vOmitChars "]*$")
}
;==================================================
[hWnds should be always be the first parameter, and allowed specifying a blank hWnd to mean the active window or control.]