Jump to content
Sign in to follow this  
junkew

IDL to AU3 generator

Recommended Posts

Working on a new version of iuiautomation and uia wrappers I needed a better way of getting my interface's

Concept version 0.6 to generate based on idl file an au3 file with the definitions.

As allways its more complicated then I thought ;-) due to small differences in the idl files on closing braces, separating inheritance colon inconsistencies in the idl tool that generates them so most likely its better to write a lexer/parser then the search/replace I do now

Alternatives

  • typelibinspector but could not generate them all at once
  • aiowrappergenerator was generating for aio and not for objcreateinterface
  • based on tli interfaces / xml but seemed incomplete

Known issues

  • Enums without given constant values to be filled in manually
  • Enum adding fix first parameter to have a $
  • Empty interfaces fail on _ to be replaced with ""
  • propput and propget deal with methods with same name
  • Must be wrapped in main function
  • $i counting to be done differently
  • Working on the typedef's and replacements of identifiers in the string (some are replaced)
    • enum automatically is a long
    • typedefs are automatically assumed an int (which is not perfect but a start)
      • struct like POINT pt is now generated as int
  • Testing/debugging

Choices done

  • get_ and put_ prefixing only for put_ as that will have less impact on existing scripts that do not use get_ like ControlViewWalker, Current.. properties etc.

    So instead of
    Global Const $sIID_IUIAutomationCacheRequest = "{B32A92B5-BC25-4078-9C08-D7EE95C48E03}"
    Global $dtagIUIAutomationCacheRequest = _
        "AddProperty hresult(int);" & _
        "AddPattern hresult(int);" & _
        "Clone hresult(ptr*);" & _
        "get_TreeScope hresult(long*);" & _
        "put_TreeScope hresult(long);" & _
        "get_TreeFilter hresult(ptr*);" & _
        "put_TreeFilter hresult(ptr);" & _
        "get_AutomationElementMode hresult(long*);" & _
        "put_AutomationElementMode hresult(long);"

    it will be like (see for example TreeScope and put_TreeScope)

    Global Const $sIID_IUIAutomationCacheRequest = "{b32a92b5-bc25-4078-9c08-d7ee95c48e03}"
    Global $dtagIUIAutomationCacheRequest= _
        "AddProperty hresult(struct);" & _ 
        "AddPattern hresult(int);" & _ 
        "Clone hresult(ptr*);" & _ 
        "TreeScope hresult(long*);" & _ 
        "put_TreeScope hresult(long);" & _ 
        "TreeFilter hresult(ptr*);" & _ 
        "put_TreeFilter hresult(ptr);" & _ 
        "AutomationElementMode hresult(long*);" & _ 
        "put_AutomationElementMode hresult(long);"

     

Prerequisites

  • Win 10 SDK installed at location as given in constants to have IDL file

Output

  • File with same name as idl in scriptdir with  extension au3 having the definitions for OBJCreateInterface
     

Example output

