bool GenerateUiStatement(Statement s, StringBuilder csharp) { if (s.Args.Count == 0) { return(ErrorMsg("Invalid #ui statement")); } if (s.Args[0].Equals("context", IGNORE_CASE)) { //# ui context [ VS ] [_int_] => _string_ [, _string_, ... ] //# ui context HWND [_int_] => _int_ if (s.Args.Count > 3 || string.IsNullOrEmpty(s.Code)) { return(ErrorMsg("Invalid #ui statement")); } bool uiVsRoot = (s.Args.Count > 1 && s.Args[1] == "VS"); bool uiHwnd = (s.Args.Count > 1 && s.Args[1] == "HWND"); string context; if (uiVsRoot) { context = string.Format("UiFind(UiVsRoot, new object[] {{ {0} }})", s.Code); } else if (uiHwnd) { context = string.Format("AutomationElement.FromHandle((IntPtr)({0}))", s.Code); } else { context = string.Format("UiFind(UiContext, new object[] {{ {0} }})", s.Code); } int timeout = 0; if (s.Args.Count > 1 && !uiVsRoot && !uiHwnd) { timeout = int.Parse(s.Args[1]); } else if (s.Args.Count > 2) { timeout = int.Parse(s.Args[2]); } if (timeout > 0) { csharp.AppendFormat(@" await WaitExpr({0}, () => UiContext = {1});", timeout, context); } else { csharp.AppendFormat(@" UiContext = {0};", context); } } else if (s.Args[0].Equals("pattern", IGNORE_CASE)) { //# ui pattern <_TypeName_> <_VarName_> [ => _string_ [, _string_, ... ] ] //# ui pattern Invoke [ => _string_ [, _string_, ... ] ] //# ui pattern Toggle [ => _string_ [, _string_, ... ] ] if (s.Args.Count < 2) { return(ErrorMsg("Invalid #ui statement")); } string typeName = s.Args[1]; string varName = (s.Args.Count > 2) ? s.Args[2] : string.Empty; if (!UI_TYPES.Contains(typeName)) { return(ErrorMsg("Invalid #ui statement")); } string uiElement; if (!string.IsNullOrEmpty(s.Code)) { uiElement = string.Format("UiFind(UiContext, new object[] {{ {0} }})", s.Code); } else { uiElement = "UiContext"; } string patternTypeId = string.Format("{0}PatternIdentifiers.Pattern", typeName); string patternType = string.Format("{0}Pattern", typeName); if (!string.IsNullOrEmpty(varName)) { csharp.AppendFormat(@" var {0} = {1}.GetCurrentPattern({2}) as {3};", varName, uiElement, patternTypeId, patternType); } else if (typeName == "Invoke" || typeName == "Toggle") { csharp.AppendFormat(@" ({0}.GetCurrentPattern({1}) as {2}).{3}();", uiElement, patternTypeId, patternType, typeName); } else { return(ErrorMsg("Invalid #ui statement")); } } else { return(ErrorMsg("Invalid #ui statement")); } return(true); }
bool GenerateStatement(Statement s, StringBuilder csharp) { switch (s.Type) { case StatementType.Quit: QuitWhenDone = true; break; case StatementType.Macro: if (csharp.Length > 0) { return(ErrorMsg("#macro must be first statement")); } if (!string.IsNullOrEmpty(Name)) { return(ErrorMsg("Only one #macro statement allowed")); } if (s.Args.Count < 1) { return(ErrorMsg("Missing macro name")); } Name = s.Args[0]; break; case StatementType.Thread: if (s.Args.Count < 1) { return(ErrorMsg("Missing thread id")); } if (s.Args[0].Equals("ui", IGNORE_CASE)) { csharp.Append( /** BEGIN generate code **/ @" await SwitchToUIThread();" /** END generate code **/); } else if (s.Args[0].Equals("default", IGNORE_CASE)) { csharp.Append( /** BEGIN generate code **/ @" await SwitchToWorkerThread();" /** END generate code **/); } else { return(ErrorMsg("Unknown thread id")); } break; case StatementType.Reference: if (!s.Args.Any()) { return(ErrorMsg("Missing args for #reference")); } SelectedAssemblies.Add(s.Args.First()); foreach (var ns in s.Args.Skip(1)) { Namespaces.Add(ns); } break; case StatementType.Using: if (!s.Args.Any()) { return(ErrorMsg("Missing args for #using")); } foreach (var ns in s.Args) { Namespaces.Add(ns); } break; case StatementType.Var: if (s.Args.Count < 2) { return(ErrorMsg("Missing args for #var")); } var typeName = s.Args[0]; var varName = s.Args[1]; var initValue = s.Code; if (varName.Where(c => char.IsWhiteSpace(c)).Any()) { return(ErrorMsg("Wrong var name")); } GlobalVars[varName] = new GlobalVar { Type = typeName, Name = varName, InitialValueExpr = initValue }; break; case StatementType.Service: if (s.Args.Count <= 1) { return(ErrorMsg("Missing args for #service")); } var serviceVarName = s.Args[0]; if (serviceVarName.Where(c => char.IsWhiteSpace(c)).Any()) { return(ErrorMsg("Invalid service var name")); } if (ServiceRefs.ContainsKey(serviceVarName)) { return(ErrorMsg("Duplicate service var name")); } ServiceRefs.Add(serviceVarName, new VSServiceRef { Name = serviceVarName, Interface = s.Args[1], Type = s.Args.Count > 2 ? s.Args[2] : s.Args[1] }); break; case StatementType.Call: if (s.Args.Count < 1) { return(ErrorMsg("Missing args for #call")); } var calleeName = s.Args[0]; var callee = GetMacro(calleeName); if (callee == null) { return(ErrorMsg("Undefined macro")); } csharp.AppendFormat( /** BEGIN generate code **/ @" await CallMacro(""{0}"");" /** END generate code **/, calleeName); foreach (var globalVar in callee.GlobalVars.Values) { if (GlobalVars.ContainsKey(globalVar.Name)) { continue; } GlobalVars[globalVar.Name] = new GlobalVar { Type = globalVar.Type, Name = globalVar.Name, IsCallOutput = true }; } break; case StatementType.Wait: if (string.IsNullOrEmpty(s.Code)) { return(ErrorMsg("Missing args for #wait")); } var expr = s.Code; uint timeout = uint.MaxValue; if (s.Args.Count > 0 && !uint.TryParse(s.Args[0], out timeout)) { return(ErrorMsg("Timeout format error in #wait")); } if (s.Args.Count > 2) { var evalVarType = s.Args[1]; var evalVarName = s.Args[2]; csharp.AppendFormat( /** BEGIN generate code **/ @" {0} {1} = default({0}); await WaitExpr({2}, () => {1} = {3});" /** END generate code **/, evalVarType, evalVarName, timeout, expr); } else { csharp.AppendFormat( /** BEGIN generate code **/ @" await WaitExpr({0}, () => {1});" /** END generate code **/, timeout, expr); } break; case StatementType.Ui: if (!GenerateUiStatement(s, csharp)) { return(false); } break; } return(true); }