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