;~    //
;~    //  IUIAutomation
;~    //
;~[object, uuid(30cbe57d-d9d0-452a-ab13-7ac5ac4825ee), pointer_default(unique)]
;~interface IUIAutomation : IUnknown
Global Const $sIID_IUIAutomation = "{30cbe57d-d9d0-452a-ab13-7ac5ac4825ee}"
Global $dtag_IUIAutomation= _
    "CompareElements hresult(IUIAutomationElement*el1,IUIAutomationElement*el2,int*);" & _
    "CompareRuntimeIds hresult(SAFEARRAY(int)runtimeId1,SAFEARRAY(int)runtimeId2,intareSame);" & _
    "GetRootElement hresult(IUIAutomationElement**);" & _
    "ElementFromHandle hresult(UIA_inthwnd,IUIAutomationElement**);" & _
    "ElementFromPoint hresult(intpt,IUIAutomationElement**);" & _
    "GetFocusedElement hresult(IUIAutomationElement**);" & _
    "GetRootElementBuildCache hresult(IUIAutomationCacheRequest*cacheRequest,IUIAutomationElement**);" & _
    "ElementFromHandleBuildCache hresult(UIA_inthwnd,IUIAutomationCacheRequest*cacheRequest,IUIAutomationElement**);" & _
    "ElementFromPointBuildCache hresult(intpt,IUIAutomationCacheRequest*cacheRequest,IUIAutomationElement**);" & _
    "GetFocusedElementBuildCache hresult(IUIAutomationCacheRequest*cacheRequest,IUIAutomationElement**);" & _
    "CreateTreeWalker hresult(IUIAutomationCondition*pCondition,IUIAutomationTreeWalker**);" & _
    "ControlViewWalker hresult(IUIAutomationTreeWalker**);" & _
    "ContentViewWalker hresult(IUIAutomationTreeWalker**);" & _
    "RawViewWalker hresult(IUIAutomationTreeWalker**);" & _
    "RawViewCondition hresult(IUIAutomationCondition**);" & _
    "ControlViewCondition hresult(IUIAutomationCondition**);" & _
    "ContentViewCondition hresult(IUIAutomationCondition**);" & _
    "CreateCacheRequest hresult(IUIAutomationCacheRequest**);" & _
    "CreateTrueCondition hresult(IUIAutomationCondition**);" & _
    "CreateFalseCondition hresult(IUIAutomationCondition**);" & _
    "CreatePropertyCondition hresult(intpropertyId,variantvalue,IUIAutomationCondition**);" & _
    "CreatePropertyConditionEx hresult(intpropertyId,variantvalue,longflags,IUIAutomationCondition**);" & _
    "CreateAndCondition hresult(IUIAutomationCondition*condition1,IUIAutomationCondition*condition2,IUIAutomationCondition**);" & _
    "CreateAndConditionFromArray hresult(SAFEARRAY(IUIAutomationCondition)conditions,IUIAutomationCondition**);" & _
    "CreateAndConditionFromNativeArray hresult(IUIAutomationCondition**conditions,intconditionCount,IUIAutomationCondition**);" & _
    "CreateOrCondition hresult(IUIAutomationCondition*condition1,IUIAutomationCondition*condition2,IUIAutomationCondition**);" & _
    "CreateOrConditionFromArray hresult(SAFEARRAY(IUIAutomationCondition)conditions,IUIAutomationCondition**);" & _
    "CreateOrConditionFromNativeArray hresult(IUIAutomationCondition**conditions,intconditionCount,IUIAutomationCondition**);" & _
    "CreateNotCondition hresult(IUIAutomationCondition*condition,IUIAutomationCondition**);" & _
    "AddAutomationEventHandler hresult(inteventId,IUIAutomationElement*element,longscope,IUIAutomationCacheRequest*cacheRequest,IUIAutomationEventHandler*);" & _
    "RemoveAutomationEventHandler hresult(inteventId,IUIAutomationElement*element,IUIAutomationEventHandler*);" & _
    "AddPropertyChangedEventHandlerNativeArray hresult(IUIAutomationElement*element,longscope,IUIAutomationCacheRequest*cacheRequest,IUIAutomationPropertyChangedEventHandler*handler,int*propertyArray,int);" & _
    "AddPropertyChangedEventHandler hresult(IUIAutomationElement*element,longscope,IUIAutomationCacheRequest*cacheRequest,IUIAutomationPropertyChangedEventHandler*handler,SAFEARRAY(PROPERTYID));" & _
    "RemovePropertyChangedEventHandler hresult(IUIAutomationElement*element,IUIAutomationPropertyChangedEventHandler*);" & _
    "AddStructureChangedEventHandler hresult(IUIAutomationElement*element,longscope,IUIAutomationCacheRequest*cacheRequest,IUIAutomationStructureChangedEventHandler*);" & _
    "RemoveStructureChangedEventHandler hresult(IUIAutomationElement*element,IUIAutomationStructureChangedEventHandler*);" & _
    "AddFocusChangedEventHandler hresult(IUIAutomationCacheRequest*cacheRequest,IUIAutomationFocusChangedEventHandler*);" & _
    "RemoveFocusChangedEventHandler hresult(IUIAutomationFocusChangedEventHandler*);" & _
    "RemoveAllEventHandlers hresult);" & _
    "IntNativeArrayToSafeArray hresult(int*array,intarrayCount,SAFEARRAY(int)*);" & _
    "IntSafeArrayToNativeArray hresult(SAFEARRAY(int)intArray,int**array,int*);" & _
    "RectTovariant hresult(intrc,variant*);" & _
    "variantToRect hresult(variantvar,int*);" & _
    "SafeArrayToRectNativeArray hresult(SAFEARRAY(double)rects,int**rectArray,int*);" & _
    "CreateProxyFactoryEntry(IUIAutomationProxyFactory hresult*factory,IUIAutomationProxyFactoryEntry);" & _
    "ProxyFactoryMapping(IUIAutomationProxyFactoryMapping hresult);" & _
    "GetPropertyProgrammaticName(int hresultproperty,int*);" & _
    "GetPatternProgrammaticName(int hresultpattern,int*);" & _
    "PollForPotentialSupportedPatterns(IUIAutomationElement hresult*pElement,SAFEARRAY(int)*patternIds,SAFEARRAY(BSTR)patternNames);" & _
    "PollForPotentialSupportedProperties(IUIAutomationElement hresult*pElement,SAFEARRAY(int)*propertyIds,SAFEARRAY(BSTR)propertyNames);" & _
    "CheckNotSupported(variant hresultvalue,intisNotSupported);" & _
    "ReservedNotSupportedValue(IUnknown hresult**notSupportedValue);" & _
    "ReservedMixedAttributeValue(IUnknown hresult**mixedAttributeValue);" & _
    "ElementFromIAccessible hresult(IAccessible*accessible,intchildId,IUIAutomationElement**);" & _
    "ElementFromIAccessibleBuildCache hresult(IAccessible*accessible,intchildId,IUIAutomationCacheRequest*cacheRequest,IUIAutomationElement**);"
;~}

 

Script

#include <FileConstants.au3>
#include <MsgBoxConstants.au3>
#include <StringConstants.au3>
#include <Array.au3>
;~ testit()
;~ Exit

Local $IDLFolder="C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\um\"
Local $IDLFileName="UIAutomationClient.idl"

Local $IDLFullFileName = $IDLFolder & $IDLFileName
Local $IDLArray = FileReadToArray($IDLFullFileName)
Local $iLineCount = @extended

Local $IDLAU3FullFileName=@ScriptDir & "\" & $IDLFileName
$IDLAU3FullFileName=stringreplace($IDLAU3FullFileName,".idl",".au3")

If @error Then
    MsgBox($MB_SYSTEMMODAL, "", "There was an error reading the file. @error: " & @error) ; An error occurred reading the current script file.
    exit
EndIf

Local $hFileOpen = FileOpen($IDLAU3FullFileName, $FO_OVERWRITE )
If $hFileOpen = -1 Then
    MsgBox($MB_SYSTEMMODAL, "", "An error occurred whilst writing the new au3 file.")
    exit
EndIf

;~TODO: Naming prefixing
Global $interfaceName
Global $GUID
Global $i=0

