ATTENTION: You are viewing a page formatted for mobile devices; to view the full web page, click HERE.

Other Software > Developer's Corner

AutoHotkey Programming Questions Megathread

(1/1)

dnm:
I didn't see an existing thread for questions about AutoHotkey programming, so I thought I'd start a catch-all here. Mouser, feel free to move this wherever is more appropriate.

The idea is that since we have sterling AutoHotkey (AHK) programmers like skrommel and others, those of us on DonationCoder who have AHK programming questions can ask them of each other here. This isn't a replacement for the AutoHotkey Community forums, just a local thread for AHK programming questions. Deeper discussions can be taken offline, moved to another thread, or moved to the AutoHotkey Community forums.

Thanks for reading!

dnm:
Here's a question to start off the thread.

Earlier today I was trying to get write some basic AHK functions which allow me to convert characters which I've copied to the clipboard to a different representation. For instance, my initial use case was something like this: I want to be able to copy a series of bytes from my hex editor (as hex bytes) and use a hotkey to trigger a function (or series of functions) which will bit-invert those bytes, then save them as hex bytes back to the clipboard. Once that's done, I can paste them back into my hex editor and see the ASCII representation of the inverted bytes.

The strategy I used to go about this was seemingly simple, but possibly too complex. I'm not sure. I assume up front that the bytes I'm copying are already valid hex bytes, 0-9 and A-F, regardless of case (uppercase everything internally), and ignore whitespace (SPC, TAB, and RET). Convert from hex to a binary value, invert the value, then convert from binary to hex and save to the clipboard.

I'm not terribly familiar with writing functions in AHK; mostly I use it for hotstrings and hotkeys only. I tried my hand at a couple different approaches, none of which worked fully. I also looked at the following code samples on the AHK Community Forums, which seemed really interesting, but also overkill for what I want.

http://www.autohotkey.com/forum/topic21172.html
http://www.autohotkey.com/forum/topic21172-105.html

