topbanner_forum
  *

avatar image

Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
  • Friday April 19, 2024, 7:39 am
  • Proudly celebrating 15+ years online.
  • Donate now to become a lifetime supporting member of the site and get a non-expiring license key for all of our programs.
  • donate

Author Topic: AutoHotkey Programming Questions Megathread  (Read 6401 times)

dnm

  • Charter Member
  • Joined in 2005
  • ***
  • default avatar
  • Posts: 25
    • View Profile
    • Donate to Member
AutoHotkey Programming Questions Megathread
« on: May 13, 2008, 06:01 PM »
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

  • Charter Member
  • Joined in 2005
  • ***
  • default avatar
  • Posts: 25
    • View Profile
    • Donate to Member
Re: AutoHotkey Programming Questions Megathread
« Reply #1 on: May 13, 2008, 06:14 PM »
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 [Select]
  1. ; baseconv.au3 -- Base conversion functions for representative strings (binary
  2. ;                 strings, decimal values, hex values).
  3.  
  4. ; ==============================================================================
  5. ; FUNCTIONS
  6. ; ==============================================================================
  7. ;
  8. ; Original code for functions by "ptrex" on AutoIt Forums
  9. ; http://www.autoitscript.com/forum/index.php?showtopic=70507
  10.  
  11. ; --------------------------------------------------------------------------
  12. ; BinStr2Dec
  13. ; --------------------------------------------------------------------------
  14. Func BinStr2Dec($strBin)
  15. Local $Return
  16. Local $lngResult
  17. Local $intIndex
  18.  
  19. If StringRegExp($strBin,'[0-1]') then
  20. $lngResult = 0
  21.   For $intIndex = StringLen($strBin) to 1 step -1
  22.     $strDigit = StringMid($strBin, $intIndex, 1)
  23.     Select
  24.       case $strDigit="0"
  25.         ; do nothing
  26.       case $strDigit="1"
  27.         $lngResult = $lngResult + (2 ^ (StringLen($strBin)-$intIndex))
  28.       case else
  29.         ; invalid binary digit, so the whole thing is invalid
  30.         $lngResult = 0
  31.         $intIndex = 0 ; stop the loop
  32.     EndSelect
  33.   Next
  34.  
  35.   $Return = $lngResult
  36.     Return $Return
  37.     MsgBox(0,"Error","Wrong input, try again ...")
  38.     Return
  39.  
  40. ; --------------------------------------------------------------------------
  41. ; Dec2BinStr
  42. ; --------------------------------------------------------------------------
  43. Func Dec2BinStr($iDec)
  44. Local $i, $sBinChar = ""
  45.  
  46. If StringRegExp($iDec,'[[:digit:]]') then
  47. $i = 1
  48.  
  49.  $x = 16^$i
  50.  $i +=1
  51.  ; Determine the Octects
  52. Until $iDec < $x
  53.  
  54. For $n = 4*($i-1) To 1 Step -1
  55.     If BitAND(2 ^ ($n-1), $iDec) Then
  56.         $sBinChar &= "1"
  57.     Else
  58.         $sBinChar &= "0"
  59.     EndIf
  60.  Return $sBinChar
  61.     MsgBox(0,"Error","Wrong input, try again ...")
  62.     Return
  63.  
  64. ; --------------------------------------------------------------------------
  65. ; Hex2Dec
  66. ; --------------------------------------------------------------------------
  67. Func Hex2Dec($Input)
  68. Local $Temp, $i, $Pos, $Ret, $Output
  69.  
  70. If StringRegExp($input,'[[:xdigit:]]') then
  71. $Temp = StringSplit($Input,"")
  72.  
  73. For $i = 1 to $Temp[0]
  74.     $Pos = $Temp[0] - $i
  75.     $Ret =  Dec (Hex ("0x" & $temp[$i] )) * 16 ^ $Pos
  76.     $Output = $Output + $Ret
  77.     return $Output
  78.     MsgBox(0,"Error","Wrong input, try again ...")
  79.     Return
  80.  
  81. ; --------------------------------------------------------------------------
  82. ; Dec2Hex
  83. ; --------------------------------------------------------------------------
  84. Func Dec2Hex($Input)
  85. local $Output, $Ret
  86.  
  87. If StringRegExp($input,'[[:digit:]]') then
  88.     $Ret = Int(mod($Input,16))
  89.     $Input = $Input/16
  90.     $Output = $Output & StringRight(Hex($Ret),1)
  91. Until Int(mod($Ret,16))= 0
  92.  
  93.     Return StringMid(_StringReverse($Output),2)
  94.     MsgBox(0,"Error","Wrong input, try again ...")
  95.     Return
  96.  
  97. ; --------------------------------------------------------------------------
  98. ; BinStr2Hex
  99. ; --------------------------------------------------------------------------
  100. Func BinStr2Hex($strBin)
  101.     Local $test, $Result = '',$numbytes,$nb
  102.  
  103. If StringRegExp($strBin,'[0-1]') then
  104.  
  105.     if $strBin = '' Then
  106.         SetError(-2)
  107.         Return
  108.     endif
  109.  
  110.     Local $bits = "0000|0001|0010|0011|0100|0101|0110|0111|1000|1001|1010|1011|1100|1101|1110|1111"
  111.     $bits = stringsplit($bits,'|')
  112.     #region check string is binary
  113.  
  114.     $test = stringreplace($strBin,'1','')
  115.     $test = stringreplace($test,'0','')
  116.     if $test <> '' Then
  117.         SetError(-1);non binary character detected
  118.         Return
  119.     endif
  120.     #endregion check string is binary
  121.  
  122.     #region make binary string an integral multiple of 4 characters
  123.     While 1
  124.         $nb = Mod(StringLen($strBin),4)
  125.         if $nb = 0 then exitloop
  126.         $strBin = '0' & $strBin
  127.     WEnd
  128.     #endregion make binary string an integral multiple of 4 characters
  129.  
  130.     $numbytes = Int(StringLen($strBin)/4);the number of bytes
  131.  
  132.     Dim $bytes[$numbytes],$Deci[$numbytes]
  133.     For $j = 0 to $numbytes - 1;for each byte
  134.     ;extract the next byte
  135.         $bytes[$j] = StringMid($strBin,1+4*$j,4)
  136.  
  137.     ;find what the dec value of the byte is
  138.         for $k = 0 to 15;for all the 16 possible hex values
  139.             if $bytes[$j] = $bits[$k+1] Then
  140.                 $Deci[$j] = $k
  141.                 ExitLoop
  142.             EndIf
  143.         next
  144.     Next
  145.  
  146. ;now we have the decimal value for each byte, so stitch the string together again
  147.     $Result = ''
  148.     for $l = 0 to $numbytes - 1
  149.         $Result &= Hex($Deci[$l],1)
  150.     Next
  151.     return $Result
  152.     MsgBox(0,"Error","Wrong input, try again ...")
  153.     Return
  154.  
  155. ; --------------------------------------------------------------------------
  156. ; Hex2BinStr
  157. ; --------------------------------------------------------------------------
  158. Func Hex2BinStr($strHex)
  159.     Local $Allowed = '0123456789ABCDEF'
  160.     Local $Test,$n
  161.     Local $Result = ''
  162.     if $strHex = '' then
  163.         SetError(-2)
  164.         Return
  165.     EndIf
  166.  
  167.     $strHex = StringSplit($strHex,'')
  168.     for $n = 1 to $strHex[0]
  169.         if not StringInStr($Allowed,$strHex[$n]) Then
  170.             SetError(-1)
  171.             return 0
  172.         EndIf
  173.     Next
  174.  
  175.     Local $bits = "0000|0001|0010|0011|0100|0101|0110|0111|1000|1001|1010|1011|1100|1101|1110|1111"
  176.     $bits = stringsplit($bits,'|')
  177.     for $n = 1 to $strHex[0]
  178.         $Result &=  $bits[Dec($strHex[$n])+1]
  179.     Next
  180.  
  181.     Return $Result
  182.  
  183.  
  184. ; ==============================================================================
  185. ; TEST CODE
  186. ; ==============================================================================
  187.  
  188. ; Quick and drity, not good test code, but works for now.
  189. ; Currently only tests Hex2BinStr.
  190.  
  191. Dim $testVal1 = "DEAD"
  192. Dim $returnVal1 = Hex2BinStr($testVal1)
  193. MsgBox(0,"Results",$returnVal1)
  194. ; Expected value: 1101111010101101
  195.  
  196. Dim $testVal2 = "2152"
  197. Dim $returnVal2 = Hex2BinStr($testVal2)
  198. MsgBox(0,"Results",$returnVal2)
  199. ; Expected value: 0010000101010010
  200.  
  201. Dim $testVal3 = "b57b"
  202. Dim $returnVal3 = Hex2BinStr($testVal3)
  203. MsgBox(0,"Results",$returnVal3)
  204. ; Expected value: 1011010101111011
« Last Edit: May 13, 2008, 06:16 PM by dnm »