Accessing CAD+ Toolset Macro+ framework form the xCAD Macro (.NET)
xCAD macro is a DLL which implements IXCadMacro interface in the Xarial.CadPlusPlus nuget package. Implementation must be also decorated with XCadMacroAttribute
Run method is called every time the macro needs to be executed.
[XCadMacro] [Title("Sample xCAD Macro")] [Description("Exampe of xCAD macro in C#")] [Icon(typeof(Resources), nameof(Resources.macro_icon))] public class XCadMacroSample : IXCadMacro { public void Run(IJobItemRunMacroOperation operation) { } }
Title, description and icon of the macro can be customized using the TitleAttribute, DescriptionAttribute and IconAttribute attributes
Accesing xCAD.NET Objects
xCAD macro is based on xCAD.NET Framework and pointers to the application and documents can be accessed using the code below
IXApplication app = operation.Application; IXDocument doc = operation.Document;
Accessing Arguments
In order to access arguments and the resolved values use the code below
foreach (IXCadMacroArgument arg in operation.Arguments) { var argVal = arg.GetValue(); }
Registering Custom Variables
It is also possible to register custom variables in the Expression Box Control that can be resolved within the macro.
public class MyContext { public string Data { get; } public MyContext(string data) { Data = data; } } public class MyMacroVariableValueProvider : VariableValueProvider<MyContext> { public const string VAR_MY_VAR_NAME = "myVar"; public override object Provide(string name, object[] args, MyContext context) { switch (name) { case VAR_MY_VAR_NAME: return "My Variable Value"; default: throw new NotSupportedException(); } } } public class MyMacroVariableLinks : List<IExpressionVariableLink> { public MyMacroVariableLinks() { Add(new ExpressionVariableLink("MyVar", "My Variable", Resources.variable_icon.ToBitmapImage(true), s => new ExpressionTokenVariable(MyMacroVariableValueProvider.VAR_MY_VAR_NAME, null), false)); } } public class MyMacroVariablesDescriptor : IExpressionVariableDescriptor { public ExpressionVariableArgumentDescriptor[] GetArguments(IExpressionTokenVariable variable, out bool dynamic) { switch (variable.Name) { case MyMacroVariableValueProvider.VAR_MY_VAR_NAME: dynamic = false; return null; default: throw new NotSupportedException(); } } public System.Windows.Media.Brush GetBackground(IExpressionTokenVariable variable) { switch (variable.Name) { case MyMacroVariableValueProvider.VAR_MY_VAR_NAME: return System.Windows.Media.Brushes.LightBlue; default: throw new NotSupportedException(); } } public string GetDescription(IExpressionTokenVariable variable) { switch (variable.Name) { case MyMacroVariableValueProvider.VAR_MY_VAR_NAME: return "My Variable"; default: throw new NotSupportedException(); } } public System.Windows.Media.ImageSource GetIcon(IExpressionTokenVariable variable) { switch (variable.Name) { case MyMacroVariableValueProvider.VAR_MY_VAR_NAME: return Resources.variable_icon.ToBitmapImage(true); default: throw new NotSupportedException(); } } public string GetTitle(IExpressionTokenVariable variable) { switch (variable.Name) { case MyMacroVariableValueProvider.VAR_MY_VAR_NAME: return "MyVar"; default: throw new NotSupportedException(); } } }
[XCadMacro] [XCadMacroCustomVariables(typeof(MyMacroVariablesDescriptor), typeof(MyMacroVariableLinks), typeof(MyMacroVariableValueProvider), MyMacroVariableValueProvider.VAR_MY_VAR_NAME)] public class MyXCadMacro : IXCadMacro
Registering Results
Use the code below to register the result file and set the individual results
public class MyResultFile : IJobItemOperationResultFile { public string Path { get; } public JobItemOperationResultFileStatus_e Status { get; set; } public MyResultFile(string path) { Path = path; Status = JobItemOperationResultFileStatus_e.Initializing; } }
var resFiles = new MyResultFile[] { new MyResultFile(@"D:\file1.stp"), new MyResultFile(@"D:\file2.stp") }; operation.SetResult(resFiles); foreach (var resFile in resFiles) { try { //TODO: process the result file (e.g. export) resFile.Status = JobItemOperationResultFileStatus_e.Succeeded; } catch { resFile.Status = JobItemOperationResultFileStatus_e.Failed; } }
Reporting
It is also possible to report the status and progress messages to the application via various ways
//Report operation issue operation.ReportIssue("Something went wrong", JobItemIssueType_e.Error); try { //TODO: perform operation } catch (Exception ex) { //Reporting the user error operation.ReportIssue(ex.ParseUserError("Unknown error"), JobItemIssueType_e.Error); } //Adds the trace message operation.Logger.Log("Starting the process", XCad.Base.Enums.LoggerMessageSeverity_e.Information); //Adds the log message into the log window operation.Log("Outputting the file"); //Sets the user result to be displayed in the report grid operation.SetResult(50);
Custom Errors
All unhandled exceptions thrown by the macro will be handled by Macro+ and displayed as the Generic Error.
In order to show the content of the exception as the error thrown Xarial.CadPlus.Plus.Exceptions.UserException or implement Xarial.XToolkit.Reporting.IUserMessageException in the custom exception
if (!(doc is IXDrawing)) { throw new UserException("Only drawing documents are supported"); }