I did find some code in AutoIt (v3) that I modified only slightly that works well (at least the one bit I've tested), but the problem is that I don't run AutoIt like I run AutoHotkey, i.e. running in my system tray, capturing key macros, replacing text, etc. I probably can run AutoIt that way (I'd have to look into it), but generally I run AutoIt scripts for specific tasks, and don't really use it the same way I use AutoHotkey. While I could just write hotkeys in AutoHotkey to call the AutoIt scripts, that gets rid of the idea of having this be self-contained in my standard AHK script, and complicates deployment.

Any ideas? I'm open to all approaches, as long as I can make sense of the code.

Thanks in advance!

Here's the edited AutoIt code (as it stands right now):


--- Code: AutoIt ---; baseconv.au3 -- Base conversion functions for representative strings (binary;                 strings, decimal values, hex values). ; ==============================================================================; FUNCTIONS; ==============================================================================;; Original code for functions by "ptrex" on AutoIt Forums; http://www.autoitscript.com/forum/index.php?showtopic=70507 ; --------------------------------------------------------------------------; BinStr2Dec; --------------------------------------------------------------------------Func BinStr2Dec($strBin)Local $ReturnLocal $lngResultLocal $intIndex If StringRegExp($strBin,'[0-1]') then$lngResult = 0  For $intIndex = StringLen($strBin) to 1 step -1    $strDigit = StringMid($strBin, $intIndex, 1)    Select      case $strDigit="0"        ; do nothing      case $strDigit="1"        $lngResult = $lngResult + (2 ^ (StringLen($strBin)-$intIndex))      case else        ; invalid binary digit, so the whole thing is invalid        $lngResult = 0        $intIndex = 0 ; stop the loop    EndSelect  Next   $Return = $lngResult    Return $ReturnElse    MsgBox(0,"Error","Wrong input, try again ...")    ReturnEndIfEndFunc ; --------------------------------------------------------------------------; Dec2BinStr; --------------------------------------------------------------------------Func Dec2BinStr($iDec)Local $i, $sBinChar = "" If StringRegExp($iDec,'[[:digit:]]') then$i = 1 Do $x = 16^$i $i +=1 ; Determine the OctectsUntil $iDec < $x For $n = 4*($i-1) To 1 Step -1    If BitAND(2 ^ ($n-1), $iDec) Then        $sBinChar &= "1"    Else        $sBinChar &= "0"    EndIfNext Return $sBinCharElse    MsgBox(0,"Error","Wrong input, try again ...")    ReturnEndIfEndFunc ; --------------------------------------------------------------------------; Hex2Dec; --------------------------------------------------------------------------Func Hex2Dec($Input)Local $Temp, $i, $Pos, $Ret, $Output If StringRegExp($input,'[[:xdigit:]]') then$Temp = StringSplit($Input,"") For $i = 1 to $Temp[0]    $Pos = $Temp[0] - $i    $Ret =  Dec (Hex ("0x" & $temp[$i] )) * 16 ^ $Pos    $Output = $Output + $RetNext    return $OutputElse    MsgBox(0,"Error","Wrong input, try again ...")    ReturnEndIfEndFunc ; --------------------------------------------------------------------------; Dec2Hex; --------------------------------------------------------------------------Func Dec2Hex($Input)local $Output, $Ret If StringRegExp($input,'[[:digit:]]') thenDo    $Ret = Int(mod($Input,16))    $Input = $Input/16    $Output = $Output & StringRight(Hex($Ret),1)Until Int(mod($Ret,16))= 0     Return StringMid(_StringReverse($Output),2)Else    MsgBox(0,"Error","Wrong input, try again ...")    ReturnEndIfEndFunc ; --------------------------------------------------------------------------; BinStr2Hex; --------------------------------------------------------------------------Func BinStr2Hex($strBin)    Local $test, $Result = '',$numbytes,$nb If StringRegExp($strBin,'[0-1]') then     if $strBin = '' Then        SetError(-2)        Return    endif     Local $bits = "0000|0001|0010|0011|0100|0101|0110|0111|1000|1001|1010|1011|1100|1101|1110|1111"    $bits = stringsplit($bits,'|')    #region check string is binary     $test = stringreplace($strBin,'1','')    $test = stringreplace($test,'0','')    if $test <> '' Then        SetError(-1);non binary character detected        Return    endif    #endregion check string is binary     #region make binary string an integral multiple of 4 characters    While 1        $nb = Mod(StringLen($strBin),4)        if $nb = 0 then exitloop        $strBin = '0' & $strBin    WEnd    #endregion make binary string an integral multiple of 4 characters     $numbytes = Int(StringLen($strBin)/4);the number of bytes     Dim $bytes[$numbytes],$Deci[$numbytes]    For $j = 0 to $numbytes - 1;for each byte    ;extract the next byte        $bytes[$j] = StringMid($strBin,1+4*$j,4)     ;find what the dec value of the byte is        for $k = 0 to 15;for all the 16 possible hex values            if $bytes[$j] = $bits[$k+1] Then                $Deci[$j] = $k                ExitLoop            EndIf        next    Next ;now we have the decimal value for each byte, so stitch the string together again    $Result = ''    for $l = 0 to $numbytes - 1        $Result &= Hex($Deci[$l],1)    Next    return $ResultElse    MsgBox(0,"Error","Wrong input, try again ...")    ReturnEndIfEndFunc ; --------------------------------------------------------------------------; Hex2BinStr; --------------------------------------------------------------------------Func Hex2BinStr($strHex)    Local $Allowed = '0123456789ABCDEF'    Local $Test,$n    Local $Result = ''    if $strHex = '' then        SetError(-2)        Return    EndIf     $strHex = StringSplit($strHex,'')    for $n = 1 to $strHex[0]        if not StringInStr($Allowed,$strHex[$n]) Then            SetError(-1)            return 0        EndIf    Next     Local $bits = "0000|0001|0010|0011|0100|0101|0110|0111|1000|1001|1010|1011|1100|1101|1110|1111"    $bits = stringsplit($bits,'|')    for $n = 1 to $strHex[0]        $Result &=  $bits[Dec($strHex[$n])+1]    Next     Return $ResultEndFunc  ; ==============================================================================; TEST CODE; ============================================================================== ; Quick and drity, not good test code, but works for now.; Currently only tests Hex2BinStr. Dim $testVal1 = "DEAD"Dim $returnVal1 = Hex2BinStr($testVal1)MsgBox(0,"Results",$returnVal1); Expected value: 1101111010101101 Dim $testVal2 = "2152"Dim $returnVal2 = Hex2BinStr($testVal2)MsgBox(0,"Results",$returnVal2); Expected value: 0010000101010010 Dim $testVal3 = "b57b"Dim $returnVal3 = Hex2BinStr($testVal3)MsgBox(0,"Results",$returnVal3); Expected value: 1011010101111011

Navigation

[0] Message Index

Go to full version