├── Libraries ├── ApplicationFramework.ahk ├── HelperFunctions.ahk ├── ManagedGuis.ahk ├── ManagedResources.ahk ├── ObjectHandling.ahk ├── StringHandling.ahk ├── TypeLibHelperFunctions.ahk ├── TypeLibInterfaces.ahk ├── VariousFunctions.ahk └── WindowsBase.ahk ├── License.txt ├── README.md ├── Resources └── UIStrings.Res ├── TypeLib2AHK.ahk ├── UIAutomationClient_Example.ahk └── UIAutomationClient_Example_AHK v2.ahk2 /Libraries/ApplicationFramework.ahk: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Version: MPL 2.0/GPL 3.0/LGPL 3.0 4 | 5 | The contents of this file are subject to the Mozilla Public License Version 6 | 2.0 (the "License"); you may not use this file except in compliance with 7 | the License. You may obtain a copy of the License at 8 | 9 | http://www.mozilla.org/MPL/ 10 | 11 | Software distributed under the License is distributed on an "AS IS" basis, 12 | WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 13 | for the specific language governing rights and limitations under the License. 14 | 15 | The Initial Developer of the Original Code is 16 | Elgin . 17 | Portions created by the Initial Developer are Copyright (C) 2010-2017 18 | the Initial Developer. All Rights Reserved. 19 | 20 | Contributor(s): 21 | 22 | Alternatively, the contents of this file may be used under the terms of 23 | either the GNU General Public License Version 3 or later (the "GPL"), or 24 | the GNU Lesser General Public License Version 3.0 or later (the "LGPL"), 25 | in which case the provisions of the GPL or the LGPL are applicable instead 26 | of those above. If you wish to allow use of your version of this file only 27 | under the terms of either the GPL or the LGPL, and not to allow others to 28 | use your version of this file under the terms of the MPL, indicate your 29 | decision by deleting the provisions above and replace them with the notice 30 | and other provisions required by the GPL or the LGPL. If you do not delete 31 | the provisions above, a recipient may use your version of this file under 32 | the terms of any one of the MPL, the GPL or the LGPL. 33 | 34 | */ 35 | 36 | ; ============================================================================== 37 | ; ============================================================================== 38 | ; todo 39 | ; ============================================================================== 40 | ; ============================================================================== 41 | 42 | ; make set and normal vars check types and ranges 43 | 44 | ; ============================================================================== 45 | ; ============================================================================== 46 | ; Contents 47 | ; ============================================================================== 48 | ; ============================================================================== 49 | /* 50 | Provides: 51 | - class ApplicationFramework 52 | Basic fle and variable management for generic applications. 53 | 54 | - class ManagedVariableClass 55 | Protected class for variables, constants and values in ini-files. 56 | 57 | - function LogLine(TxtLn,LogFile="Default") 58 | Writes logfile entries. Uses buffered write after 3 sec to reduce performance 59 | impact of writes. 60 | 61 | - function LogWrite() 62 | Writes logfile buffer to disk. 63 | 64 | */ 65 | ; ============================================================================== 66 | ; ============================================================================== 67 | ; Code 68 | ; ============================================================================== 69 | ; ============================================================================== 70 | 71 | #Include ObjectHandling.ahk 72 | #Include ManagedResources.ahk 73 | #Include ManagedGuis.ahk 74 | #Include HelperFunctions.ahk 75 | 76 | 77 | ; ============================================================================== 78 | ; ============================================================================== 79 | ; class ApplicationFramework 80 | ; Settings 81 | ; __New(ApplicationName="NoName", Version=0, DefaultUILanguage="English") 82 | ; ApplicationName[] 83 | ; SettingsPath[] 84 | ; UserFilePath[] 85 | ; UserSettingsFile[] 86 | ; LogFile[] 87 | ; ============================================================================== 88 | ; ============================================================================== 89 | 90 | class ApplicationFramework 91 | { 92 | Data:=Object() 93 | Resources:="" 94 | Settings:="" 95 | 96 | __New(ApplicationName="NoName", Version=0, DefaultUILanguage="English") 97 | { 98 | global 99 | local SettingsPath, UserFilePath, UserSettingsFile, FirstRun, LogFileSize 100 | SettingsPath:= A_AppData "\" ApplicationName 101 | UserFilePath:= A_MyDocuments "\" ApplicationName 102 | UserSettingsFile:=UserFilePath "\UserSettings.ini" 103 | 104 | IfNotExist, % SettingsPath 105 | { 106 | FileCreateDir, % SettingsPath 107 | } 108 | IfNotExist, % UserFilePath 109 | { 110 | FileCreateDir, % UserFilePath 111 | } 112 | IfNotExist, % UserSettingsFile 113 | FirstRun:=1 114 | else 115 | FirstRun:=0 116 | this.Settings:=new ManagedVariableClass(UserSettingsFile, "Main") 117 | this.Settings.SetConstant("ApplicationName", ApplicationName) 118 | this.Settings.SetConstant("ApplicationVersion", Version) 119 | this.Settings.SetConstant("SettingsPath", SettingsPath) 120 | this.Settings.SetConstant("UserFilePath", UserFilePath) 121 | this.Settings.SetConstant("UserSettingsFile", UserSettingsFile) 122 | this.Settings.SetConstant("FirstRun", FirstRun) 123 | 124 | this.Settings.SetConstant("LogFile", UserFilePath "\LogFile.txt") 125 | this.Settings["DebugModeEnabled"]:=0 126 | Loop, %0% 127 | { 128 | LogLine("Command line parameter" A_Index ": " %A_Index%) 129 | If (%A_Index%="-debug") 130 | this.Settings["DebugModeEnabled"]:=1 131 | } 132 | If (!A_IsCompiled) 133 | this.Settings["DebugModeEnabled"]:=1 134 | LogWriteBuffer:=Object() 135 | LogWriteBuffer["DefaultLogFile"]:=this.LogFile 136 | FileGetSize, LogFileSize, % this.LogFile, K 137 | If (LogFileSize>1000) 138 | { 139 | FileMove, % this.LogFile, % this.LogFile ".bak", 1 140 | } 141 | LogLine("*----------------------------------------------------------------*") 142 | LogLine(ApplicationName " Version: " Version " started.") 143 | 144 | this.Settings.CreateIni("UILanguage", DefaultUILanguage) ; language for GUI strings 145 | this.Settings.SetConstant("ResourceFile", this.SettingsPath "\UIStrings.Res") 146 | If (this.Settings["DebugModeEnabled"]) 147 | { 148 | FileDelete, % this.Settings.ResourceFile 149 | } 150 | fileinstall, Resources\UIStrings.Res, % this.Settings.ResourceFile 151 | this.Resources:=new ManagedResourcesClass(this.Settings["ResourceFile"], this.Settings["UILanguage"], DefaultUILanguage) 152 | this.ManagedGuis:=new GuiManagerMainClass(this.Settings) 153 | } 154 | 155 | CleanUp(ExitReason, ExitCode) 156 | { 157 | LogLine(this.ApplicationName " Version: " this.Settings["ApplicationVersion"] " exit: " ExitReason) 158 | LogLine("*----------------------------------------------------------------*") 159 | LogWrite() 160 | } 161 | 162 | ApplicationName[] 163 | { 164 | get 165 | { 166 | return this.Settings.ApplicationName 167 | } 168 | 169 | set 170 | { 171 | return this.Settings.ApplicationName 172 | } 173 | } 174 | 175 | SettingsPath[] 176 | { 177 | get 178 | { 179 | return this.Settings.SettingsPath 180 | } 181 | 182 | set 183 | { 184 | return this.Settings.SettingsPath 185 | } 186 | } 187 | 188 | UserFilePath[] 189 | { 190 | get 191 | { 192 | return this.Settings.UserFilePath 193 | } 194 | 195 | set 196 | { 197 | return this.Settings.UserFilePath 198 | } 199 | } 200 | 201 | UserSettingsFile[] 202 | { 203 | get 204 | { 205 | return this.Settings.UserSettingsFile 206 | } 207 | 208 | set 209 | { 210 | return this.Settings.UserSettingsFile 211 | } 212 | } 213 | 214 | LogFile[] 215 | { 216 | get 217 | { 218 | return this.Settings.LogFile 219 | } 220 | 221 | set 222 | { 223 | return this.Settings.LogFile 224 | } 225 | } 226 | } 227 | 228 | 229 | -------------------------------------------------------------------------------- /Libraries/HelperFunctions.ahk: -------------------------------------------------------------------------------- 1 | ; ============================================================================== 2 | ; ============================================================================== 3 | ; HotKeyFormat(input) 4 | ; Formats readable hotkeystring to AHK Send format 5 | ; ============================================================================== 6 | ; ============================================================================== 7 | 8 | HotKeyFormat(input) 9 | { 10 | StringLower, tempstr, input 11 | shift:=False 12 | control:=False 13 | alt:=False 14 | 15 | ifinstring, tempstr, shift- 16 | { 17 | shift:=True 18 | StringReplace, tempstr, tempstr, shift-, , All 19 | } 20 | ifinstring, tempstr, ctrl- 21 | { 22 | control:=True 23 | StringReplace, tempstr, tempstr, ctrl-, , All 24 | } 25 | ifinstring, tempstr, alt- 26 | { 27 | alt:=True 28 | StringReplace, tempstr, tempstr, alt-, , All 29 | } 30 | ifinstring, tempstr, win- 31 | { 32 | lwin:=True 33 | StringReplace, tempstr, tempstr, win-, , All 34 | } 35 | output:= Trim(tempstr) 36 | if shift 37 | { 38 | output:="+" output 39 | } 40 | if Control 41 | { 42 | output:="^" output 43 | } 44 | if Alt 45 | { 46 | output:="!" output 47 | } 48 | if lWin 49 | { 50 | output:="#" output 51 | } 52 | output:= Trim(output) 53 | return output 54 | } 55 | 56 | 57 | ; ============================================================================== 58 | ; ============================================================================== 59 | ; IsInsideVisibleArea(x,y,w,h) 60 | ; Checks if the coordinates are inside the visible area 61 | ; ============================================================================== 62 | ; ============================================================================== 63 | 64 | IsInsideVisibleArea(x,y,w,h) 65 | { 66 | isVis:=0 67 | SysGet, MonitorCount, MonitorCount 68 | Loop, %MonitorCount% 69 | { 70 | SysGet, Monitor%A_Index%, MonitorWorkArea, %A_Index% 71 | if (x+w-10>Monitor%A_Index%Left) and (x+10Monitor%A_Index%Top) and (y+20"DefaultLogFile" and LogStr<>"") 117 | { 118 | FileAppend, %LogStr%, %LogFile% 119 | LogWriteBuffer[LogFile]:="" 120 | } 121 | } 122 | LogWriteBuffer["Timer"]:=0 123 | } 124 | 125 | 126 | ; ============================================================================== 127 | ; ============================================================================== 128 | ; MsgBox(Text,Title="",Options=0,Timeout=0) 129 | ; Wrapper for msgbox command 130 | ; ============================================================================== 131 | ; ============================================================================== 132 | 133 | MsgBox(Text,Title="",Options=0,Timeout=0) 134 | { 135 | MsgBox, % Options, %Title%, %Text%, %Timeout% 136 | } 137 | 138 | 139 | -------------------------------------------------------------------------------- /Libraries/ManagedGuis.ahk: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Version: MPL 2.0/GPL 3.0/LGPL 3.0 4 | 5 | The contents of this file are subject to the Mozilla Public License Version 6 | 2.0 (the "License"); you may not use this file except in compliance with 7 | the License. You may obtain a copy of the License at 8 | 9 | http://www.mozilla.org/MPL/ 10 | 11 | Software distributed under the License is distributed on an "AS IS" basis, 12 | WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 13 | for the specific language governing rights and limitations under the License. 14 | 15 | The Initial Developer of the Original Code is 16 | Elgin . 17 | Portions created by the Initial Developer are Copyright (C) 2010-2017 18 | the Initial Developer. All Rights Reserved. 19 | 20 | Contributor(s): 21 | 22 | Alternatively, the contents of this file may be used under the terms of 23 | either the GNU General Public License Version 3 or later (the "GPL"), or 24 | the GNU Lesser General Public License Version 3.0 or later (the "LGPL"), 25 | in which case the provisions of the GPL or the LGPL are applicable instead 26 | of those above. If you wish to allow use of your version of this file only 27 | under the terms of either the GPL or the LGPL, and not to allow others to 28 | use your version of this file under the terms of the MPL, indicate your 29 | decision by deleting the provisions above and replace them with the notice 30 | and other provisions required by the GPL or the LGPL. If you do not delete 31 | the provisions above, a recipient may use your version of this file under 32 | the terms of any one of the MPL, the GPL or the LGPL. 33 | 34 | */ 35 | 36 | ; todo 37 | 38 | ; Menu, SB_ commads in status bar 39 | 40 | #Include WindowsBase.ahk 41 | 42 | class GuiManagerMainClass 43 | { 44 | ; variables for internal use only 45 | ; use properties to access the values 46 | Settings := 47 | ManagedGuisByName := Object() 48 | ManagedGuisByHWND := Object() 49 | ManagedControls := Object() 50 | DefaultFont:=Object() 51 | 52 | __New(ManagedVariableObject="") 53 | { 54 | global GuiManagerCallback 55 | this.Settings := ManagedVariableObject 56 | GuiManagerCallback:=this 57 | ; retrieve Windows default font settings as AHK normally uses a different font and size 58 | ncm:=GetNONCLIENTMETRICS() 59 | If (IsObject(ncm)) 60 | { 61 | this.DefaultFont.Name:=ncm.lfMenuFont.lfFaceName 62 | this.DefaultFont.Size:=-ncm.lfMenuFont.lfHeight*72/A_ScreenDPI 63 | this.DefaultFont.Weight:=ncm.lfMenuFont.lfWeight 64 | this.DefaultFont.Italic:=ncm.lfMenuFont.lfItalic 65 | this.DefaultFont.Underline:=ncm.lfMenuFont.lfUnderline 66 | this.DefaultFont.StrikeOut:=ncm.lfMenuFont.lfStrikeOut 67 | } 68 | } 69 | 70 | NewGUI(GuiName, Title="", Options="") 71 | { 72 | this.ManagedGuisByName[GuiName]:=new ManagedGui(GuiName, this, Title, Options) 73 | this.ManagedGuisByHWND[this.ManagedGuisByName[GuiName].HWND]:=this.ManagedGuisByName[GuiName] 74 | return, this.ManagedGuisByName[GuiName] 75 | } 76 | 77 | ; Close gui GuiHwnd. GuiHwnd=0 to close all managed Guis. 78 | Close(GuiHwnd=0) 79 | { 80 | If (GuiHwnd=0) 81 | { 82 | ret:=0 83 | For HWND, ManagedGui in ManagedGuisByHWND 84 | ManagedGui.Close() 85 | } 86 | return, this.ManagedGuisByHWND[GuiHwnd].Close() 87 | } 88 | 89 | ContextMenu(GuiHwnd, CtrlHwnd, EventInfo, IsRightClick, X, Y) 90 | { 91 | return, this.ManagedGuisByHWND[GuiHwnd].ContextMenu(CtrlHwnd, EventInfo, IsRightClick, X, Y) 92 | } 93 | 94 | ControlEvent(CtrlHwnd="", GuiEvent="", EventInfo="", ErrorLvl="") 95 | { 96 | ;~ ToolTip, Hwnd: %CtrlHwnd%`nGuiEvent: %GuiEvent%`nEventInfo: %EventInfo%`nErrorLvl: %ErrorLvl% 97 | CallToFunc:=this.ManagedControls[CtrlHwnd].SendEvents 98 | %CallToFunc%(CtrlHwnd, GuiEvent, EventInfo, ErrorLvl) 99 | } 100 | 101 | DropFiles(GuiHwnd, FileArray, CtrlHwnd, X, Y) 102 | { 103 | return, this.ManagedGuisByHWND[GuiHwnd].DropFiles(FileArray, CtrlHwnd, X, Y) 104 | } 105 | 106 | Escape(GuiHwnd) 107 | { 108 | return, this.ManagedGuisByHWND[GuiHwnd].Escape() 109 | } 110 | 111 | Show(GuiName, Title="", Options="") 112 | { 113 | this.ManagedGuisByName[GuiName].Show(Title, Options) 114 | } 115 | 116 | Size(GuiHwnd, EventInfo, Width, Height) 117 | { 118 | return, this.ManagedGuisByHWND[GuiHwnd].Size(EventInfo, Width, Height) 119 | } 120 | 121 | Submit(GuiName, Hide=0) 122 | { 123 | return, this.ManagedGuisByName[GuiName].Submit(Hide) 124 | } 125 | 126 | } 127 | 128 | class ManagedGui 129 | { 130 | GuiManager:="" 131 | GuiHWND:=0 132 | GuiName:="" 133 | Title:="" 134 | Handlers:=Object() 135 | Handlers.OnClose:=Object() 136 | Handlers.OnContextMenu:=Object() 137 | Handlers.OnDropFiles:=Object() 138 | Handlers.OnEscape:=Object() 139 | Handlers.OnSize:=Object() 140 | Controls:=Object() 141 | AutoSize:=0 142 | AutoSizeReady:=0 143 | SizingInfo:=Object() 144 | 145 | __New(GuiName, GuiManager, Title="", Options="") 146 | { 147 | Gui, New, %Options% +HwndGuiHwnd, %Title% 148 | this.GuiManager := GuiManager 149 | this.GuiName:=GuiName 150 | this.GuiHWND:=GuiHwnd 151 | this.Title:=Title 152 | this.Font("S"this.GuiManager.DefaultFont.Size " W"this.GuiManager.DefaultFont.Weight " " (this.GuiManager.DefaultFont.Italic ? "italic " : "") (this.GuiManager.DefaultFont.Underline ? "underline " : "") (this.GuiManager.DefaultFont.StrikeOut ? "strike" : ""),this.GuiManager.DefaultFont.Name) 153 | } 154 | 155 | Add(ControlType, Name, Content="", Options="", GetEvents=0, GetData=0) 156 | { 157 | global 158 | local HWND, CNum 159 | HWND:=this.GuiHWND 160 | this.Controls.Push(Object()) 161 | CNum:=this.Controls.MaxIndex() 162 | If (GetEvents) 163 | { 164 | Options.= " gManagedControlEventHandler" 165 | } 166 | If (GetData) 167 | { 168 | vVar:="ManagedGui" Name CNum 169 | Options.=" v" vVar 170 | } 171 | else 172 | vVar:="" 173 | Gui, %HWND%: Add, %ControlType%, %Options% +HwndControlHwnd, %Content% 174 | this.Controls[CNum]:=new Managed%ControlType%(ControlHwnd, Name, vVar, GetEvents, GetData) 175 | this.GuiManager.ManagedControls[ControlHwnd]:=this.Controls[CNum] 176 | return, this.Controls[CNum] 177 | } 178 | 179 | ; AddSizingInfo("X", "*", 1, "M", 0, "MyButton", 0, "C", 0, "*", 1, "M", 0) 180 | AddSizingInfo(Axis, params*) 181 | { 182 | If (Mod(params.MaxIndex(),4)<>0 or params.MaxIndex()<4) 183 | throw, "Invalid number of arguments passed to AddSizingInfo" 184 | If (SubStr(Axis,1,1)="X" or Substr(Axis,1,1)="Y") 185 | { 186 | tSizingInfo:=Object() 187 | tSizingInfo.Axis:=Axis 188 | tSizingInfo.Elements:=Object() 189 | v1:="" 190 | v2:="" 191 | v3:="" 192 | ; if first or last element is not a space add a margin sized space 193 | If (params[1]<>"*" and params[1]<>"0") 194 | tSizingInfo.Elements.Push({"ID":0,"Scale":0,"MinValue":"M","MaxValue":0}) 195 | For index, value in params 196 | { 197 | If (v1<>"" and v2<>"" and v3<>"") 198 | { 199 | to:=Object() 200 | If !(IsObject(v1)) 201 | { 202 | val:=v1 203 | v1:=Object() 204 | v1.Push(val) 205 | } 206 | for index, cc in v1 207 | { 208 | If cc is not integer 209 | { 210 | If (cc="*") 211 | v1[index]:=0 212 | for index2, control in this.Controls 213 | { 214 | if (control.Name=cc) 215 | v1[index]:=control.HWND 216 | } 217 | If v1 is integer 218 | { 219 | throw "Invalid control passed to AddSizingInfo: " v1 220 | } 221 | } 222 | } 223 | to.ID:=v1 224 | to.Scale:=v2 225 | to.MinValue:=v3 226 | to.MaxValue:=value 227 | tSizingInfo.Elements.Push(to) 228 | v1:="" 229 | v2:="" 230 | v3:="" 231 | } 232 | else 233 | If (v1<>"" and v2<>"") 234 | { 235 | v3:=value 236 | } 237 | else 238 | If (v1<>"") 239 | { 240 | v2:=value 241 | } 242 | else 243 | { 244 | v1:=value 245 | } 246 | } 247 | ; if first or last element is not a space add a margin sized space 248 | If (params[params.MaxIndex()-3]<>"*" and params[params.MaxIndex()-3]<>"0") 249 | tSizingInfo.Elements.Push({"ID":0,"Scale":0,"MinValue":"M","MaxValue":0}) 250 | LastElemWasSpacer:=0 251 | for index, element in tSizingInfo.Elements 252 | { 253 | if (element.id=0) 254 | { 255 | If(LastElemWasSpacer) 256 | { 257 | throw "Invalid sizing info passed. No more than one spacer between two controls allowed." 258 | } 259 | else 260 | { 261 | LastElemWasSpacer:=1 262 | } 263 | } 264 | else 265 | { 266 | LastElemWasSpacer:=0 267 | } 268 | } 269 | return this.AddSizingInfoByObj(tSizingInfo) 270 | } 271 | else 272 | throw "Invalid sizing info: " Axis 273 | } 274 | 275 | /* Structure for SizingInfo object 276 | optional: Index for several SI o's in one object 277 | Axis:="X" or "Y"; nMin nMax to use current rule to set minimum/maximum size of GUI 278 | Elements:=Object() 279 | Elements[Index].ID:=single space */0 or array of "control name"/"hwnd" 280 | Elements[Index].Scale:=number ; >0 relative scaling <0 absolute scaling 281 | Elements[Index].MinValue:=C/D/M/R/number ; C: calculated by CalculateSizingInfo on Show; D: elements are not resized but spaced evenly in the available space; M is set to current margin; R: use size of referenced control; number MinValue for scaling if >0; used as size if scale=0 282 | Elements[Index].MaxValue:="C"/number ; C: calculated by CalculateSizingInfo on Show; MaxValue for scaling if >0 283 | */ 284 | AddSizingInfoByObj(InObj) 285 | { 286 | this.AutoSize:=1 287 | this.SizingInfo.Push(InObj) 288 | return this.SizingInfo.MaxIndex() 289 | } 290 | 291 | CalculateSizingInfo(SizingInfo) 292 | { 293 | HWND:=this.GuiHWND 294 | If (TryKey(SizingInfo, "Axis")) 295 | { 296 | ; get information of main window and prepare 297 | GuiRect:=GetClientRect(this.GuiHWND) 298 | Coords:=Object() 299 | If (SubStr(SizingInfo.Axis,1,1)="X") 300 | { 301 | Coords[0]:={"v":GuiRect.x, "e":0} 302 | Coords[SizingInfo.Elements.MaxIndex()]:={"v":GuiRect.w,"e":0} 303 | cv:="x" 304 | ce:="w" 305 | Margin:=Floor(this.GuiManager.DefaultFont.Size*1.25) 306 | } 307 | else 308 | { 309 | Coords[0]:={"v":GuiRect.y, "e":0} 310 | Coords[SizingInfo.Elements.MaxIndex()]:={"v":GuiRect.w,"e":0} 311 | cv:="y" 312 | ce:="h" 313 | Margin:=Floor(this.GuiManager.DefaultFont.Size*0.75) 314 | } 315 | ; get information about current real elements 316 | for index, elcontain in SizingInfo.Elements 317 | { 318 | vmax:=0 319 | emax:=0 320 | If (elcontain.MinValue="D") 321 | { 322 | Minval:=0 323 | for index, elem in elcontain.ID 324 | { 325 | GuiControlGet, cpos, Pos, % elem 326 | vmax:=vmax0) 338 | { 339 | GuiControlGet, cpos, Pos, % ehwnd 340 | vmax:=vmax0 and SizeSet[index].Extent>element.Maxvalue) 723 | SizeSet[index].Extent:=element.Maxvalue 724 | SizeSet[index].Fixed:=1 725 | } 726 | } 727 | } 728 | } 729 | ; calculate available rubber 730 | rv:=WinExtent 731 | rub:=0 732 | for index, element in SizingInfo.Elements 733 | { 734 | rv-=SizeSet[index].Extent 735 | If (element.Scale>0) 736 | rub+=element.Scale 737 | } 738 | if (rv<0) 739 | rv:=0 740 | rubber:=Round(rv/rub) 741 | ; calculate extents with rubber 742 | for index, element in SizingInfo.Elements 743 | { 744 | If (element.Scale>0) 745 | { 746 | SizeSet[index].Extent+=rubber*element.Scale 747 | } 748 | } 749 | ; check if anything got too big 750 | rerun:=0 751 | for index, element in SizingInfo.Elements 752 | { 753 | If (element.Scale>0) 754 | { 755 | If (element.Maxvalue>0 and SizeSet[index].Extent>element.Maxvalue) 756 | { 757 | SizeSet[index].Extent:=element.Maxvalue 758 | SizeSet[index].Fixed:=1 759 | rerun:=1 760 | } 761 | } 762 | } 763 | } until rerun=0 764 | ; set the positions 765 | vpos:=0 766 | for index, element in SizingInfo.Elements 767 | { 768 | If (element.ID[1]=0) 769 | { 770 | vpos+=SizeSet[index].Extent 771 | } 772 | else 773 | { 774 | If (element.MinValue="D") 775 | { 776 | Midspacing:=SizeSet[index].Extent/(element.ID.Maxindex()) 777 | ; check if elements can be placed with their centers evenly distributed 778 | ; if not distribute with even spacing inbetween 779 | distribute:=1 780 | for index2, elem in element.ID 781 | { 782 | GuiControlGet, cpos, Pos, % elem 783 | If (index2=1 or index2=element.ID.Maxindex()) 784 | { 785 | If ((cpos%ce%+Margin)>Midspacing) 786 | distribute:=0 787 | } 788 | else 789 | If (index2>1) 790 | { 791 | If ((savesize+cpos%ce%)/2>Midspacing) 792 | distribute=0 793 | } 794 | savesize:=cpos%ce% 795 | } 796 | If (distribute) 797 | { 798 | dpos:=vpos+Midspacing/2 799 | for index2, elem in element.ID 800 | { 801 | GuiControlGet, cpos, Pos, % elem 802 | GuiControl, % this.GuiManager.ManagedControls[elem].MoveMode, %elem%, % cv dpos-(cpos%ce%/2) 803 | dpos+=Midspacing 804 | } 805 | } 806 | else 807 | { 808 | Minval:=0 809 | for index, elem in element.ID 810 | { 811 | GuiControlGet, cpos, Pos, % elem 812 | Minval+=cpos%ce% + Margin 813 | } 814 | If (Minval) 815 | Minval-=Margin 816 | Drubber:=(SizeSet[index].Extent-Minval)/(element.ID.Maxindex()+1) 817 | dpos:=vpos+Drubber 818 | for index2, elem in element.ID 819 | { 820 | GuiControl, % this.GuiManager.ManagedControls[elem].MoveMode, %elem%, % cv dpos 821 | GuiControlGet, cpos, Pos, % elem 822 | dpos+=cpos%ce% + DRubber + Margin 823 | } 824 | } 825 | } 826 | else 827 | { 828 | for index2, elem in element.ID 829 | { 830 | GuiControl, % this.GuiManager.ManagedControls[elem].MoveMode, %elem%, % cv vpos " " ce SizeSet[index].Extent 831 | } 832 | } 833 | vpos+=SizeSet[index].Extent 834 | } 835 | } 836 | } 837 | else 838 | If (IsObject(SizingInfo)) 839 | { 840 | For index, obj in SizingInfo 841 | { 842 | this.SizeSet(obj, Width, Height) 843 | } 844 | } 845 | } 846 | 847 | Submit(Hide=0) 848 | { 849 | global 850 | local Options, HWND, RetObj, Index, Control, Var 851 | HWND:=this.GuiHWND 852 | If !(Hide) 853 | Options:="NoHide" 854 | else 855 | Options:="" 856 | Gui %HWND%: Submit, %Options% 857 | RetObj:=Object() 858 | for Index, Control in this.Controls 859 | { 860 | If (this.Controls[Index]["SubmitTo"]) 861 | { 862 | Var:=Control["Var"] 863 | RetObj[this.Controls[Index]["SubmitTo"]]:=%Var% 864 | } 865 | } 866 | return, RetObj 867 | } 868 | 869 | HWND[] 870 | { 871 | get 872 | { 873 | return, this.GuiHWND 874 | } 875 | 876 | set 877 | { 878 | return, this.GuiHWND 879 | } 880 | } 881 | 882 | Name[] 883 | { 884 | get 885 | { 886 | return, this.GuiName 887 | } 888 | 889 | set 890 | { 891 | return, this.GuiName 892 | } 893 | } 894 | 895 | OnClose[] 896 | { 897 | Get 898 | { 899 | return, this.Handlers.OnClose.MaxIndex 900 | } 901 | 902 | Set 903 | { 904 | return, this.Handlers.OnClose.Push(value) 905 | } 906 | } 907 | 908 | OnContextMenu[] 909 | { 910 | Get 911 | { 912 | return, this.Handlers.OnContextMenu.MaxIndex 913 | } 914 | 915 | Set 916 | { 917 | return, this.Handlers.OnContextMenu.Push(value) 918 | } 919 | } 920 | 921 | OnDropFiles[] 922 | { 923 | Get 924 | { 925 | return, this.Handlers.OnDropFiles.MaxIndex 926 | } 927 | 928 | Set 929 | { 930 | return, this.Handlers.OnDropFiles.Push(value) 931 | } 932 | } 933 | 934 | OnEscape[] 935 | { 936 | Get 937 | { 938 | return, this.Handlers.OnEscape.MaxIndex 939 | } 940 | 941 | Set 942 | { 943 | return, this.Handlers.OnEscape.Push(value) 944 | } 945 | } 946 | 947 | OnSize[] 948 | { 949 | Get 950 | { 951 | return, this.Handlers.OnSize.MaxIndex 952 | } 953 | 954 | Set 955 | { 956 | return, this.Handlers.OnSize.Push(value) 957 | } 958 | } 959 | } 960 | 961 | class ManagedButton extends ManagedControl 962 | { 963 | } 964 | 965 | class ManagedText extends ManagedControl 966 | { 967 | } 968 | 969 | class ManagedEdit extends ManagedControl 970 | { 971 | } 972 | 973 | class ManagedUpDown extends ManagedControl 974 | { 975 | } 976 | 977 | class ManagedPicture extends ManagedControl 978 | { 979 | } 980 | 981 | class ManagedCheckBox extends ManagedControl 982 | { 983 | } 984 | 985 | class ManagedRadio extends ManagedControl 986 | { 987 | } 988 | 989 | class ManagedDropDownList extends ManagedControl 990 | { 991 | } 992 | 993 | class ManagedComboBox extends ManagedControl 994 | { 995 | } 996 | 997 | class ManagedListBox extends ManagedControl 998 | { 999 | } 1000 | 1001 | class ManagedLink extends ManagedControl 1002 | { 1003 | } 1004 | 1005 | class ManagedHotkey extends ManagedControl 1006 | { 1007 | } 1008 | 1009 | class ManagedDateTime extends ManagedControl 1010 | { 1011 | } 1012 | 1013 | class ManagedMonthCal extends ManagedControl 1014 | { 1015 | } 1016 | 1017 | class ManagedSlider extends ManagedControl 1018 | { 1019 | } 1020 | 1021 | class ManagedProgress extends ManagedControl 1022 | { 1023 | } 1024 | 1025 | class ManagedGroupBox extends ManagedControl 1026 | { 1027 | } 1028 | 1029 | class ManagedTab2 extends ManagedControl 1030 | { 1031 | } 1032 | 1033 | class ManagedStatusBar extends ManagedControl 1034 | { 1035 | } 1036 | 1037 | class ManagedActiveX extends ManagedControl 1038 | { 1039 | __New(ControlHwnd, Name, vVar, GetEvents="", GetData="") 1040 | { 1041 | base.__New(ControlHwnd, Name, vVar, GetEvents, GetData) 1042 | this.EmbeddedControl:=%vVar% 1043 | } 1044 | } 1045 | 1046 | class ManagedCustom extends ManagedControl 1047 | { 1048 | } 1049 | 1050 | class ManagedListView extends ManagedControl 1051 | { 1052 | Add(param*) 1053 | { 1054 | return LV_Add(param*) 1055 | } 1056 | 1057 | Delete(param*) 1058 | { 1059 | return LV_Delete(param*) 1060 | } 1061 | 1062 | DeleteCol(ColumnNumber) 1063 | { 1064 | return LV_DeleteCol(ColumnNumber) 1065 | } 1066 | 1067 | GetCount(param*) 1068 | { 1069 | return LV_GetCount(param*) 1070 | } 1071 | 1072 | GetNext(param*) 1073 | { 1074 | return LV_GetNext(param*) 1075 | } 1076 | 1077 | GetText(byref OutputVar, RowNumber, param*) 1078 | { 1079 | return LV_GetText(OutputVar, RowNumber, param*) 1080 | } 1081 | 1082 | Insert(RowNumber, param*) 1083 | { 1084 | return LV_Insert(RowNumber, param*) 1085 | } 1086 | 1087 | InsertCol(ColumnNumber, param*) 1088 | { 1089 | return LV_InsertCol(ColumnNumber, param*) 1090 | } 1091 | 1092 | Modify(RowNumber, Options, NewCol*) 1093 | { 1094 | return LV_Modify(RowNumber, Options, NewCol*) 1095 | } 1096 | 1097 | ModifyCol(param*) 1098 | { 1099 | return LV_ModifyCol(param*) 1100 | } 1101 | 1102 | SetImageList(ImageListID, param*) 1103 | { 1104 | return LV_SetImageList(ImageListID, Option) 1105 | } 1106 | } 1107 | 1108 | class ManagedExtendedTreeView extends ManagedTreeView 1109 | { 1110 | Resources:=Object() 1111 | 1112 | Add(Name, ParentItemID=0, Options="", Resource="") 1113 | { 1114 | Item:=base.Add(Name, ParentItemID, Options) 1115 | this.Resources[Item]:=Object() 1116 | this.Resources[Item]["Depth"]:=this.Resources[ParentItemID]["Depth"]+1 1117 | this.Resources[Item]["Name"]:=Name 1118 | this.Resources[Item]["Resource"]:=Resource 1119 | return Item 1120 | } 1121 | 1122 | FindInName(SearchText, addline=1) 1123 | { 1124 | fr:=TV_GetSelection() 1125 | frs:=fr 1126 | Loop, %addline% 1127 | { 1128 | frs:=TV_GetNext(frs, "Full") 1129 | } 1130 | found:=0 1131 | while (frs<>0) 1132 | { 1133 | TV_GetText(Output, frs) 1134 | if (InStr(Output, SearchText)) 1135 | { 1136 | found:=1 1137 | break 1138 | } 1139 | frs:=TV_GetNext(frs, "Full") 1140 | } 1141 | if (!found) 1142 | { 1143 | frs:=TV_GetNext() 1144 | while (frs<>fr) 1145 | { 1146 | TV_GetText(Output, frs) 1147 | if (InStr(Output, SearchText)) 1148 | { 1149 | found:=1 1150 | break 1151 | } 1152 | frs:=TV_GetNext(frs, "Full") 1153 | } 1154 | } 1155 | if (found) 1156 | { 1157 | return frs 1158 | } 1159 | else 1160 | { 1161 | return 0 1162 | } 1163 | } 1164 | 1165 | GetResource(Item=0) 1166 | { 1167 | return Reources[Item]["Resource"] 1168 | } 1169 | 1170 | GetDepth(Item=0) 1171 | { 1172 | return Reources[Item]["Depth"] 1173 | } 1174 | 1175 | Modify(ItemID, Options="", NewName="") 1176 | { 1177 | If (NewName<>"") 1178 | { 1179 | this.Resources[ItemID]["Name"]:=NewName 1180 | } 1181 | return TV_Modify(ItemID, Options, NewName) 1182 | } 1183 | 1184 | } 1185 | 1186 | class ManagedTreeView extends ManagedControl 1187 | { 1188 | Add(Name, ParentItemID=0, Options="") 1189 | { 1190 | return TV_Add(Name, ParentItemID, Options) 1191 | } 1192 | 1193 | Delete(ItemID="") 1194 | { 1195 | return TV_Delete(ItemID) 1196 | } 1197 | 1198 | Get(ItemID, Attribute="") 1199 | { 1200 | return TV_Get(ItemID, Attribute) 1201 | } 1202 | 1203 | GetChild(ParentItemID) 1204 | { 1205 | return TV_GetChild(ParentItemID) 1206 | } 1207 | 1208 | GetCount() 1209 | { 1210 | return TV_GetCount() 1211 | } 1212 | 1213 | GetNext(ItemID=0, Attribute="") 1214 | { 1215 | return TV_GetNext(ItemID, Attribute) 1216 | } 1217 | 1218 | GetParent(ItemId) 1219 | { 1220 | return TV_GetParent(ItemId) 1221 | } 1222 | 1223 | GetPrev(ItemID) 1224 | { 1225 | return TV_GetPrev(ItemID) 1226 | } 1227 | 1228 | GetSelection() 1229 | { 1230 | return TV_GetSelection() 1231 | } 1232 | 1233 | GetText(byref OutputVar, ItemID) 1234 | { 1235 | return TV_GetText(OutputVar, ItemID) 1236 | } 1237 | 1238 | Modify(ItemID, Options="", NewName="") 1239 | { 1240 | return TV_Modify(ItemID, Options, NewName) 1241 | } 1242 | } 1243 | 1244 | class ManagedControl 1245 | { 1246 | MoveMode:="Move" 1247 | 1248 | __New(ControlHwnd, Name, vVar="", GetEvents="", GetData="") 1249 | { 1250 | this.HWND:=ControlHwnd 1251 | this.Name:=Name 1252 | this.Type:=SubStr(this.__Class,8) 1253 | this.SendEvents:=GetEvents 1254 | this.SubmitTo:=GetData 1255 | this.Var:=vVar 1256 | } 1257 | 1258 | Control(SubCommand="", Param3="") 1259 | { 1260 | GuiControl, %SubCommand%, % this.HWND, %Param3% 1261 | } 1262 | 1263 | ControlGet(SubCommand="", Param4="") 1264 | { 1265 | GuiControlGet, OutputVar, %SubCommand%, % this.HWND, %Param4% 1266 | If (SubCommand="Pos") 1267 | { 1268 | TempOut:=Object() 1269 | tempOut.X:=OutputVarX 1270 | tempOut.Y:=OutputVarY 1271 | tempOut.W:=OutputVarW 1272 | tempOut.H:=OutputVarH 1273 | } 1274 | else 1275 | return OutputVar 1276 | } 1277 | } 1278 | 1279 | 1280 | ManagedControlEventHandler(CtrlHwnd="", GuiEvent="", EventInfo="", ErrorLvl="") 1281 | { 1282 | global GuiManagerCallback 1283 | GuiManagerCallback.ControlEvent(CtrlHwnd, GuiEvent, EventInfo, ErrorLvl) 1284 | } 1285 | 1286 | GuiClose(GuiHwnd) 1287 | { 1288 | global GuiManagerCallback 1289 | return, GuiManagerCallback.Close(GuiHwnd) 1290 | } 1291 | 1292 | GuiEscape(GuiHwnd) 1293 | { 1294 | global GuiManagerCallback 1295 | return, GuiManagerCallback.Escape(GuiHwnd) 1296 | } 1297 | 1298 | GuiSize(GuiHwnd, EventInfo, Width, Height) 1299 | { 1300 | global GuiManagerCallback 1301 | return, GuiManagerCallback.Size(GuiHwnd, EventInfo, Width, Height) 1302 | } 1303 | 1304 | GuiContextMenu(GuiHwnd, CtrlHwnd, EventInfo, IsRightClick, X, Y) 1305 | { 1306 | global GuiManagerCallback 1307 | return, GuiManagerCallback.ContextMenu(GuiHwnd, CtrlHwnd, EventInfo, IsRightClick, X, Y) 1308 | } 1309 | 1310 | GuiDropFiles(GuiHwnd, FileArray, CtrlHwnd, X, Y) 1311 | { 1312 | global GuiManagerCallback 1313 | return, GuiManagerCallback.DropFiles(GuiHwnd, FileArray, CtrlHwnd, X, Y) 1314 | } 1315 | 1316 | /* 1317 | 1318 | Gui commands: 1319 | ------------- 1320 | 1321 | GuiCreate([Title, Options, FuncPrefixOrObj]) 1322 | Creates a new Gui object (Same as v1 Gui, New). 1323 | The third parameter specifies the function prefix or object to bind events to. 1324 | If a function prefix is specified, Gui events such as OnClose or OnDropFiles are automatically bound. 1325 | If an object is specified, it is used as an event sink; meaning event names are used as method names 1326 | to invoke on the object. 1327 | This mechanism is both similar to that of ComObjConnect() and the old v1 +Label system. 1328 | 1329 | GuiFromHwnd(Hwnd [, RecurseParent := false]) 1330 | Returns the Gui object associated with the specified Gui HWND. 1331 | If RecurseParent is true, the closest parent to the specified HWND that is a Gui is automatically 1332 | searched for and retrieved. 1333 | 1334 | GuiCtrlFromHwnd(Hwnd) 1335 | Returns the Gui Control object associated with the specified Gui Control HWND. 1336 | 1337 | Gui object: 1338 | ----------- 1339 | 1340 | gui.Destroy() 1341 | Destroys the window. Same as v1 Gui, Destroy. 1342 | If the Gui is closed and there are no references to the Gui object, the Gui is destroyed. 1343 | 1344 | gui.Add(Ctrl [, Text, Options]) 1345 | gui.AddCtrl([Text, Options]) where Ctrl is a valid control type 1346 | Adds a new control to the Gui. (Text was renamed to Label). 1347 | In v1.x, some control types such as ListView accept a string with a changeable delimiter (by default |). 1348 | In v2, arrays are also supported, and this obviates the need to support changing the delimiter. 1349 | The g-label option now specifies the function or method name to call in order to receive 1350 | events from the control (equivalent to v1 g-labels). 1351 | The 'v' option is now repurposed to give an explicit name to the control, instead of binding a variable. 1352 | For Button controls, if the g-label is omitted, the same v1 transformation rules are applied to 1353 | automatically generate a function or method name (expanded to accomodate for stricter identifier 1354 | names). 1355 | Returns a GuiControl object. 1356 | 1357 | gui.Show([Options, Title]) 1358 | Same as v1 Gui, Show 1359 | 1360 | gui.Submit([Hide := false]) 1361 | Returns an associative array containing the values of all the controls that have been explicitly named. 1362 | Similar to v1 Gui, Submit 1363 | 1364 | gui.Hide() 1365 | gui.Cancel() 1366 | Same as v1 Gui, Hide (Cancel) 1367 | 1368 | gui.SetFont([Options, FontName]) 1369 | Same as v1 Gui, Font 1370 | 1371 | gui.BgColor := color 1372 | gui.CtrlColor := color 1373 | Same as v1 Gui, Color 1374 | 1375 | gui.MarginX := value 1376 | gui.MarginY := value 1377 | Same as v1 Gui, Margin 1378 | 1379 | gui.Opt(options) 1380 | gui.Options(options) 1381 | Same as v1 Gui +/-Option1 +/-Option2 1382 | 1383 | gui.Menu := menuObj 1384 | Same as v1 Gui, Menu 1385 | 1386 | gui.Hide() 1387 | gui.Minimize() 1388 | gui.Maximize() 1389 | gui.Restore() 1390 | Same as v1 Gui, Hide/Minimize/Maximize/Restore 1391 | 1392 | gui.Flash([onOrOff := true]) 1393 | Same as v1 Gui, Flash [, Off] 1394 | 1395 | gui.Hwnd 1396 | Retrieves the Gui's Hwnd 1397 | 1398 | gui.Title 1399 | Sets or retrieves the Gui's title 1400 | 1401 | gui.Control[Name] 1402 | Retrieves the GuiControl object associated with the specified name, ClassNN or HWND. 1403 | Compare: 1404 | GuiControl,, Static1, SomeValue 1405 | gui.Control["Static1"].Value := "SomeValue" 1406 | 1407 | gui._NewEnum() 1408 | Iterates through the Gui's controls. 1409 | The first output variable is the HWND, and the second is the control object. 1410 | 1411 | gui.OnClose 1412 | gui.OnEscape 1413 | gui.OnSize 1414 | gui.OnContextMenu 1415 | gui.OnDropFiles 1416 | These properties can be get/set in order to change the event handlers, especially for 1417 | binding an arbitrary callable object. 1418 | 1419 | Events: 1420 | 1421 | OnClose(gui) 1422 | OnEscape(gui) 1423 | OnSize(gui, eventInfo, width, height) 1424 | OnContextMenu(gui, control, eventInfo, isRightClick, x, y) 1425 | OnDropFiles(gui, fileArray, control, x, y) 1426 | 1427 | OnClose now has a return value. If OnClose() returns a false value (such as nothing), the Gui is closed 1428 | (as if the OnClose event handler did not exist). If it returns a true value, the Gui is not closed. 1429 | 1430 | GuiControl object 1431 | ----------------- 1432 | 1433 | ctrl.Type 1434 | Retrieves the type of the control. (Not implemented yet) 1435 | 1436 | ctrl.Hwnd 1437 | Retrieves the HWND of the control. 1438 | 1439 | ctrl.Name 1440 | Retrieves or sets the explicit name of the control. 1441 | 1442 | ctrl.ClassNN 1443 | Retrieves the ClassNN of the control. 1444 | 1445 | ctrl.Gui 1446 | Retrieves the control's Gui parent. 1447 | 1448 | ctrl.Event 1449 | Retrieves or sets the control's event handler, which can be either a function/method name 1450 | or an arbitrary callable object. 1451 | 1452 | ctrl.Opt(options) 1453 | ctrl.Options(options) 1454 | Same as v1 GuiControl, +/-Option1 +/-Option2 1455 | 1456 | ctrl.Move(pos[, draw:=false]) 1457 | Same as v1 GuiControl Move(Draw) 1458 | 1459 | ctrl.Focus() 1460 | Same as v1 GuiControl Focus 1461 | 1462 | ctrl.Choose(Value [, additionalActions := 0]) 1463 | Same as v1 GuiControl Choose(String). If Value is a pure integer, it is an item index; 1464 | otherwise it is treated as the item text. additionalActions replaces the pipe-prepending 1465 | mechanism of the v1 command (instead of prepending N pipes, this parameter is set to N). 1466 | 1467 | ctrl.UseTab([Value, exactMatch := false]) 1468 | Same as v1 Gui Tab. If Value is a pure intege, it is a tab index; otherwise it is text. 1469 | Omit all parameters to stop adding controls inside this Tab control. 1470 | 1471 | ctrl.Value 1472 | Same as v1 GuiControl/Get with no subcommand 1473 | 1474 | ctrl.Text 1475 | Same as v1 GuiControl/Get Text 1476 | 1477 | ctrl.Enabled 1478 | Specifies whether the user can interact with the control 1479 | 1480 | ctrl.Visible 1481 | Same as v1 GuiControl/Get Visible 1482 | 1483 | ctrl.Focused 1484 | Same as v1 GuiControlGet Focused 1485 | 1486 | ctrl.Pos 1487 | Returns the position in an object containing x,y,w,h fields. 1488 | 1489 | Control event function: 1490 | ControlEvent(ctrl, guiEvent, eventInfo, extra) 1491 | The 'extra' parameter is only passed on Link or Custom control events. 1492 | 1493 | LV_/TV_/SB_ functions are now methods of LV/TV/SB control objects. 1494 | 1495 | tv.GetText() and lv.GetText() now return the text directly instead of having an 1496 | OutputVar (failure results in an exception being thrown). 1497 | 1498 | ------------------------------------------------------------------------------- 1499 | 1500 | ; Converted Example: Simple image viewer: 1501 | 1502 | GuiCreate gui, ImageViewer, Resize, MyGui_ 1503 | gui.AddButton &Load New Image, Default 1504 | radio := gui.AddRadio("Load &actual size", "ym+5 x+10 checked") 1505 | gui.AddRadio Load to &fit screen, ym+5 x+10 1506 | pic := gui.AddPic(, "xm") 1507 | gui.Show() 1508 | 1509 | ; Due to v2's Persistence rules, it is no longer necessary to include a 1510 | ; GuiClose() { ExitApp } event handler in order for the script to properly close. 1511 | 1512 | MyGui_ButtonLoadNewImage() ; using automatic event handler name 1513 | { 1514 | global gui, radio, pic 1515 | FileSelect file, a,, Select an image:, Images (*.gif; *.jpg; *.bmp; *.png; *.tif; *.ico; *.cur; *.ani; *.exe; *.dll) 1516 | if !file 1517 | return 1518 | if radio.Value = 1 ; Display image at its actual size. 1519 | { 1520 | Width := 0 1521 | Height := 0 1522 | } 1523 | else ; Second radio is selected: Resize the image to fit the screen. 1524 | { 1525 | Width := A_ScreenWidth - 28 ; Minus 28 to allow room for borders and margins inside. 1526 | Height := -1 ; "Keep aspect ratio" seems best. 1527 | } 1528 | pic.Value := "*w%width% *h%height% %file%" ; Load the image. 1529 | gui.Show xCenter y0 AutoSize, %file% - Image Viewer ; Resize the window to match the picture size. 1530 | } 1531 | 1532 | ----------------------------------------------------------------------- 1533 | 1534 | ; Converted Example: A moving progress bar overlayed on a background image. 1535 | 1536 | GuiCreate gui, Progress Example,, MyGui_ 1537 | gui.BgColor := "White" 1538 | gui.AddPicture %A_WinDir%\system32\ntimage.gif, x0 y0 h350 w450 1539 | gui.AddButton Start the Bar Moving, Default xp+20 yp+250 1540 | MyProgress := gui.AddProgress(, "w416") 1541 | MyText := gui.AddLabel(, "wp") ; wp means "use width of previous". 1542 | gui.Show() 1543 | 1544 | MyGui_ButtonStartTheBarMoving() 1545 | { 1546 | global MyProgress, MyText 1547 | Loop Files, %A_WinDir%\*.* 1548 | { 1549 | if A_Index > 100 1550 | break 1551 | MyProgress.Value := A_Index 1552 | MyText.Value := A_LoopFileName 1553 | Sleep 50 1554 | } 1555 | MyText.Value := "Bar finished." 1556 | } 1557 | -------------------------------------------------------------------------------- /Libraries/ManagedResources.ahk: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Version: MPL 2.0/GPL 3.0/LGPL 3.0 4 | 5 | The contents of this file are subject to the Mozilla Public License Version 6 | 2.0 (the "License"); you may not use this file except in compliance with 7 | the License. You may obtain a copy of the License at 8 | 9 | http://www.mozilla.org/MPL/ 10 | 11 | Software distributed under the License is distributed on an "AS IS" basis, 12 | WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 13 | for the specific language governing rights and limitations under the License. 14 | 15 | The Initial Developer of the Original Code is 16 | Elgin . 17 | Portions created by the Initial Developer are Copyright (C) 2010-2017 18 | the Initial Developer. All Rights Reserved. 19 | 20 | Contributor(s): 21 | 22 | Alternatively, the contents of this file may be used under the terms of 23 | either the GNU General Public License Version 3 or later (the "GPL"), or 24 | the GNU Lesser General Public License Version 3.0 or later (the "LGPL"), 25 | in which case the provisions of the GPL or the LGPL are applicable instead 26 | of those above. If you wish to allow use of your version of this file only 27 | under the terms of either the GPL or the LGPL, and not to allow others to 28 | use your version of this file under the terms of the MPL, indicate your 29 | decision by deleting the provisions above and replace them with the notice 30 | and other provisions required by the GPL or the LGPL. If you do not delete 31 | the provisions above, a recipient may use your version of this file under 32 | the terms of any one of the MPL, the GPL or the LGPL. 33 | 34 | */ 35 | 36 | ; ============================================================================== 37 | ; ============================================================================== 38 | ; class ManagedResourcesClass 39 | ; ============================================================================== 40 | ; ============================================================================== 41 | 42 | class ManagedResourcesClass 43 | { 44 | Resources:=Object() 45 | 46 | __New(ResourceFile, Language="English", DefaultLanguage="English") 47 | { 48 | this.Language:=Language 49 | this.DefaultLanguage:=DefaultLanguage 50 | IfExist, %ResourceFile% 51 | { 52 | ObjLoad(this.Resources, ResourceFile) 53 | } 54 | else 55 | { 56 | Throw, "Resource file not found: " ResourceFile 57 | } 58 | } 59 | 60 | __Get(ResName) 61 | { 62 | If (TryKey(this.Resources, "Common", ResName)) 63 | return, this.Resources["Common"][ResName] 64 | else 65 | If (TryKey(this.Resources, this.Language, ResName)) 66 | return, this.Resources[this.Language][ResName] 67 | else 68 | If (TryKey(this.Resources, this.DefaultLanguage, ResName)) 69 | return, this.Resources[this.DefaultLanguage][ResName] 70 | else 71 | { 72 | Throw, "Undefined resource: " ResName 73 | ListLines 74 | } 75 | } 76 | 77 | __Set() 78 | { 79 | } 80 | 81 | } 82 | 83 | ; ============================================================================== 84 | ; ============================================================================== 85 | ; class ManagedVariableClass 86 | ; ============================================================================== 87 | ; ============================================================================== 88 | 89 | class ManagedVariableClass 90 | { 91 | 92 | __New(IniFile="", Section="Main") 93 | { 94 | ManagedVariableClass.hidden[this]:= { Values: [], Vars: [], Consts: [], Inis: []} 95 | ManagedVariableClass.hidden[this].Inis.DefaultIniFilePath:=IniFile 96 | ManagedVariableClass.hidden[this].Inis.DefaultIniSection:=Section 97 | ManagedVariableClass.hidden[this].Inis.INIValues:=Object() 98 | } 99 | 100 | __Get(VarName) 101 | { 102 | If (ManagedVariableClass.hidden[this].Values.HasKey(VarName)) 103 | return, ManagedVariableClass.hidden[this].Values[VarName] 104 | else 105 | { 106 | Throw, "Read from undefined variable: " VarName 107 | ListLines 108 | } 109 | } 110 | 111 | _NewEnum() 112 | { 113 | return, ManagedVariableClass.hidden[this].Values._NewEnum() 114 | } 115 | 116 | __Set(VarName, byref Value) 117 | { 118 | If (ManagedVariableClass.hidden[this].Consts.HasKey(VarName)) 119 | { 120 | Throw, "Attempt to write to constant: " VarName 121 | return 122 | } 123 | else If (ManagedVariableClass.hidden[this].Inis.INIValues.HasKey(VarName)) 124 | { 125 | If (ManagedVariableClass.hidden[this].Inis.INIValues[VarName]["Type"]<>"") 126 | { 127 | If Value is not % ManagedVariableClass.hidden[this].Inis.INIValues[VarName]["Type"] 128 | throw "Invalid type set for variable: " VarName ". Type must be " ManagedVariableClass.hidden[this].Inis.INIValues[VarName]["Type"] ". Attempted to set to: " Value 129 | If (ManagedVariableClass.hidden[this].Inis.INIValues[VarName]["MinValue"]<>"") 130 | { 131 | If (ManagedVariableClass.hidden[this].Inis.INIValues[VarName]["MinValue"]=" " and Value="") 132 | { 133 | Value:=ManagedVariableClass.hidden[this].Inis.INIValues[VarName]["DefaultValue"] 134 | } 135 | else 136 | If (Value"" and Value>ManagedVariableClass.hidden[this].Inis.INIValues[VarName]["MaxValue"]) 142 | { 143 | Value:=ManagedVariableClass.hidden[this].Inis.INIValues[VarName]["MaxValue"] 144 | } 145 | } 146 | If (ManagedVariableClass.hidden[this].Inis.INIValues[VarName].HasKey("File")) 147 | File:=ManagedVariableClass.hidden[this].Inis.INIValues[VarName]["File"] 148 | else 149 | File:=ManagedVariableClass.hidden[this].Inis.DefaultIniFilePath 150 | If (ManagedVariableClass.hidden[this].Inis.INIValues[VarName].HasKey("Section")) 151 | Section:=ManagedVariableClass.hidden[this].Inis.INIValues[VarName]["Section"] 152 | else 153 | Section:=ManagedVariableClass.hidden[this].Inis.DefaultIniSection 154 | If (File<>"") 155 | { 156 | IniWrite, %Value%, %File%, %Section%, %VarName% 157 | } 158 | ManagedVariableClass.hidden[this].Values[VarName]:=Value 159 | return Value 160 | } 161 | else 162 | { 163 | ManagedVariableClass.hidden[this].Values[VarName]:=Value 164 | ManagedVariableClass.hidden[this].Vars[VarName]:=1 165 | return, Value 166 | } 167 | } 168 | 169 | HasKey(Key) ; 0 not found, 1 constant, 2 ini, 3 variable 170 | { 171 | If (ManagedVariableClass.hidden[this].Consts.HasKey(Key)) 172 | return, 1 173 | else 174 | If (ManagedVariableClass.hidden[this].Inis.INIValues.HasKey(Key)) 175 | return, 2 176 | else 177 | If (ManagedVariableClass.hidden[this].Vars.HasKey(Key)) 178 | return, 3 179 | else 180 | return, 0 181 | } 182 | 183 | SetConstant(VarName, byref Value) 184 | { 185 | If (ManagedVariableClass.hidden[this].Consts.HasKey(VarName)) 186 | { 187 | Throw, "Attempt to write to constant: " VarName 188 | return 189 | } 190 | else 191 | { 192 | ManagedVariableClass.hidden[this].Consts[VarName]:=1 193 | ManagedVariableClass.hidden[this].Values[VarName]:=Value 194 | return, value 195 | } 196 | } 197 | 198 | CreateIni(VarName, DefaultValue, IniSection="", IniFile="", Type="", MinValue="", MaxValue="") ; MinValue, MaxValue for numbers, setting MinValue to " " means it must not be empty 199 | { 200 | If (ManagedVariableClass.hidden[this].Consts.HasKey(VarName)) 201 | { 202 | Throw, "Attempt to overload constant: " VarName 203 | return 204 | } 205 | else 206 | { 207 | If (IniFile<>"") 208 | ReadFile:=IniFile 209 | else 210 | ReadFile:=ManagedVariableClass.hidden[this].Inis.DefaultIniFilePath 211 | If (IniSection<>"") 212 | ReadSection:=IniSection 213 | else 214 | ReadSection:=ManagedVariableClass.hidden[this].Inis.DefaultIniSection 215 | If (ReadFile<>"") 216 | { 217 | IniRead, Value, %ReadFile%, %ReadSection%, %VarName%, EMPTYVALUE 218 | If (Value="EMPTYVALUE") 219 | { 220 | IniWrite, %DefaultValue%, %ReadFile%, %ReadSection%, %VarName% 221 | Value:=DefaultValue 222 | } 223 | If (Type<>"") 224 | If Value is not %Type% 225 | Value:=DefaultValue 226 | If (MinValue<>"") 227 | { 228 | If (MinValue=" " and Value="") 229 | { 230 | Value:=DefaultValue 231 | } 232 | else 233 | If (Value"" and Value<>"" and Value>MaxValue) 239 | { 240 | Value:=DefaultValue 241 | } 242 | ManagedVariableClass.hidden[this].Inis.INIValues[VarName]:=Object() 243 | ManagedVariableClass.hidden[this].Values[VarName]:=Value 244 | If (IniFile<>"") 245 | ManagedVariableClass.hidden[this].Inis.INIValues[VarName]["File"]:=IniFile 246 | If (IniSection<>"") 247 | ManagedVariableClass.hidden[this].Inis.INIValues[VarName]["Section"]:=IniSection 248 | If (Type<>"") 249 | ManagedVariableClass.hidden[this].Inis.INIValues[VarName]["Type"]:=Type 250 | If (MinValue<>"") 251 | ManagedVariableClass.hidden[this].Inis.INIValues[VarName]["MinValue"]:=MinValue 252 | If (MaxValue<>"") 253 | ManagedVariableClass.hidden[this].Inis.INIValues[VarName]["MaxValue"]:=MaxValue 254 | ManagedVariableClass.hidden[this].Inis.INIValues[VarName]["DefaultValue"]:=DefaultValue 255 | return Value 256 | } 257 | else 258 | Throw, "Error creating ini variable " VarName " : No ini file defined. Variable will not be defined." 259 | } 260 | } 261 | 262 | GetIniFilePath(VarName) 263 | { 264 | If (ManagedVariableClass.hidden[this].Inis.INIValues.HasKey(VarName)) 265 | { 266 | rval:=Object() 267 | If (ManagedVariableClass.hidden[this].Inis.INIValues[VarName].HasKey("File")) 268 | rval.File:=ManagedVariableClass.hidden[this].Inis.INIValues[VarName]["File"] 269 | else 270 | rval.File:=ManagedVariableClass.hidden[this].Inis.DefaultIniFilePath 271 | If (ManagedVariableClass.hidden[this].Inis.INIValues[VarName].HasKey("Section")) 272 | rval.Section:=ManagedVariableClass.hidden[this].Inis.INIValues[VarName]["Section"] 273 | else 274 | rval.Section:=ManagedVariableClass.hidden[this].Inis.DefaultIniSection 275 | return, rval 276 | } 277 | else 278 | return, "" 279 | } 280 | 281 | __Delete() 282 | { 283 | this.Delete("Values") 284 | this.Delete("Vars") 285 | this.Delete("Consts") 286 | this.Delete("Inis") 287 | } 288 | } 289 | -------------------------------------------------------------------------------- /Libraries/ObjectHandling.ahk: -------------------------------------------------------------------------------- 1 | ; ============================================================================== 2 | ; ============================================================================== 3 | ; Object handling functions 4 | ; 5 | ; object EnsureObj(BaseObject, params*) 6 | ; boolean TryKey(BaseObject, params*) 7 | ; boolean TryObj(ByRef BaseObject, params*) 8 | ; integer ObjGetCount(BaseObject) 9 | ; ObjMerge(SourceObject, TargetObject, Mode="", CallBack="") 10 | ; 11 | ; string ObjToStr(ByRef InObject) 12 | ; string ObjToXML(InObject) 13 | ; XMLToObj(BaseObject, InString) 14 | ; 15 | ; ObjLoad(BaseObject, FileName) 16 | ; ObjSave(InObject, FileName, Mode="w") 17 | ; 18 | ; ============================================================================== 19 | ; ============================================================================== 20 | 21 | #Include StringHandling.ahk 22 | 23 | ; ============================================================================== 24 | ; ============================================================================== 25 | ; object EnsureObj(BaseObject, params*) 26 | ; creates an object following params* from the base object 27 | ; Example: 28 | ; EnsureObj(BS, "Level1", "Level2", "Level3") 29 | ; creates: 30 | ; BS["Level1"]["Level2"]["Level3"] = Object() 31 | ; if it did not previously exist 32 | ; ============================================================================== 33 | ; ============================================================================== 34 | 35 | EnsureObj(BaseObject, Params*) 36 | { 37 | If !(IsObject(BaseObject)) 38 | BaseObject:=Object() 39 | TempBase:=BaseObject 40 | for Index, Param in Params 41 | { 42 | If !(TempBase.HasKey(param)) or !(IsObject(TempBase[Param])) 43 | TempBase[Param]:=Object() 44 | TempBase:=TempBase[Param] 45 | } 46 | return, TempBase 47 | } 48 | 49 | ; ============================================================================== 50 | ; ============================================================================== 51 | ; boolean TryKey(BaseObject, params*) 52 | ; tests if a key following params* from the base object exists 53 | ; Example: 54 | ; TryObject(BS, "Level1", "Level2", "Level3") 55 | ; returns true if: 56 | ; BS["Level1"]["Level2"]["Level3"] exists 57 | ; ============================================================================== 58 | ; ============================================================================== 59 | 60 | TryKey(BaseObject, Params*) 61 | { 62 | If !(IsObject(BaseObject)) 63 | return, 0 64 | TempBase:=BaseObject 65 | for Index,Param in Params 66 | { 67 | If (Index=Params.MaxIndex()) 68 | { 69 | If (!TempBase.HasKey(Param)) 70 | return, 0 71 | } 72 | else 73 | If !(TempBase.HasKey(Param)) or !(IsObject(TempBase[Param])) 74 | return, 0 75 | TempBase:=TempBase[Param] 76 | } 77 | return, 1 78 | } 79 | 80 | ; ============================================================================== 81 | ; ============================================================================== 82 | ; boolean TryObj(ByRef BaseObject, params*) 83 | ; tests if an object following params* from the base object exists 84 | ; Example: 85 | ; TryObj(BS, "Level1", "Level2", "Level3") 86 | ; returns true if: 87 | ; BS["Level1"]["Level2"]["Level3"] = Object() 88 | ; exists 89 | ; ============================================================================== 90 | ; ============================================================================== 91 | 92 | TryObj(BaseObject, Params*) 93 | { 94 | If !(IsObject(BaseObject)) 95 | return, 0 96 | TempBase:=BaseObject 97 | for Index,Param in Params 98 | { 99 | If !(TempBase.HasKey(Param)) or !(IsObject(TempBase[Param])) 100 | return, 0 101 | TempBase:=TempBase[Param] 102 | } 103 | return, 1 104 | } 105 | 106 | ; ============================================================================== 107 | ; ============================================================================== 108 | ; integer ObjGetCount(BaseObject) 109 | ; return the number of keys in an object 110 | ; ============================================================================== 111 | ; ============================================================================== 112 | 113 | ObjGetCount(BaseObject) 114 | { 115 | If !(IsObject(BaseObject)) 116 | return, 0 117 | cnt:=0 118 | for Index in BaseObject 119 | { 120 | cnt++ 121 | } 122 | return, cnt 123 | } 124 | 125 | ; ============================================================================== 126 | ; ============================================================================== 127 | ; ObjMerge(SourceObject, TargetObject, Mode="", CallBack="") 128 | ; merges contents of SourceObject into TargetObject 129 | ; Mode: w - overwrite, s - skip, else - warn through CallBack function 130 | ; Callback should return: 131 | ; -1: skip all 132 | ; 0: skip one 133 | ; 1: overwrite one 134 | ; 2: overwrite all 135 | ; ============================================================================== 136 | ; ============================================================================== 137 | 138 | ObjMerge(SourceObject, TargetObject, Mode="", CallBack="") 139 | { 140 | CBResultSave:=0 141 | for Index, Value in SourceObject 142 | { 143 | if (IsObject(Value)) 144 | { 145 | If (!TargetObject.HasKey(Index)) 146 | TargetObject[Index]:=Object() 147 | ObjMerge(Value,TargetObject[Index], Mode, CallBack) 148 | } 149 | else 150 | { 151 | If (Mode="w") 152 | TargetObject[Index]:=Value 153 | else 154 | { 155 | If (Mode="s") 156 | { 157 | if (!TargetObject.Haskey(Index)) 158 | TargetObject[Index]:=Value 159 | } 160 | else 161 | { 162 | if (TargetObject.Haskey(Index) and CallBack<>"" and IsFunc(CallBack)) 163 | { 164 | If (CBResultSave<>0) 165 | { 166 | CBResult:=%CallBack%(Index, Value) 167 | } 168 | else 169 | CBResult:=CBResultSave 170 | If (CBResult=-1) 171 | { 172 | CBResultSave:=CBResult 173 | } 174 | else 175 | If (CBResult=2) 176 | { 177 | CBResultSave:=CBResult 178 | TargetObject[Index]:=Value 179 | } 180 | else 181 | If (CBResult=1) 182 | { 183 | TargetObject[Index]:=Value 184 | } 185 | } 186 | else 187 | TargetObject[Index]:=Value 188 | } 189 | } 190 | } 191 | } 192 | } 193 | 194 | ; ============================================================================== 195 | ; ============================================================================== 196 | ; string ObjToStr(ByRef InObject) 197 | ; attempts to output a string showing the structure and values of InObject 198 | ; ============================================================================== 199 | ; ============================================================================== 200 | 201 | ObjToStr(InObject, Depth=1) 202 | { 203 | OutStr:="" 204 | DepthString:="" 205 | Loop, % Depth-2 206 | DepthString.=" " 207 | If (Depth>1) 208 | DepthString.="└ " 209 | DepthStringVal:= DepthString "└ " 210 | try 211 | { 212 | For Index, Value in InObject 213 | { 214 | If (IsObject(Value)) 215 | { 216 | OutStr.=DepthString Index "`r`n" 217 | OutStr.=ObjToStr(Value, Depth+1) 218 | } 219 | else 220 | { 221 | if Value is number 222 | OutStr.=DepthString Index " := " Value "`r`n" 223 | else 224 | If (Value="") 225 | OutStr.=DepthString Index " := """"`r`n" 226 | else 227 | Loop, Parse, Value, `n, `r 228 | { 229 | If (A_Index=1) 230 | { 231 | OutStr.=DepthString Index " := " """" A_LoopField """`r`n" 232 | } 233 | else 234 | OutStr.=DepthStringVal """" A_LoopField """`r`n" 235 | } 236 | } 237 | } 238 | } 239 | catch 240 | { 241 | OutStr.=DepthString " Object cannot be enumerated.`r`n" 242 | } 243 | return, OutStr 244 | } 245 | 246 | ; ============================================================================== 247 | ; ============================================================================== 248 | ; void ObjToTreeView(InObject, FormatObj=0, MaxDepth=0) 249 | ; transfers data from InObject to the currently active TreeView control 250 | ; FormatObj can contain a callable reference to a function 251 | ; FormatCallBack(Depth, Index, Value) 252 | ; that returns and object with the following keys: 253 | ; Text : the text of the node or object holding treenodes to be added 254 | ; Options : the options for the node 255 | ; Add : 1 to add this node; 0 to ignore 256 | ; Continue : 1 to continue with the next index; 0 to stop 257 | ; RecurseInto : 1 to recurse into this object; 0 to stop (overrides MaxDepth) 258 | ; ============================================================================== 259 | ; ============================================================================== 260 | 261 | ObjToTreeView(InObject, FormatFunc=0, MaxDepth=0, Depth=1, Parent=0) 262 | { 263 | thisItem:=0 264 | try 265 | { 266 | For Index, Value in InObject 267 | { 268 | If (FormatFunc and ret:=%FormatFunc%(Depth, Index, Value)) 269 | { 270 | If (ret.Add) 271 | { 272 | If (IsObject(ret.Text)) 273 | { 274 | thisItem:=ObjToTreeView(ret.Text, 0, 0, 1, Parent) 275 | } 276 | else 277 | thisItem:=TV_Add(ret.Text, Parent, ret.Options) 278 | } 279 | else 280 | thisItem:=Parent 281 | If !(ret.Continue) 282 | break 283 | If (ret.RecurseInto) 284 | { 285 | If (IsObject(Value)) 286 | { 287 | ObjToTreeView(Value, FormatFunc, MaxDepth, Depth+1, thisItem) 288 | } 289 | else 290 | { 291 | if Value is number 292 | TV_Add(Value, thisItem) 293 | else 294 | TV_Add("""" Value """", thisItem) 295 | } 296 | } 297 | } 298 | else 299 | { 300 | thisItem:=TV_Add(Index, Parent) 301 | If (IsObject(Value) and (MaxDepth=0 or Depth`r`n" 342 | If (IsObject(Value)) 343 | { 344 | OutStr.=ObjToXML(Value, Depth+1) 345 | } 346 | else 347 | { 348 | if Value is number 349 | OutStr.=DepthStringVal Value "`r`n" 350 | else 351 | If (Value="") 352 | OutStr.=DepthStringVal """""`r`n" 353 | else 354 | Loop, Parse, Value, `n, `r 355 | { 356 | OutStr.=DepthStringVal """" EscapeVarStr(A_LoopField) """`r`n" 357 | } 358 | } 359 | OutStr.=DepthString "<\" Index ">`r`n" 360 | } 361 | } 362 | catch 363 | { 364 | OutStr.=DepthString " Object cannot be enumerated.`r`n" 365 | } 366 | return, OutStr 367 | } 368 | 369 | ; ============================================================================== 370 | ; ============================================================================== 371 | ; XMLToObj(BaseObject, InString) 372 | ; attempts to convert simplified XML InString into an object in BaseObject 373 | ; ============================================================================== 374 | ; ============================================================================== 375 | 376 | XMLToObj(BaseObject, InString) 377 | { 378 | Value:="" 379 | CurrentLevel:=1 380 | KeyStarted:=0 381 | LevelObjects:={} 382 | LevelObjects[1]:=BaseObject 383 | KeyChain:=Object() 384 | Loop, Parse, InString, `n, `r 385 | { 386 | Line:=Trim(A_LoopField) 387 | If (Instr(Line,"<\")=1) 388 | { 389 | starttag:=Keychain.Pop() 390 | If (starttag=Substr(Line, 3, -1)) 391 | { 392 | CurrentLevel-- 393 | If (KeyValue<>"") 394 | { 395 | LevelObjects[CurrentLevel][KeyName]:=KeyValue 396 | KeyValue:="" 397 | } 398 | } 399 | else 400 | { 401 | throw {message: "Error in input string: end tag " Substr(Line, 3, -1) " does not match start tag " starttag " in line " A_Index, line: A_Index} 402 | } 403 | } 404 | else If (Instr(Line,"<")=1) 405 | { 406 | KeyName:=Substr(Line, 2, -1) 407 | KeyChain.Push(KeyName) 408 | If not IsObject(LevelObjects[CurrentLevel][KeyName]) 409 | { 410 | LevelObjects[CurrentLevel][KeyName]:=Object() 411 | } 412 | CurrentLevel++ 413 | LevelObjects[CurrentLevel]:=LevelObjects[CurrentLevel-1][KeyName] 414 | KeyValue:="" 415 | } 416 | else 417 | { 418 | If (KeyValue<>"") 419 | KeyValue.="`r`n" 420 | If (InStr(Line,"""")=1) 421 | KeyValue.=UnEscapeVarStr(Line) 422 | } 423 | } 424 | } 425 | 426 | 427 | ; ============================================================================== 428 | ; ============================================================================== 429 | ; ObjSave(InObject, FileName, Mode="w") 430 | ; saves the structure and values of InObject as simplified XML 431 | ; ============================================================================== 432 | ; ============================================================================== 433 | 434 | ObjSave(InObject, FileName, Mode="w") 435 | { 436 | FESave:=A_FileEncoding 437 | FileEncoding, UTF-16 438 | File:=FileOpen(FileName, Mode " `n") 439 | If (File=0) 440 | { 441 | RVal:="Error opening file """ FileName """: " A_LastError 442 | } 443 | else 444 | { 445 | File.Write(ObjToXML(InObject)) 446 | File.Close() 447 | RVal:=0 448 | } 449 | FileEncoding, %FESave% 450 | return, rval 451 | } 452 | 453 | ; ============================================================================== 454 | ; ============================================================================== 455 | ; ObjLoad(BaseObject, FileName) 456 | ; loads the structure and values of an object from simplified XML 457 | ; ============================================================================== 458 | ; ============================================================================== 459 | 460 | ObjLoad(BaseObject, FileName) 461 | { 462 | FileRead, InString, %FileName% 463 | XMLToObj(BaseObject, InString) 464 | } 465 | 466 | 467 | -------------------------------------------------------------------------------- /Libraries/StringHandling.ahk: -------------------------------------------------------------------------------- 1 | ; ============================================================================== 2 | ; ============================================================================== 3 | ; String handling functions 4 | ; ============================================================================== 5 | ; ============================================================================== 6 | 7 | ; ============================================================================== 8 | ; ============================================================================== 9 | ; string EscapeVarStr(StringIn) 10 | ; converts StringIn to escaped string for saving 11 | ; ============================================================================== 12 | ; ============================================================================== 13 | 14 | EscapeVarStr(StringIn) 15 | { 16 | tline:=StringIn 17 | StringReplace, tline, tline, ", "", All 18 | StringReplace, tline, tline, `,, ```,, All 19 | StringReplace, tline, tline, `%, ```%, All 20 | StringReplace, tline, tline, `;, ```;, All 21 | StringReplace, tline, tline, `::, ```::, All 22 | StringReplace, tline, tline, `n, ``n, All 23 | StringReplace, tline, tline, `r, ``r, All 24 | StringReplace, tline, tline, `b, ``b, All 25 | StringReplace, tline, tline, `t, ``t, All 26 | StringReplace, tline, tline, `v, ``v, All 27 | StringReplace, tline, tline, `a, ``a, All 28 | StringReplace, tline, tline, `f, ``f, All 29 | Return, tline 30 | } 31 | 32 | 33 | ; ============================================================================== 34 | ; ============================================================================== 35 | ; string UnEscapeVarStr(StringIn) 36 | ; converts double quotes and special characteres in StringIn and removes outer 37 | ; quotes if present 38 | ; ============================================================================== 39 | ; ============================================================================== 40 | 41 | UnEscapeVarStr(StringIn) 42 | { 43 | tline:=StringIn 44 | StringReplace, tline, tline, "", ", All 45 | StringReplace, tline, tline, ```,, `,, All 46 | StringReplace, tline, tline, ```%, `%, All 47 | StringReplace, tline, tline, ```;, `;, All 48 | StringReplace, tline, tline, ```::, `::, All 49 | StringReplace, tline, tline, ``n, `n, All 50 | StringReplace, tline, tline, ``r, `r, All 51 | StringReplace, tline, tline, ``b, `b, All 52 | StringReplace, tline, tline, ``t, `t, All 53 | StringReplace, tline, tline, ``v, `v, All 54 | StringReplace, tline, tline, ``a, `a, All 55 | StringReplace, tline, tline, ``f, `f, All 56 | If (InStr(tline,"""")=1 and InStr(tline, """", False, 0)=StrLen(tline)) 57 | tline:=Substr(tline,2,-1) 58 | Return, tline 59 | } 60 | 61 | ; ============================================================================== 62 | ; ============================================================================== 63 | ; string RangeExpand(StringIn) 64 | ; converts double quotes and special characteres in StringIn and removes outer 65 | ; quotes if present 66 | ; ============================================================================== 67 | ; ============================================================================== 68 | 69 | RangeExpand(InStr) 70 | { 71 | while RegExMatch(InStr, "(\d+)-(\d+)", f) 72 | { 73 | loop % (f2 ? f2-f1 : 0) + 1 74 | ret .= "," (A_Index-1) + f1 75 | InStr:=RegExReplace(InStr, "(\d+)-(\d+)", SubStr(ret, 2), "", 1) 76 | } 77 | return InStr 78 | } 79 | 80 | -------------------------------------------------------------------------------- /Libraries/TypeLibHelperFunctions.ahk: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Version: MPL 2.0/GPL 3.0/LGPL 3.0 4 | 5 | The contents of this file are subject to the Mozilla Public License Version 6 | 2.0 (the "License"); you may not use this file except in compliance with 7 | the License. You may obtain a copy of the License at 8 | 9 | http://www.mozilla.org/MPL/ 10 | 11 | Software distributed under the License is distributed on an "AS IS" basis, 12 | WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 13 | for the specific language governing rights and limitations under the License. 14 | 15 | The Initial Developer of the Original Code is 16 | Elgin . 17 | Portions created by the Initial Developer are Copyright (C) 2010-2017 18 | the Initial Developer. All Rights Reserved. 19 | 20 | Contributor(s): 21 | 22 | Alternatively, the contents of this file may be used under the terms of 23 | either the GNU General Public License Version 3 or later (the "GPL"), or 24 | the GNU Lesser General Public License Version 3.0 or later (the "LGPL"), 25 | in which case the provisions of the GPL or the LGPL are applicable instead 26 | of those above. If you wish to allow use of your version of this file only 27 | under the terms of either the GPL or the LGPL, and not to allow others to 28 | use your version of this file under the terms of the MPL, indicate your 29 | decision by deleting the provisions above and replace them with the notice 30 | and other provisions required by the GPL or the LGPL. If you do not delete 31 | the provisions above, a recipient may use your version of this file under 32 | the terms of any one of the MPL, the GPL or the LGPL. 33 | 34 | */ 35 | 36 | ; ============================================================================== 37 | ; ============================================================================== 38 | ; Contents 39 | ; ============================================================================== 40 | ; ============================================================================== 41 | /* 42 | Provides: higher level functions to retrieve data from type libraries 43 | 44 | */ 45 | 46 | ; sorded headings for file construction 47 | TypeLibToHeadingsObj(TypeLib) 48 | { 49 | If (TypeLib.__Class<>"ITypeLib") 50 | { 51 | throw "Not a valid type library." 52 | return 0 53 | } 54 | Out:=Object() 55 | Out._TypeLibraryInfo:=TypeLib.GetDocumentation(-1) 56 | Attr:=TypeLib.GetLibAttr() 57 | ObjMerge(Attr,Out._TypeLibraryInfo) 58 | Out._TypeLibraryInfo.LibFlagsNames:=LIBFLAGS(Attr.wLibFlags) 59 | Out._TypeLibraryInfo.syskindStr:=SYSKIND(Attr.syskind) 60 | Loop, % TypeLib.GetTypeInfoCount() 61 | { 62 | Progress, % (A_Index-1)/TypeLib.GetTypeInfoCount()*100, % A_Index-1 " of " TypeLib.GetTypeInfoCount(), Reading type library elements, Reading type library 63 | TK:=SubStr(TYPEKIND(TypeLib.GetTypeInfoType(A_Index-1)),7) 64 | EnsureObj(Out,TK) 65 | Out[TK].Push({"Name":TypeLib.GetDocumentation(A_Index-1).Name,"Index":A_Index-1}) 66 | } 67 | TypeLib.ReleaseTLibAttr(Attr.__Ptr) 68 | Progress, Off 69 | return Out 70 | } 71 | 72 | 73 | ; full view use for debugging purposes only 74 | TypeLibToVerboseObj(TypeLib, Index=0) 75 | { 76 | If (TypeLib.__Class<>"ITypeLib") 77 | { 78 | throw "Not a valid type library." 79 | return 0 80 | } 81 | Out:=TypeLib.GetDocumentation(-1) 82 | Attr:=TypeLib.GetLibAttr() 83 | ObjMerge(Attr,Out) 84 | Out.LibFlagsNames:=LIBFLAGS(Attr.wLibFlags) 85 | Out.syskindStr:=SYSKIND(Attr.syskind) 86 | If (Index) 87 | { 88 | Out[Index]:=TypeInfoToVerboseObj(TypeLib.GetTypeInfo(Index),TypeLib) 89 | } 90 | else 91 | { 92 | Loop, % TypeLib.GetTypeInfoCount() 93 | { 94 | fileappend, % "Info " A_Index-1 "`n", test.txt 95 | Progress, % (A_Index-1)/TypeLib.GetTypeInfoCount()*100, % A_Index-1 " of " TypeLib.GetTypeInfoCount(), Reading type library elements, Reading type library 96 | Out[A_Index-1]:=TypeInfoToVerboseObj(TypeLib.GetTypeInfo(A_Index-1),TypeLib) 97 | } 98 | Progress, Off 99 | } 100 | TypeLib.ReleaseTLibAttr(Attr.__Ptr) 101 | return Out 102 | } 103 | 104 | TypeInfoToVerboseObj(TypeInfo, Typelib) 105 | { 106 | If (TypeLib.__Class<>"ITypeLib" or TypeInfo.__Class<>"ITypeInfo") 107 | { 108 | throw "Not a valid type library or type info type." 109 | return 0 110 | } 111 | Out:=TypeInfo.GetDocumentation(-1) 112 | Attr:=TypeInfo.GetTypeAttr() 113 | ObjMerge(Attr,Out) 114 | Out.typekindStr:=TYPEKIND(Attr.typekind) 115 | Out.wTypeFlagsSts:=TYPEFLAGS(Attr.wTypeFlags) 116 | Out.Variables:=Object() 117 | Loop, % Attr.cVars 118 | { 119 | fileappend, % "var " A_Index-1 "`n", test.txt 120 | Out.Variables[A_Index-1]:=Object() 121 | VarDescVar:=TypeInfo.GetVarDesc(A_Index-1) 122 | Out.Variables[A_Index-1]:=TypeInfo.GetDocumentation(VarDescVar.memid) 123 | ObjMerge(VarDescVar,Out.Variables[A_Index-1]) 124 | TypeInfo.ReleaseVarDesc(VarDesc.__Ptr) 125 | } 126 | Out.Functions:=Object() 127 | Loop, % Attr.cFuncs 128 | { 129 | fileappend, % "func " A_Index-1 "`n", test.txt 130 | FuncIndex:=A_Index-1 131 | Out.Functions[FuncIndex]:=Object() 132 | FuncDescVar:=TypeInfo.GetFuncDesc(FuncIndex) 133 | Out.Functions[FuncIndex]:=TypeInfo.GetDocumentation(FuncDescVar.memid) 134 | ObjMerge(FuncDescVar,Out.Functions[FuncIndex]) 135 | Out.Functions[FuncIndex].ReturnTypeStr:=VARENUM(FuncDescVar.elemdescFunc.tdesc.vt) 136 | Out.Functions[FuncIndex].Parameters:=Object() 137 | ParamNames:=TypeInfo.GetNames(FuncDescVar.memid,FuncDescVar.cParams+1) 138 | fileappend, % "Func" Funcindex " " Out.Functions[FuncIndex].Name "`n", test.txt 139 | Loop, % FuncDescVar.cParams 140 | { 141 | Out.Functions[FuncIndex].Parameters[A_Index-1]:=Object() 142 | Out.Functions[FuncIndex].Parameters[A_Index-1].ParamName:=ParamNames[A_Index+1] 143 | fileappend, % "Param " A_Index-1 "/" FuncDescVar.cParams ";" ParamNames[A_Index+1] "`n", test.txt 144 | param:=new ELEMDESC(FuncDescVar.lprgelemdescParam+(A_Index-1)*ELEMDESC.SizeOf()) 145 | ObjMerge(param,Out.Functions[FuncIndex].Parameters[A_Index-1]) 146 | Out.Functions[FuncIndex].Parameters[A_Index-1].TypeStr:=GetVarStr(param, TypeInfo) 147 | } 148 | TypeInfo.ReleaseFuncDesc(FuncDescVar.__Ptr) 149 | } 150 | Out.ImplementedTypes:=Object() 151 | Loop, % Attr.cImplTypes 152 | { 153 | Out.ImplementedTypes[A_Index-1]:=Object() 154 | Out.ImplementedTypes[A_Index-1].Name:=TypeInfo.GetRefTypeOfImplType(A_Index-1).GetDocumentation(-1).Name ; 155 | ; removed: do not recurse into implemented types for performance reasons 156 | ;~ Out.ImplementedTypes[A_Index-1]:=TypeInfoToVerboseObj(TypeInfo.GetRefTypeOfImplType(A_Index-1), Typelib) 157 | Out.ImplementedTypes[A_Index-1].Flags:=IMPLTYPEFLAGS(TypeInfo.GetImplTypeFlags(A_Index-1)) 158 | } 159 | TypeInfo.ReleaseTypeAttr(Attr.__Ptr) 160 | return Out 161 | } 162 | 163 | ; standard TL view 164 | TypeLibToCondensedObj(TypeLib, Index=0) 165 | { 166 | If (TypeLib.__Class<>"ITypeLib") 167 | { 168 | throw "Not a valid type library." 169 | return 0 170 | } 171 | Out:=Object() 172 | Out._TypeLibraryInfo:=TypeLib.GetDocumentation(-1) 173 | Attr:=TypeLib.GetLibAttr() 174 | ObjMerge(Attr,Out._TypeLibraryInfo) 175 | Out._TypeLibraryInfo.LibFlagsNames:=LIBFLAGS(Attr.wLibFlags) 176 | Out._TypeLibraryInfo.syskindStr:=SYSKIND(Attr.syskind) 177 | If (Index) 178 | { 179 | Out[Index]:=TypeInfoToCondensedObj(TypeLib.GetTypeInfo(Index),TypeLib) 180 | } 181 | else 182 | { 183 | Loop, % TypeLib.GetTypeInfoCount() 184 | { 185 | Progress, % (A_Index-1)/TypeLib.GetTypeInfoCount()*100, % A_Index-1 " of " TypeLib.GetTypeInfoCount(), Reading type library elements, Reading type library 186 | TK:=TYPEKIND(TypeLib.GetTypeInfoType(A_Index-1)) 187 | EnsureObj(Out,TK) 188 | Out[TK][TypeLib.GetDocumentation(A_Index-1).Name]:=TypeInfoToCondensedObj(TypeLib.GetTypeInfo(A_Index-1),TypeLib) 189 | } 190 | Progress, Off 191 | } 192 | TypeLib.ReleaseTLibAttr(Attr.__Ptr) 193 | return Out 194 | } 195 | 196 | TypeInfoToCondensedObj(TypeInfo, Typelib) 197 | { 198 | If (TypeLib.__Class<>"ITypeLib" or TypeInfo.__Class<>"ITypeInfo") 199 | { 200 | throw "Not a valid type library or type info type." 201 | return 0 202 | } 203 | Out:=Object() 204 | Attr:=TypeInfo.GetTypeAttr() 205 | Out.GUID:=Attr.guid 206 | If (Attr.cVars) 207 | { 208 | Out.Variables:=Object() 209 | Loop, % Attr.cVars 210 | { 211 | Out.Variables[A_Index-1]:=Object() 212 | VarDescVar:=TypeInfo.GetVarDesc(A_Index-1) 213 | Doc:=TypeInfo.GetDocumentation(VarDescVar.memid) 214 | If (VarDescVar.varkind=0) ; Perinstance 215 | { 216 | Out.Variables[A_Index-1]:=Doc.Name "; Offset: " VarDescVar.lpvarvalue ", Type: " GetVarStr(VarDescVar.elemdescVar, TypeInfo) 217 | If (Doc.DocString<>"") 218 | Out.Variables[A_Index-1]:=.=" `; " Doc.DocString 219 | } 220 | else 221 | If (VarDescVar.varkind=2) ; Const 222 | { 223 | 224 | Out.Variables[A_Index-1]:=Doc.Name " := " VarDescVar.oInst 225 | If (Doc.DocString<>"") 226 | Out.Variables[A_Index-1].=" `; " Doc.DocString 227 | Out.Variables[A_Index-1].="; Type: " GetVarStr(VarDescVar.elemdescVar, TypeInfo) 228 | } 229 | TypeInfo.ReleaseVarDesc(VarDescVar.__Ptr) 230 | } 231 | } 232 | If (Attr.cFuncs) 233 | { 234 | Out.Functions:=Object() 235 | Loop, % Attr.cFuncs 236 | { 237 | FuncIndex:=A_Index-1 238 | FuncDescVar:=TypeInfo.GetFuncDesc(FuncIndex) 239 | Doc:=TypeInfo.GetDocumentation(FuncDescVar.memid) 240 | Name:=Doc.Name 241 | If Name not in QueryInterface,AddRef,Release,GetTypeInfoCount,GetTypeInfo,GetIDsOfNames,Invoke 242 | { 243 | tout:=INVOKEKIND(FuncDescVar.invkind) " " Name 244 | Out.Functions[FuncDescVar.oVft//A_PtrSize]:=tout 245 | } 246 | TypeInfo.ReleaseFuncDesc(FuncDescVar.__Ptr) 247 | } 248 | } 249 | If (Attr.cImplTypes) 250 | { 251 | Out.ImplementedTypes:=Object() 252 | If (Attr.typekind=5) ; TKIND_COCLASS 253 | { 254 | Loop, % Attr.cImplTypes 255 | { 256 | Name:=TypeInfo.GetRefTypeOfImplType(A_Index-1).GetDocumentation(-1).Name 257 | Out.ImplementedTypes.Insert(Name) 258 | } 259 | } 260 | else 261 | { 262 | Loop, % Attr.cImplTypes 263 | { 264 | Out.ImplementedTypes[TypeInfo.GetRefTypeOfImplType(A_Index-1).GetDocumentation(-1).Name]:=Object() 265 | } 266 | } 267 | } 268 | If (Attr.typekind=6) ; TKIND_ALIAS 269 | { 270 | Out.tdescAlias:=GetVarStrFromTD(Attr.tdescAlias, TypeInfo) 271 | } 272 | TypeInfo.ReleaseTypeAttr(Attr.__Ptr) 273 | return Out 274 | } 275 | 276 | GetRequiresInitialization(elemDescVar, TypeInfo) 277 | { 278 | If (!IsObject(elemDescVar) or !IsObject(elemDescVar.tdesc)) 279 | return 280 | return GetRequiresInitializationFromTD(elemDescVar.tdesc, TypeInfo) 281 | } 282 | 283 | GetRequiresInitializationFromTD(typeDescVar, TypeInfo) 284 | { 285 | vstr:="" 286 | If (VARENUM(typeDescVar.vt)) 287 | { 288 | If (typeDescVar.vt=26) 289 | { 290 | vstr:=GetRequiresInitializationFromTD(typeDescVar.lptdesc, TypeInfo) 291 | } 292 | else 293 | If (typeDescVar.vt=29) 294 | { 295 | ref:=TypeInfo.GetRefTypeInfo(typeDescVar.hreftype) 296 | refAttr:=ref.GetTypeAttr() 297 | If (refAttr.typekind=1 or refAttr.typekind=1) 298 | vstr:=ref.GetDocumentation(-1).Name 299 | ref.ReleaseTypeAttr(refAttr.__Ptr) 300 | } 301 | } 302 | return vstr 303 | } 304 | 305 | GetVarStr(elemDescVar, TypeInfo) 306 | { 307 | If (!IsObject(elemDescVar) or !IsObject(elemDescVar.tdesc)) 308 | return 309 | return GetVarStrFromTD(elemDescVar.tdesc, TypeInfo) 310 | } 311 | 312 | GetVarStrFromTD(typeDescVar, TypeInfo) 313 | { 314 | If (VARENUM(typeDescVar.vt)) 315 | { 316 | If (typeDescVar.vt=26) 317 | { 318 | vstr:=GetVarStrFromTD(typeDescVar.lptdesc, TypeInfo) 319 | If (vstr<>"") 320 | vstr.="*" 321 | else 322 | vstr:=VARENUM(typeDescVar.vt) 323 | return vstr 324 | } 325 | else 326 | If (typeDescVar.vt=29) 327 | { 328 | ref:=TypeInfo.GetRefTypeInfo(typeDescVar.hreftype) 329 | return ref.GetDocumentation(-1).Name ; MEMBERID_NIL 330 | } 331 | else 332 | { 333 | return VARENUM(typeDescVar.vt) 334 | } 335 | } 336 | else 337 | return "VarType: " Format("{:#X}", typeDescVar.vt) 338 | } 339 | 340 | GetTypeObj(elemDescVar, TypeInfo) 341 | { 342 | If (!IsObject(elemDescVar) or !IsObject(elemDescVar.tdesc)) 343 | return 344 | TypeObj:=Object() 345 | GetTypeObjFromTD(elemDescVar.tdesc, TypeInfo, TypeObj) 346 | return TypeObj 347 | } 348 | 349 | GetTypeObjFromTD(typeDescVar, TypeInfo, TypeObj) 350 | { 351 | to:=Object() 352 | to.Type:=typeDescVar.vt 353 | TypeObj.Push(to) 354 | If (typeDescVar.vt=26) 355 | { 356 | GetTypeObjFromTD(typeDescVar.lptdesc, TypeInfo, TypeObj) 357 | } 358 | else 359 | If (typeDescVar.vt=29) 360 | { 361 | ref:=TypeInfo.GetRefTypeInfo(typeDescVar.hreftype) 362 | Attr:=ref.GetTypeAttr() 363 | If (Attr.typekind=3 or Attr.typekind=4 or Attr.typekind=5) 364 | to.IsInterface:=1 365 | else 366 | to.IsInterface:=0 367 | If (Attr.typekind=0) ; TKIND_ENUM 368 | to.RefType:=19 369 | else 370 | to.RefType:=13 371 | to.Name:=ref.GetDocumentation(-1).Name 372 | ref.ReleaseTypeAttr(Attr.__Ptr) 373 | } 374 | } 375 | 376 | GetAHKDllCallTypeFromVarObj(TypeObj) 377 | { 378 | If (TypeObj[1].Type=26 and TypeObj[2].Type<>0 and TypeObj[2].Type<>24 and TypeObj[2].Type<>29) 379 | return VT2AHK(TypeObj[2].Type) . "*" 380 | else 381 | If (TypeObj[1].Type=26 and TypeObj[2].Type=29) 382 | { 383 | If (TypeObj[2].RefType="") 384 | return "Ptr" 385 | else 386 | return VT2AHK(TypeObj[2].RefType) 387 | } 388 | else 389 | If (TypeObj[1].Type=29) 390 | { 391 | If (TypeObj[1].RefType="") 392 | return "Ptr" 393 | else 394 | return VT2AHK(TypeObj[1].RefType) 395 | } 396 | else 397 | return VT2AHK(TypeObj[1].Type) 398 | } 399 | 400 | GetTypeObjPostProcessing(TypeObj) 401 | { 402 | tout:=Object() 403 | For index, type in TypeObj 404 | { 405 | If (type.Type=8) 406 | tout.Push("out:= StrGet(out)") 407 | else 408 | If (type.Type=12) 409 | tout.Push("out:=ComObject(0x400C, out+0, flag)[]") 410 | else 411 | If (type.Type=29 and type.IsInterface=1) 412 | tout.Push("out:= new " type.Name "(out)") 413 | } 414 | return tout 415 | } -------------------------------------------------------------------------------- /Libraries/TypeLibInterfaces.ahk: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Version: MPL 2.0/GPL 3.0/LGPL 3.0 4 | 5 | The contents of this file are subject to the Mozilla Public License Version 6 | 2.0 (the "License"); you may not use this file except in compliance with 7 | the License. You may obtain a copy of the License at 8 | 9 | http://www.mozilla.org/MPL/ 10 | 11 | Software distributed under the License is distributed on an "AS IS" basis, 12 | WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 13 | for the specific language governing rights and limitations under the License. 14 | 15 | The Initial Developer of the Original Code is 16 | Elgin . 17 | Portions created by the Initial Developer are Copyright (C) 2010-2017 18 | the Initial Developer. All Rights Reserved. 19 | 20 | Contributor(s): 21 | 22 | Alternatively, the contents of this file may be used under the terms of 23 | either the GNU General Public License Version 3 or later (the "GPL"), or 24 | the GNU Lesser General Public License Version 3.0 or later (the "LGPL"), 25 | in which case the provisions of the GPL or the LGPL are applicable instead 26 | of those above. If you wish to allow use of your version of this file only 27 | under the terms of either the GPL or the LGPL, and not to allow others to 28 | use your version of this file under the terms of the MPL, indicate your 29 | decision by deleting the provisions above and replace them with the notice 30 | and other provisions required by the GPL or the LGPL. If you do not delete 31 | the provisions above, a recipient may use your version of this file under 32 | the terms of any one of the MPL, the GPL or the LGPL. 33 | 34 | */ 35 | 36 | ; ============================================================================== 37 | ; ============================================================================== 38 | ; Contents 39 | ; ============================================================================== 40 | ; ============================================================================== 41 | /* 42 | Provides: definitions for interfaces, structures and constants to retrieve 43 | data from type libraries 44 | 45 | */ 46 | 47 | class ITypeLib extends BaseComClass 48 | { 49 | static __IID := "{00020402-0000-0000-C000-000000000046}" 50 | 51 | GetTypeInfoCount() 52 | { 53 | return DllCall(this.vt(3), "Ptr", this.Ptr, "UInt") 54 | } 55 | 56 | GetTypeInfo(Index) 57 | { 58 | out:=0 59 | return DllCall(this.vt(4), "Ptr", this.Ptr, "UInt", Index, "Ptr*", out, "Int")=0 ? new ITypeInfo(out) : 0 60 | } 61 | 62 | GetTypeInfoType(Index) 63 | { 64 | out:=0 65 | return DllCall(this.vt(5), "Ptr", this.Ptr, "UInt", Index, "UInt*", out, "Int")=0 ? out : 0 66 | } 67 | 68 | GetLibAttr() 69 | { 70 | VarSetCapacity(out, TLIBATTR.SizeOf(),0) 71 | return DllCall(this.vt(7), "Ptr", this.Ptr, "Ptr*", out)=0 ? new TLIBATTR(out) : 0 72 | } 73 | 74 | GetDocumentation(Index) 75 | { 76 | Name:=0 77 | DocString:=0 78 | HelpContext:=0 79 | HelpFile:=0 80 | If (DllCall(this.vt(9), "Ptr", this.Ptr, "Int", Index, "ptr*", Name, "ptr*", DocString, "ptr*", HelpContext, "ptr*", HelpFile)=0) 81 | { 82 | TempInfo:=Object() 83 | TempInfo.Name:=StrGet(Name, "UTF-16") 84 | TempInfo.DocString:=StrGet(DocString, "UTF-16") 85 | TempInfo.HelpContext:=HelpContext 86 | TempInfo.HelpFile:=StrGet(HelpFile, "UTF-16") 87 | } 88 | return TempInfo 89 | } 90 | 91 | ReleaseTLibAttr(Ptr) 92 | { 93 | DllCall(this.vt(12), "Ptr", this.Ptr, "Ptr", Ptr) 94 | } 95 | 96 | } 97 | 98 | class ITypeInfo extends BaseComClass 99 | { 100 | static __IID := "{00020401-0000-0000-C000-000000000046}" 101 | 102 | GetTypeAttr() 103 | { 104 | VarSetCapacity(out, TYPEATTR.SizeOf(),0) 105 | return DllCall(this.vt(3), "Ptr", this.Ptr, "Ptr*", out, "Int")=0 ? new TYPEATTR(out) : 0 106 | } 107 | 108 | GetFuncDesc(Index) 109 | { 110 | VarSetCapacity(out, FUNCDESC.SizeOf(),0) 111 | return DllCall(this.vt(5), "Ptr", this.Ptr, "Int", Index, "Ptr*", out, "Int")=0 ? new FUNCDESC(out) : 0 112 | } 113 | 114 | GetVarDesc(Index) 115 | { 116 | VarSetCapacity(out, VARDESC.SizeOf(),0) 117 | return, DllCall(this.vt(6), "Ptr", this.Ptr, "Int", Index, "Ptr*", out, "Int")=0 ? new VARDESC(out) : 0 118 | } 119 | 120 | GetNames(ID, MaxNum=1) 121 | { 122 | pcNames:=0 123 | VarSetCapacity(out, MaxNum * A_PtrSize, 0) 124 | HR:=DllCall(this.vt(7), "Ptr", this.Ptr, "Int", ID, "Ptr", &out, "UInt", MaxNum, "UInt*", pcNames, "Int") 125 | If (pcNames) 126 | { 127 | TempInfo:=Object() 128 | Loop, %pcNames% 129 | { 130 | TempInfo.Push(StrGet(NumGet(&out+A_PtrSize*(A_Index-1), "Ptr"), "UTF-16")) 131 | } 132 | return TempInfo 133 | } 134 | return HR 135 | } 136 | 137 | GetRefTypeOfImplType(Index) 138 | { 139 | out:=0 140 | If (DllCall(this.vt(8), "Ptr", this.Ptr, "UInt", Index, "UInt*", out, "Int")=0) 141 | { 142 | return this.GetRefTypeInfo(out+0) 143 | } 144 | } 145 | 146 | GetImplTypeFlags(Index) 147 | { 148 | out:=0 149 | If (DllCall(this.vt(9), "Ptr", this.Ptr, "UInt", Index, "UInt*", out, "Int")=0) 150 | { 151 | return out 152 | } 153 | } 154 | 155 | GetDocumentation(ID) 156 | { 157 | Name:=0 158 | DocString:=0 159 | HelpContext:=0 160 | HelpFile:=0 161 | If (DllCall(this.vt(12), "Ptr", this.Ptr, "Int", ID, "ptr*", Name, "ptr*", DocString, "ptr*", HelpContext, "ptr*", HelpFile)=0) 162 | { 163 | TempInfo:=Object() 164 | TempInfo.Name:=StrGet(Name, "UTF-16") 165 | TempInfo.DocString:=StrGet(DocString, "UTF-16") 166 | TempInfo.HelpContext:=HelpContext 167 | TempInfo.HelpFile:=StrGet(HelpFile, "UTF-16") 168 | } 169 | return TempInfo 170 | } 171 | 172 | GetRefTypeInfo(hRefType) 173 | { 174 | out:=0 175 | return DllCall(this.vt(14), "Ptr", this.Ptr, "Int", hRefType, "ptr*", out)=0 ? new ITypeInfo(out) : 0 176 | } 177 | 178 | GetMops(ID) 179 | { 180 | out:=0 181 | return DllCall(this.vt(17), "Ptr", this.Ptr, "Int", ID, "ptr*", out)=0 ? StrGet(out, "UTF-16") : 0 182 | } 183 | 184 | GetContainingTypeLib(byref pindex) 185 | { 186 | out:=0 187 | pindex:=0 188 | return DllCall(this.vt(18), "Ptr", this.Ptr, "Ptr*", out, "UInt*", pindex)=0 ? new ITypeLib(out) : 0 189 | } 190 | 191 | ReleaseTypeAttr(Ptr) 192 | { 193 | DllCall(this.vt(19), "Ptr", this.Ptr, "Ptr", Ptr) 194 | } 195 | 196 | ReleaseFuncDesc(Ptr) 197 | { 198 | DllCall(this.vt(20), "Ptr", this.Ptr, "Ptr", Ptr) 199 | } 200 | 201 | ReleaseVarDesc(Ptr) 202 | { 203 | DllCall(this.vt(21), "Ptr", this.Ptr, "Ptr", Ptr) 204 | } 205 | 206 | 207 | ;~ 4 (get-type-comp :pointer) 208 | ;~ 10 (get-ids-of-names :pointer) 209 | ;~ 11 (invoke :pointer) 210 | ;~ 13 (get-dll-entry :pointer) 211 | ;~ 15 (address-of-member :pointer) 212 | ;~ 16 (create-instance :pointer) 213 | } 214 | 215 | ; checked 32/64 bit 216 | class ELEMDESC extends BaseStruct 217 | { 218 | GetFromStruct(p) 219 | { 220 | this.tdesc := new TYPEDESC(p+0) 221 | this.idldesc := new IDLDESC(p+TYPEDESC.SizeOf()) 222 | this.paramdesc := new PARAMDESC(p+TYPEDESC.SizeOf()) 223 | return, 1 224 | } 225 | 226 | SizeOf() 227 | { 228 | return TYPEDESC.SizeOf()+PARAMDESC.SizeOf() 229 | } 230 | } 231 | 232 | 233 | ; checked 32/64 bit 234 | class FUNCDESC extends BaseStruct 235 | { 236 | GetFromStruct(p) 237 | { 238 | this.memid:=NumGet(p+0, "UInt") 239 | If (A_PtrSize=4) 240 | { 241 | this.lprgscode:=NumGet(NumGet(p+A_PtrSize, "UInt")) 242 | this.lprgelemdescParam:=NumGet(p+2*A_PtrSize, "Ptr") 243 | this.funckind:=NumGet(p+3*A_PtrSize, "UInt") 244 | this.invkind:=NumGet(p+4+3*A_PtrSize, "Short") 245 | this.callconv:=NumGet(p+8+3*A_PtrSize, "UInt") 246 | this.cParams:=NumGet(p+12+3*A_PtrSize, "Short") 247 | this.cParamsOpt:=NumGet(p+14+3*A_PtrSize, "UShort") 248 | this.oVft:=NumGet(p+16+3*A_PtrSize, "Short") 249 | this.cScodes:=NumGet(p+18+3*A_PtrSize, "Short") 250 | this.elemdescFunc:=new ELEMDESC(p+20+3*A_PtrSize) 251 | this.wFuncFlags:=NumGet(p+22+3*A_PtrSize+ELEMDESC.SizeOf(), "Short") 252 | } 253 | else 254 | { 255 | this.lprgscode:=NumGet(NumGet(p+8, "UInt")) 256 | this.lprgelemdescParam:=NumGet(p+16, "Ptr") 257 | this.funckind:=NumGet(p+24, "UInt") 258 | this.invkind:=NumGet(p+28, "Short") 259 | this.callconv:=NumGet(p+32, "UInt") 260 | this.cParams:=NumGet(p+36, "Short") 261 | this.cParamsOpt:=NumGet(p+38, "UShort") 262 | this.oVft:=NumGet(p+40, "Short") 263 | this.cScodes:=NumGet(p+42, "Short") 264 | this.elemdescFunc:=new ELEMDESC(p+48) 265 | this.wFuncFlags:=NumGet(p+80, "Short") 266 | } 267 | return, 1 268 | } 269 | 270 | SizeOf() 271 | { 272 | If (A_PtrSize=4) 273 | { 274 | return 28+2*A_PtrSize+ELEMDESC.SizeOf() 275 | } 276 | else 277 | return 88 278 | } 279 | 280 | } 281 | 282 | ; checked 32/64 bit 283 | class IDLDESC extends BaseStruct 284 | { 285 | GetFromStruct(p) 286 | { 287 | this.dwReserved:= NumGet(p+0,"Ptr") 288 | this.wIDLFlags:= NumGet(p+A_PtrSize, "UShort") 289 | return, 1 290 | } 291 | 292 | SizeOf() 293 | { 294 | return 2*A_PtrSize 295 | } 296 | } 297 | 298 | ; checked 32/64 bit 299 | class PARAMDESC extends BaseStruct 300 | { 301 | GetFromStruct(p) 302 | { 303 | this.wParamFlags:=Numget(p+A_PtrSize,"UShort") 304 | if (this.wParamFlags & 0x20) ; hasdefault 305 | { 306 | this.pparamdescex:=new PARAMDESCEX(NumGet(p+0, "Ptr")) 307 | } 308 | else 309 | this.pparamdescex:=NumGet(p+0, "Ptr") 310 | return, 1 311 | } 312 | 313 | SizeOf() 314 | { 315 | return 2*A_PtrSize 316 | } 317 | } 318 | 319 | ; checked 32/64 bit 320 | class PARAMDESCEX extends BaseStruct 321 | { 322 | GetFromStruct(p) 323 | { 324 | this.cBytes:=NumGet(p+0, "UInt") 325 | If (this.cBytes=16 or this.cBytes=24) 326 | { 327 | this.varDefaultValue:=GetVariantData(p+8) 328 | return, 1 329 | } 330 | else 331 | return, 0 332 | } 333 | 334 | SizeOf() 335 | { 336 | return 8+8+2*A_PtrSize 337 | } 338 | } 339 | 340 | ; checked 32/64 bit 341 | class TLIBATTR extends BaseStruct 342 | { 343 | GetFromStruct(p) 344 | { 345 | this.guid:= GUID2Str(p) 346 | this.lcid:= NumGet(p+16, "UInt") 347 | this.syskind:= NumGet(p+20, "UInt") 348 | this.wMajorVerNum:= NumGet(p+24, "UShort") 349 | this.wMinorVerNum:= NumGet(p+26, "UShort") 350 | this.wLibFlags:= NumGet(p+28, "UShort") 351 | return, 1 352 | } 353 | 354 | SizeOf() 355 | { 356 | return 30+2 357 | } 358 | } 359 | 360 | ; checked 32/64 bit 361 | class TYPEATTR extends BaseStruct 362 | { 363 | GetFromStruct(p) 364 | { 365 | this.guid:= GUID2Str(p) 366 | this.lcid:= NumGet(p+16, "UInt") 367 | this.dwReserved:= NumGet(p+20, "UInt") 368 | this.memidConstructor:= NumGet(p+24, "Int") 369 | this.memidDestructor:= NumGet(p+28, "Int") 370 | this.lpstrSchema:= StrGet(NumGet(p+32, "UPtr"), "UTF-16") 371 | this.cbSizeInstance:= NumGet(p+32+A_PtrSize, "UInt") 372 | this.typekind:= NumGet(p+36+A_PtrSize, "UInt") 373 | this.cFuncs:= NumGet(p+40+A_PtrSize, "UShort") 374 | this.cVars:= NumGet(p+42+A_PtrSize, "UShort") 375 | this.cImplTypes:= NumGet(p+44+A_PtrSize, "UShort") 376 | this.cbSizeVft:= NumGet(p+46+A_PtrSize, "UShort") 377 | this.cbAlignment:= NumGet(p+48+A_PtrSize, "UShort") 378 | this.wTypeFlags:= NumGet(p+50+A_PtrSize, "UShort") 379 | this.wMajorVerNum:= NumGet(p+52+A_PtrSize, "UShort") 380 | this.wMinorVerNum:= NumGet(p+54+A_PtrSize, "UShort") 381 | this.tdescAlias:= new TYPEDESC(p+56+A_PtrSize) 382 | this.idldescType:= new IDLDESC(p+56+A_PtrSize+TYPEDESC.SizeOf()) 383 | return, 1 384 | } 385 | 386 | SizeOf() 387 | { 388 | return 56+A_PtrSize+TYPEDESC.SizeOf()+IDLDESC.SizeOf() 389 | } 390 | } 391 | 392 | ; checked 32/64 bit 393 | class TYPEDESC extends BaseStruct 394 | { 395 | GetFromStruct(p) 396 | { 397 | this.vt:=NumGet(p+A_PtrSize, "UShort") 398 | If (this.vt=26 or this.vt=27) ; VtPtr VtSafearray 399 | { 400 | this.lptdesc:=new TYPEDESC(NumGet(p+0, "Ptr")) 401 | } 402 | else 403 | If (this.vt=28) ; or this.vt=0x2000) ; VtCarray VtArray 404 | { 405 | this.lpadesc:=new ARRAYDESC(NumGet(p+0, "Ptr")) 406 | } 407 | else 408 | If (this.vt=29) ; VtPtr 409 | { 410 | this.hreftype:=NumGet(p+0, "Ptr") 411 | } 412 | return, 1 413 | } 414 | 415 | SizeOf() 416 | { 417 | return 2*A_PtrSize 418 | } 419 | } 420 | 421 | ; checked 32/64 bit 422 | class ARRAYDESC extends BaseStruct 423 | { 424 | GetFromStruct(p) 425 | { 426 | this.tdescElem:=new TYPEDESC(p+0) 427 | this.cDims:=NumGet(p+TYPEDESC.SizeOf(), "UShort") 428 | this.rgbounds:=Object() 429 | Loop, % this.cDims 430 | { 431 | this.rgbounds[A_Index-1]:=new SAFEARRAYBOUND(p+TYPEDESC.SizeOf()+4+(A_Index)*SAFEARRAYBOUND.SizeOf()) 432 | } 433 | return, 1 434 | } 435 | 436 | SizeOf() 437 | { 438 | return TYPEDESC.SizeOf()+A_PtrSize+SAFEARRAYBOUND.SizeOf() 439 | } 440 | } 441 | 442 | ; checked 32/64 bit 443 | class SAFEARRAYBOUND extends BaseStruct 444 | { 445 | GetFromStruct(p) 446 | { 447 | this.cElements:=NumGet(p+0, "UInt") 448 | this.lLbound:=NumGet(p+4, "Int") 449 | return, 1 450 | } 451 | 452 | SizeOf() 453 | { 454 | return 8 455 | } 456 | } 457 | 458 | class VARDESC extends BaseStruct 459 | { 460 | GetFromStruct(p) 461 | { 462 | this.memid:=NumGet(p+0, "UInt") 463 | this.lpstrSchema:=NumGet(p+A_PtrSize, "Ptr") 464 | this.elemdescVar:=new ELEMDESC(p+3*A_PtrSize) 465 | this.wVarFlags:=NumGet(p+3*A_PtrSize+ELEMDESC.SizeOf(), "Short") 466 | this.varkind:=NumGet(p+4+3*A_PtrSize+ELEMDESC.SizeOf(), "Short") 467 | If (this.varkind=2) 468 | { 469 | this.oInst:=GetVariantData(NumGet(p+2*A_PtrSize, "Ptr")) 470 | } 471 | else 472 | this.lpvarvalue:=NumGet(p+2*A_PtrSize, "Int") 473 | return, 1 474 | } 475 | 476 | SizeOf() 477 | { 478 | return 4*A_PtrSize+ELEMDESC.SizeOf() 479 | } 480 | 481 | } 482 | 483 | 484 | CALLCONV(kind) 485 | { 486 | static Enum:={"CC_FASTCALL":0,"CC_CDECL":1,"CC_MSCPASCAL":2,"CC_PASCAL":2,"CC_MACPASCAL":3,"CC_STDCALL":4,"CC_FPFASTCALL":5,"CC_SYSCALL":6,"CC_MPWCDECL":7,"CC_MPWPASCAL":8,"CC_MAX":9,0:"CC_FASTCALL",1:"CC_CDECL",2:"CC_PASCAL",3:"CC_MACPASCAL",4:"CC_STDCALL",5:"CC_FPFASTCALL",6:"CC_SYSCALL",7:"CC_MPWCDECL",8:"CC_MPWPASCAL",9:"CC_MAX"} 487 | return Enum[kind] 488 | } 489 | 490 | FUNCFLAGS(flags) 491 | { 492 | static Enum:={"FUNCFLAG_FRESTRICTED":0x1,"FUNCFLAG_FSOURCE":0x2,"FUNCFLAG_FBINDABLE":0x4,"FUNCFLAG_FREQUESTEDIT":0x8,"FUNCFLAG_FDISPLAYBIND":0x10,"FUNCFLAG_FDEFAULTBIND":0x20,"FUNCFLAG_FHIDDEN":0x40,"FUNCFLAG_FUSESGETLASTERROR":0x80,"FUNCFLAG_FDEFAULTCOLLELEM":0x100,"FUNCFLAG_FUIDEFAULT":0x200,"FUNCFLAG_FNONBROWSABLE":0x400,"FUNCFLAG_FREPLACEABLE":0x800,"FUNCFLAG_FIMMEDIATEBIND":0x1000} 493 | If (IsObject(flags)) 494 | { 495 | Out:=0 496 | for index, flag in flags 497 | Out|=Enum[flag] 498 | } 499 | else 500 | { 501 | Out:=Object() 502 | For str, flag in Enum 503 | { 504 | If (flags & flag) 505 | Out.Push(str) 506 | } 507 | } 508 | return Out 509 | } 510 | 511 | FUNCKIND(kind) 512 | { 513 | static Enum:={"FUNC_VIRTUAL":0,"FUNC_PUREVIRTUAL":1,"FUNC_NONVIRTUAL":2,"FUNC_STATIC":3,"FUNC_DISPATCH":4,0:"FUNC_VIRTUAL",1:"FUNC_PUREVIRTUAL",2:"FUNC_NONVIRTUAL",3:"FUNC_STATIC",4:"FUNC_DISPATCH"} 514 | return Enum[kind] 515 | } 516 | 517 | IMPLTYPEFLAGS(flags) 518 | { 519 | static Enum:={"IMPLTYPEFLAG_FDEFAULT":0x1,"IMPLTYPEFLAG_FSOURCE":0x2,"IMPLTYPEFLAG_FRESTRICTED":0x4,"IMPLTYPEFLAG_FDEFAULTVTABLE":0x8} 520 | If (IsObject(flags)) 521 | { 522 | Out:=0 523 | for index, flag in flags 524 | Out|=Enum[flag] 525 | } 526 | else 527 | { 528 | Out:=Object() 529 | For str, flag in Enum 530 | { 531 | If (flags & flag) 532 | Out.Push(str) 533 | } 534 | } 535 | return Out 536 | } 537 | 538 | INVOKEKIND(kind) 539 | { 540 | static Enum:={"INVOKE_FUNC":1,"INVOKE_PROPERTYGET":2,"INVOKE_PROPERTYPUT":4,"INVOKE_PROPERTYPUTREF":8,1:"INVOKE_FUNC",2:"INVOKE_PROPERTYGET",4:"INVOKE_PROPERTYPUT",8:"INVOKE_PROPERTYPUTREF"} 541 | return Enum[kind] 542 | } 543 | 544 | LIBFLAGS(flags) 545 | { 546 | static Enum:={"LIBFLAG_FRESTRICTED":0x1,"LIBFLAG_FCONTROL":0x2,"LIBFLAG_FHIDDEN":0x4,"LIBFLAG_FHASDISKIMAGE":0x8} 547 | If (IsObject(flags)) 548 | { 549 | Out:=0 550 | for index, flag in flags 551 | Out|=Enum[flag] 552 | } 553 | else 554 | { 555 | Out:=Object() 556 | For str, flag in Enum 557 | { 558 | If (flags & flag) 559 | Out.Push(str) 560 | } 561 | } 562 | return Out 563 | } 564 | 565 | PARAMFLAG(flags) 566 | { 567 | static Enum:={"PARAMFLAG_NONE":0x0,"PARAMFLAG_FIN":0x1,"PARAMFLAG_FOUT":0x2,"PARAMFLAG_FLCID":0x4,"PARAMFLAG_FRETVAL":0x8,"PARAMFLAG_FOPT":0x10,"PARAMFLAG_FHASDEFAULT":0x20,"PARAMFLAG_FHASCUSTDATA":0x40} 568 | If (IsObject(flags)) 569 | { 570 | Out:=0 571 | for index, flag in flags 572 | Out|=Enum[flag] 573 | } 574 | else 575 | { 576 | Out:=Object() 577 | For str, flag in Enum 578 | { 579 | If (flags & flag) 580 | Out.Push(str) 581 | } 582 | If (flags=0) 583 | Out.Push("PARAMFLAG_NONE") 584 | } 585 | return Out 586 | } 587 | 588 | SYSKIND(kind) 589 | { 590 | static Enum:={"SYS_WIN16":0,"SYS_WIN32":1,"SYS_MAC":2,"SYS_WIN64":3,0:"SYS_WIN16",1:"SYS_WIN32",2:"SYS_MAC",3:"SYS_WIN64"} 591 | return Enum[kind] 592 | } 593 | 594 | TYPEFLAGS(flags) 595 | { 596 | static Enum:={"TYPEFLAG_FAPPOBJECT":0x1,"TYPEFLAG_FCANCREATE":0x2,"TYPEFLAG_FLICENSED":0x4,"TYPEFLAG_FPREDECLID":0x8,"TYPEFLAG_FHIDDEN":0x10,"TYPEFLAG_FCONTROL":0x20,"TYPEFLAG_FDUAL":0x40,"TYPEFLAG_FNONEXTENSIBLE":0x80,"TYPEFLAG_FOLEAUTOMATION":0x100,"TYPEFLAG_FRESTRICTED":0x200,"TYPEFLAG_FAGGREGATABLE":0x400,"TYPEFLAG_FREPLACEABLE":0x800,"TYPEFLAG_FDISPATCHABLE":0x1000,"TYPEFLAG_FREVERSEBIND":0x2000,"TYPEFLAG_FPROXY":0x4000} 597 | If (IsObject(flags)) 598 | { 599 | Out:=0 600 | for index, flag in flags 601 | Out|=Enum[flag] 602 | } 603 | else 604 | { 605 | Out:=Object() 606 | For str, flag in Enum 607 | { 608 | If (flags & flag) 609 | Out.Push(str) 610 | } 611 | } 612 | return Out 613 | } 614 | 615 | TYPEKIND(kind) 616 | { 617 | static Enum:={"TKIND_ENUM":0,"TKIND_RECORD":1,"TKIND_MODULE":2,"TKIND_INTERFACE":3,"TKIND_DISPATCH":4,"TKIND_COCLASS":5,"TKIND_ALIAS":6,"TKIND_UNION":7,"TKIND_MAX":8,0:"TKIND_ENUM",1:"TKIND_RECORD",2:"TKIND_MODULE",3:"TKIND_INTERFACE",4:"TKIND_DISPATCH",5:"TKIND_COCLASS",6:"TKIND_ALIAS",7:"TKIND_UNION",8:"TKIND_MAX"} 618 | return Enum[kind] 619 | } 620 | 621 | VARKIND(kind) 622 | { 623 | static Enum:={"VAR_PERINSTANCE":0,"VAR_STATIC":1,"VAR_CONST":2,"VAR_DISPATCH":3,0:"VAR_PERINSTANCE",1:"VAR_STATIC",2:"VAR_CONST",3:"VAR_DISPATCH"} 624 | return Enum[kind] 625 | } 626 | 627 | VARENUM(kind) 628 | { 629 | static Enum:={"Vt_Empty":0,"Vt_Null":1,"Vt_I2":2,"Vt_I4":3,"Vt_R4":4,"Vt_R8":5,"Vt_Cy":6,"Vt_Date":7,"Vt_Bstr":8,"Vt_Dispatch":9,"Vt_Error":10,"Vt_Bool":11,"Vt_Variant":12,"Vt_Unknown":13,"Vt_Decimal":14,"Vt_I1":16,"Vt_Ui1":17,"Vt_Ui2":18,"Vt_Ui4":19,"Vt_I8":20,"Vt_Ui8":21,"Vt_Int":22,"Vt_Uint":23,"Vt_Void":24,"Vt_Hresult":25,"Vt_Ptr":26,"Vt_Safearray":27,"Vt_Carray":28,"Vt_Userdefined":29,"Vt_Lpstr":30,"Vt_Lpwstr":31,"Vt_Record":36,"Vt_IntPtr":37,"Vt_UintPtr":38,"Vt_Filetime":64,"Vt_Blob":65,"Vt_Stream":66,"Vt_Storage":67,"Vt_StreamedObject":68,"Vt_StoredObject":69,"Vt_BlobObject":70,"Vt_Cf":71,"Vt_Clsid":72,"Vt_VersionedStream":73,"Vt_BstrBlob":0xfff,"Vt_Vector":0x1000,"Vt_Array":0x2000,"Vt_Byref":0x4000,"Vt_Reserved":0x8000,"Vt_Illegal":0xffff,"Vt_Illegalmasked":0xfff,"Vt_Typemask":0xfff,0:"Vt_Empty",1:"Vt_Null",2:"Vt_I2",3:"Vt_I4",4:"Vt_R4",5:"Vt_R8",6:"Vt_Cy",7:"Vt_Date",8:"Vt_Bstr",9:"Vt_Dispatch",10:"Vt_Error",11:"Vt_Bool",12:"Vt_Variant",13:"Vt_Unknown",14:"Vt_Decimal",16:"Vt_I1",17:"Vt_Ui1",18:"Vt_Ui2",19:"Vt_Ui4",20:"Vt_I8",21:"Vt_Ui8",22:"Vt_Int",23:"Vt_Uint",24:"Vt_Void",25:"Vt_Hresult",26:"Vt_Ptr",27:"Vt_Safearray",28:"Vt_Carray",29:"Vt_Userdefined",30:"Vt_Lpstr",31:"Vt_Lpwstr",36:"Vt_Record",37:"Vt_IntPtr",38:"Vt_UintPtr",64:"Vt_Filetime",65:"Vt_Blob",66:"Vt_Stream",67:"Vt_Storage",68:"Vt_StreamedObject",69:"Vt_StoredObject",70:"Vt_BlobObject",71:"Vt_Cf",72:"Vt_Clsid",73:"Vt_VersionedStream",0xfff:"Vt_BstrBlob",0x1000:"Vt_Vector",0x2000:"Vt_Array",0x4000:"Vt_Byref",0x8000:"Vt_Reserved",0xffff:"Vt_Illegal"} 630 | return Enum[kind] 631 | 632 | } 633 | 634 | VT2AHK(kind) 635 | { 636 | static Enum:={0:"Ptr",1:"Ptr",2:"Short",3:"Int",4:"Float",5:"Double",6:"Int64",7:"Int64",8:"Ptr",9:"Ptr",10:"Int",11:"Short",12:"Ptr",13:"Ptr",14:"Int64",16:"Char",17:"UChar",18:"UShort",19:"UInt",20:"Int64",21:"UInt64",22:"Int",23:"Uint",24:"Ptr",25:"Int",26:"Ptr",27:"Ptr",28:"Ptr",29:"Ptr",30:"Ptr",31:"Ptr",36:"Ptr",37:"Int*",38:"UInt*",64:"Ptr",65:"Ptr",66:"Ptr",67:"Ptr",68:"Ptr",69:"Ptr",70:"Ptr",71:"Ptr",72:"Ptr",73:"Ptr",0xfff:"Ptr",0x1000:"Ptr",0x2000:"Ptr",0x4000:"Ptr",0x8000:"Ptr",0xffff:"Ptr"} 637 | return Enum[kind] 638 | } 639 | 640 | VTSize(kind, bitness=0) 641 | { 642 | static Enum4:={0:A_PtrSize,1:A_PtrSize,2:2,3:4,4:4,5:8,6:8,7:8,8:A_PtrSize,9:A_PtrSize,10:4,11:2,12:16,13:A_PtrSize,14:8,16:1,17:1,18:2,19:4,20:8,21:8,22:4,23:4,24:A_PtrSize,25:4,26:A_PtrSize,27:A_PtrSize,28:A_PtrSize,29:A_PtrSize,30:A_PtrSize,31:A_PtrSize,36:A_PtrSize,37:A_PtrSize,38:A_PtrSize,64:A_PtrSize,65:A_PtrSize,66:A_PtrSize,67:A_PtrSize,68:A_PtrSize,69:A_PtrSize,70:A_PtrSize,71:A_PtrSize,72:A_PtrSize,73:A_PtrSize,0xfff:A_PtrSize,0x1000:A_PtrSize,0x2000:A_PtrSize,0x4000:A_PtrSize,0x8000:A_PtrSize,0xffff:A_PtrSize} 643 | static Enum8:={0:A_PtrSize,1:A_PtrSize,2:2,3:4,4:4,5:8,6:8,7:8,8:A_PtrSize,9:A_PtrSize,10:4,11:2,12:24,13:A_PtrSize,14:8,16:1,17:1,18:2,19:4,20:8,21:8,22:4,23:4,24:A_PtrSize,25:4,26:A_PtrSize,27:A_PtrSize,28:A_PtrSize,29:A_PtrSize,30:A_PtrSize,31:A_PtrSize,36:A_PtrSize,37:A_PtrSize,38:A_PtrSize,64:A_PtrSize,65:A_PtrSize,66:A_PtrSize,67:A_PtrSize,68:A_PtrSize,69:A_PtrSize,70:A_PtrSize,71:A_PtrSize,72:A_PtrSize,73:A_PtrSize,0xfff:A_PtrSize,0x1000:A_PtrSize,0x2000:A_PtrSize,0x4000:A_PtrSize,0x8000:A_PtrSize,0xffff:A_PtrSize} 644 | If (bitness=0) 645 | bitness:=A_PtrSize 646 | return Enum%bitness%[kind] 647 | } 648 | 649 | -------------------------------------------------------------------------------- /Libraries/VariousFunctions.ahk: -------------------------------------------------------------------------------- 1 | ; GetActiveObjects v1.0 by Lexikos 2 | ; http://ahkscript.org/boards/viewtopic.php?f=6&t=6494 3 | GetActiveObjects(Prefix:="", CaseSensitive:=false) { 4 | objects := {} 5 | malloc:=0 6 | bindCtx:=0 7 | rot:=0 8 | enum:=0 9 | mon:=0 10 | pname:=0 11 | punk:=0 12 | DllCall("ole32\CoGetMalloc", "uint", 1, "ptr*", malloc) ; malloc: IMalloc 13 | DllCall("ole32\CreateBindCtx", "uint", 0, "ptr*", bindCtx) ; bindCtx: IBindCtx 14 | DllCall(NumGet(NumGet(bindCtx+0)+8*A_PtrSize), "ptr", bindCtx, "ptr*", rot) ; rot: IRunningObjectTable 15 | DllCall(NumGet(NumGet(rot+0)+9*A_PtrSize), "ptr", rot, "ptr*", enum) ; enum: IEnumMoniker 16 | while DllCall(NumGet(NumGet(enum+0)+3*A_PtrSize), "ptr", enum, "uint", 1, "ptr*", mon, "ptr", 0) = 0 ; mon: IMoniker 17 | { 18 | DllCall(NumGet(NumGet(mon+0)+20*A_PtrSize), "ptr", mon, "ptr", bindCtx, "ptr", 0, "ptr*", pname) ; GetDisplayName 19 | name := StrGet(pname, "UTF-16") 20 | DllCall(NumGet(NumGet(malloc+0)+5*A_PtrSize), "ptr", malloc, "ptr", pname) ; Free 21 | if InStr(name, Prefix, CaseSensitive) = 1 { 22 | DllCall(NumGet(NumGet(rot+0)+6*A_PtrSize), "ptr", rot, "ptr", mon, "ptr*", punk) ; GetObject 23 | ; Wrap the pointer as IDispatch if available, otherwise as IUnknown. 24 | if (pdsp := ComObjQuery(punk, "{00020400-0000-0000-C000-000000000046}")) 25 | obj := ComObject(9, pdsp, 1), ObjRelease(punk) 26 | else 27 | obj := ComObject(13, punk, 1) 28 | ; Store it in the return array by suffix. 29 | objects[SubStr(name, StrLen(Prefix) + 1)] := obj 30 | } 31 | ObjRelease(mon) 32 | } 33 | ObjRelease(enum) 34 | ObjRelease(rot) 35 | ObjRelease(bindCtx) 36 | ObjRelease(malloc) 37 | return objects 38 | } 39 | -------------------------------------------------------------------------------- /Libraries/WindowsBase.ahk: -------------------------------------------------------------------------------- 1 | ; ============================================================================== 2 | ; ============================================================================== 3 | ; str GUID2Str(guid) 4 | ; Converts GUID to string 5 | ; ============================================================================== 6 | ; ============================================================================== 7 | 8 | GUID2Str(guid) 9 | { 10 | out:=0 11 | DllCall("Ole32.dll\StringFromCLSID", "UPtr", guid, "UPtr*", out) 12 | return StrGet(out, "UTF-16") 13 | } 14 | 15 | 16 | ; ============================================================================== 17 | ; ============================================================================== 18 | ; RECT GetClientRect(hwnd) 19 | ; Retrieves the client rectangle of a window as RECT object 20 | ; ============================================================================== 21 | ; ============================================================================== 22 | 23 | GetClientRect(hwnd) 24 | { 25 | VarSetCapacity(rc, RECT.SizeOf(), 0) 26 | DllCall("GetClientRect", "UInt", hwnd, "Ptr", &rc) 27 | return new Rect(&rc) 28 | } 29 | 30 | ; ============================================================================== 31 | ; ============================================================================== 32 | ; NONCLIENTMETRICS GetNONCLIENTMETRICS() 33 | ; Retrieves the NONCLIENTMETRICS object 34 | ; ============================================================================== 35 | ; ============================================================================== 36 | 37 | GetNONCLIENTMETRICS() 38 | { 39 | VarSetCapacity(metrics,NONCLIENTMETRICS.SizeOf(),0) 40 | NumPut(NONCLIENTMETRICS.SizeOf(),metrics,0,"UInt") 41 | ret:=DllCall("SystemParametersInfo", "UInt", 0x29, "UInt", NONCLIENTMETRICS.SizeOf(), "Ptr", &metrics, "UInt", 0, "Int") ; SPI_GETNONCLIENTMETRICS 42 | If (ret) 43 | return new NONCLIENTMETRICS(&metrics) 44 | else 45 | return 0 46 | } 47 | 48 | ; ============================================================================== 49 | ; ============================================================================== 50 | ; Variable GetVariantData(p, flag=1) 51 | ; Retrieves contents of a Variant 52 | ; ============================================================================== 53 | ; ============================================================================== 54 | 55 | GetVariantData(p, flag=1) 56 | { 57 | return, ComObject(0x400C, p+0, flag)[] 58 | } 59 | 60 | 61 | ; ============================================================================== 62 | ; ============================================================================== 63 | ; class BaseComClass 64 | ; Basic definitions to wrap an IUnknown COM object 65 | ; ============================================================================== 66 | ; ============================================================================== 67 | 68 | class BaseComClass 69 | { 70 | __New(p="") 71 | { 72 | this.Ptr:=p 73 | } 74 | 75 | vt(Index) 76 | { 77 | 78 | return NumGet(NumGet(this.Ptr+0,"Ptr"), Index*A_PtrSize, "Ptr") 79 | } 80 | 81 | } 82 | 83 | 84 | ; ============================================================================== 85 | ; ============================================================================== 86 | ; class RECT 87 | ; RECT structure definition 88 | ; ============================================================================== 89 | ; ============================================================================== 90 | 91 | class RECT extends BaseStruct 92 | { 93 | GetFromStruct(p) 94 | { 95 | this.x := NumGet(p+0, "Int") 96 | this.y := NumGet(p+4, "Int") 97 | this.w := NumGet(p+8, "Int") 98 | this.h := NumGet(p+12, "Int") 99 | return, 1 100 | } 101 | 102 | SizeOf() 103 | { 104 | return 16 105 | } 106 | } 107 | 108 | 109 | ; ============================================================================== 110 | ; ============================================================================== 111 | ; class NONCLIENTMETRICS 112 | ; NONCLIENTMETRICS structure definition 113 | ; ============================================================================== 114 | ; ============================================================================== 115 | 116 | class NONCLIENTMETRICS extends BaseStruct 117 | { 118 | GetFromStruct(p) 119 | { 120 | this.cbSize:=Numget(p+0,"UInt") 121 | this.iBorderWidth:=Numget(p+4,"Int") 122 | this.iScrollWidth:=Numget(p+8,"Int") 123 | this.iScrollHeight:=Numget(p+12,"Int") 124 | this.iCaptionWidth:=Numget(p+16,"Int") 125 | this.iCaptionHeight:=Numget(p+20,"Int") 126 | this.lfCaptionFont:=new LOGFONT(p+24) 127 | this.iSmCaptionWidth:=Numget(p+24+LOGFONT.SizeOf(),"Int") 128 | this.iSmCaptionHeight:=Numget(p+28+LOGFONT.SizeOf(),"Int") 129 | this.lfSmCaptionFont:=new LOGFONT(p+32+LOGFONT.SizeOf()) 130 | this.iMenuWidth:=Numget(p+32+2*LOGFONT.SizeOf(),"Int") 131 | this.iMenuHeight:=Numget(p+36+2*LOGFONT.SizeOf(),"Int") 132 | this.lfMenuFont:=new LOGFONT(p+40+2*LOGFONT.SizeOf()) 133 | this.lfStatusFont:=new LOGFONT(p+40+3*LOGFONT.SizeOf()) 134 | this.lfMessageFont:=new LOGFONT(p+40+4*LOGFONT.SizeOf()) 135 | this.iPaddedBorderWidth:=Numget(p+40+5*LOGFONT.SizeOf(),"Int") 136 | return, 1 137 | } 138 | 139 | SizeOf() 140 | { 141 | return 44+5*LOGFONT.SizeOf() 142 | } 143 | } 144 | 145 | 146 | ; ============================================================================== 147 | ; ============================================================================== 148 | ; class LOGFONT 149 | ; LOGFONT structure definition 150 | ; ============================================================================== 151 | ; ============================================================================== 152 | 153 | class LOGFONT extends BaseStruct 154 | { 155 | GetFromStruct(p) 156 | { 157 | this.lfHeight:=Numget(p+0,"Int") 158 | this.lfWidth:=Numget(p+4,"Int") 159 | this.lfEscapement:=Numget(p+8,"Int") 160 | this.lfOrientation:=Numget(p+12,"Int") 161 | this.lfWeight:=Numget(p+16,"Int") 162 | this.lfItalic:=Numget(p+20,"UChar") 163 | this.lfUnderline:=Numget(p+21,"UChar") 164 | this.lfStrikeOut:=Numget(p+22,"UChar") 165 | this.lfCharSet:=Numget(p+23,"UChar") 166 | this.lfOutPrecision:=Numget(p+24,"UChar") 167 | this.lfClipPrecision:=Numget(p+25,"UChar") 168 | this.lfQuality:=Numget(p+26,"UChar") 169 | this.lfPitchAndFamily:=Numget(p+27,"UChar") 170 | this.lfFaceName:="" 171 | this.lfFaceName.=DllCall("MulDiv", "Int", p+28, "Int", 1, "Int", 1, "Str") ; Chr(Numget(p+28+(A_Index-1)*(A_IsUnicode ? 2 : 1), A_IsUnicode ? "UShort" : "UChar")) 172 | return, 1 173 | } 174 | 175 | SizeOf() 176 | { 177 | return 28+32*(A_IsUnicode ? 2 : 1) 178 | } 179 | } 180 | 181 | ; ============================================================================== 182 | ; ============================================================================== 183 | ; class BaseStruct 184 | ; Basic definitions to wrap a structure pointer 185 | ; ============================================================================== 186 | ; ============================================================================== 187 | 188 | class BaseStruct 189 | { 190 | __New(p=0) 191 | { 192 | If (!p) 193 | { 194 | VarSetCapacity(p,this.SizeOf(),0) 195 | } 196 | this.__Ptr:=p 197 | If (!this.GetFromStruct(p)) 198 | return, 0 199 | } 200 | 201 | GetFromStruct(p) 202 | { 203 | throw "Abstract method GetFromStruct not implemented in " this.__Class 204 | return 0 205 | } 206 | 207 | UpdateStruct(p=0) 208 | { 209 | throw "Abstract method UpdateStruct not implemented in " this.__Class 210 | return 0 211 | } 212 | 213 | SizeOf() 214 | { 215 | throw "Abstract method GetSizeOf not implemented in " this.__Class 216 | return 0 217 | } 218 | 219 | } 220 | -------------------------------------------------------------------------------- /License.txt: -------------------------------------------------------------------------------- 1 | Version: MPL 2.0/GPL 3.0/LGPL 3.0 2 | 3 | The contents of this project are subject to the Mozilla Public License Version 4 | 2.0 (the "License"); you may not use this file except in compliance with 5 | the License. You may obtain a copy of the License at 6 | 7 | http://www.mozilla.org/MPL/ 8 | 9 | Software distributed under the License is distributed on an "AS IS" basis, 10 | WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 11 | for the specific language governing rights and limitations under the License. 12 | 13 | The Initial Developer of the Original Code is 14 | Elgin . 15 | Portions created by the Initial Developer are Copyright (C) 2010-2017 16 | the Initial Developer. All Rights Reserved. 17 | 18 | Contributor(s): 19 | 20 | Alternatively, the contents of this file may be used under the terms of 21 | either the GNU General Public License Version 3 or later (the "GPL"), or 22 | the GNU Lesser General Public License Version 3.0 or later (the "LGPL"), 23 | in which case the provisions of the GPL or the LGPL are applicable instead 24 | of those above. If you wish to allow use of your version of this file only 25 | under the terms of either the GPL or the LGPL, and not to allow others to 26 | use your version of this file under the terms of the MPL, indicate your 27 | decision by deleting the provisions above and replace them with the notice 28 | and other provisions required by the GPL or the LGPL. If you do not delete 29 | the provisions above, a recipient may use your version of this file under 30 | the terms of any one of the MPL, the GPL or the LGPL. 31 | 32 | _____________________________________________________________________________ 33 | 34 | Some portions of the code were found on the internet and are assumed to be in 35 | the public domain. Sources are noted below and in the code: 36 | 37 | - GetActiveObjects v1.0 by Lexikos 38 | retrieved from 39 | http://ahkscript.org/boards/viewtopic.php?f=6&t=6494 40 | 41 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TypeLib2AHK # 2 | 3 | TypeLib2AHK is a free, open source tool to convert information about COM interfaces stored in type libraries to code usable with AutoHotkey 1.1 and AutoHotkey v2 (https://autohotkey.com/). 4 | 5 | The aim is to make it more comfortable and seamless to work with COM from AutoHotkey by providing class wrappers for structures and non-dispatch interfaces which are not natively supported by AutoHotkey and also the named constants associated with the interfaces. 6 | 7 | ## How to use ## 8 | 9 | TypeLib2AHK.ahk can either be run directly as a standalone application or be used in an AutoHotkey script to retrieve information about specific COM objects (see examples at the beginning of the code in TypeLib2AHK.ahk). It can be used with AutoHotkey 32bit and 64bit Unicode releases. AutoHotkey ANSI releases are not supported. 10 | 11 | TypeLib2AHK.ahk currently only runs under AutoHotkey 1.1 but can create code for AutoHotkey 1.1 and AutoHotkey v2. 12 | 13 | The standalone application offers the user a list of type libraries stored on the computer and retrieved from applications currently in memory. Type library information can also be loaded from DLL files. 14 | 15 | Type libraries can be viewed or directly converted. The viewing functionality is fairly basic; to get more complete information you can use Oleview.exe which is part of the Windows SDK, which can be downloaded for free from Microsoft. 16 | 17 | ## How to use the created code ## 18 | 19 | The resulting code is structured as follows (all examples refer to the UIAutomationClient type library): 20 | 21 | * Header: Information about the type library. 22 | * CoClasses: The code in this section allows to instantiate the underlying COM interfaces. Example: UIA:=CUIAutomation() 23 | * Alias type definitions: For information only as type definitions are usually not relevant in AHK. 24 | * Constants (enumerations and modules): They can be used directly (Example: myTreeScope:=UIAutomationClientTLConst.TreeScope_Ancestors) or the wrapper class can be instantiated as needed. Reverse lookup of a constant name is also possible (Example ValueName:=UIAutomationClientTLConst.UIA_ControlTypeIds(Value)) 25 | * Structures (records and unions): The structures are wrapped as classes for transparent use in AHK scripts (see Example code below). Wrapped structures can be used directly as parameters in function calls or wrapped interfaces. 26 | * Interfaces: The interfaces are wrapped as classes for transparent use in AHK scripts (see Example code below). 27 | * Dispatch interfaces: Dispatch interfaces are handled natively by AHK. Their contents are included for information only. 28 | 29 | The code may not contain all the above sections, depending on what is defined in the respective type library. 30 | 31 | IMPORTANT: 32 | * Before using the created code carefully read the definitions and make sure that it doesn't redefine any Autohotkey functions. As an example: mscorlib.dll overrides Object(). 33 | * Many basic structures are defined in several type libraries. You may need to edit the created code to avoid doubles. 34 | * The converted AutoHotkey code will most likely be different for 32bit and 64bit (most notably: differences in structure offsets and variant handling in DLL-calls), so be sure to use the correct version and take care when manually merging the code for different bit versions. 35 | 36 | Occasionally the type libraries make reference to interfaces or structures which are not included in the library. These can usually be found in other type libraries. Many basic structures and interfaces are defined in the type library "mscorlib.dll". 37 | 38 | 39 | ## Known issues ## 40 | 41 | - some memory leaks 42 | 43 | ## Related ## 44 | 45 | ImportTypeLib by maul.esel (https://github.com/maul-esel/ImportTypeLib) wraps type libraries directly at run-time. It requires a slightly more complex syntax in use and seems to have issues in 64bit. 46 | 47 | 48 | ## Example code AHK v1: ## 49 | 50 | ```ahk 51 | ; to use this example code first convert the type library UIAutomationClient with TypeLib2AHK 52 | 53 | #Include UIAutomationClient_1_0_64bit.ahk ; comment out as necessary 54 | ;~ #Include UIAutomationClient_1_0_32bit.ahk ; uncomment as necessary 55 | 56 | ; Instantiate the CoClass; retrieves wrapper for IUIAutomation interface 57 | UIA:=CUIAutomation() 58 | 59 | ; definition to set the correct variant type for CreatePropertyCondition below 60 | Vt_Bool:=11 61 | 62 | ; Call an interface function; retrieves wrapper of the root IUIAutomationElement in the active window 63 | CurrentWinRootElem := UIA.ElementFromHandle(WinExist("A")) 64 | 65 | t:= "Root element:`n" 66 | ; gather information about the element 67 | t.= ElemInfo(CurrentWinRootElem) 68 | t.= "`n" 69 | 70 | ; The function CreateAndConditionFromArray expects a SAFEARRAY. The SAFEARRAY can be passed directly 71 | ; or as shown here as an AHK object which is then converted by the wrapper 72 | Conditions:=Object() 73 | ; only collect elements which are not offscreen 74 | Conditions.Insert(UIA.CreatePropertyCondition(UIAutomationClientTLConst.UIA_IsOffscreenPropertyId, False, Vt_Bool)) 75 | ; only collect elements which are controls 76 | Conditions.Insert(UIA.ControlViewCondition) 77 | ; combine the above conditions with and 78 | Condition := UIA.CreateAndConditionFromArray(Conditions) 79 | 80 | ; retrieve all decendants of the root element which meet the conditions 81 | Descendants:=CurrentWinRootElem.FindAll(UIAutomationClientTLConst.TreeScope_Descendants, Condition) 82 | 83 | ; retrieve how many descendants were found 84 | t.="Number of descendants: " Descendants.Length "`n`n" 85 | 86 | ; gather information about the first descendant element 87 | t.= "First descendant element:`n" 88 | ; gather information about the first descendant element 89 | t.=ElemInfo(Descendants.GetElement(1)) 90 | 91 | ; display the result 92 | msgbox, % t 93 | return 94 | 95 | ElemInfo(elem) 96 | { 97 | ; retrieve various properties of the IUIAutomationElement 98 | t := "Type: " UIAutomationClientTLConst.UIA_ControlTypeIds(elem.CurrentControlType) "`n" 99 | t .= "Name:`t " elem.CurrentName "`n" 100 | ; CurrentBoundingRectangle returns a tagRECT structure which is defined in the type library and also wrapped into an AHK object 101 | rect := elem.CurrentBoundingRectangle 102 | t .= "Location:`t Left: " rect.Left " Top: " rect.Top " Right: " rect.Right " Bottom: " rect.Bottom "`n" 103 | ; GetClickablePoint expects a tagPOINT structure as parameter 104 | ; the structure can either be passed as an instance of the tagPOINT-wrapper as defined in the type library 105 | point:=new tagPOINT() 106 | out:=elem.GetClickablePoint(point) 107 | t.="Clickable point (using tagPoint structure): x: " point.x " y: " point.y " Has clickable point: " out "`n" 108 | ; or it can be passed as a buffer of the right size 109 | VarSetCapacity(p,tagPOINT.__SizeOf(),0) 110 | out:=elem.GetClickablePoint(p) 111 | point:=new tagPOINT(p) 112 | t.="Clickable point (using buffer): x: " point.x " y: " point.y " Has clickable point: " out "`n" 113 | return t 114 | } 115 | ``` 116 | 117 | ## Example code AHK v2: ## 118 | 119 | ```ahk 120 | ; to use this example code first convert the type library UIAutomationClient with TypeLib2AHK 121 | 122 | #Include UIAutomationClient_1_0_64bit.ahk2 ; comment out as necessary 123 | ;~ #Include UIAutomationClient_1_0_32bit.ahk2 ; uncomment as necessary 124 | 125 | ; Instantiate the CoClass; retrieves wrapper for IUIAutomation interface 126 | UIA:=CUIAutomation() 127 | ; definition to set the correct variant type for CreatePropertyCondition below 128 | Vt_Bool:=11 129 | 130 | ; Call an interface function; retrieves wrapper of the root IUIAutomationElement in the active window 131 | CurrentWinRootElem := UIA.ElementFromHandle(WinExist("A")) 132 | 133 | t:= "Root element:`n" 134 | ; gather information about the element 135 | t.= ElemInfo(CurrentWinRootElem) 136 | t.= "`n" 137 | 138 | ; The function CreateAndConditionFromArray expects a SAFEARRAY. The SAFEARRAY can be passed directly 139 | ; or as shown here as an AHK object which is then converted by the wrapper 140 | Conditions:=Object() 141 | ; only collect elements which are not offscreen 142 | Conditions.Push(UIA.CreatePropertyCondition(UIAutomationClientTLConst.UIA_IsOffscreenPropertyId, False, Vt_Bool)) 143 | ; only collect elements which are controls 144 | Conditions.Push(UIA.ControlViewCondition) 145 | ; combine the above conditions with and 146 | Condition := UIA.CreateAndConditionFromArray(Conditions) 147 | 148 | ; retrieve all decendants of the root element which meet the conditions 149 | Descendants:=CurrentWinRootElem.FindAll(UIAutomationClientTLConst.TreeScope_Descendants, Condition) 150 | 151 | ; retrieve how many descendants were found 152 | t.="Number of descendants: " Descendants.Length "`n`n" 153 | 154 | ; gather information about the first descendant element 155 | t.= "First descendant element:`n" 156 | ; gather information about the first descendant element 157 | t.=ElemInfo(Descendants.GetElement(1)) 158 | 159 | ; display the result 160 | msgbox t 161 | return 162 | 163 | ElemInfo(elem) 164 | { 165 | ; retrieve various properties of the IUIAutomationElement 166 | t := "Type: " UIAutomationClientTLConst.UIA_ControlTypeIds(elem.CurrentControlType) "`n" 167 | t .= "Name:`t " elem.CurrentName "`n" 168 | ; CurrentBoundingRectangle returns a tagRECT structure which is defined in the type library and also wrapped into an AHK object 169 | rect := elem.CurrentBoundingRectangle 170 | t .= "Location:`t Left: " rect.Left " Top: " rect.Top " Right: " rect.Right " Bottom: " rect.Bottom "`n" 171 | ; GetClickablePoint expects a tagPOINT structure as parameter 172 | ; the structure can either be passed as an instance of the tagPOINT-wrapper as defined in the type library 173 | point:=new tagPOINT() 174 | out:=elem.GetClickablePoint(point) 175 | t.="Clickable point (using tagPoint structure): x: " point.x " y: " point.y " Has clickable point: " out "`n" 176 | ; or it can be passed as a buffer of the right size 177 | VarSetCapacity(p,tagPOINT.__SizeOf(),0) 178 | out:=elem.GetClickablePoint(p) 179 | point:=new tagPOINT(p) 180 | t.="Clickable point (using buffer): x: " point.x " y: " point.y " Has clickable point: " out "`n" 181 | return t 182 | } 183 | ``` 184 | 185 | -------------------------------------------------------------------------------- /Resources/UIStrings.Res: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Elgin1/TypeLib2AHK/0057cd368739fc2174c88dede3232efe5b8ac01b/Resources/UIStrings.Res -------------------------------------------------------------------------------- /TypeLib2AHK.ahk: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Version: MPL 2.0/GPL 3.0/LGPL 3.0 4 | 5 | The contents of this file are subject to the Mozilla Public License Version 6 | 2.0 (the "License"); you may not use this file except in compliance with 7 | the License. You may obtain a copy of the License at 8 | 9 | http://www.mozilla.org/MPL/ 10 | 11 | Software distributed under the License is distributed on an "AS IS" basis, 12 | WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 13 | for the specific language governing rights and limitations under the License. 14 | 15 | The Initial Developer of the Original Code is 16 | Elgin . 17 | Portions created by the Initial Developer are Copyright (C) 2010-2017 18 | the Initial Developer. All Rights Reserved. 19 | 20 | Contributor(s): 21 | 22 | Alternatively, the contents of this file may be used under the terms of 23 | either the GNU General Public License Version 3 or later (the "GPL"), or 24 | the GNU Lesser General Public License Version 3.0 or later (the "LGPL"), 25 | in which case the provisions of the GPL or the LGPL are applicable instead 26 | of those above. If you wish to allow use of your version of this file only 27 | under the terms of either the GPL or the LGPL, and not to allow others to 28 | use your version of this file under the terms of the MPL, indicate your 29 | decision by deleting the provisions above and replace them with the notice 30 | and other provisions required by the GPL or the LGPL. If you do not delete 31 | the provisions above, a recipient may use your version of this file under 32 | the terms of any one of the MPL, the GPL or the LGPL. 33 | 34 | */ 35 | 36 | ; ============================================================================== 37 | ; ============================================================================== 38 | ; known problems 39 | ; ============================================================================== 40 | ; ============================================================================== 41 | 42 | ; parameters of referenced type are not resolved if they point to another 43 | ; referenced type -> probably never happens 44 | 45 | ; ============================================================================== 46 | ; ============================================================================== 47 | ; todo 48 | ; ============================================================================== 49 | ; ============================================================================== 50 | 51 | ; create code for referenced types not covered by the type library? 52 | 53 | ; ============================================================================== 54 | ; ============================================================================== 55 | ; Code 56 | ; ============================================================================== 57 | ; ============================================================================== 58 | 59 | #SingleInstance Force 60 | #Persistent 61 | #Warn All, MsgBox 62 | "".base.__Get := "".base.__Set := "".base.__Call := Func("Default__Warn") 63 | 64 | ; ============================================================================== 65 | ; Example: run to show the type information of a single COM object 66 | ; 67 | ;~ MainApp:=new TypeLib2AHKMain(ComObjCreate("InternetExplorer.Application")) 68 | ; ============================================================================== 69 | 70 | ; default: run to show a list of installed type libraries 71 | MainApp:=new TypeLib2AHKMain() 72 | return 73 | 74 | ;@Ahk2Exe-SetName TypeLib2AHK 75 | ;@Ahk2Exe-SetDescription TypeLib2AHK 76 | ;@Ahk2Exe-SetCopyright Elgin 77 | ;@Ahk2Exe-SetOrigFilename TypeLib2AHK.exe 78 | ;@Ahk2Exe-SetVersion 0.9.0.0 79 | 80 | #Include .\Libraries 81 | #Include TypeLibHelperFunctions.ahk 82 | #Include TypeLibInterfaces.ahk 83 | #Include ApplicationFramework.ahk 84 | #Include VariousFunctions.ahk 85 | 86 | 87 | ; ============================================================================== 88 | ; ============================================================================== 89 | ; class TypeLib2AHK 90 | ; __New(ApplicationName="NoName", DefaultUILanguage="English") 91 | ; ============================================================================== 92 | ; ============================================================================== 93 | 94 | 95 | class TypeLib2AHKMain extends ApplicationFramework 96 | { 97 | AppName:="TypeLib2AHK" 98 | Ver:="0.9.5.0" 99 | AuthorName:="Elgin" 100 | DefUILang:="English" 101 | 102 | BaseCOMObject:=0 103 | BaseCOMIndexInTypeLib:=0 104 | BaseCOMTypeInfo:=0 105 | BaseFileName:="" 106 | ActiveComObjects:=Object() 107 | 108 | __New(InObj=0) ; set InObj to a COM object to retrieve its type library information 109 | { 110 | base.__New(this.AppName, this.Ver, this.DefUILang) 111 | this.Settings.CreateIni("OutPutFolder", A_MyDocuments) 112 | this.Settings.CreateIni("LoadFromFolder", A_MyDocuments) 113 | this.Run(InObj) 114 | } 115 | 116 | CleanUp(ExitReason, ExitCode) 117 | { 118 | base.CleanUp(ExitReason, ExitCode) 119 | } 120 | 121 | LaunchSelectTypeLibraryDialog() 122 | { 123 | this.STLGui:=this.ManagedGuis.NewGUI("TL2AHKSTL", this.Resources.SelectTypeLibraryDialogTitle, "+Resize +MaximizeBox +MinimizeBox") 124 | this.STLGui.OnClose:=ObjBindMethod(this,"STLClose") 125 | this.STLGui.OnEscape:=ObjBindMethod(this,"STLClose") 126 | 127 | this.STLLV:=this.STLGui.Add("ListView", "RegTypeLibs", this.Resources.SelectTypeLibraryDialogLVColumns, "r20 w700", ObjBindMethod(this,"STLLVEvent")) 128 | Loop, Reg, HKEY_CLASSES_ROOT\TypeLib, K 129 | { 130 | IID:=A_LoopRegName 131 | Loop, Reg, HKEY_CLASSES_ROOT\TypeLib\%IID%, K 132 | { 133 | RegRead, LibName, HKEY_CLASSES_ROOT\TypeLib\%IID%\%A_LoopRegName% 134 | If (LibName="") 135 | { 136 | VarSetCapacity(mem, 16, 00) 137 | hr:=DllCall("Ole32\CLSIDFromString", "Str", IID, "Ptr", &mem) 138 | RegExMatch(A_LoopRegName, "^(?P\d+)\.(?P\d+)$", ver) 139 | lib:=0 140 | hr := DllCall("OleAut32\LoadRegTypeLib", "Ptr", &mem, "UShort", verMajor, "UShort", verMinor, "UInt", 0, "Ptr*", lib, "Int") 141 | If ((hr="" or hr>=0) and lib) 142 | { 143 | TypeLib:=new ITypeLib(lib) 144 | Doc:=TypeLib.GetDocumentation(-1) 145 | LibName:=Doc.Name 146 | If (LibName="") 147 | Libname:=Doc.DocString 148 | If (LibName="") 149 | LibName:=this.Resources.SelectTypeLibraryDialogNoNameStr 150 | } 151 | else 152 | LibName:="" 153 | } 154 | If (LibName<>"") ; no need to add a library that can't be opened anyway 155 | this.STLLV.Add("",LibName,A_LoopRegName,IID) 156 | } 157 | } 158 | this.STLLV.ModifyCol(1, "Sort") 159 | pctinfo:=0 160 | out:=0 161 | cnt:=1 162 | for name, obj in GetActiveObjects() 163 | { 164 | base:=ComObjValue(Obj) 165 | If (DllCall(NumGet(NumGet(base+0,"Ptr"), 03*A_PtrSize, "Ptr"), "Ptr", base, "UInt*", pctinfo, "Int")=0 and pctinfo>0 and DllCall(NumGet(NumGet(base+0,"Ptr"), 04*A_PtrSize, "Ptr"), "Ptr", base, "UInt", 0, "UInt", 0, "Ptr*", out, "Int")=0) 166 | { 167 | BaseTypeInfo:=new ITypeInfo(out) 168 | idoc:=BaseTypeInfo.GetDocumentation(-1) 169 | TypeLib:=BaseTypeInfo.GetContainingTypeLib(pindex) 170 | tdoc:=TypeLib.GetDocumentation(-1) ; MEMBERID_NIL 171 | tattr:=TypeLib.GetLibAttr() 172 | 173 | this.STLLV.Insert(cnt, "",Format(this.Resources.SelectTypeLibraryDialogRunningStr, idoc.Name, pindex, tdoc.Name, tdoc.DocString), tattr.wMajorVerNum "." tattr.wMinorVerNum, tattr.guid,cnt) 174 | TypeLib.ReleaseTLibAttr(tattr.__Ptr) 175 | this.ActiveComObjects[cnt]:=Object() 176 | this.ActiveComObjects[cnt].TypeLib:=TypeLib 177 | this.ActiveComObjects[cnt].Index:=pindex 178 | cnt++ 179 | } 180 | } 181 | this.Settings.CreateIni("OutPutV2", 0) 182 | this.STLLV.ModifyCol(1, "AutoHdr") 183 | this.STLLV.ModifyCol(2, "AutoHdr") 184 | this.STLLV.ModifyCol(3, "AutoHdr") 185 | this.STLGui.Add("Button", "Convert", this.Resources.SelectTypeLibraryDialogButtonConvert, "", ObjBindMethod(this,"STLConvertButEvent")) 186 | this.STLGui.Add("Button", "View", this.Resources.SelectTypeLibraryDialogButtonView, "", ObjBindMethod(this,"STLSelectButEvent")) 187 | this.STLGui.Add("Button", "LoadFromFile", this.Resources.SelectTypeLibraryDialogButtonLoad, "x+m", ObjBindMethod(this,"STLLoadFromFileButEvent")) 188 | this.STLGui.Add("Button", "ConvertAll", this.Resources.SelectTypeLibraryDialogButtonConvertAll, "", ObjBindMethod(this,"STLConvertAllButEvent")) 189 | this.STLGui.Add("CheckBox", "CreateV2", this.Resources.SelectTypeLibraryDialogCheckV2, "Checked" this.Settings.OutPutV2, ObjBindMethod(this,"STLConvertCheckV2"), "CreateV2") 190 | this.STLGui.AddSizingInfo("XMin", ["Convert", "View", "LoadFromFile", "ConvertAll", "CreateV2"], 1, "D", 0) 191 | this.STLGui.AddSizingInfo("YMin", "RegTypeLibs", 1, 200, 0, "*", 0, "M", 0, ["Convert", "View", "LoadFromFile", "ConvertAll", "CreateV2"], 0, "C", 0) 192 | this.STLGui.AddSizingInfo("X", "RegTypeLibs", 1, 100, 0) 193 | this.STLGui.Show() 194 | } 195 | 196 | Run(InObj=0) 197 | { 198 | If (!InObj) 199 | { 200 | this.LaunchSelectTypeLibraryDialog() 201 | } 202 | else 203 | { 204 | this.BaseCOMObject:=ComObjValue(InObj) 205 | pctinfo:=0 206 | out:=0 207 | If (DllCall(NumGet(NumGet(this.BaseCOMObject+0,"Ptr"), 03*A_PtrSize, "Ptr"), "Ptr", this.BaseCOMObject, "UInt*", pctinfo, "Int")=0 and pctinfo>0 and DllCall(NumGet(NumGet(this.BaseCOMObject+0,"Ptr"), 04*A_PtrSize, "Ptr"), "Ptr", this.BaseCOMObject, "UInt", 0, "UInt", 0, "Ptr*", out, "Int")=0) 208 | { 209 | this.BaseCOMTypeInfo:=new ITypeInfo(out) 210 | this.TypeLib:=this.BaseCOMTypeInfo.GetContainingTypeLib(pindex) 211 | this.BaseCOMIndexInTypeLib:=pindex 212 | this.ShowInfo(pindex) 213 | } 214 | else 215 | { 216 | this.BaseComObject:=0 217 | msgbox, % this.Resources.LoadCOMFailed 218 | this.LaunchSelectTypeLibraryDialog() 219 | } 220 | } 221 | } 222 | 223 | ShowInfo(Index="") 224 | { 225 | ;~ this.TLShow:=TypeLibToVerboseObj(this.TypeLib, Index) ; show complete information of the type library; very slow and hard to look through... 226 | this.TLShow:=TypeLibToCondensedObj(this.TypeLib, Index) ; show basic, formatted information of the type library 227 | If (this.TLShow) 228 | { 229 | this.TLIGui:=this.ManagedGuis.NewGUI("TL2AHKSTL", "TypeLib2AHK - View Type Library", "+Resize +MaximizeBox +MinimizeBox") 230 | this.TLIGui.OnClose:=ObjBindMethod(this,"TLIClose") 231 | this.TLIGui.OnEscape:=ObjBindMethod(this,"TLIClose") 232 | this.TLITV:=this.TLIGui.Add("TreeView", "TypeLibsView", "", "r20 w700", ObjBindMethod(this,"TLITVEvent")) 233 | this.TLIGui.Add("Button", "Convert", this.Resources.SelectTypeLibraryDialogButtonConvert, "", ObjBindMethod(this,"TLIConvertButEvent")) 234 | this.TLIGui.Add("Button", "Cancel", this.Resources.SelectTypeLibraryDialogButtonCancel, "x+m", ObjBindMethod(this,"TLIClose")) 235 | this.TLIGui.AddSizingInfo("XMin", ["Convert","Cancel"], 1, "D", 0) 236 | this.TLIGui.AddSizingInfo("YMin", "TypeLibsView", 1, 200, 0, "*", 0, "M", 0, ["Convert","Cancel"], 0, "C", 0) 237 | this.TLIGui.AddSizingInfo("X", "TypeLibsView", 1, 100, 0) 238 | this.TLIGui.Show() 239 | this.TLITV.Add(this.Resources.TreeUpdateMsg) 240 | sleep, 10 241 | this.TLITV.Control("-Redraw") 242 | this.TLITV.Delete() 243 | ObjToTreeView(this.TLShow, ObjBindMethod(this,"TLITVFormatFunc")) 244 | this.TLITV.Control("+Redraw") 245 | } 246 | } 247 | 248 | STLClose() 249 | { 250 | ExitApp 251 | } 252 | 253 | STLConvertCheckV2(CtrlHwnd="", GuiEvent="", EventInfo="", ErrorLvl="") 254 | { 255 | this.Settings.OutPutV2:=this.STLGui.Submit().CreateV2 256 | } 257 | 258 | STLLoadFromFileButEvent(CtrlHwnd="", GuiEvent="", EventInfo="", ErrorLvl="") 259 | { 260 | FileSelectFile, FileName, , % this.Settings.LoadFromFolder, % this.Resources.LoadFileSelect, % this.Resources.LoadFileFiles 261 | If (FileName<>"") 262 | { 263 | ResourceNumber:=1 264 | matchcnt:=RegExMatch(FileName, "O)_([0-9]+)$", match) 265 | if (matchcnt>0) 266 | { 267 | ResourceNumber:=match.Value(1) 268 | FileName:=Substr(FileName,1,match.Pos(1)-2) 269 | } 270 | SplitPath, FileName, , OutDir 271 | this.Settings.LoadFromFolder:=OutDir 272 | lib:=0 273 | hr := DllCall("OleAut32\LoadTypeLib", "Str", FileName "\" ResourceNumber, "Ptr*", lib, "Int") 274 | If (!hr) 275 | { 276 | this.TypeLib:=new ITypeLib(lib) 277 | this.BaseFileName:=FileName 278 | this.ShowInfo() 279 | } 280 | else 281 | { 282 | If (hr=-2147319779) 283 | msgbox, % this.Resources.LoadFileFailed FileName " : Library not registered." 284 | else 285 | msgbox, % this.Resources.LoadFileFailed FileName " : 0x" Format("{:x}", hr & 0xFFFFFFFF) " (" hr ")" 286 | } 287 | 288 | } 289 | } 290 | 291 | STLLVEvent(CtrlHwnd="", GuiEvent="", EventInfo="", ErrorLvl="") 292 | { 293 | If (GuiEvent="DOUBLECLICK") 294 | { 295 | this.STLSelectButEvent() 296 | } 297 | } 298 | 299 | STLConvertButEvent(CtrlHwnd="", GuiEvent="", EventInfo="", ErrorLvl="") 300 | { 301 | this.STLGui.SelectViewControl("RegTypeLibs") 302 | row:=this.STLLV.GetNext(0,"Focused") 303 | if (this.ActiveComObjects.Haskey(row)) 304 | { 305 | this.TypeLib:=this.ActiveComObjects[row].TypeLib 306 | this.TLIConvertButEvent() 307 | } 308 | else 309 | { 310 | this.STLLV.GetText(version,row,2) 311 | this.STLLV.GetText(GUID,row,3) 312 | VarSetCapacity(mem, 16, 00) 313 | hr:=DllCall("Ole32\CLSIDFromString", "Str", GUID, "Ptr", &mem) 314 | RegExMatch(version, "^(?P\d+)\.(?P\d+)$", ver) 315 | lib:=0 316 | hr := DllCall("OleAut32\LoadRegTypeLib", "Ptr", &mem, "UShort", verMajor, "UShort", verMinor, "UInt", 0, "Ptr*", lib, "Int") 317 | If ((hr="" or hr>=0) and lib) 318 | { 319 | this.TypeLib:=new ITypeLib(lib) 320 | this.TLIConvertButEvent() 321 | } 322 | else 323 | { 324 | If (hr=-2147319779) 325 | msgbox, % this.Resources.LoadFileFailed " Library not registered." 326 | else 327 | msgbox, % this.Resources.LoadFileFailed " 0x" Format("{:x}", hr & 0xFFFFFFFF) " (" hr ")" 328 | } 329 | } 330 | } 331 | 332 | STLConvertAllButEvent(CtrlHwnd="", GuiEvent="", EventInfo="", ErrorLvl="") ; existing files will not be overwritten 333 | { 334 | FileSelectFolder, FolderName, % "*" this.Settings.OutPutFolder 335 | If (ErrorLevel=1) 336 | return 337 | this.Settings.OutPutFolder:=RegExReplace(FolderName, "\\$") 338 | If (FileExist(this.Settings.OutPutFolder)<>"D") 339 | FileCreateDir, % this.Settings.OutPutFolder 340 | Loop, Reg, HKEY_CLASSES_ROOT\TypeLib, K 341 | { 342 | IID:=A_LoopRegName 343 | Loop, Reg, HKEY_CLASSES_ROOT\TypeLib\%IID%, K 344 | { 345 | VarSetCapacity(mem, 16, 00) 346 | hr:=DllCall("Ole32\CLSIDFromString", "Str", IID, "Ptr", &mem) 347 | RegExMatch(A_LoopRegName, "^(?P\d+)\.(?P\d+)$", ver) 348 | lib:=0 349 | hr := DllCall("OleAut32\LoadRegTypeLib", "Ptr", &mem, "UShort", verMajor, "UShort", verMinor, "UInt", 0, "Ptr*", lib, "Int") 350 | If ((hr="" or hr>=0) and lib) 351 | { 352 | this.TypeLib:=new ITypeLib(lib) 353 | this.ConvertTL() 354 | } 355 | } 356 | } 357 | } 358 | 359 | STLSelectButEvent(CtrlHwnd="", GuiEvent="", EventInfo="", ErrorLvl="") 360 | { 361 | this.STLGui.SelectViewControl("RegTypeLibs") 362 | row:=this.STLLV.GetNext(0,"Focused") 363 | if (this.ActiveComObjects.Haskey(row)) 364 | { 365 | this.TypeLib:=this.ActiveComObjects[row].TypeLib 366 | this.ShowInfo(this.ActiveComObjects[row].Index) 367 | } 368 | else 369 | { 370 | this.STLLV.GetText(version,row,2) 371 | this.STLLV.GetText(GUID,row,3) 372 | VarSetCapacity(mem, 16, 00) 373 | hr:=DllCall("Ole32\CLSIDFromString", "Str", GUID, "Ptr", &mem) 374 | RegExMatch(version, "^(?P\d+)\.(?P\d+)$", ver) 375 | lib:=0 376 | hr := DllCall("OleAut32\LoadRegTypeLib", "Ptr", &mem, "UShort", verMajor, "UShort", verMinor, "UInt", 0, "Ptr*", lib, "Int") ; error handling is done below 377 | If ((hr="" or hr>=0) and lib) 378 | { 379 | this.TypeLib:=new ITypeLib(lib) 380 | this.ShowInfo() 381 | } 382 | else 383 | { 384 | If (hr=-2147319779) 385 | msgbox, % this.Resources.LoadFileFailed " Library not registered." 386 | else 387 | msgbox, % this.Resources.LoadFileFailed " 0x" Format("{:x}", hr & 0xFFFFFFFF) " (" hr ")" 388 | } 389 | } 390 | } 391 | 392 | TLITVFormatFunc(Depth, Index, Value) 393 | { 394 | Out:=Object() 395 | If (IsObject(Value)) 396 | { 397 | Out.Text:=Index 398 | Out.RecurseInto:=1 399 | } 400 | else 401 | { 402 | Out.Text:=Index ": " Value 403 | Out.RecurseInto:=0 404 | } 405 | If (Depth<2) 406 | Out.Options:="Expand" 407 | else 408 | Out.Options:="" 409 | Out.Add:=1 410 | Out.Continue:=1 411 | return Out 412 | } 413 | 414 | TLIClose() 415 | { 416 | this.TLIGui.Hide() 417 | } 418 | 419 | TLIConvertButEvent(CtrlHwnd="", GuiEvent="", EventInfo="", ErrorLvl="") 420 | { 421 | this.TLInfo:=TypeLibToHeadingsObj(this.TypeLib) 422 | bit:=A_PtrSize*8 423 | FileSelectFile, FileName, S 18, % this.Settings.OutPutFolder "\" this.TLInfo._TypeLibraryInfo.Name "_" this.TLInfo._TypeLibraryInfo.wMajorVerNum "_" this.TLInfo._TypeLibraryInfo.wMinorVerNum "_" bit "bit.ahk" (this.Settings.OutPutV2 ? "2":"") 424 | If (FileName<>"") 425 | { 426 | SplitPath, FileName, OutFileName, OutDir 427 | this.Settings.OutPutFolder:=OutDir 428 | File:=FileOpen(FileName, "w") 429 | File.Write(this.MakeHeader(OutFileName)) 430 | If (IsObject(this.TLInfo.COCLASS)) 431 | File.Write(this.MakeCoClass()) 432 | If (IsObject(this.TLInfo.ALIAS)) 433 | File.Write(this.MakeGeneric("ALIAS")) 434 | If (IsObject(this.TLInfo.ENUM)) 435 | File.Write(this.MakeConst()) 436 | If (IsObject(this.TLInfo.RECORD)) 437 | File.Write(this.MakeRecord("Record")) 438 | If (IsObject(this.TLInfo.UNION)) 439 | File.Write(this.MakeRecord("Union")) 440 | If (IsObject(this.TLInfo.INTERFACE)) 441 | File.Write(this.MakeInterface()) 442 | If (IsObject(this.TLInfo.DISPATCH)) 443 | File.Write(this.MakeGeneric("DISPATCH")) 444 | File.Close() 445 | this.TLIGui.Close() 446 | } 447 | } 448 | 449 | ConvertTL() 450 | { 451 | this.TLInfo:=TypeLibToHeadingsObj(this.TypeLib) 452 | bit:=A_PtrSize*8 453 | FileName:=this.Settings.OutPutFolder "\" this.TLInfo._TypeLibraryInfo.Name "_" this.TLInfo._TypeLibraryInfo.wMajorVerNum "_" this.TLInfo._TypeLibraryInfo.wMinorVerNum "_" bit "bit.ahk" (this.Settings.OutPutV2 ? "2":"") 454 | If (FileExist(FileName)) 455 | return 456 | If (FileName<>"") 457 | { 458 | SplitPath, FileName, OutFileName, OutDir 459 | this.Settings.OutPutFolder:=OutDir 460 | File:=FileOpen(FileName, "w") 461 | File.Write(this.MakeHeader(OutFileName)) 462 | If (IsObject(this.TLInfo.COCLASS)) 463 | File.Write(this.MakeCoClass()) 464 | If (IsObject(this.TLInfo.ALIAS)) 465 | File.Write(this.MakeGeneric("ALIAS")) 466 | If (IsObject(this.TLInfo.ENUM)) 467 | File.Write(this.MakeConst()) 468 | If (IsObject(this.TLInfo.RECORD)) 469 | File.Write(this.MakeRecord("Record")) 470 | If (IsObject(this.TLInfo.UNION)) 471 | File.Write(this.MakeRecord("Union")) 472 | If (IsObject(this.TLInfo.INTERFACE)) 473 | File.Write(this.MakeInterface()) 474 | If (IsObject(this.TLInfo.DISPATCH)) 475 | File.Write(this.MakeGeneric("DISPATCH")) 476 | File.Close() 477 | } 478 | } 479 | 480 | MakeHeader(FileName) 481 | { 482 | t:=this.Resources.StartComment 483 | t.=Format(this.Resources.IntroComment1,FileName,this.TLInfo._TypeLibraryInfo.Name,this.TLInfo._TypeLibraryInfo.wMajorVerNum,this.TLInfo._TypeLibraryInfo.wMinorVerNum, this.TLInfo._TypeLibraryInfo.DocString,this.AppName, this.Ver, this.AuthorName) 484 | s:="" 485 | for, index, key in this.TLInfo._TypeLibraryInfo.LibFlagsNames 486 | s.=", " SubStr(key, 9) 487 | t.=Format(this.Resources.IntroComment2, this.TLInfo._TypeLibraryInfo.guid, this.TLInfo._TypeLibraryInfo.lcid,this.TLInfo._TypeLibraryInfo.HelpFile, this.TLInfo._TypeLibraryInfo.HelpContext, SubStr(SYSKIND(this.TLInfo._TypeLibraryInfo.SysKind),5), SubStr(s, 3)) 488 | t.=this.Resources.EndComment 489 | return t 490 | } 491 | 492 | MakeCoClass() 493 | { 494 | t:=this.Resources.StartComment this.Resources.StartComment this.Resources.IntroCoClass this.Resources.StartComment this.Resources.EndComment 495 | for index, obj in this.TLInfo["COCLASS"] 496 | { 497 | Progress, % (Index)/this.TLInfo["COCLASS"].MaxIndex()*100, % Index this.Resources.Of this.TLInfo["COCLASS"].MaxIndex(), % this.Resources.ProgressWindowText "CoClass", % this.Resources.ProgressWindowCaption ": " this.TLInfo._TypeLibraryInfo.Name 498 | TI:=this.TypeLib.GetTypeInfo(obj.Index) 499 | t.=this.Resources.StartComment "; " TI.GetDocumentation(-1).Name "`r`n" this.Resources.EndComment 500 | Attr:=TI.GetTypeAttr() 501 | t.=this.Resources.StartBlockComment this.Resources.GUID Attr.guid "`r`n" 502 | DefName:="" 503 | If (Attr.cImplTypes) 504 | { 505 | If (Attr.typekind=5) ; TKIND_COCLASS 506 | { 507 | Loop, % Attr.cImplTypes 508 | { 509 | ImplT:=TI.GetRefTypeOfImplType(A_Index-1) 510 | Name:=ImplT.GetDocumentation(-1).Name 511 | t.=this.Resources.Implements Name "; " 512 | ImplAttr:=ImplT.GetTypeAttr() 513 | t.=this.Resources.GUID ImplAttr.guid "; " 514 | t.=this.Resources.Flags 515 | for index, flag in IMPLTYPEFLAGS(TI.GetImplTypeFlags(A_Index-1)) 516 | { 517 | If (index>1) 518 | t.=", " 519 | t.=flag 520 | } 521 | t.="`r`n" 522 | If (TI.GetImplTypeFlags(A_Index-1) & 0x1) ; IMPLTYPEFLAG_FDEFAULT 523 | { 524 | DefName:=Name 525 | DefGUID:=ImplAttr.guid 526 | DefTypeKind:=ImplAttr.typekind 527 | } 528 | ImplAttr.ReleaseTypeAttr(ImplAttr.__Ptr) 529 | } 530 | } 531 | } 532 | TI.ReleaseTypeAttr(Attr.__Ptr) 533 | t.=this.Resources.EndBlockComment 534 | If (DefName<>"") 535 | { 536 | t.=TI.GetDocumentation(-1).Name "()`r`n{`r`n try`r`n {`r`n If (impl:=ComObjCreate(""" Attr.guid ""","""DefGUID """))`r`n" 537 | If (DefTypeKind=3) ; Interface 538 | t.=" return new " DefName "(impl)`r`n" 539 | else 540 | t.=" return impl`r`n" 541 | t.=" throw """ DefName this.Resources.CodeComNotInitialized 542 | t.=" }`r`n catch e`r`n" 543 | If (this.Settings.OutPutV2) 544 | t.=" MsgBox, 262160, " DefName " Error, IsObject(e)?""" DefName this.Resources.CodeComNotRegistered ":e.Message`r`n" 545 | else 546 | t.=" MsgBox, 262160, " DefName " Error, % IsObject(e)?""" DefName this.Resources.CodeComNotRegistered ":e.Message`r`n" 547 | t.="}`r`n`r`n" 548 | } 549 | } 550 | Progress, Off 551 | return t 552 | } 553 | 554 | MakeConst() 555 | { 556 | t:=this.Resources.StartComment 557 | t.=this.Resources.StartComment 558 | t.=this.Resources.IntroENUM1 559 | t.=this.Resources.StartComment 560 | t.=this.Resources.EndComment 561 | t.="class " this.TLInfo._TypeLibraryInfo.Name "TLConst`r`n{`r`n" 562 | for index, obj in this.TLInfo.ENUM 563 | { 564 | Progress, % (Index)/this.TLInfo.ENUM.MaxIndex()*100, % Index " of " this.TLInfo.ENUM.MaxIndex(), % this.Resources.ProgressWindowText "Enum", % this.Resources.ProgressWindowCaption ": " this.TLInfo._TypeLibraryInfo.Name 565 | TI:=this.TypeLib.GetTypeInfo(obj.Index) 566 | t.="`t" this.Resources.StartComment 567 | t.="`t" Format(this.Resources.IntroENUM2, TI.GetDocumentation(-1).Name) 568 | t.="`t" this.Resources.EndComment 569 | Attr:=TI.GetTypeAttr() 570 | If (Attr.cVars) 571 | { 572 | vcount:=1 573 | tRev:="`t" TI.GetDocumentation(-1).Name "(Value)`r`n {`r`n static v1:={" 574 | Loop, % Attr.cVars 575 | { 576 | If (Mod(A_Index,126)=0) ; need several variables to store the data due to the limit of 512 operators and operands per expression 577 | { 578 | vcount++ 579 | tRev.="}`r`n static v" vcount ":={" 580 | } 581 | VarDescVar:=TI.GetVarDesc(A_Index-1) 582 | Doc:=TI.GetDocumentation(VarDescVar.memid) 583 | If (VarDescVar.varkind=2) ; Const 584 | { 585 | 586 | t.="`tstatic " Doc.Name " := " Format("0x{1:X}", VarDescVar.oInst) ; "`r`n" 587 | If (Doc.DocString<>"") 588 | t.=" `; " Doc.DocString 589 | t.="`r`n" 590 | tRev.=(A_Index>1 and Mod(A_Index,126)<>0) ? ", " : "" 591 | tRev.=Format("0x{1:X}", VarDescVar.oInst) ":""" Doc.Name """" 592 | } 593 | TI.ReleaseVarDesc(VarDescVar.__Ptr) 594 | } 595 | t.="`r`n" tRev "}`r`n" 596 | Loop, %vcount% 597 | { 598 | If (A_Index>1) 599 | t.=" else`r`n" 600 | t.=" If (v" A_Index "[Value])`r`n" 601 | t.=" return v" A_Index "[Value]`r`n" 602 | } 603 | t.=" }`r`n" 604 | } 605 | TI.ReleaseTypeAttr(Attr.__Ptr) 606 | t.="`r`n" 607 | } 608 | for index, obj in this.TLInfo.MODULE 609 | { 610 | Progress, % (Index)/this.TLInfo.MODULE.MaxIndex()*100, % Index " of " this.TLInfo.MODULE.MaxIndex(), % this.Resources.ProgressWindowText "Module", % this.Resources.ProgressWindowCaption ": " this.TLInfo._TypeLibraryInfo.Name 611 | TI:=this.TypeLib.GetTypeInfo(obj.Index) 612 | t.="`t" this.Resources.StartComment 613 | t.="`t" Format(this.Resources.IntroMODULE2, TI.GetDocumentation(-1).Name) 614 | t.="`t" this.Resources.EndComment 615 | Attr:=TI.GetTypeAttr() 616 | If (Attr.cFuncs) 617 | { 618 | t.=this.Resources.StartBlockComment 619 | Loop, % Attr.cFuncs 620 | { 621 | FuncIndex:=A_Index-1 622 | FuncDescVar:=TI.GetFuncDesc(FuncIndex) 623 | Doc:=TI.GetDocumentation(FuncDescVar.memid) 624 | Name:=Doc.Name 625 | If Name not in QueryInterface,AddRef,Release,GetTypeInfoCount,GetTypeInfo,GetIDsOfNames,Invoke 626 | { 627 | t.=this.Resources.VTablePositon ": " FuncDescVar.oVft//A_PtrSize ":`r`n" 628 | t.=INVOKEKIND(FuncDescVar.invkind) " " 629 | t.=SubStr(VARENUM(FuncDescVar.elemdescFunc.tdesc.vt), 4) " " 630 | t.=Name "(" 631 | ParamNames:=TI.GetNames(FuncDescVar.memid,FuncDescVar.cParams+1) 632 | Loop, % FuncDescVar.cParams 633 | { 634 | If (A_Index>1) 635 | t.=", " 636 | param:=new ELEMDESC(FuncDescVar.lprgelemdescParam+(A_Index-1)*ELEMDESC.SizeOf()) 637 | for index, key in PARAMFLAG(param.paramdesc.wParamFlags) 638 | t.="[" SubStr(key, 11) "] " 639 | vstr:=GetVarStr(param, TI) 640 | If (InStr(vstr,"VT_")=1) 641 | t.=Substr(vstr, 4) ": " 642 | else 643 | t.=vstr ": " 644 | t.=ParamNames[A_Index+1] 645 | If (param.paramdesc.wParamFlags & 0x20) ; Hasdefault 646 | { 647 | t.=" = " param.paramdesc.pPARAMDescEx.varDefaultValue 648 | } 649 | } 650 | t.=")`r`n" 651 | If (Doc.DocString<>"") 652 | t.=Doc.DocString "`r`n" 653 | t.="`r`n" 654 | } 655 | TI.ReleaseFuncDesc(FuncDescVar.__Ptr) 656 | } 657 | t.=this.Resources.StartBlockComment 658 | } 659 | If (Attr.cVars) 660 | { 661 | vcount:=1 662 | tRev:="`t" TI.GetDocumentation(-1).Name "(Value)`r`n {`r`n static v1:={" 663 | Loop, % Attr.cVars 664 | { 665 | If (Mod(A_Index,126)=0) ; need several variables to store the data due to the limit of 512 operators and operands per expression 666 | { 667 | vcount++ 668 | tRev.="}`r`n static v" vcount ":={" 669 | } 670 | VarDescVar:=TI.GetVarDesc(A_Index-1) 671 | Doc:=TI.GetDocumentation(VarDescVar.memid) 672 | If (VarDescVar.varkind=2) ; Const 673 | { 674 | vs:=GetVarStr(VarDescVar.elemdescVar, TI) 675 | If (vs="Vt_Bstr") 676 | t.="`tstatic " Doc.Name " := """ VarDescVar.oInst """ `; Type: " vs ; "`r`n" 677 | else 678 | t.="`tstatic " Doc.Name " := " VarDescVar.oInst " `; Type: " vs ; "`r`n" 679 | If (Doc.DocString<>"") 680 | t.=" `; " Doc.DocString 681 | t.="`r`n" 682 | tRev.=(A_Index>1 and Mod(A_Index,126)<>0) ? ", " : "" 683 | tRev.=Format("0x{1:X}", VarDescVar.oInst) ":""" Doc.Name """" 684 | } 685 | TI.ReleaseVarDesc(VarDescVar.__Ptr) 686 | } 687 | t.="`r`n" tRev "}`r`n" 688 | Loop, %vcount% 689 | { 690 | If (A_Index>1) 691 | t.=" else`r`n" 692 | t.=" If (v" A_Index "[Value])`r`n" 693 | t.=" return v" A_Index "[Value]`r`n" 694 | } 695 | t.=" }`r`n" 696 | } 697 | TI.ReleaseTypeAttr(Attr.__Ptr) 698 | t.="`r`n" 699 | } 700 | Progress, Off 701 | t.="}`r`n`r`n" 702 | return t 703 | } 704 | 705 | MakeInterface() 706 | { 707 | t:=this.Resources.StartComment this.Resources.StartComment this.Resources.IntroINTERFACE this.Resources.StartComment this.Resources.EndComment 708 | for index, obj in this.TLInfo.INTERFACE 709 | { 710 | Progress, % (Index)/this.TLInfo.INTERFACE.MaxIndex()*100, % Index this.Resources.Of this.TLInfo.INTERFACE.MaxIndex(), % this.Resources.ProgressWindowText "Interface", % this.Resources.ProgressWindowCaption ": " this.TLInfo._TypeLibraryInfo.Name 711 | TI:=this.TypeLib.GetTypeInfo(obj.Index) 712 | t.=this.Resources.StartComment 713 | t.="; " TI.GetDocumentation(-1).Name "`r`n" 714 | Attr:=TI.GetTypeAttr() 715 | t.="; " this.Resources.GUID Attr.guid "`r`n" 716 | t.=this.Resources.EndComment 717 | t.="`r`n" 718 | extends:="" 719 | If (Attr.cImplTypes) 720 | { 721 | If (Attr.typekind=3 or Attr.typekind=4 or Attr.typekind=5) ; TKIND_INTERFACE, TKIND_DISPATCH, TKIND_COCLASS 722 | { 723 | Loop, % Attr.cImplTypes 724 | { 725 | Name:=TI.GetRefTypeOfImplType(A_Index-1).GetDocumentation(-1).Name 726 | If (Name<>"IUnknown") 727 | extends.=Name 728 | } 729 | } 730 | else 731 | If (Attr.typekind=6) ; TKIND_ALIAS 732 | { 733 | t.=this.Resources.StartComment 734 | t.=this.Resources.Alias GetVarStrFromTD(Attr.tdescAlias, TI) 735 | t.=this.Resources.EndComment 736 | } 737 | else 738 | { 739 | Loop, % Attr.cImplTypes 740 | { 741 | Name:=TI.GetRefTypeOfImplType(A_Index-1).GetDocumentation(-1).Name 742 | t.=this.Resources.StartComment 743 | t.=this.Resources.Implements Name "`r`n" 744 | t.=this.Resources.EndComment 745 | } 746 | } 747 | } 748 | t.="class " TI.GetDocumentation(-1).Name 749 | if (extends) 750 | t.=" extends " extends "`r`n{" 751 | else 752 | { 753 | t.="`r`n{ `r`n " this.Resources.CodeGeneric 754 | t.=" static __IID := """ Attr.guid """`r`n" "`r`n" 755 | If (this.Settings.OutPutV2) 756 | t.=" __New(p:="""", flag:=1)`r`n {`r`n this.__Type:=""" TI.GetDocumentation(-1).Name """`r`n this.__Value:=p`r`n this.__Flag:=flag`r`n }`r`n`r`n __Delete()`r`n {`r`n this.__Flag? ObjRelease(this.__Value):0`r`n }`r`n`r`n __Vt(n)`r`n {`r`n return NumGet(NumGet(this.__Value+0, ""Ptr"")+n*A_PtrSize,""Ptr"")`r`n }`r`n" 757 | else 758 | t.=" __New(p="""", flag=1)`r`n {`r`n this.__Type:=""" TI.GetDocumentation(-1).Name """`r`n this.__Value:=p`r`n this.__Flag:=flag`r`n }`r`n`r`n __Delete()`r`n {`r`n this.__Flag? ObjRelease(this.__Value):0`r`n }`r`n`r`n __Vt(n)`r`n {`r`n return NumGet(NumGet(this.__Value+0, ""Ptr"")+n*A_PtrSize,""Ptr"")`r`n }`r`n" 759 | ;~ t.=" __New(p="""", flag=1)`r`n {`r`n ObjInsert(this, ""__Type"", """ TI.GetDocumentation(-1).Name """)`r`n ,ObjInsert(this, ""__Value"", p)`r`n ,ObjInsert(this, ""__Flag"", flag)`r`n }`r`n`r`n __Delete()`r`n {`r`n this.__Flag? ObjRelease(this.__Value):0`r`n }`r`n`r`n __Vt(n)`r`n {`r`n return NumGet(NumGet(this.__Value+0, ""Ptr"")+n*A_PtrSize,""Ptr"")`r`n }`r`n" 760 | } 761 | t.="`r`n" 762 | If (Attr.cVars) 763 | { 764 | t.=" " this.Resources.CodeInterfaceConstants 765 | Loop, % Attr.cVars 766 | { 767 | VarDescVar:=TI.GetVarDesc(A_Index-1) 768 | Doc:=TI.GetDocumentation(VarDescVar.memid) 769 | If (VarDescVar.varkind=2) ; Const 770 | { 771 | 772 | t.="`t" Doc.Name " := " Format("0x{1:X}", VarDescVar.oInst) ; "`r`n" 773 | If (Doc.DocString<>"") 774 | t.=" `; " Doc.DocString 775 | t.="`r`n" 776 | } 777 | TI.ReleaseVarDesc(VarDescVar.__Ptr) 778 | } 779 | } 780 | If (Attr.cFuncs) 781 | { 782 | PropertyStore:=Object() 783 | t.=" " this.Resources.CodeInterfaceFunctions 784 | Loop, % Attr.cFuncs 785 | { 786 | FuncIndex:=A_Index-1 787 | FuncDescVar:=TI.GetFuncDesc(FuncIndex) 788 | Doc:=TI.GetDocumentation(FuncDescVar.memid) 789 | Name:=Doc.Name 790 | If (FuncDescVar.invkind=1) ; Is a function not a property 791 | { 792 | ReturnIsHRESULT:=0 793 | HasRetValParam:=0 794 | RetValTypeObj:= 795 | RetValName:="" 796 | t.=" " "; " this.Resources.VTablePositon " " FuncDescVar.oVft//A_PtrSize ": " 797 | t.=INVOKEKIND(FuncDescVar.invkind) " " 798 | result:=FuncDescVar.elemdescFunc.tdesc.vt 799 | If (result=25) ; VT_HRESULT 800 | ReturnIsHRESULT:=1 801 | t.=VARENUM(result) " " 802 | t.=Name "(" 803 | ParamNames:=TI.GetNames(FuncDescVar.memid,FuncDescVar.cParams+1) 804 | Loop, % FuncDescVar.cParams 805 | { 806 | If (A_Index>1) 807 | t.=", " 808 | param:=new ELEMDESC(FuncDescVar.lprgelemdescParam+(A_Index-1)*ELEMDESC.SizeOf()) 809 | vstr:=GetVarStr(param, TI) 810 | If (param.paramdesc.wParamFlags & 0x8) 811 | { 812 | HasRetValParam:=1 813 | RetValName:=ParamNames[A_Index+1] 814 | RetValTypeObj:=GetTypeObj(param, TI) 815 | } 816 | for index, key in PARAMFLAG(param.paramdesc.wParamFlags) 817 | { 818 | t.="[" SubStr(key, 11) "] " 819 | } 820 | If (InStr(vstr,"VT_")=1) 821 | t.=Substr(vstr, 4) ": " 822 | else 823 | t.=vstr ": " 824 | t.=ParamNames[A_Index+1] 825 | If (param.paramdesc.wParamFlags & 0x20) ; Hasdefault 826 | { 827 | t.=" = " param.paramdesc.pPARAMDescEx.varDefaultValue 828 | } 829 | } 830 | t.=")`r`n" 831 | If (Doc.DocString<>"") 832 | t.=" `; " Doc.DocString "`r`n" 833 | 834 | t.=" " Name "(" 835 | Loop, % FuncDescVar.cParams 836 | { 837 | param:=new ELEMDESC(FuncDescVar.lprgelemdescParam+(A_Index-1)*ELEMDESC.SizeOf()) 838 | If (ReturnIsHRESULT and HasRetValParam and (param.paramdesc.wParamFlags & 0x8)) ; skip PARAMFLAG_FRETVAL 839 | continue 840 | If (A_Index>1) 841 | t.=", " 842 | If (param.paramdesc.wParamFlags & 0x2) ; PARAMFLAG_FOUT 843 | t.="byref " 844 | t.=ParamNames[A_Index+1] 845 | If (param.paramdesc.wParamFlags & 0x20) ; Hasdefault 846 | { 847 | If (this.Settings.OutPutV2) 848 | t.=" := " param.paramdesc.pPARAMDescEx.varDefaultValue 849 | else 850 | t.=" = " param.paramdesc.pPARAMDescEx.varDefaultValue 851 | } 852 | else 853 | If (param.paramdesc.wParamFlags & 0x10) ; PARAMFLAG_FOPT 854 | { 855 | If (this.Settings.OutPutV2) 856 | t.=":=0" 857 | else 858 | t.="=0" 859 | } 860 | If (param.tdesc.vt=12) ; VT_Variant 861 | t.=", " ParamNames[A_Index+1] "VariantType" 862 | } 863 | t.=")`r`n {`r`n" 864 | Loop, % FuncDescVar.cParams 865 | { 866 | param:=new ELEMDESC(FuncDescVar.lprgelemdescParam+(A_Index-1)*ELEMDESC.SizeOf()) 867 | If (param.tdesc.vt=12) ; VT_Variant 868 | { 869 | If (A_PtrSize=8) 870 | { 871 | t.=" if (" ParamNames[A_Index+1] "VariantType!=12) `; " ParamNames[A_Index+1] " is not a variant`r`n" 872 | t.=" {`r`n" 873 | t.=" VarSetCapacity(ref" ParamNames[A_Index+1] ",8+2*A_PtrSize)`r`n" 874 | t.=" variant_ref := ComObject(0x400C, &ref" ParamNames[A_Index+1] ")`r`n" 875 | t.=" variant_ref[] := " ParamNames[A_Index+1] "`r`n" 876 | t.=" NumPut(" ParamNames[A_Index+1] "VariantType, ref" ParamNames[A_Index+1] ", 0, ""short"")`r`n" 877 | t.=" }`r`n" 878 | t.=" else`r`n" 879 | t.=" ref" ParamNames[A_Index+1] ":=" ParamNames[A_Index+1] "`r`n" 880 | } 881 | else 882 | { 883 | t.=" if (" ParamNames[A_Index+1] "VariantType=8)`r`n" 884 | t.=" " ParamNames[A_Index+1] ":=DllCall(""oleaut32\SysAllocString"", ""wstr"", ref" ParamNames[A_Index+1] ",""Ptr"")`r`n" 885 | } 886 | } 887 | } 888 | Loop, % FuncDescVar.cParams 889 | { 890 | param:=new ELEMDESC(FuncDescVar.lprgelemdescParam+(A_Index-1)*ELEMDESC.SizeOf()) 891 | to:=GetTypeObj(param, TI) 892 | If ((to[1].Type=26 and to[2].Type=27) or (to[1].Type=27)) ; create code to handle safearrays 893 | { 894 | t.=" If (ComObjValue(" ParamNames[A_Index+1] ") & 0x2000)`r`n" 895 | t.=" ref" ParamNames[A_Index+1] ":=" ParamNames[A_Index+1] "`r`n" 896 | t.=" else`r`n" 897 | t.=" {`r`n" 898 | t.=" ref" ParamNames[A_Index+1] ":=ComObject(0x2003, DllCall(""oleaut32\SafeArrayCreateVector"", ""UInt"", 13, ""UInt"", 0, ""UInt"", " ParamNames[A_Index+1] ".MaxIndex()),1)`r`n" 899 | t.=" For ind, val in " ParamNames[A_Index+1] "`r`n" 900 | t.=" ref" ParamNames[A_Index+1] "[A_Index-1]:= val.__Value, ObjAddRef(val.__Value)`r`n" 901 | t.=" }`r`n" 902 | } 903 | If ((to[1].Type=26 and to[2].Type=29 and to[2].RefType=13) or (to[1].Type=29 and to[1].RefType=13)) ; create code to handle referenced types 904 | { 905 | If ((to[1].Type=26 and to[2].Type=29 and to[2].IsInterface=1) or (to[1].Type=29 and to[1].IsInterface=1)) 906 | { 907 | ; Check if the passed parameter is an object handled by this converted library and pass the referenced COM object 908 | t.=" If (IsObject(" ParamNames[A_Index+1] ") and (ComObjType(" ParamNames[A_Index+1] ")=""""))`r`n" 909 | t.=" ref" ParamNames[A_Index+1] ":=" ParamNames[A_Index+1] ".__Value`r`n" 910 | ; If the parameter is a COM object, pass it through 911 | t.=" else`r`n" 912 | t.=" ref" ParamNames[A_Index+1] ":=" ParamNames[A_Index+1] "`r`n" 913 | } 914 | else 915 | { 916 | ; Check if the passed parameter is an object handled by this converted library and pass the adress of the referenced structure 917 | t.=" If (IsObject(" ParamNames[A_Index+1] ") and (ComObjType(" ParamNames[A_Index+1] ")=""""))`r`n" 918 | t.=" ref" ParamNames[A_Index+1] ":=" ParamNames[A_Index+1] ".__Value`r`n" 919 | ; If the parameter is a structure, pass it's address 920 | t.=" else`r`n" 921 | t.=" ref" ParamNames[A_Index+1] ":=&" ParamNames[A_Index+1] "`r`n" 922 | } 923 | } 924 | } 925 | t.=" res:=DllCall(this.__Vt(" FuncDescVar.oVft//A_PtrSize "), ""Ptr"", this.__Value" 926 | Loop, % FuncDescVar.cParams 927 | { 928 | param:=new ELEMDESC(FuncDescVar.lprgelemdescParam+(A_Index-1)*ELEMDESC.SizeOf()) 929 | t.=", " 930 | If (param.tdesc.vt=12) ; VT_Variant requires different handling in 32/64Bit 931 | { 932 | If (A_PtrSize=4) 933 | { 934 | t.= """int64"", " ParamNames[A_Index+1] "VariantType, ""int64"", ref" ParamNames[A_Index+1] 935 | } 936 | else 937 | { 938 | t.= """Ptr"", &ref" ParamNames[A_Index+1] 939 | } 940 | } 941 | else 942 | { 943 | to:=GetTypeObj(param, TI) 944 | t.="""" GetAHKDllCallTypeFromVarObj(to) """, " 945 | If (ReturnIsHRESULT and HasRetValParam and (param.paramdesc.wParamFlags & 0x8)) 946 | t.="out" 947 | else 948 | If ((to[1].Type=26 and to[2].Type=29 and to[2].RefType=13) or (to[1].Type=29 and to[1].RefType=13)) 949 | t.="ref" ParamNames[A_Index+1] 950 | else 951 | If ((to[1].Type=26 and to[2].Type=27) or (to[1].Type=27)) 952 | t.="ComObjValue(ref" ParamNames[A_Index+1] ")" 953 | else 954 | t.=ParamNames[A_Index+1] 955 | } 956 | } 957 | t.=", """ VT2AHK(result) """)`r`n" 958 | 959 | If (ReturnIsHRESULT and HasRetValParam) 960 | { 961 | t.=" If (res<0 and res<>"""")`r`n Throw Exception(""COM HResult: 0x"" Format(""{:x}"", res & 0xFFFFFFFF) "" from " Name " in " TI.GetDocumentation(-1).Name """)`r`n" 962 | for index, str in GetTypeObjPostProcessing(RetValTypeObj) 963 | t.=" " str "`r`n" 964 | t.=" return out`r`n" 965 | } 966 | else 967 | { 968 | t.=" return res`r`n" 969 | } 970 | t.=" }`r`n`r`n" 971 | } 972 | else ; it's a property 973 | { 974 | If (!IsObject(PropertyStore[Name])) 975 | { 976 | PropertyStore[Name]:=Object() 977 | PropertyStore[Name].Get:=0 978 | PropertyStore[Name].Put:=0 979 | PropertyStore[Name].PutRef:=0 980 | } 981 | vtype:="" 982 | ParamNames:=TI.GetNames(FuncDescVar.memid,FuncDescVar.cParams+1) 983 | param:=new ELEMDESC(FuncDescVar.lprgelemdescParam) 984 | VType.=GetVarStr(param, TI) 985 | VObj:=GetTypeObj(param, TI) 986 | VName:=ParamNames[2] 987 | If (FuncDescVar.invkind=2) 988 | { 989 | PropertyStore[Name].Get:=FuncDescVar.oVft//A_PtrSize 990 | PropertyStore[Name].GetType:=VType 991 | PropertyStore[Name].GetTypeObj:=VObj 992 | PropertyStore[Name].GetName:=VName 993 | PropertyStore[Name].RequiresInitialization:=GetRequiresInitialization(param, TI) 994 | } 995 | else 996 | If (FuncDescVar.invkind=3) 997 | { 998 | PropertyStore[Name].Put:=FuncDescVar.oVft//A_PtrSize 999 | PropertyStore[Name].PutType:=VType 1000 | PropertyStore[Name].PutTypeObj:=VObj 1001 | PropertyStore[Name].PutName:=VName 1002 | } 1003 | else 1004 | If (FuncDescVar.invkind=4) 1005 | { 1006 | PropertyStore[Name].PutRef:=FuncDescVar.oVft//A_PtrSize 1007 | PropertyStore[Name].PutRefType:=VType 1008 | PropertyStore[Name].PutRefTypeObj:=VObj 1009 | PropertyStore[Name].PutRefName:=VName 1010 | } 1011 | } 1012 | } 1013 | TI.ReleaseFuncDesc(FuncDescVar.__Ptr) 1014 | For Name, PropObj in PropertyStore 1015 | { 1016 | t.=" " "; " this.Resources.Property Name 1017 | If (PropObj.Get<>0) 1018 | t.="; " this.Resources.VTablePositon this.Resources.Get PropObj.Get "; output : " PropObj.GetType ": " PropObj.GetName 1019 | If (PropObj.Put<>0) 1020 | t.="; " this.Resources.VTablePositon this.Resources.Put PropObj.Put "; input : " PropObj.PutType ": " PropObj.PutName 1021 | If (PropObj.PutRef<>0) 1022 | t.="; " this.Resources.VTablePositon this.Resources.Put PropObj.PutRef "; input : " PropObj.PutRefType ": " PropObj.PutRefName 1023 | t.="`r`n" 1024 | t.=" " Name "[]`r`n {`r`n" 1025 | If (PropObj.Get<>0) 1026 | { 1027 | t.=" get {`r`n" 1028 | If (PropObj.RequiresInitialization<>"") 1029 | { 1030 | t.=" out:=new " PropObj.RequiresInitialization "()`r`n" 1031 | t.=" If !DllCall(this.__Vt(" PropObj.Get "), ""Ptr"", this.__Value, """ GetAHKDllCallTypeFromVarObj(PropObj.GetTypeObj) """, out.__Value)`r`n" 1032 | } 1033 | else 1034 | t.=" If !DllCall(this.__Vt(" PropObj.Get "), ""Ptr"", this.__Value, """ GetAHKDllCallTypeFromVarObj(PropObj.GetTypeObj) """,out)`r`n" 1035 | t.=" {`r`n" 1036 | for index, str in GetTypeObjPostProcessing(PropObj.GetTypeObj) 1037 | t.=" " str "`r`n" 1038 | t.=" return out`r`n" 1039 | t.=" }`r`n }`r`n" 1040 | } 1041 | If (PropObj.Put<>0) 1042 | { 1043 | t.=" set {`r`n If !DllCall(this.__Vt(" PropObj.Put "), ""Ptr"", this.__Value, """ GetAHKDllCallTypeFromVarObj(PropObj.PutTypeObj) """, value)`r`n" 1044 | t.=" return value`r`n }`r`n" 1045 | } 1046 | If (PropObj.PutRef<>0) 1047 | { 1048 | t.=" set {`r`n If !DllCall(this.__Vt(" PropObj.PutRef "), ""Ptr"", this.__Value, """ GetAHKDllCallTypeFromVarObj(PropObj.PutRefTypeObj) """, value)`r`n" 1049 | t.=" return value`r`n }`r`n" 1050 | } 1051 | t.=" }`r`n" 1052 | } 1053 | } 1054 | TI.ReleaseTypeAttr(Attr.__Ptr) 1055 | t.="}`r`n`r`n" 1056 | } 1057 | Progress, Off 1058 | return t 1059 | } 1060 | 1061 | MakeRecord(Type) ; Type "RECORD", "UNION" 1062 | { 1063 | t:=this.Resources.StartComment 1064 | t.=this.Resources.StartComment 1065 | t.="; " Type "`r`n" 1066 | t.=this.Resources.StartComment 1067 | t.=this.Resources.EndComment 1068 | for index, obj in this.TLInfo[Type] 1069 | { 1070 | Progress, % (Index)/this.TLInfo[Type].MaxIndex()*100, % Index this.Resources.Of this.TLInfo.RECORD.MaxIndex(), % this.Resources.ProgressWindowText Type, % this.Resources.ProgressWindowCaption ": " this.TLInfo._TypeLibraryInfo.Name 1071 | TI:=this.TypeLib.GetTypeInfo(obj.Index) 1072 | t.=this.Resources.StartComment 1073 | t.="; " TI.GetDocumentation(-1).Name "`r`n" 1074 | Attr:=TI.GetTypeAttr() 1075 | t.="; " this.Resources.GUID Attr.guid "`r`n" 1076 | t.=this.Resources.EndComment 1077 | If (Attr.cVars) 1078 | { 1079 | If (this.Settings.OutPutV2) 1080 | t.="class " TI.GetDocumentation(-1).Name "`r`n{`r`n __New(byref p:=""empty"")`r`n {`r`n If (p=""empty"")`r`n {`r`n VarSetCapacity(p,this.__SizeOf(),0)`r`n }`r`n ObjRawSet(this, ""__Value"", &p)`r`n }`r`n`r`n __Get(VarName)`r`n {`r`n If (VarName=""__Value"")`r`n return this__Value`r`n" 1081 | else 1082 | t.="class " TI.GetDocumentation(-1).Name "`r`n{`r`n __New(byref p=""empty"")`r`n {`r`n If (p=""empty"")`r`n {`r`n VarSetCapacity(p,this.__SizeOf(),0)`r`n }`r`n ObjInsert(this, ""__Value"", &p)`r`n }`r`n`r`n __Get(VarName)`r`n {`r`n If (VarName=""__Value"")`r`n return this.__Value`r`n" 1083 | Loop, % Attr.cVars 1084 | { 1085 | VarDescVar:=TI.GetVarDesc(A_Index-1) 1086 | Doc:=TI.GetDocumentation(VarDescVar.memid) 1087 | If (VarDescVar.varkind=0) ; PerInstance 1088 | { 1089 | t.=" If (VarName=""" Doc.Name """)`r`n return NumGet(this.__Value+" VarDescVar.lpvarvalue ", 0, """ VT2AHK(VarDescVar.elemdescVar.tdesc.vt) """) `; " this.Resources.Type GetVarStr(VarDescVar.elemdescVar, TI) 1090 | If (Doc.DocString<>"") 1091 | t.=": " Doc.DocString 1092 | t.="`r`n" 1093 | } 1094 | TI.ReleaseVarDesc(VarDescVar.__Ptr) 1095 | } 1096 | t.=" }`r`n`r`n __Set(VarName, byref Value)`r`n {`r`n" 1097 | Loop, % Attr.cVars 1098 | { 1099 | VarDescVar:=TI.GetVarDesc(A_Index-1) 1100 | Doc:=TI.GetDocumentation(VarDescVar.memid) 1101 | If (VarDescVar.varkind=0) ; PerInstance 1102 | { 1103 | t.=" If (VarName=""" Doc.Name """)`r`n NumPut(Value, this.__Value+" VarDescVar.lpvarvalue ", 0, """ VT2AHK(VarDescVar.elemdescVar.tdesc.vt) """) `; " this.Resources.Type GetVarStr(VarDescVar.elemdescVar, TI) 1104 | If (Doc.DocString<>"") 1105 | t.=": " Doc.DocString 1106 | t.="`r`n" 1107 | } 1108 | Size:=VarDescVar.lpvarvalue+VTSize(VarDescVar.elemdescVar.tdesc.vt) 1109 | TI.ReleaseVarDesc(VarDescVar.__Ptr) 1110 | } 1111 | t.=" return Value`r`n }`r`n`r`n __SizeOf()`r`n {`r`n return " Size "`r`n }`r`n}`r`n`r`n" 1112 | } 1113 | TI.ReleaseTypeAttr(Attr.__Ptr) 1114 | } 1115 | Progress, Off 1116 | return t 1117 | } 1118 | 1119 | MakeGeneric(Type) ; outputs the type library information as formatted comments 1120 | { 1121 | t:=this.Resources.StartComment 1122 | t.=this.Resources.StartComment 1123 | t.="; " Type "`r`n" 1124 | t.=this.Resources.StartComment 1125 | t.=this.Resources.EndComment 1126 | for index, obj in this.TLInfo[type] 1127 | { 1128 | Progress, % (Index)/this.TLInfo[Type].MaxIndex()*100, % Index this.Resources.Of this.TLInfo[Type].MaxIndex(), % this.Resources.ProgressWindowText Type, % this.Resources.ProgressWindowCaption ": " this.TLInfo._TypeLibraryInfo.Name 1129 | TI:=this.TypeLib.GetTypeInfo(obj.Index) 1130 | t.=this.Resources.StartComment 1131 | t.="; " TI.GetDocumentation(-1).Name "`r`n" 1132 | t.=this.Resources.EndComment 1133 | Attr:=TI.GetTypeAttr() 1134 | t.=this.Resources.StartBlockComment 1135 | t.=this.Resources.GUID Attr.guid "`r`n`r`n" 1136 | If (Attr.cVars) 1137 | { 1138 | Loop, % Attr.cVars 1139 | { 1140 | VarDescVar:=TI.GetVarDesc(A_Index-1) 1141 | Doc:=TI.GetDocumentation(VarDescVar.memid) 1142 | If (VarDescVar.varkind=0) ; PerInstance 1143 | { 1144 | t.=Doc.Name "; " this.Resources.Offset VarDescVar.lpvarvalue ", " this.Resources.Type GetVarStr(VarDescVar.elemdescVar, TI) 1145 | If (Doc.DocString<>"") 1146 | t.=" `; " Doc.DocString 1147 | t.="`r`n" 1148 | } 1149 | else 1150 | If (VarDescVar.varkind=2) ; Const 1151 | { 1152 | vs:=GetVarStr(VarDescVar.elemdescVar, TI) 1153 | If (vs="Vt_Bstr") 1154 | t.=Doc.Name " := """ VarDescVar.oInst """ `; " this.Resources.Type vs ; "`r`n" 1155 | else 1156 | t.=Doc.Name " := " VarDescVar.oInst " `; " this.Resources.Type vs ; "`r`n" 1157 | If (Doc.DocString<>"") 1158 | t.=" `; " Doc.DocString 1159 | t.="`r`n" 1160 | } 1161 | TI.ReleaseVarDesc(VarDescVar.__Ptr) 1162 | } 1163 | } 1164 | If (Attr.cFuncs) 1165 | { 1166 | Loop, % Attr.cFuncs 1167 | { 1168 | FuncIndex:=A_Index-1 1169 | FuncDescVar:=TI.GetFuncDesc(FuncIndex) 1170 | Doc:=TI.GetDocumentation(FuncDescVar.memid) 1171 | Name:=Doc.Name 1172 | If Name not in QueryInterface,AddRef,Release,GetTypeInfoCount,GetTypeInfo,GetIDsOfNames,Invoke 1173 | { 1174 | t.=this.Resources.VTablePositon ": " FuncDescVar.oVft//A_PtrSize ":`r`n" 1175 | t.=INVOKEKIND(FuncDescVar.invkind) " " 1176 | t.=SubStr(VARENUM(FuncDescVar.elemdescFunc.tdesc.vt), 4) " " 1177 | t.=Name "(" 1178 | ParamNames:=TI.GetNames(FuncDescVar.memid,FuncDescVar.cParams+1) 1179 | Loop, % FuncDescVar.cParams 1180 | { 1181 | If (A_Index>1) 1182 | t.=", " 1183 | param:=new ELEMDESC(FuncDescVar.lprgelemdescParam+(A_Index-1)*ELEMDESC.SizeOf()) 1184 | for index, key in PARAMFLAG(param.paramdesc.wParamFlags) 1185 | t.="[" SubStr(key, 11) "] " 1186 | vstr:=GetVarStr(param, TI) 1187 | If (InStr(vstr,"VT_")=1) 1188 | t.=Substr(vstr, 4) ": " 1189 | else 1190 | t.=vstr ": " 1191 | t.=ParamNames[A_Index+1] 1192 | If (param.paramdesc.wParamFlags & 0x20) ; Hasdefault 1193 | { 1194 | t.=" = " param.paramdesc.pPARAMDescEx.varDefaultValue 1195 | } 1196 | } 1197 | t.=")`r`n" 1198 | If (Doc.DocString<>"") 1199 | t.=Doc.DocString "`r`n" 1200 | t.="`r`n" 1201 | } 1202 | TI.ReleaseFuncDesc(FuncDescVar.__Ptr) 1203 | } 1204 | } 1205 | If (Attr.cImplTypes) 1206 | { 1207 | If (Attr.typekind=5) ; TKIND_COCLASS 1208 | { 1209 | Loop, % Attr.cImplTypes 1210 | { 1211 | ImplT:=TI.GetRefTypeOfImplType(A_Index-1) 1212 | Name:=ImplT.GetDocumentation(-1).Name 1213 | t.=this.Resources.Implements Name "`r`n" 1214 | Attr:=ImplT.GetTypeAttr() 1215 | t.="; " this.Resources.GUID Attr.guid "`r`n" 1216 | t.=this.Resources.Flags 1217 | for index, flag in IMPLTYPEFLAGS(TI.GetImplTypeFlags(A_Index-1)) 1218 | { 1219 | If (index>1) 1220 | t.=", " 1221 | t.=flag 1222 | } 1223 | } 1224 | } 1225 | else 1226 | { 1227 | Loop, % Attr.cImplTypes 1228 | { 1229 | Name:=TI.GetRefTypeOfImplType(A_Index-1).GetDocumentation(-1).Name 1230 | t.=this.Resources.Implements Name "`r`n" 1231 | t.=this.Resources.Flags 1232 | for index, flag in IMPLTYPEFLAGS(TI.GetImplTypeFlags(A_Index-1)) 1233 | { 1234 | If (index>1) 1235 | t.=", " 1236 | t.=flag 1237 | } 1238 | t.="`r`n" 1239 | } 1240 | } 1241 | } 1242 | If (Attr.typekind=6) ; TKIND_ALIAS 1243 | { 1244 | t.=this.Resources.Alias GetVarStrFromTD(Attr.tdescAlias, TI) "`r`n" 1245 | for index, flag in IMPLTYPEFLAGS(TI.GetImplTypeFlags(A_Index-1)) 1246 | { 1247 | If (index=1) 1248 | t.=this.Resources.Flags 1249 | else 1250 | t.=", " 1251 | t.=flag 1252 | } 1253 | t.="`r`n" 1254 | } 1255 | TI.ReleaseTypeAttr(Attr.__Ptr) 1256 | t.=this.Resources.EndBlockComment 1257 | } 1258 | Progress, Off 1259 | return t 1260 | } 1261 | } 1262 | -------------------------------------------------------------------------------- /UIAutomationClient_Example.ahk: -------------------------------------------------------------------------------- 1 | ; to use this example code first convert the type library UIAutomationClient with TypeLib2AHK 2 | 3 | #Include UIAutomationClient_1_0_64bit.ahk ; comment out as necessary 4 | ;~ #Include UIAutomationClient_1_0_32bit.ahk ; uncomment as necessary 5 | 6 | ; Instantiate the CoClass; retrieves wrapper for IUIAutomation interface 7 | UIA:=CUIAutomation() 8 | 9 | ; definition to set the correct variant type for CreatePropertyCondition below 10 | Vt_Bool:=11 11 | 12 | ; Call an interface function; retrieves wrapper of the root IUIAutomationElement in the active window 13 | CurrentWinRootElem := UIA.ElementFromHandle(WinExist("A")) 14 | 15 | t:= "Root element:`n" 16 | ; gather information about the element 17 | t.= ElemInfo(CurrentWinRootElem) 18 | t.= "`n" 19 | 20 | ; The function CreateAndConditionFromArray expects a SAFEARRAY. The SAFEARRAY can be passed directly 21 | ; or as shown here as an AHK object which is then converted by the wrapper 22 | Conditions:=Object() 23 | ; only collect elements which are not offscreen 24 | Conditions.Push(UIA.CreatePropertyCondition(UIAutomationClientTLConst.UIA_IsOffscreenPropertyId, False, Vt_Bool)) 25 | ; only collect elements which are controls 26 | Conditions.Push(UIA.ControlViewCondition) 27 | ; combine the above conditions with and 28 | Condition := UIA.CreateAndConditionFromArray(Conditions) 29 | 30 | ; retrieve all decendants of the root element which meet the conditions 31 | Descendants:=CurrentWinRootElem.FindAll(UIAutomationClientTLConst.TreeScope_Descendants, Condition) 32 | 33 | ; retrieve how many descendants were found 34 | t.="Number of descendants: " Descendants.Length "`n`n" 35 | 36 | ; gather information about the first descendant element 37 | t.= "First descendant element:`n" 38 | ; gather information about the first descendant element 39 | t.=ElemInfo(Descendants.GetElement(1)) 40 | 41 | ; display the result 42 | msgbox, % t 43 | return 44 | 45 | ElemInfo(elem) 46 | { 47 | ; retrieve various properties of the IUIAutomationElement 48 | t := "Type: " UIAutomationClientTLConst.UIA_ControlTypeIds(elem.CurrentControlType) "`n" 49 | t .= "Name:`t " elem.CurrentName "`n" 50 | ; CurrentBoundingRectangle returns a tagRECT structure which is defined in the type library and also wrapped into an AHK object 51 | rect := elem.CurrentBoundingRectangle 52 | t .= "Location:`t Left: " rect.Left " Top: " rect.Top " Right: " rect.Right " Bottom: " rect.Bottom "`n" 53 | ; GetClickablePoint expects a tagPOINT structure as parameter 54 | ; the structure can either be passed as an instance of the tagPOINT-wrapper as defined in the type library 55 | point:=new tagPOINT() 56 | out:=elem.GetClickablePoint(point) 57 | t.="Clickable point (using tagPoint structure): x: " point.x " y: " point.y " Has clickable point: " out "`n" 58 | ; or it can be passed as a buffer of the right size 59 | VarSetCapacity(p,tagPOINT.__SizeOf(),0) 60 | out:=elem.GetClickablePoint(p) 61 | point:=new tagPOINT(p) 62 | t.="Clickable point (using buffer): x: " point.x " y: " point.y " Has clickable point: " out "`n" 63 | return t 64 | } -------------------------------------------------------------------------------- /UIAutomationClient_Example_AHK v2.ahk2: -------------------------------------------------------------------------------- 1 | ; to use this example code first convert the type library UIAutomationClient with TypeLib2AHK 2 | 3 | #Include UIAutomationClient_1_0_64bit.ahk2 ; comment out as necessary 4 | ;~ #Include UIAutomationClient_1_0_32bit.ahk2 ; uncomment as necessary 5 | 6 | ; Instantiate the CoClass; retrieves wrapper for IUIAutomation interface 7 | UIA:=CUIAutomation() 8 | ; definition to set the correct variant type for CreatePropertyCondition below 9 | Vt_Bool:=11 10 | 11 | ; Call an interface function; retrieves wrapper of the root IUIAutomationElement in the active window 12 | CurrentWinRootElem := UIA.ElementFromHandle(WinExist("A")) 13 | 14 | t:= "Root element:`n" 15 | ; gather information about the element 16 | t.= ElemInfo(CurrentWinRootElem) 17 | t.= "`n" 18 | 19 | ; The function CreateAndConditionFromArray expects a SAFEARRAY. The SAFEARRAY can be passed directly 20 | ; or as shown here as an AHK object which is then converted by the wrapper 21 | Conditions:=Object() 22 | ; only collect elements which are not offscreen 23 | Conditions.Push(UIA.CreatePropertyCondition(UIAutomationClientTLConst.UIA_IsOffscreenPropertyId, False, Vt_Bool)) 24 | ; only collect elements which are controls 25 | Conditions.Push(UIA.ControlViewCondition) 26 | ; combine the above conditions with and 27 | Condition := UIA.CreateAndConditionFromArray(Conditions) 28 | 29 | ; retrieve all decendants of the root element which meet the conditions 30 | Descendants:=CurrentWinRootElem.FindAll(UIAutomationClientTLConst.TreeScope_Descendants, Condition) 31 | 32 | ; retrieve how many descendants were found 33 | t.="Number of descendants: " Descendants.Length "`n`n" 34 | 35 | ; gather information about the first descendant element 36 | t.= "First descendant element:`n" 37 | ; gather information about the first descendant element 38 | t.=ElemInfo(Descendants.GetElement(1)) 39 | 40 | ; display the result 41 | msgbox t 42 | return 43 | 44 | ElemInfo(elem) 45 | { 46 | ; retrieve various properties of the IUIAutomationElement 47 | t := "Type: " UIAutomationClientTLConst.UIA_ControlTypeIds(elem.CurrentControlType) "`n" 48 | t .= "Name:`t " elem.CurrentName "`n" 49 | ; CurrentBoundingRectangle returns a tagRECT structure which is defined in the type library and also wrapped into an AHK object 50 | rect := elem.CurrentBoundingRectangle 51 | t .= "Location:`t Left: " rect.Left " Top: " rect.Top " Right: " rect.Right " Bottom: " rect.Bottom "`n" 52 | ; GetClickablePoint expects a tagPOINT structure as parameter 53 | ; the structure can either be passed as an instance of the tagPOINT-wrapper as defined in the type library 54 | point:=new tagPOINT() 55 | out:=elem.GetClickablePoint(point) 56 | t.="Clickable point (using tagPoint structure): x: " point.x " y: " point.y " Has clickable point: " out "`n" 57 | ; or it can be passed as a buffer of the right size 58 | VarSetCapacity(p,tagPOINT.__SizeOf(),0) 59 | out:=elem.GetClickablePoint(p) 60 | point:=new tagPOINT(p) 61 | t.="Clickable point (using buffer): x: " point.x " y: " point.y " Has clickable point: " out "`n" 62 | return t 63 | } --------------------------------------------------------------------------------