Code Monkey home page Code Monkey logo

paris / ironahk Goto Github PK

View Code? Open in Web Editor NEW
405.0 36.0 74.0 3.53 MB

Cross platform .NET rewrite of the popular AutoHotkey scripting language for desktop automation.

Home Page: https://autohotkey.com/board/topic/50354-ironahk-alpha-cross-platform-net-rewrite-of-autohotkey/

License: BSD 2-Clause "Simplified" License

C# 78.00% AutoHotkey 17.46% PHP 0.04% Shell 0.07% JavaScript 0.04% CSS 0.27% HTML 3.72% XSLT 0.31% Makefile 0.05% Batchfile 0.05%
autohotkey desktop scripting-language c-sharp cross-platform

ironahk's Introduction

IronAHK is a rewrite of AutoHotkey, a powerful and easy to use scripting language for automation on the desktop. It is developed in C# for .NET and Mono which brings cross-platform compatibility, increased performance, enhanced security, Unicode, native 64-bit support, smaller file sizes for compiled binaries and much more.

Follow development on:

Note: this project has been discontinued.

ironahk's People

Contributors

henrypate avatar isnull avatar madewokherd avatar paris avatar raptorone avatar tobiaskappe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ironahk's Issues

IronAHK

Hi,

I have created ahk script.Trying to run through ironahk.Its not giving the same output.

Run Notepad

Send , Hi {Enter} +Prabhu
Send , {S 30}
Send , +a

Send , ^a
return

.I need to run similiar kind of script in c# application.I tried with the help of IronAHK.Rusty.dll.But it is not working.Need more documentation for IronAHK.Rusty.dll funcitons.

RegisterCallback

I was trying to translate com.ahk to use with IronAHK.
com.ahk uses RegisterCallback, which fails when I test with _COMPlusExceptionCode = -532459699

EnumWindowsProc(hwnd, lParam)
{
    global Output
    WinGetTitle, title, ahk_id %hwnd%
    WinGetClass, class, ahk_id %hwnd%
    if title
        Output .= "HWND: " . hwnd . "`tTitle: " . title . "`tClass: " . class . "`n"
    return true  ; Tell EnumWindows() to continue until all windows have been enumerated.
}
EnumAddress := RegisterCallback("EnumWindowsProc")

object index increment parsing error

This error is shown before it starts running:

x := {}
x.l := 0
x.l := x.l + 1 ;parses fine, acts normally
x.l++ ;error: "test.ia:0 - Index was out of range. Must be non-negative and less than the size of the collection."

Expressions of the form (A and *(b)) parse incorrectly

Given this testcase:

if ( 1 and *( 0 ) )
MsgBox, yes
else
MsgBox, no

the parser interprets the * as a binary multiplication operator, instead of a unary dereference. This eventually causes an exception due to the broken CodeDom tree that results:

Unhandled Exception: System.Exception: Top type can not be null
at IronAHK.Scripting.MethodWriter.ConditionalBox (System.Type Top) [0x00032] in /home/meh/source/ironahk/Scripting/Compiler/Emission/EmitVars.cs:161

Send doesn't work with IronAHK on OSX

What doesn't work:

Following Script.ahk:
^j::Send "b"

invoked in terminal with:
ironahk Script.ahk

doesn't send "b" to any application and produces following terminal output:

Nov 26 18:23:25 MacBook-Air-Micha.local mono[23287] : kCGErrorInvalidConnection: CGSGetWindowTags: Invalid connection
Nov 26 18:23:25 MacBook-Air-Micha.local mono[23287] : kCGErrorFailure: Set a breakpoint @ CGErrorBreakpoint() to catch errors as they are logged.

What works:

Example.ahk included in the IronAHK installation archive.

Configuration:

OSX Lion 10.7.2
Mono http://download.mono-project.com/archive/2.10.6/macos-10-x86/1/MonoFramework-MDK-2.10.6_1.macos10.xamarin.x86.dmg
IronAHK http://cloud.github.com/downloads/polyethene/IronAHK/IronAHK-0.7.0.19793.zip

Unable to use some chars in hotkeys