while $i < $iLineCount - 1
;~      consolewrite($i)
    $tLine=$IDLArray[$i]

    $blockType=0

    if stringleft($tLine,2)="//" then $blockType=1
    if stringleft($tLine,4)="cpp_" then $blockType=1
    if stringleft($tLine,1)="#" then $blockType=1
    if stringleft($tLine,6)="import" then $blockType=1
    if stringleft($tLine,4)="midl" then $blockType=1
    if $blockType=1 Then
        writeCommentedLine()
        continueloop;
    EndIf

    if stringleft($tLine,4)="enum" then
        $blockType=2
        handleEnumBlock()
    EndIf

    if stringinstr($tLine, "module ") > 0 then
        $blockType=3
        handleModuleBlock()
    EndIf

    if stringinstr($tLine, "[object") > 0 then
        $blockType=4
        handleObjectBlock()
    EndIf

    if stringinstr($tLine, "interface ") > 0 then
        $blockType=5
        handleInterfaceBlock()
    EndIf

    if $blockType=0 Then
        writeUnhandledLine()
    EndIf
WEnd


func writeUnhandledLine()
    filewriteline($hFileOpen,";~" & $tline)
    $i=$i+1
EndFunc

func writeCommentedLine()
    $tLineOut=stringstripws($tLine, $STR_STRIPLEADING +  $STR_STRIPTRAILING)
    if $tLineOut <> "" Then $tLineOut=";~" & $tLineOut
    filewriteline($hFileOpen, $tLineOut)
    $i=$i+1
EndFunc

func handleEnumBlock()
    writeCommentedLine() ;~ Copy enum line
    $tLine=$IDLArray[$i]
    writeCommentedLine() ;~ Copy curly brace line
    $tLine=$IDLArray[$i]
    while stringstripws($tLine, $STR_STRIPLEADING +  $STR_STRIPTRAILING) <> "};"
        $tPos=getPosFirstNonWhiteSpace($tLine)
        if ($tpos=0) or (stringmid($tLine,$tPos+1,2)="//") Then
            writeCommentedLine()
        Else
            $tLine=stringleft($tLine,$tPos) & "Global Const $" & stringmid($tline,$tPos+1)
            $tLine=stringreplace($tLine, ",","")
            $tLine=stringreplace($tLine, "| ","+ $")
            writeEnumLine()
        EndIf
        $tLine=$IDLArray[$i]
    WEnd
EndFunc

func writeEnumLine()
    filewriteline($hFileOpen, $tline)
    $i=$i+1
EndFunc

func handleModuleBlock()
    writeCommentedLine() ;~ Copy module line
    $tLine=$IDLArray[$i]
    writeCommentedLine() ;~ Copy curly brace line
    $tLine=$IDLArray[$i]

    $tValue=stringstripws($tLine, $STR_STRIPLEADING +  $STR_STRIPTRAILING)
;~  Some end with }; and some with }
    while  stringleft($tValue,1) <> "}"
        $tPos=getPosFirstNonWhiteSpace($tLine)
        if ($tpos=0) or (stringmid($tLine,$tPos+1,2)="//") Then
            if ($tpos=0) then
                $i=$i+1  ;~ Do no output
            Else
                writeCommentedLine()
            EndIf
        Else
            $tLine=stringreplace($tline,"const long ", "Global Const $")
            $tLine=stringreplace($tLine, ";","")
            writeModuleLine()
        EndIf
        $tLine=$IDLArray[$i]
        $tValue=stringstripws($tLine, $STR_STRIPLEADING +  $STR_STRIPTRAILING)
    WEnd
    writeCommentedLine() ;~ Copy curly closing brace line
EndFunc

func writeModuleLine()
    filewriteline($hFileOpen, $tline)
    $i=$i+1
EndFunc

func handleObjectBlock()
    writeCommentedLine()
    $tPos=stringinstr($tLine,"(")
    $tPos2=stringinstr($tLine,")")
    $GUID=stringmid($tLine,$tpos+1, $tPos2-1 - $tpos)
;~  consolewrite($GUID & @CRLF)
EndFunc

func handleInterfaceBlock()
    if stringright($tLine,1)=";" Then
        writeCommentedLine() ;~ Copy Interface line its just a definition line
        Return
    EndIf

    writeCommentedLine() ;~ Copy interface line
    $interfaceName=getInterfaceName()
    writeInterFaceLine1()

    $tLine=$IDLArray[$i]
;~  writeCommentedLine() ;~ Copy curly brace line
    $i=$i+1  ;~ Do no output
    $tLine=$IDLArray[$i]

    $tValue=stringstripws($tLine, $STR_STRIPLEADING +  $STR_STRIPTRAILING)
;~  Some end with }; and some with }
    while  stringleft($tValue,1) <> "}"

        $tPos=getPosFirstNonWhiteSpace($tLine)
        if ($tpos=0) or (stringmid($tLine,$tPos+1,2)="//") Then
            if ($tpos=0) then
                $i=$i+1  ;~ Do no output
            Else
                $i=$i+1  ;~ Do no output, AU3 does not like it in multiline strings
;~              writeCommentedLine()
            EndIf
        Else
            while stringright($tLine,1) <> ";"
                $i=$i+1
                $tLine=$tLine & stringstripws($IDLArray[$i], $STR_STRIPLEADING +  $STR_STRIPTRAILING)
            wend
            writeInterfaceLine()
        EndIf
        $tLine=$IDLArray[$i]
        $tValue=stringstripws($tLine, $STR_STRIPLEADING +  $STR_STRIPTRAILING)
    WEnd

;~  consolewrite($IDLArray[$i-1] & @CRLF)
;~  consolewrite($IDLArray[$i] & @CRLF)
;~  consolewrite($IDLArray[$i+1] & @CRLF)

    writeCommentedLine() ;~ Copy curly closing brace line

EndFunc