The following code :
:c_:$>::$this->
:c_:$ù::log(
(Replace $> with $this-> and $ù with log( )

Displays the following error in shell when I try to execute the shortcuts
Warning, could not look up key: <
Warning, could not look up key: Ù

I should note that I am using Ubuntu 10.04 with an azerty keyboard. I guess my Ubuntu is still in en_US but there may be parts of fr_FR somewhere as I bought it from Dell France, if that can help you.

Also, it seems that most of the "exotic" chars on my keyboard (I mean, anything apart from [a-zA-Z0-9]) triggers some kind of look up error in the shell.

Bug in WinExist and WinClose (only in windows 7?)

In Windows 7, when you try and use WinExist or WinClose, and possibly others, it hangs. It did this in on two seperate 7 machines and worked fine on a windows XP machine, this maybe coincidence. I discovered at this was WindowsAPI. GetWindowText method, it was hanging on the SendMessage() for certain hWnd.

Yosemite?

Has anyone confirmed if this works for Yosemite? What are the build steps?

Random Numbers are repeated if it gets executed too fast

Hello,

This Issue was reported first by RaptorOne. Thanks!

If the Random Command gets used too fast, the same ("random") Number is returned.
This makes the Random Number Generator unusable for several usages.

It can easily reproduced with the following script:
str := ""
Loop, 20
{
Random, out, 1, 1000
str .= out "`n"
}

  msgbox % str
  exitapp

Click moves mouse but doesn't actually click; getting runtime version WARNING

I am running my script.ahk which contains the following:

Sleep, 1000       ; sleep for 1 second
Click, 3833, 500 ; click once at given coordinates
Return                ; exit

During the sleep, I select the window which will be clicked, then the script moves the mouse to the desired position. However, it never actuall clicks. I've tried adding a Click, 2 just to be sure and I'm still getting the same thing. Here is the output when running from terminal:

$ ironahk script.ahk 
WARNING: The runtime version supported by this application is unavailable.
Using default runtime: v4.0.30319

Wrong Window Sizing

There is a Problem with the Window sizing.

You can see this Problem with following Script:
;=====================================

Gui,Add,Edit,x0 y0 w500 h500,
Gui,Show,x5 y5 w550 h550,Test
return

Guiclose:
ExitApp
;=====================================

The Edit must have an Distance to the Right side of the gui from 50Pixel
(GuiSize=550 , EditSize=500 = 550-500=50)

The same Bug occured in the Height.

But it isn´t
I localized the bug in
Rusty\Gui\Gui.cs

You use the .Size Property ,but this Property is for the whole window
You have to use the .ClientSize Property

I Corrected:
//===========================================
if (auto || pos[0] == null && pos[1] == null)
{
guis[id].Size = guis[id].PreferredSize; // in this case you have to use the normal Size Property because PreferredSize describes also the whole window!

                        var status = GuiAssociatedInfo(guis[id]).StatusBar;
                        int d = status == null ? 0 : status.Height;

                        if (d > 0)
                            guis[id].ClientSize = new Size(guis[id].ClientSize.Width, guis[id].ClientSize.Height + d); //ClientSize
                    }
                    else
                    {
                        var size = guis[id].PreferredSize;

                        if (pos[0] != null)
                            size.Width = (int)pos[0];
                        if (pos[1] != null)
                            size.Height = (int)pos[1];

                        guis[id].ClientSize = size; //ClientSize
                    }

//===========================================

reegards
Raptor

@IsNull
Ich weiss nicht ob die PN nicht angekommen ist.
Dort hatte ich den Bug auch schon gemeldet. Allerding
vergess ich hin und wieder auf abschicken zu drücken

System.Delegate parsing problem

I think the parser is not recognizing System.Delegate type.

The example on http://www.ironahk.net/docs/syntax/variable/ for functions fails:

f := { hash : crc32 }
msgbox % f                ; shows {}
msgbox % f.hash("test")   ; blank

Here are some variations. They all return null with f.hash("test")

f := { "hash" : crc32 }    ; f shows: {}
f := { hash : "crc32" }    ; f shows: { "hash" : "crc32" }
f := { "hash" : "crc32" }  ; f shows: { "hash" : "crc32" }

Make API layer callable from IronPython, add IronPython samples

Python is good language for automation [1]
I experimenting with IronPython for AutoIt/AutoHotkey/IronAhk as language for automation. Was able to use AutoItX [2].

I hoped IronAHK could be best target as fully C#. But failed to run next samples correct with harder to satisfy API then in AutoItX.

import sys
import clr


clr.AddReference("IronAHK.Rusty")



# next is only half cause needs message loop and freaking hard to invoke
from IronAHK.Rusty.Core import Gui, GuiControl

Gui("Add","GroupBox", "w255 r3 Section", "Select")
Gui("Add", "Text", "xs+10 ys+25 Section", "Time:")
Gui("Add", "Edit", "vTimeValue ys-2 Limit3 gValidate","")
Gui("Add", "UpDown", "vTime Range1-60", "10")
Gui("Add", "Radio", "vSecs", "Seconds")
Gui("Add", "Radio", "vMins xp+65 yp Checked", "Minutes")
Gui("Font", "bold","","")
Gui("Add", "Button", "vRun ys-4 w65 Default gRun", "Start")
Gui( "Font","","","")
Gui("Add", "GroupBox", "xm w255 r4 Section", "Progress")
Gui("Font", "s24 bold", "Calibri","")
Gui("Add", "Text", "vCount xs+10 ys+20 w235 Center", "00:00")
Gui("Add", "Progress", "vProgress wp r0.5 -Smooth","")
Gui( "Font","","","")
GuiControl("Focus","Time", "")
Gui("Show","", "Countdown Timer", "") 


from IronAHK.Rusty.Core import Run, WinWaitActive, Send, WinClose

# out parameter in C# is bad for python
# does not works, but work of AutoItX
r = clr.Reference[int]()
Run("notepad.exe", "","min",r)
WinWaitActive("Untitled - Notepad")
Send("This is some text.")
WinClose("Untitled - Notepad")
WinWaitActive("Notepad", "Save")
#WinWaitActive("Notepad", "Do you want to save") # for windows xp
Send("!n")

[1] https://www.diigo.com/list/dzmitry_lahoda/Python+UI+Automation/2tiwxcs10
[2] https://github.com/asd-and-Rizzo/pyautoit

Untitled

v:0.7.0.37106

works as expected:
x := ["a","b","c","d"]
i := 0
while i < 4
{
msgbox % "index: " (i) "`nx[i]: " (x[i])
i++
}

doesn't work. acts as if i is initialized to 1
x := "abcd"
i := 0
while i < 4
{
msgbox % "index: " (i) "`nx[i]: " (x[i])
i++
}

no protocol specified

hi, when i run it on any of the two scripts here, it just says:

No protocol specified
Buggy-Mouse.ahk (0): ==> Object reference not set to an instance of an object
Buggy-Mouse.ahk (0): ==> An exception was thrown by the type initializer for IronAHK.Scripting.Script
Compilation failed.
No protocol specified

parsing error

f := { hash : crc32 }
test := f.hash("test")   "`n"   ; compile error
test := f.hash("test") . "`n"   ; compile error
test := (f.hash("test")) "`n"   ; compiles
test := f.hash("test")  ("`n")  ; compiles

btw, even if it does compile, the f.hash() doesn't return anything (there's a different ticket for that issue)

IronAHK won't open after install (UBUNTU)

I installed IronAHK using WINE and that was fine.

Now when i double click the IronAHK to launch the program the cursor starts spinning like it's going to load up and then just stops.

"System.Byte[]" cannot be converted to "System.IConvertible"

Hi,

I tried to run the following script with IronAHK

; ============= config =============
IronAHK := true ; set to true if you're using IronAHK.
;  =================================

ptr_size := A_PtrSize ? A_PtrSize : 4 ; ensure AutoHotkey classic / IronAHK compatibility
ptr := A_PtrSize ? "UPtr" : "UInt"

MB_ABORTRETRYIGNORE := 0x00000002 ; define flags
MB_USERICON := 0x00000080
flags := MB_ABORTRETRYIGNORE | MB_USERICON ; set the button we will use + indicate we will provide a custom icon

text := "This box is produced with a DllCall() to the MessageBoxIndirect function, passing a MSGBOXPARAMS structure.`n`n"
        . "This allows you to set a custom icon and more." ; set the text that will be shown
caption := "ahkbook example" ; set the title that will be used

hModule := DllCall("GetModuleHandle") ; get a handle to the running AutoHotkey.exe: we will use an icon from inside it
icon := IronAHK ? 32512 : 159 ; choose the icon id to use (IronAHK has a different one)

struct_size := 4*3 + ptr_size*7 ; calculate struct size:
; cbSize, dwStyle and dwLanguageId are 4 bytes, others depend on system pointer size

VarSetCapacity(params, struct_size, 0) ; initialize structure

; filling in structure members we need:
NumPut(struct_size, params, 00+0*ptr_size,  "UInt") ; "The structure size, in bytes."
NumPut(hModule,     params, 04+1*ptr_size,  ptr) ; "A handle to the module that contains the icon resource identified by the lpszIcon member... "
NumPut(&text,       params, 04+2*ptr_size,  ptr) ; "A null-terminated string that contains the message to be displayed."
NumPut(&caption,    params, 04+3*ptr_size,  ptr) ; "A null-terminated string that contains the message box title."
NumPut(flags,       params, 04+4*ptr_size,  "UInt") ; "The contents and behavior of the dialog box."
NumPut(icon,        params, 08+4*ptr_size,  "UPtr") ; "Identifies an icon resource."

; call the function and pass a pointer to the structure:
DllCall("MessageBoxIndirect", ptr, &params)

This gives the following error:

Could not execute: Das Objekt des Typs "System.Byte[]" kann nicht in Typ "System.IConvertible" umgewandelt werden.
(the object of type "System.Byte[]" cannot be converted to type "System.IConvertible".)

It works fine for AutoHotkey classic, AutoHotkey_L and AutoHotkey v2.

Regards
maul.esel

P-Invoke - several AccessViolation Exceptions

dR gave me a script and as I tested it with ia, I got several unhandled Exceptions, mostly in VarSetCapacy and NumPut/Get Functions.

Please have a look after it.
; show topix
SetBatchLines, -1

Gosub, InitVars

Gui,Add,Tab2,w780 h450 vForumTabs,

Gui,Tab
Gui,Add,CheckBox, y+10 x10 vAnnouncements Checked, Announcements 
Gui,Add,CheckBox, yp x+10 vSticky Checked, Sticky 
Gui,Add,CheckBox, yp x+10 vLocked Checked, Locked
Gui,Add,Radio, Group vMode x+10 yp Checked, All
Gui,Add,Radio,yp x+10, New only
Gui,Add,Statusbar
Gui,Show,w800,AHK Forum Tool

SB_SetParts(100,500,200)
SB_SetProgress(0,3,"Range1-100000 ")

SB_SetText( "Loading and parsing forum index file...", 2)
p := 0, url := ForumUrl, html := httpQuery( url )
while ( p := RegExMatch( html, "Jism`a)" forum_idx_needle ,M_, p == 0 ? 1 : p + strlen( M_ ) ) )
   l_idx .= ( StrLen( l_Idx ) == 0 ? "" : "|" ) m_id, t_idx .= ( StrLen( t_Idx ) == 0 ? "" : "|" ) m_name
t_idx := RegExReplace( t_idx, "&", "&&" )
GuiControl,,ForumTabs, % "|" t_idx

Loop,Parse,l_idx,|
{
   Gui,Tab, % A_Index
   Gui, Add, ListView, h400 w760 x+10 y+10 Checked -Multi NoSortHdr NoSort ReadOnly -WantF2 vLV%A_LoopField%, DeleteID|Title|Created by|LastPoster|Posts|Views

   url  := ForumURL "viewforum.php?f=" A_LoopField 
   SB_SetText( "Getting data from " url, 2 )

   SetTimer,showSize,10
   html := httpQuery( url ), p := 0
   SetTimer,showSize,Off

   SB_SetText( "", 2 )
   UpdateList( html, "LV" A_LoopField )

   Gui,Tab
}
SB_SetProgress( 0, 3, "Hide" )
return

GuiClose:
GuiEscape:
Esc::
   ExitApp

InitVars:
   forum_idx_needle=
   (LTrim Join Comments
      (?<=class..forumlink..).*?(?<=a href..)(forum-(?P<ID>\d+)|viewforum.php.f.(?P<ID>\d+))
      .*?(?<=class..forumlink..)(?P<Name>[^<]+)
   )

   allTopixNeedle=
   (LTrim Join
      ((?<=href..viewtopic.php\?t=)(?P<ID>\d+)|(?<=href..topic)(?P<ID>\d+))
      .*?(?<=class..topictitle..)(?P<Title>[^<]+)
      .*?(?<=class..postdetails..)(?P<Cnt>\d+)
      .*?(?<=class..name..)(<a[^>]+>)?(?P<PostCreator>[^<]+)
      .*?(?<=class..postdetails..)(?P<Views>\d+)
      .*?(?<=<span.class..postdetails.>).*?<[^>]+>(<a[^>]+>)?(?P<LastPoster>[^<]+)
   )

   ForumURL := "http://de.autohotkey.com/forum/"
   httpQueryOps := "updateSize storeHeader"

Return

showSize:
   SB_SetProgress(HttpQueryCurrentSize,3)
return

UpdateList( html, LV, p=0 ) {
   Global allTopixNeedle
   Gui, ListView, % LV
   while ( p := RegExMatch( html, "Jism`a)" AllTopixNeedle ,M_, p == 0 ? 1 : p + strlen( M_ ) ) )
      LV_Add( "", M_ID, M_Title, M_PostCreator, M_LastPoster, M_Cnt, M_Views )
   Loop, 6
      LV_ModifyCol( A_Index, "AutoHdr" )
}

; SB_SetProgress
; (w) by DerRaphael / Released under the Terms of EUPL 1.0 
; see http://ec.europa.eu/idabc/en/document/7330 for details

SB_SetProgress(Value=0,Seg=1,Ops="")
{
   ; Definition of Constants   
   Static SB_GETRECT      := 0x40a      ; (WM_USER:=0x400) + 10
        , SB_GETPARTS     := 0x406
        , SB_PROGRESS                   ; Container for all used hwndBar:Seg:hProgress
        , PBM_SETPOS      := 0x402      ; (WM_USER:=0x400) + 2
        , PBM_SETRANGE32  := 0x406
        , PBM_SETBARCOLOR := 0x409
        , PBM_SETBKCOLOR  := 0x2001 
        , dwStyle         := 0x50000001 ; forced dwStyle WS_CHILD|WS_VISIBLE|PBS_SMOOTH

   ; Find the hWnd of the currentGui's StatusbarControl
   Gui,+LastFound
   ControlGet,hwndBar,hWnd,,msctls_statusbar321

   if (!StrLen(hwndBar)) { 
      rErrorLevel := "FAIL: No StatusBar Control"     ; Drop ErrorLevel on Error
   } else If (Seg<=0) {
      rErrorLevel := "FAIL: Wrong Segment Parameter"  ; Drop ErrorLevel on Error
   } else if (Seg>0) {
      ; Segment count
      SendMessage, SB_GETPARTS, 0, 0,, ahk_id %hwndBar%
      SB_Parts :=  ErrorLevel - 1
      If ((SB_Parts!=0) && (SB_Parts<Seg)) {
         rErrorLevel := "FAIL: Wrong Segment Count"  ; Drop ErrorLevel on Error
      } else {
         ; Get Segment Dimensions in any case, so that the progress control
         ; can be readjusted in position if neccessary
         if (SB_Parts) {
            VarSetCapacity(RECT,16,0)     ; RECT = 4*4 Bytes / 4 Byte <=> Int
            ; Segment Size :: 0-base Index => 1. Element -> #0
            SendMessage,SB_GETRECT,Seg-1,&RECT,,ahk_id %hwndBar%
            If ErrorLevel
               Loop,4
                  n%A_index% := NumGet(RECT,(a_index-1)*4,"Int")
            else
               rErrorLevel := "FAIL: Segmentdimensions" ; Drop ErrorLevel on Error
         } else { ; We dont have any parts, so use the entire statusbar for our progress
            n1 := n2 := 0
            ControlGetPos,,,n3,n4,,ahk_id %hwndBar%
         } ; if SB_Parts

         If (InStr(SB_Progress,":" Seg ":")) {

            hWndProg := (RegExMatch(SB_Progress, hwndBar "\:" seg "\:(?P<hWnd>([^,]+|.+))",p)) ? phWnd :

         } else {

            If (RegExMatch(Ops,"i)-smooth"))
               dwStyle ^= 0x1

            hWndProg := DllCall("CreateWindowEx","uint",0,"str","msctls_progress32"
               ,"uint",0,"uint", dwStyle
               ,"int",0,"int",0,"int",0,"int",0 ; segment-progress :: X/Y/W/H
               ,"uint",DllCall("GetAncestor","uInt",hwndBar,"uInt",1) ; gui hwnd
               ,"uint",0,"uint",0,"uint",0)

            SB_Progress .= (StrLen(SB_Progress) ? "," : "") hwndBar ":" Seg ":" hWndProg

         } ; If InStr Prog <-> Seg

         ; HTML Colors
         Black:=0x000000,Green:=0x008000,Silver:=0xC0C0C0,Lime:=0x00FF00,Gray:=0x808080
         Olive:=0x808000,White:=0xFFFFFF,Yellow:=0xFFFF00,Maroon:=0x800000,Navy:=0x000080
         Red:=0xFF0000,Blue:=0x0000FF,Fuchsia:=0xFF00FF,Aqua:=0x00FFFF

         If (RegExMatch(ops,"i)\bBackground(?P<C>[a-z0-9]+)\b",bg)) {
              if ((strlen(bgC)=6)&&(RegExMatch(bgC,"i)([0-9a-f]{6})")))
                  bgC := "0x" bgC
              else if !(RegExMatch(bgC,"i)^0x([0-9a-f]{1,6})"))
                  bgC := %bgC%
              if (bgC+0!="")
                  SendMessage, PBM_SETBKCOLOR, 0
                      , ((bgC&255)<<16)+(((bgC>>8)&255)<<8)+(bgC>>16) ; BGR
                      ,, ahk_id %hwndProg%
         } ; If RegEx BGC
         If (RegExMatch(ops,"i)\bc(?P<C>[a-z0-9]+)\b",fg)) {
              if ((strlen(fgC)=6)&&(RegExMatch(fgC,"i)([0-9a-f]{6})")))
                  fgC := "0x" fgC
              else if !(RegExMatch(fgC,"i)^0x([0-9a-f]{1,6})"))
                  fgC := %fgC%
              if (fgC+0!="")
                  SendMessage, PBM_SETBARCOLOR, 0
                      , ((fgC&255)<<16)+(((fgC>>8)&255)<<8)+(fgC>>16) ; BGR
                      ,, ahk_id %hwndProg%
         } ; If RegEx FGC

         If ((RegExMatch(ops,"(?P<In>[^ ])?range((?P<Lo>\-?\d+)\-(?P<Hi>\-?\d+))?",r)) 
              && (rIn!="-") && (rHi>rLo)) {    ; Set new LowRange and HighRange
              SendMessage,0x406,rLo,rHi,,ahk_id %hWndProg%
         } else if ((rIn="-") || (rLo>rHi)) {  ; restore defaults on remove or invalid values
              SendMessage,0x406,0,100,,ahk_id %hWndProg%
         } ; If RegEx Range

         If (RegExMatch(ops,"i)\bEnable\b"))
            Control, Enable,,, ahk_id %hWndProg%
         If (RegExMatch(ops,"i)\bDisable\b"))
            Control, Disable,,, ahk_id %hWndProg%
         If (RegExMatch(ops,"i)\bHide\b"))
            Control, Hide,,, ahk_id %hWndProg%
         If (RegExMatch(ops,"i)\bShow\b"))
            Control, Show,,, ahk_id %hWndProg%

         ControlGetPos,xb,yb,,,,ahk_id %hwndBar%
         ControlMove,,xb+n1,yb+n2,n3-n1,n4-n2,ahk_id %hwndProg%
         SendMessage,PBM_SETPOS,value,0,,ahk_id %hWndProg%

      } ; if Seg greater than count
   } ; if Seg greater zero

   If (regExMatch(rErrorLevel,"^FAIL")) {
      ErrorLevel := rErrorLevel
      Return -1
   } else 
      Return hWndProg

}




; httpQuery-0-3-6.ahk
httpQuery(byref p1 = "", p2 = "", p3="", p4="")
{   ; v0.3.6 (w) Oct, 26 2010 by derRaphael / zLib-Style release
   ; currently the verbs showHeader, storeHeader, and updateSize are supported in httpQueryOps
   ; in case u need a different UserAgent, Proxy, ProxyByPass, Referrer, and AcceptType just
   ; specify them as global variables - mind the varname for referrer is httpQueryReferer [sic].
   ; Also if any special dwFlags are needed such as INTERNET_FLAG_NO_AUTO_REDIRECT or cache
   ; handling this might be set using the httpQueryDwFlags variable as global
   global httpQueryOps, httpAgent, httpProxy, httpProxyByPass, httpQueryReferer, httpQueryAcceptType
       , httpQueryDwFlags
   ; Get any missing default Values

   ;v0.3.6
   ; check for syntax
   if ( VarSetCapacity(p1) != 0 )
      dReturn:=true,  result := "", lpszUrl := p1, POSTDATA := p2, HEADERS  := p3
   else
      result := p1, lpszUrl := p2, POSTDATA := p3, HEADERS  := p4

   defaultOps =
   (LTrim Join|
      httpAgent=AutoHotkeyScript|httpProxy=0|httpProxyByPass=0|INTERNET_FLAG_SECURE=0x00800000
      SECURITY_FLAG_IGNORE_UNKNOWN_CA=0x00000100|SECURITY_FLAG_IGNORE_CERT_CN_INVALID=0x00001000
      SECURITY_FLAG_IGNORE_CERT_DATE_INVALID=0x00002000|SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE=0x00000200
      INTERNET_OPEN_TYPE_PROXY=3|INTERNET_OPEN_TYPE_DIRECT=1|INTERNET_SERVICE_HTTP=3
   )
   Loop,Parse,defaultOps,|
   {
      RegExMatch(A_LoopField,"(?P<Option>[^=]+)=(?P<Default>.*)",http)
      if StrLen(%httpOption%)=0
         %httpOption% := httpDefault
   }

   ; Load Library
   hModule := DllCall("LoadLibrary", "Str", "WinINet.Dll")

   ; SetUpStructures for URL_COMPONENTS / needed for InternetCrackURL
   ; http://msdn.microsoft.com/en-us/library/aa385420(VS.85).aspx
   offset_name_length:= "4-lpszScheme-255|16-lpszHostName-1024|28-lpszUserName-1024|"
                  . "36-lpszPassword-1024|44-lpszUrlPath-1024|52-lpszExtrainfo-1024"
   VarSetCapacity(URL_COMPONENTS,60,0)
   ; Struc Size               ; Scheme Size                  ; Max Port Number
   NumPut(60,URL_COMPONENTS,0), NumPut(255,URL_COMPONENTS,12), NumPut(0xffff,URL_COMPONENTS,24)

   Loop,Parse,offset_name_length,|
   {
      RegExMatch(A_LoopField,"(?P<Offset>\d+)-(?P<Name>[a-zA-Z]+)-(?P<Size>\d+)",iCU_)
      VarSetCapacity(%iCU_Name%,iCU_Size,0)
      NumPut(&%iCU_Name%,URL_COMPONENTS,iCU_Offset)
      NumPut(iCU_Size,URL_COMPONENTS,iCU_Offset+4)
   }

   ; Split the given URL; extract scheme, user, pass, authotity (host), port, path, and query (extrainfo)
   ; http://msdn.microsoft.com/en-us/library/aa384376(VS.85).aspx
   DllCall("WinINet\InternetCrackUrlA","Str",lpszUrl,"uInt",StrLen(lpszUrl),"uInt",0,"uInt",&URL_COMPONENTS)

   ; Update variables to retrieve results
   Loop,Parse,offset_name_length,|
   {
      RegExMatch(A_LoopField,"-(?P<Name>[a-zA-Z]+)-",iCU_)
      VarSetCapacity(%iCU_Name%,-1)
   }
   nPort:=NumGet(URL_COMPONENTS,24,"uInt")

   ; Import any set dwFlags
   dwFlags := httpQueryDwFlags
   ; For some reasons using a selfsigned https certificates doesnt work
   ; such as an own webmin service - even though every security is turned off
   ; https with valid certificates works when
   if (lpszScheme = "https")
      dwFlags |= (INTERNET_FLAG_SECURE|SECURITY_FLAG_IGNORE_CERT_CN_INVALID
               |SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE)

   ; Check for Header and drop exception if unknown or invalid URL
   if (lpszScheme="unknown") {
      Result := "ERR: No Valid URL supplied."
      Return StrLen(Result)
   }

   ; Initialise httpQuery's use of the WinINet functions.
   ; http://msdn.microsoft.com/en-us/library/aa385096(VS.85).aspx
   hInternet := DllCall("WinINet\InternetOpenA"
                  ,"Str",httpAgent,"UInt"
                  ,(httpProxy != 0 ?  INTERNET_OPEN_TYPE_PROXY : INTERNET_OPEN_TYPE_DIRECT )
                  ,"Str",httpProxy,"Str",httpProxyBypass,"Uint",0)

   ; Open HTTP session for the given URL
   ; http://msdn.microsoft.com/en-us/library/aa384363(VS.85).aspx
   hConnect := DllCall("WinINet\InternetConnectA"
                  ,"uInt",hInternet,"Str",lpszHostname, "Int",nPort
                  ,"Str",lpszUserName, "Str",lpszPassword,"uInt",INTERNET_SERVICE_HTTP
                  ,"uInt",0,"uInt*",0)

   ; Do we POST? If so, check for header handling and set default
   if (Strlen(POSTDATA)>0) {
      HTTPVerb:="POST"
      if StrLen(Headers)=0
         Headers:="Content-Type: application/x-www-form-urlencoded"
   } else ; otherwise mode must be GET - no header defaults needed
      HTTPVerb:="GET"   

   ; Form the request with proper HTTP protocol version and create the request handle
   ; http://msdn.microsoft.com/en-us/library/aa384233(VS.85).aspx
   hRequest := DllCall("WinINet\HttpOpenRequestA"
                  ,"uInt",hConnect,"Str",HTTPVerb,"Str",lpszUrlPath . lpszExtrainfo
                  ,"Str",ProVer := "HTTP/1.1", "Str",httpQueryReferer,"Str",httpQueryAcceptTypes
                  ,"uInt",dwFlags,"uInt",Context:=0 )

   ; Send the specified request to the server
   ; http://msdn.microsoft.com/en-us/library/aa384247(VS.85).aspx
   sRequest := DllCall("WinINet\HttpSendRequestA"
                  , "uInt",hRequest,"Str",Headers, "uInt",Strlen(Headers)
                  , "Str",POSTData,"uInt",Strlen(POSTData))

   VarSetCapacity(header, 2048, 0)  ; max 2K header data for httpResponseHeader
   VarSetCapacity(header_len, 4, 0)

   ; Check for returned server response-header (works only _after_ request been sent)
   ; http://msdn.microsoft.com/en-us/library/aa384238.aspx
   Loop, 5
     if ((headerRequest:=DllCall("WinINet\HttpQueryInfoA","uint",hRequest
      ,"uint",21,"uint",&header,"uint",&header_len,"uint",0))=1)
      break

   If (headerRequest=1) {
      VarSetCapacity(res,headerLength:=NumGet(header_len),32)
      DllCall("RtlMoveMemory","uInt",&res,"uInt",&header,"uInt",headerLength)
      Loop,% headerLength
         if (*(&res-1+a_index)=0) ; Change binary zero to linefeed
            NumPut(Asc("`n"),res,a_index-1,"uChar")
      VarSetCapacity(res,-1)
   } else
      res := "timeout"

   ; Get 1st Line of Full Response
   Loop,Parse,res,`n,`r
   {
      RetValue := A_LoopField
      break
   }

   ; No Connection established - drop exception
   If (RetValue="timeout") {
      html := "Error: timeout"
      return -1
   }
   ; Strip protocol version from return value
   RetValue := RegExReplace(RetValue,"HTTP/1\.[01]\s+")

    ; List taken from http://en.wikipedia.org/wiki/List_of_HTTP_status_codes
   HttpRetCodes := "100=Continue|101=Switching Protocols|102=Processing (WebDAV) (RFC 2518)|"
              . "200=OK|201=Created|202=Accepted|203=Non-Authoritative Information|204=No"
              . " Content|205=Reset Content|206=Partial Content|207=Multi-Status (WebDAV)"
              . "|300=Multiple Choices|301=Moved Permanently|302=Found|303=See Other|304="
              . "Not Modified|305=Use Proxy|306=Switch Proxy|307=Temporary Redirect|400=B"
              . "ad Request|401=Unauthorized|402=Payment Required|403=Forbidden|404=Not F"
              . "ound|405=Method Not Allowed|406=Not Acceptable|407=Proxy Authentication "
              . "Required|408=Request Timeout|409=Conflict|410=Gone|411=Length Required|4"
              . "12=Precondition Failed|413=Request Entity Too Large|414=Request-URI Too "
              . "Long|415=Unsupported Media Type|416=Requested Range Not Satisfiable|417="
              . "Expectation Failed|418=I'm a teapot (RFC 2324)|422=Unprocessable Entity "
              . "(WebDAV) (RFC 4918)|423=Locked (WebDAV) (RFC 4918)|424=Failed Dependency"
              . " (WebDAV) (RFC 4918)|425=Unordered Collection (RFC 3648)|426=Upgrade Req"
              . "uired (RFC 2817)|449=Retry With|500=Internal Server Error|501=Not Implem"
              . "ented|502=Bad Gateway|503=Service Unavailable|504=Gateway Timeout|505=HT"
              . "TP Version Not Supported|506=Variant Also Negotiates (RFC 2295)|507=Insu"
              . "fficient Storage (WebDAV) (RFC 4918)|509=Bandwidth Limit Exceeded|510=No"
              . "t Extended (RFC 2774)"

   ; Gather numeric response value
   RetValue := SubStr(RetValue,1,3)

   ; Parse through return codes and set according informations
   Loop,Parse,HttpRetCodes,|
   {
      HttpReturnCode := SubStr(A_LoopField,1,3)    ; Numeric return value see above
      HttpReturnMsg  := SubStr(A_LoopField,5)      ; link for additional information
      if (RetValue=HttpReturnCode) {
         RetMsg := HttpReturnMsg
         break
      }
   }

   ; Global HttpQueryOps handling
   if strlen(HTTPQueryOps)>0 {
      ; Show full Header response (usefull for debugging)
      if (instr(HTTPQueryOps,"showHeader"))
         MsgBox % res
      ; Save the full Header response in a global Variable
      if (instr(HTTPQueryOps,"storeHeader"))
         global HttpQueryHeader := res
      ; Check for size updates to export to a global Var
      if (instr(HTTPQueryOps,"updateSize")) {
         Loop,Parse,res,`n
            If RegExMatch(A_LoopField,"Content-Length:\s+?(?P<Size>\d+)",full) {
               global HttpQueryFullSize := fullSize
               break
            }
         if (fullSize+0=0)
            HttpQueryFullSize := "size unavailable"
      }
   }

   ; Check for valid codes and drop exception if suspicious
   if !(InStr("100 200 201 202 302",RetValue)) {
      Result := RetValue " " RetMsg
      return StrLen(Result)
   }

   VarSetCapacity(BytesRead,4,0)
   fsize := 0
   Loop            ; the receiver loop - rewritten in the need to enable
   {               ; support for larger file downloads
      bc := A_Index
      VarSetCapacity(buffer%bc%,1024,0) ; setup new chunk for this receive round
      ReadFile := DllCall("wininet\InternetReadFile"
                  ,"uInt",hRequest,"uInt",&buffer%bc%,"uInt",1024,"uInt",&BytesRead)
      ReadBytes := NumGet(BytesRead)    ; how many bytes were received?
      If ((ReadFile!=0)&&(!ReadBytes))  ; we have had no error yet and received no more bytes
         break                         ; we must be done! so lets break the receiver loop
      Else {
         fsize += ReadBytes            ; sum up all chunk sizes for correct return size
         sizeArray .= ReadBytes "|"
      }
      if (instr(HTTPQueryOps,"updateSize"))
         Global HttpQueryCurrentSize := fsize
   }
   sizeArray := SubStr(sizeArray,1,-1)   ; trim last PipeChar

   VarSetCapacity( ( dReturn == true ) ? result : p1 ,fSize+1,0)      ; reconstruct the result from above generated chunkblocks
   Dest := ( dReturn == true ) ? &result : &p1                 ; to a our ByRef result variable
   Loop,Parse,SizeArray,|
      DllCall("RtlMoveMemory","uInt",Dest,"uInt",&buffer%A_Index%,"uInt",A_LoopField)
      , Dest += A_LoopField

   DllCall("WinINet\InternetCloseHandle", "uInt", hRequest)   ; close all opened
   DllCall("WinINet\InternetCloseHandle", "uInt", hInternet)
   DllCall("WinINet\InternetCloseHandle", "uInt", hConnect)
   DllCall("FreeLibrary", "UInt", hModule)                    ; unload the library

   if ( dReturn == true ) {
      VarSetCapacity( result, -1 )
      ErrorLevel := fSize
      return Result
   } else 
      return fSize                      ; return the size - strings need update via VarSetCapacity(res,-1)
}

dotless string concatination

string concatinations without dots result in only the 1st string taken into result

eg

MsgBox % "This " "is " "a " Test."

Hotstring bugs under GNU/Linux

I am running Lubuntu Maverick, and tried to use IronAHK, both from v0.7 source and from the nightly build, both of which seem to function more or less OK, in that they start and run scripts. The example script runs fine. However, there are some big bugs in the handling of hotkeys and hotstrings which prevent IronAHK from being useful to me right now. I used to be an AHK user on Windows, and I'm itching to get back to AHK-goodness on Linux!

I'll put them all here since they may all be manifestations of the same problem. If needed I can create separate issues.

::catt::[[Category]]

autcorrects to "{{Category}}", but I'm expecting "[[Category:]]". This is the exact hotstring that used to work in Windows fine.

::alpha::α

just removes "alpha", but doesn't paste "α". Is this the right way to do Unicode in IronAHK?

::a,::a

doesn't fire the hotstring, and indeed any hotstring with a comma, full-stop, underscore, tilde, etc. won't fire.

Any hotstring with a colon or backtick-colon in the replacement strips the colon out. Eg, I get "Category" from
::catt::Cat:egory
or
::catt::Cat`:gory

Whenever the apostrophe key is pressed, the following message appears in the terminal I am running the script from:
Warning, could not look up key: '

#V Run, vlc

causes VLC to start correctly, but the "v" goes through to the window with focus instead of being squashed. If the hotkey is "^V", the Ctrl-V key goes through, and starts pasting the clipboard content. This doesn't just happen with "V" - all hotkeys go though IronAHK, triggering the action in IronAHK, but also in the application with focus.

GUI, submit dictionary bug

GUI, submit is not proper implemented:

GUI.cs incase Keyword_Submit:

                    foreach (Control ctrl in guis[id].Controls)
                        table.Add(ctrl.Name, ctrl.Text);

the above add fails if the key "ctrl.Name" is already persitent. (Actually, it is often empty so it fails everytime)

Added check to prevent flow interuption.

Documentation is lacking

Currently, there's no instructions on how to download, compile or use the software.

It's preferable that this information is found in the project's Readme file.

wtf bitwise-AND logic

The best wtf logic I've seen in a long time:

msgbox(  0      == 0 )  ; returns true (good)
msgbox( (1 & 0)      )  ; returns 0    (good)
msgbox( (1 & 0) == 0 )  ; returns false (wtf?) should be same as the first

Error upon compiling script with functions on smart-compiler branch (.NET)

Filing this for future reference; yours truly and polyethene have researched this bug extensively and as of yet did not come up with with a solution.

To reproduce, check out the smart-compiler branch and enable merge, either at compile-time or manually in Program.cs. Then compile the following:

f() {
    MsgBox, test
}
f()

On .NET a TypeLoadException of sorts will be thrown (poly, could you please insert the actual stacktrace?).

NullRefException - Unbalanced parentheses in expr

Reproduce with:

If (true) {    ; Comment
        msgbox hi
}

This throws the Exception from issue title. If you remove the comment, it works - parse error!?

OS:
win 7, 32bit; build: IronAHK-0.7.0.11637-x86

make mappings like a::b and b::a work

This is mainly an excuse to get down some thoughts about the X protocol and how to use it to do these crazy things. Maybe you guys have already figured this stuff out.

As a concrete example, consider the following script:

a::b
b::a
CapsLock & B::Send, Bacon

In order to make this work properly, we need to block "a" and "b" keypresses from the user, in all cases, from arriving at their destinations. This is fairly easy to do; use XGrabKey. However, our own events will also trigger XGrabKey, and we need to make sure they go through.

So, here's what I have so far:

  • First, grab all our hotkeys on the root window with XGrabKey and GrabModeSync.
  • When we get a keypress from our passive grab, make a note that we now have effectively grabbed the keyboard, and make a note of all the keypresses we get without a corresponding keyrelease during that effective grab. The corresponding keyreleases will go to our client so that keyups and keyreleases always match.
  • When we block an event that we did not Send (for various reasons because of a passive grab), decide whether that event should go through to other applications. If not, call XAllowEvents(SyncKeyboard). If we do want the event to go through, call XAllowEvents(ReplayKeyboard).
  • To Send an event, use XTestFakeKeyEvent to simulate the appropriate event. Make a note of the sequence of events we've simulated so we can ignore our own events.
    • When we get an event that we haven't simulated, clear our list of simulated events.
    • In some cases, such as CapsLock & B, we'll have to grab keys temporarily in response to other passive grabs that trigger.

Problems:

  • I don't know whether it's possible to grab the keyboard using XGrabKeyboard while it is frozen. If it's not possible, we won't be able to activate menus using hotkey presses.
  • We still can't get any events during an active grab. AFAIK that's unsolveable.
  • This may have some race conditions. For example, if we simulate an event on a key release that triggers a menu, followed by keypresses that would go to one of our passive grabs, our passive grab may never trigger (because menus actively grab the keyboard). If the user later presses that passively grabbed key, without any other input in between, we won't be able to tell that the keypress wasn't caused by us. Conversely, we can't be sure that all our simulated input will go through before user input.
  • I'm unsure of whether we'll get keyup events that correspond to keydown events that we replay during a passive grab.
  • Some combinations can still cause problems because a key can't be in two logical states at once. I.e. if we simulate a keyup in response to a keydown, we have no way of finding out when the real keyup happens. This also means that the remappings for "a" and "b" above cannot be used at the same time. We could try to simulate some events with XSendEvent instead, but that has its own problems.

I saw talk in another issue of using at-spi2 for keyboard events, but I don't think it will get us much in that areas. In particular, I don't think it will allow us to block keyboard events from being delivered when we need to. In any case, these ideas are not mutually exclusive; we can use X to grab keys and get events during passive keyboard grabs, and at-spi2 to get them the rest of the time. Maybe it will provide a way to simulate events without sending them through X, which could help, but I doubt it. (That said, at-spi2 allows for manipulating guis in a lot of other ways, which is awesome.)

ByRef variables

The following code throws a very odd exception:

Run, notepad, , , pid ; replace with /usr/bin/monodevelop on Unix
MsgBox, %pid%

Reflector shows valid IL code, I cannot understand why this happens.
Omitting all but the first parameter (i.e. compiler generated temporary variable) works.

Could not Execute - protected memory

Reproduce with:

msgbox % sin(65 * 1)

This shows the msgbox with 0.0000, and after that it throws the "Could not Execute - protected memory" Exception.

OS:
win 7, 32bit; build: IronAHK-0.7.0.11637-x86

ErrorLevel does not work with InputBox

When we use inputBox, we must have ErrorLevel variable which take a value according if OK or Cancel button has been clicked.

However : ErrorLevel is empty

Hotkey on Ctrl+Windows key does not fire on Ubuntu

Assigning a shortcut to a combination of Windows (#) and Ctrl (!) does not seem to work on Ubuntu using mono.

The following command won't be triggered:
^#C::Run("chromium-browser", ~/., min, TestPID, true)
While the simpler
#C::Run("chromium-browser", ~/., min, TestPID, true)
or
^C::Run("chromium-browser", ~/., min, TestPID, true) will.

Also note that assigning the #C shortcut will correctly launch chromium, but will still send the initial C key.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.