func writeInterFaceLine1()
    $tOutputLine="Global Const $sIID_" & getInterfaceName() & " = "
    $tOutputLine=$tOutputLine & """"
    $tOutputLine=$tOutputLine & "{" & $GUID & "}"
    $tOutputLine=$tOutputLine & """"
    filewriteline($hFileOpen, $tOutputLine)

    $toutputLine = "Global $dtag" & getInterfaceName() & "= _" & @CRLF
    filewriteline($hFileOpen, $tOutputLine)
EndFunc

func writeInterfaceLine()
    $tmpLine=stringstripws($tLine, $STR_STRIPLEADING +  $STR_STRIPTRAILING)
    if stringleft($tmpLine,1)="}" Then
        filewriteline($hFileOpen, $tmpLine)
        $i=$i+1
        return
    EndIf

;~ Handle get/put properties prefix
    local $strPrefix=""
    if stringinstr($tmpLine,"[propget]")>0 then
;~ no prefix for the get as its more logical/natural in AutoIt to do it without (as oppossed to C where get_ is more logical
;~      $strPrefix="get_"
;~      consolewrite($tmpLine & @CRLF)
        $tmpLine=stringreplace($tmpLine, "[propget] ", "", 0, $STR_CASESENSE)
    EndIf

    if stringinstr($tmpLine,"[propput]")>0 then
;~ prefix for the put as it can get in conflict with the get duplicate name
        $strPrefix="put_"
;~      consolewrite($tmpLine & @CRLF)
        $tmpLine=stringreplace($tmpLine, "[propput] ", "", 0, $STR_CASESENSE)
    EndIf

;       $tmpLine ="HRESULT FindAll ([in] enum TreeScope scope,[in] IUIAutomationCondition * condition, [out, retval] IUIAutomationElementArray ** found );"
;~     $tmpLine="[propget] HRESULT PropertyId ([out, retval] PROPERTYID * propertyId );"
;~  $tmpLine="HRESULT GetCurrentPropertyValue ([in] PROPERTYID propertyId,[out, retval] VARIANT * retVal);"
;~  $tmpLine="HRESULT FindAllBuildCache ([in] enum TreeScope scope,[in] IUIAutomationCondition * condition,[in] IUIAutomationCacheRequest * cacheRequest,[out, retval] IUIAutomationElementArray ** found );"
    $tmpLine=stringreplace($tmpLine, "HRESULT", "hresult", 0, $STR_CASESENSE)
    $tmpLine=stringreplace($tmpLine, "VARIANT", "variant", 0, $STR_CASESENSE)
    $tmpLine=stringreplace($tmpLine, "BSTR", "bstr", 0, $STR_CASESENSE)
    $tmpLine=stringreplace($tmpLine, "BOOL", "bool", 0, $STR_CASESENSE)
    $tmpLine=stringreplace($tmpLine, "void", "none", 0, $STR_CASESENSE)

;~ Some where we are sure it should not be an int
    $tmpLine=stringreplace($tmpLine, "POINT", "struct", 0, $STR_CASESENSE)
    $tmpLine=stringreplace($tmpLine, "PROPERTYID", "struct", 0, $STR_CASESENSE)
    $tmpLine=stringreplace($tmpLine, "RECT", "struct", 0, $STR_CASESENSE)
    $tmpLine=stringreplace($tmpLine, "UIA_HWND", "hwnd", 0, $STR_CASESENSE)

;~ Some cleanup for parsing later
    $tmpLine=stringreplace($tmpLine, "(", " (")
    $tmpLine=stringreplace($tmpLine, "  (", " (")

    $tmpLine=stringreplace($tmpLine, " );", ");")

;~  remove the pointer references for in/out parameters
    if stringinstr($tmpLine,"[in")>0 then
        $tmpLine=stringreplace($tmpLine, "[propget] ", "", 0, $STR_CASESENSE)
        $tmpLine=stringreplace($tmpLine, "**", "SINGLESTAR")
        $tmpLine=stringreplace($tmpLine, "*", "")
        $tmpLine=stringreplace($tmpLine, "SINGLESTAR", "*")
    EndIf
;~  For out parameter we keep the pointer *
    if stringinstr($tmpLine,"[out")>0 then
        $tmpLine=stringreplace($tmpLine, "[propget] ", "", 0, $STR_CASESENSE)
        $tmpLine=stringreplace($tmpLine, "**", "SINGLESTAR")
;~      $tmpLine=stringreplace($tmpLine, "*", "")
        $tmpLine=stringreplace($tmpLine, "SINGLESTAR", "*")
    EndIf


    $tmpLine=StringRegExpReplace($tmpLine,"[A-Z]+ ","int ")     ;~ TODO: assumption full uppercase is a TYPEDEF frequently int but definitily not sure
    $tmpLine=StringRegExpReplace($tmpLine,"enum [A-Za-z_]+ ","long ")  ;~ An enum followed by an identifier is normally a long
    $tmpLine=StringRegExpReplace($tmpLine,"\[.*?] "," ")          ;~ [in, out]  stuff followed by space we normally ignore, space we keep for separator

;~ reshuffle and remove varnames
    $aArray=stringsplit($tmpLine," ")

    if ($aArray[0] < 2) then
        _arraydisplay($aArray)
        consolewrite(stringstripws($tLine, $STR_STRIPLEADING +  $STR_STRIPTRAILING))
        consolewrite($tmpLine)
    EndIf
    $tOutputLine= $strPrefix & $aArray[2] & " " & $aArray[1]

    For $j = 3 To $aArray[0]
        $strAppend= $aArray[$j]
        if (stringright($aArray[$j],1))= "," then $strAppend= ";"
        if (stringright($aArray[$j],1))= ";" then
            if $aArray[$j]<>"();" then $strAppend= ");"
        EndIf
        $strAppend=getnewtype($strAppend)
        $tOutputLine= $tOutputLine & $strAppend
    Next

;~  $tOutputLine= $tOutputLine & $aarray[$aArray[0]]

    $tOutputline = @TAB & """" & $tOutputLine & """"
    $tValue=stringstripws($IDLArray[$i+1], $STR_STRIPLEADING +  $STR_STRIPTRAILING)
;~  sometimes its not just 1 line ahead for closing but 2 lines ahead
    if $tValue="" then
        $tValue=stringstripws($IDLArray[$i+2], $STR_STRIPLEADING +  $STR_STRIPTRAILING)
    endif
    if (stringleft($tValue,1) <> "}") then $tOutputLine= $tOutputLine & " & _ "

    filewriteline($hFileOpen, $tOutputLine)
    $i=$i+1
EndFunc

func getPosFirstNonWhiteSpace($str)
    Local $aArray = StringToASCIIArray($str)

    for $i=0 to ubound($aArray)-1
        if $aArray[$i]<>32 Then return $i
    Next

    return 0
EndFunc

func getInterfaceName()
    $tmpLine=stringstripws($tLine, $STR_STRIPLEADING +  $STR_STRIPTRAILING)
    $tArr=stringsplit($tmpLine," ")
    $tName=$tarr[2]
    if stringright($tname,1)=":" then $tName=stringleft($tname,stringlen($tname)-1)
    return $tname
EndFunc

func testIt()
;~  $tmpline="HRESULT SetFocus ( );"

;       $tmpLine ="HRESULT FindAll ([in] enum TreeScope scope,[in] IUIAutomationCondition * condition, [out, retval] IUIAutomationElementArray ** found );"
    $tmpLine="[propget] HRESULT PropertyId ([out, retval] PROPERTYID * propertyId );"
;~  $tmpLine="HRESULT GetCurrentPropertyValue ([in] PROPERTYID propertyId,[out, retval] VARIANT * retVal);"
;~  $tmpLine="HRESULT FindAllBuildCache ([in] enum TreeScope scope,[in] IUIAutomationCondition * condition,[in] IUIAutomationCacheRequest * cacheRequest,[out, retval] IUIAutomationElementArray ** found );"
    $strPrefix=""
    if stringinstr($tmpLine,"[propget]")>0 then $strPrefix="get_"
    if stringinstr($tmpLine,"[propput]")>0 then $strPrefix="put_"
consolewrite($strPrefix)
;~      consolewrite($tOutputline & @CRLF)
;~      consolewrite($tmpLine)
;~      _arraydisplay($aArray)
EndFunc

func getNewType($str)
    $retVal=stringregexp($str, "[A-Za-z0-9_]+", $STR_REGEXPMATCH)
;~  if stringleft($str,"3") = "ret" then consolewrite($retVal & $str & @CRLF)
    if $retval=0 then return $str
    $tStr=$str & ","
    $objTypes="none,byte,boolean,short,word,ushort,int,long,bool,dword," & _
              "ulong,uint,hresult,int64,uint64,ptr,hwnd,handle,float," & _
              "double,int_ptr,long_ptr,lresult,lparam,uint_ptr,ulong_ptr,"& _
              "dword_ptr,wparam,str,wstr,bstr,variant,idispatch,object," & _
              "clsid,struct,*,**"

    if stringinstr($objtypes,$tstr)>0 Then return $str
    return "ptr"
EndFunc

 

Edited by junkew
01/01/2019 many small enhancements in script

Share this post


Link to post
Share on other sites

Small steps created a lexer for an idl file

#include <MsgBoxConstants.au3>
#include <Array.au3> ; Required for _ArrayDisplay() only.


global const $TOKEN_OPERATOR_OPENBLOCK=1
global const $TOKEN_OPERATOR_CLOSEBLOCK=2
global const $TOKEN_IDENTIFIER=3
global const $TOKEN_KEYWORD=4
global const $TOKEN_NUMBER=5
global const $TOKEN_STRING=6
global const $TOKEN_STRING_UID=7
global const $TOKEN_SINGLECHAR=8
global const $TOKEN_COMMENT=9

global $MIDLkeywords="" & _
"aggregatable,allocate,annotate,appobject,arrays,async,async_uuid,auto_handle,bindable," & _
"Boolean,broadcast,byte,byte_count,call_as,callback,char,coclass,code,comm_status,const," & _
"context_handle,context_handle_noserialize,context_handle_serialize,control,cpp_quote," & _
"custom,decode,default,defaultbind,defaultcollelem,defaultvalue,defaultvtable," & _
"disable_consistency_check,dispinterface,displaybind,dllname,double,dual,enable_allocate," & _
"encode,endpoint,entry,enum,error_status_t,explicit_handle,fault_status,first_is,float," & _
"force_allocate,handle,handle_t,helpcontext,helpfile,helpstring,helpstringcontext,helpstringdll," & _
"hidden,hyper,id,idempotent,ignore,iid_is,immediatebind,implicit_handle,import,importlib,in,include," & _
"in_line,int,__int32,__int64,interface,last_is,lcid,length_is,library,licensed,local,long,max_is," & _
"maybe,message,midl_pragma,warning,midl_user_allocate,midl_user_free,min_is,module,ms_union,ncacn_at_dsp," & _
"ncacn_dnet_nsp,ncacn_http,ncacn_ip_tcp,ncacn_nb_ipx,ncacn_nb_nb,ncacn_nb_tcp,ncacn_np,ncacn_spx,ncacn_vns_spp," & _
"ncadg_ip_udp,ncadg_ipx,ncadg_mq,ncalrpc,nocode,nonbrowsable,noncreatable,nonextensible,notify,notify_flag," & _
"object,odl,oleautomation,optimize,optional,out,out_of_line,partial_ignore,pipe,pointer_default,pragma," & _
"propget,propput,propputref,proxy,ptr,public,range,readonly,ref,represent_as,requestedit,restricted," & _
"retval,shape,short,signed,size_is,small,source,strict_context_handle,string,struct,switch,switch_is," & _
"switch_type,transmit_as,typedef,uidefault,unique,union,unsigned,user_marshal,usesgetlasterror,uuid," & _
"v1_enum,vararg,version,void,wchar_t,wire_marshal,"

global $g_keywords=$MIDLkeywords
global $g_value=""
global $g_tokenIndex=0
global $g_tokens[2500][2]
;~ example()

func example()
;~  local $test[0][2]
;~  _ArrayAdd($test, "1|AAP")
;~  _ArrayAdd($test, "2|NOOT")
;~  _ARRAYDISPLAY($test)

    tokenizer("This is 1234 void 0x123 " & """" & "ni  ce doublequoted" & """" & "  just 'more string 123 singlequoted' object<> odl a SIMPLE[] way of tokenizing();123//nice comment at the end" & @CRLF)
    tokenizer("cpp_quote("& """" & "// -------------------------------------------------------------" & """" & ")" & @CRLF)

    $testString = "struct ExtendedProperty {" & @CRLF & _
                  "BSTR PropertyName;" & @CRLF & _
                  "BSTR PropertyValue;" & @CRLF & _
                  "};" & @CRLF

    tokenizer($teststring)

$testString = "typedef void * UIA_HWND;" & @CRLF & _
"" & @CRLF & _
"[" & @CRLF & _
"    uuid(944de083-8fb8-45cf-bcb7-c477acb2f897)," & @CRLF & _
"    lcid(0)," & @CRLF & _
"    version(1.0)," & @CRLF & _
"]" & @CRLF

    tokenizer($teststring)

    $testString = "typedef void * UIA_HWND;" & @CRLF & _
"" & @CRLF & _
"[" & @CRLF & _
"    uuid(""944de083-8fb8-45cf-bcb7-c477acb2f897"")," & @CRLF & _
"    lcid(0)," & @CRLF & _
"    version(1.0)," & @CRLF & _
"]" & @CRLF

tokenizer($teststring)

EndFunc
Func _TokenAdd($tokentype, $tokenvalue)
    $g_value=$tokenvalue
    $g_tokens[$g_tokenIndex][0]=$tokenType
    $g_tokens[$g_tokenIndex][1]=$tokenValue

    $g_tokenIndex=$g_tokenIndex+1
    if $g_tokenIndex >= ubound($g_tokens) Then
        redim $g_tokens[$g_tokenIndex+2500][2]
    EndIf
EndFunc
func tokenizer($input)
    local $index=0
    local $lineId=1
;~  local $tokens[0][2]  ;~= ObjCreate("WIA.vector")  ;~ Any array/list type would be fine
    local $allChars=stringregexp($input,"(?s).", $STR_REGEXPARRAYGLOBALMATCH)  ;~ include mathcing on characters CR LF
;~  local $allChars2=StringToASCIIArray($input)

;~  _ArrayDisplay($allchars)

    $inputLength=stringlen($input)
    while ($index < $inputLength)
        local $singleChar=$allChars[$index]

;~ Open blocks
        if stringinstr("[({<",$singleChar) > 0 then
;~          _ArrayAdd($tokens, $TOKEN_OPERATOR_OPENCLOSE & "|" & $singleChar)
            _TokenAdd($TOKEN_OPERATOR_OPENBLOCK , $singleChar)
            $index=$index+1
            ContinueLoop
        EndIf

;~      Whitespace
        if ($singleChar=" ") _
            or ($singleChar=@tab) _
            or ($singleChar=@cr) _
            or ($singleChar=@lf) Then
            if ($singleChar=@lf) then
                $lineId=$lineId+1;
            EndIf
            $index=$index+1
            ContinueLoop
        EndIf

;~      Comment
        if ($singleChar="/") Then
            if $allChars[$index+1]="/" Then
                $value=""

                while ($singleChar<>@CR) and ($singleChar<>@LF)
                    $value = $value & $singleChar
                    $index=$index+1
                    $singleChar = $allChars[$index]
                wend
;~              _ArrayAdd($tokens, $TOKEN_COMMENT & "|" & $value)
                _TokenAdd($TOKEN_COMMENT , $value)

                $index=$index+1
                ContinueLoop
            endif
        EndIf

;~      Decimal, Octal, Hex numbers
        if stringinstr("0123456789",$singleChar) > 0 Then
            $value=""
            while stringinstr("0123456789ABCDEFabcdefxX",$singleChar,$STR_CASESENSE) > 0
                $value = $value & $singleChar
                $index=$index+1
                $singleChar = $allChars[$index]
            wend
;~          _ArrayAdd($tokens, $TOKEN_NUMBER & "|" & $value)
            _TokenAdd($TOKEN_NUMBER , $value)
            ContinueLoop
        EndIf

;~      string doublequoted
        if $singleChar="""" Then
            $value=""
            $index=$index+1
            $singleChar = $allChars[$index]
            while $singleChar<>""""
                $value = $value & $singleChar
                $index=$index+1
                $singleChar = $allChars[$index]
            wend
;~          _ArrayAdd($tokens, $TOKEN_STRING & "|" & $value)
            _TokenAdd($TOKEN_STRING , $value)
            $index=$index+1 ;~ skip the doublequote
            ContinueLoop
        EndIf

;~      string singlequoted
        if $singleChar="'" Then
            $value=""
            $index=$index+1
            $singleChar = $allChars[$index]
            while $singleChar<>"'"
                $value = $value & $singleChar
                $index=$index+1
                $singleChar = $allChars[$index]
            wend
;~          _ArrayAdd($tokens, $TOKEN_STRING & "|" & $value)
            _TokenAdd($TOKEN_STRING , $value)
            $index=$index+1 ;~ skip the single quote
            ContinueLoop
        EndIf

;~      Identifier_or_keyword
        if stringinstr("abcdefghijklmnopqrstuvwxyz_",$singleChar) > 0 Then
            $value=""
            while stringinstr("abcdefghijklmnopqrstuvwxyz_",$singleChar) > 0
                $value = $value & $singleChar
                $index=$index+1
                $singleChar = $allChars[$index]
            wend
            IF stringinstr($g_keywords,$value & ",",$STR_CASESENSE) then
;~              Handle specific keywords directly to make parsing easier
                if (stringlower($value)="uuid") or (stringlower($value)="async_uuid") Then
                    $value=""
                    $index=$index+1
                    $singleChar = $allChars[$index]
                    while $singleChar<>")"
                        if stringinstr("0123456789abcdefABCDEF-",$singleChar) then
                            $value = $value & $singleChar
                        EndIf
                        $index=$index+1
                        $singleChar = $allChars[$index]
                    wend
;~                  _ArrayAdd($tokens, $TOKEN_STRING_UID & "|" & $value)
                    _TokenAdd($TOKEN_STRING_UID , $value)
                    $index=$index+1 ;~ skip the doublequote
                    ContinueLoop
                EndIf
;~              _ArrayAdd($tokens, $TOKEN_KEYWORD & "|" & $value)
                _TokenAdd($TOKEN_KEYWORD , $value)

            Else
;~              _ArrayAdd($tokens, $TOKEN_IDENTIFIER & "|" & $value)
                _TokenAdd($TOKEN_IDENTIFIER , $value)
            EndIf
            ContinueLoop
        EndIf

        if stringinstr(",#;+-*/=:!.|",$singleChar) Then
;~              _ArrayAdd($tokens, $TOKEN_SINGLECHAR & "|" & $value)
            _TokenAdd($TOKEN_SINGLECHAR , $singleChar)
            $index=$index+1
            ContinueLoop
        EndIf

;~      Open Close block characters
        if stringinstr("])}>",$singleChar) > 0 then
            if $allChars[$index+1]=";" Then
;~              _ArrayAdd($tokens, $TOKEN_OPERATOR_CLOSEBLOCK & "|" & $singleChar)
                _TokenAdd($TOKEN_OPERATOR_CLOSEBLOCK, $singleChar)
                $index=$index+1
                $index=$index+1
                ContinueLoop
            endif
;~          if $allChars[$index-1]="""" Then
;~              _ArrayAdd($tokens, $TOKEN_OPERATOR_CLOSEBLOCK & "|" & $singleChar)
                _TokenAdd($TOKEN_OPERATOR_CLOSEBLOCK, $singleChar)
                $index=$index+1
                ContinueLoop
;~          endif
        EndIf

;~ unmatched stuff, should not happen
        consolewrite("Lexing error: " & $lineId & " :<" & $allChars[$index-5] & $allChars[$index-4] & $allChars[$index-3] & $allChars[$index-2] & $allChars[$index-1] & $singlechar & " >" & @CRLF)

        $index=$index+1
    Wend
;~  _arraydisplay($tokens)
;~  return $tokens

endFunc

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By autotin
      Hello I am a first time user of AutoIT with little coding experience and I would REALLY really appreciate your help.
      I work in a warehouse where I am responsible for data entry along with a slew of other different tasks such as auditing and managing paperwork. Most of my time is tied up entering info to close receipts of product orders (8-12+ hours for thousands of products). The quantity actually produced by the warehouse is sometimes different from the quantity listed on the reciept (in this case 20). I need to change all the build qty for sublocation "1-WIP" from 20 to the actual quantity 22 and set all other numbers as 0. The form is an iframe coded with jQuery and freezes for 1-2 seconds after every entry and refreshes. As such, it doesn't allow me to use tab and I need to click and type every incorrect field.
      I have attached an image as an example from the webapp, FinaleInventory.
      I'm thinking that I probably need a macro that has a message box entry where I can type the corrected number entry I want. Then it uses image/character recognition (Tesseract?) to find "WIP" sublocation =,   Move the mouse over to the right to "Quantity" relative to location of WIP If quantity number = entry, then move to next "WIP" image (Not quite sure how to make Tesseract "find next") Elseif quantity number ≠ entry then click quantity number of "WIP" and type corrected entry Scroll down Loop until bottom of page I would greatly appreciate any help, ideas or pointers for this project. Thank you!
      -A newbie scripter

    • By BigDaddyO
      I have been using Auto IT along with the IUIAutomation for the nasty bits to perform automation in the Trizetto Facets application and everything is going well, until I was asked to use some of my scripts to generate Load on the system. 
      In order to do this, I would need to Launch My AutoIT script "which opens the Facets application" multiple times.  Each time it is launched a new Facets App on the same computer will open.
      Couple problems with this that I'm hoping someone will be able to help me out with
      On Launch of Facets, I get the PID from Shellexecute which I can then pass into the IUIA to search the proper window which is great, but the Click and Send functions from IUIA don't actually send directly to the control so It can get flaky when 5+ Facets screens are being controlled at the same time. On Launch of Facets, I use the PID to then get the Windows Hwnd.  When trying to do ControlClick, or Control* I can't seem to find any of the Popup windows such as the Database Select, or Login Creds using the Handle from the Main App and text from the Pop window. ex... ControlClick($MainUIhwnd, "text from popup", "Button1")  Is there some other way to identify popup windows for ControlClick type functions?  
    • By parrishjason
      Hello all.

      I currently have an AutoIT script that uses INetGet to retrieve and run files over a network. However, as it stands the app has currently changed to the point where I must open an actual browser in order to be able to get to the file (at least, this is the easiest way).
       
      Right now I have an extremely unreliable and clunky set of Send and Click commands to accomplish this task with sleeps in between everything to the point where I *hope* my file was downloaded before I try to click the "Run" button in microsoft edge. 
       
      I've been looking into IUIautomation, but I'm having quite a time understanding how to actually use it properly.
       
      I'd think that a script to navigate to a URL, download a file, then click "Run" in the browser would be simple. If I can get any help that'd be highly appreciated.
       
      Once I see a sample of how to download the file, the navigation part should be quite trivial to figure out.
    • By Ontosy
      I have tryed to compile this "com object" and then use with AutoIt3 but not work: "err.number 0x80020006.
      How to do?
      #include-once Local $oErrorHandler = ObjEvent("AutoIt.Error", "_ErrFunc") Local Const $sCLSID_TaskbarList = "{7233b105-bc01-41ff-b72e-582c5954b76d}" Local Const $sIID_ITaskbarList = "{702d63b3-d7d1-4f17-ab11-2f2ed770fdc8}" Local Const $sTagITaskbarList = 'SetString(wstr:cdecl);wstr:cdecl GetString();' Local $oIExample = ObjCreateInterface($sCLSID_TaskbarList, $sIID_ITaskbarList, $sTagITaskbarList) $a=$oIExample.SetString("Abc") msgbox(0,@error,$a) $a=$oIExample.GetString() ;.GetRootElement.CurrentClassName exit msgbox(0,0,$a) Func _ErrFunc($oError) ; Do anything here. ConsoleWrite(@ScriptName & " (" & $oError.scriptline & ") : ==> COM Error intercepted !" & @CRLF & _ @TAB & "err.number is: " & @TAB & @TAB & "0x" & Hex($oError.number) & @CRLF & _ @TAB & "err.windescription:" & @TAB & $oError.windescription & @CRLF & _ @TAB & "err.description is: " & @TAB & $oError.description & @CRLF & _ @TAB & "err.source is: " & @TAB & @TAB & $oError.source & @CRLF & _ @TAB & "err.helpfile is: " & @TAB & $oError.helpfile & @CRLF & _ @TAB & "err.helpcontext is: " & @TAB & $oError.helpcontext & @CRLF & _ @TAB & "err.lastdllerror is: " & @TAB & $oError.lastdllerror & @CRLF & _ @TAB & "err.scriptline is: " & @TAB & $oError.scriptline & @CRLF & _ @TAB & "err.retcode is: " & @TAB & "0x" & Hex($oError.retcode) & @CRLF & @CRLF) EndFunc ;==>_ErrFunc  
    • By Danyfirex
      well. Reading in msdn I found an interface to run a Gadget. So I wrote it. 
       
      #include <Array.au3> #include <File.au3> Global Const $sCLSID_DesktopGadget = "{924CCC1B-6562-4C85-8657-D177925222B6}" Global Const $sIID_IDesktopGadget = "{C1646BC4-F298-4F91-A204-EB2DD1709D1A}" Global Const $sTagIDesktopGadget = "RunGadget hresult(wstr);" Global Enum $eNoShared = 1, $eShared, $eAll Local $aGadGets = _GetGadget($eAll) If IsArray($aGadGets) Then For $i = 1 To $aGadGets[0] If StringInStr($aGadGets[$i], "CPU") Then ;Run CPU GadGet RunGadget($aGadGets[$i]) EndIf Next EndIf Func RunGadget($sGadGetPath) Local $oDesktopGadget = ObjCreateInterface($sCLSID_DesktopGadget, $sIID_IDesktopGadget, $sTagIDesktopGadget) if not IsObj($oDesktopGadget) then Return False return SUCCEEDED($oDesktopGadget.RunGadget($sGadGetPath)) EndFunc ;==>RunGadget Func _GetGadget($GadgetType = $eNoShared) Local $aNoSharedGadGets = 0 Local $aSharedGadGets = 0 Local $aGadGets = 0 Local $Size = 0 Local Const $sSharedGadget = @ProgramFilesDir & "\Windows Sidebar\Shared Gadgets" Local Const $sNoShared = @ProgramFilesDir & "\Windows Sidebar\Gadgets" If $GadgetType < $eNoShared Or $GadgetType > $eAll Then Return 0 If BitAND($GadgetType, $eNoShared) Then $aNoSharedGadGets = _FileListToArray($sNoShared, Default, Default, True) If BitAND($GadgetType, $eShared) Then $aSharedGadGets = _FileListToArray($sSharedGadget, Default, Default, True) If IsArray($aSharedGadGets) And IsArray($aNoSharedGadGets) Then $Size = UBound($aNoSharedGadGets) - 1 + (UBound($aSharedGadGets) - 1) _ArrayConcatenate($aNoSharedGadGets, $aSharedGadGets, 1) $aGadGets = $aNoSharedGadGets $aGadGets[0] = $Size Else If IsArray($aSharedGadGets) Then $aGadGets = $aSharedGadGets If IsArray($aNoSharedGadGets) Then $aGadGets = $aNoSharedGadGets EndIf $aSharedGadGets = 0;Free $aNoSharedGadGets = 0 ;Free Return $aGadGets EndFunc ;==>_GetGadget Func SUCCEEDED($hr) Return ($hr >= 0) EndFunc ;==>SUCCEEDED Saludos
       
       
       
×
×
  • Create New...