hexagon logo

PC-Dmis Automation C#

So I retired as of last July, but had all this stuff about PC-Dmis Automation which I've finally got around to uploading. Don't know it it is of any interest, but here it is.

The zip file has to Visual Studio project folders, both written in C#. One folder is a Class Library which has all the code for connecting with and dynamically interacting with PC-Dmis. The second folder is a C# application with uses the Class Library to connect and interact with PC-Dmis.

I also included two documents one explains how to setup the two Projects the other is about the application program.

Rather than trying to anticipate every possible question, the provided documents should be sufficient for someone familiar with visual studio and C#. Otherwise, I'll watch for questions to show up here. I can't promise to answer every question, given the complexity of what the answer might require. But I have taken phone calls and zoom opens up the possibility to demo live.

Good Luck

https://drive.google.com/drive/folders/1EDMe0GvN6TC_0Fcr_7Zt7_UqH-EV_8o2?usp=sharing
Parents
  • Tolerance Test program continued

    Code from the PcdmisHelper.cs source file.
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace UpdateTolerances
    {
    
    public partial class MainForm : Form
    {
    //Global variable are declared here
    PCDLRN.Application pcdSession = null; // pcdSession will become the PC-Dmis Application session.
    PCDLRN.IPartPrograms pcdProgramList = null;
    PCDLRN.PartProgram pcdProgram = null;
    PCDLRN.Commands pcdCommands = null;
    PCDLRN.Command pcdCommand = null;
    
    // Name of CMM.
    private string pcdDefaultMachine = "CMM1";
    
    
    
    /// <summary>
    /// Define a delegate that points to a method which has as input, a boolean value.
    /// </summary>
    /// <param name="results">Indicates the true or false status of the connection to PCDLRN.
    /// A delegate is similar to a function pointer in C++. Delegates encapsulate both an object
    /// and a method.
    public delegate void ConnectionDelegate(Boolean results);
    
    /// <summary>
    /// This method is executed in a new thread created in the btnConnect_Click method.
    /// It performs the work of starting PC-Dmis.
    /// </summary>
    /// <returns>A connection status of true or false.</returns>
    private Boolean Connect()
    {
    try
    {
    Type pcdmisType = Type.GetTypeFromProgID("PCDLRN.Application");
    pcdSession = Activator.CreateInstance(pcdmisType) as PCDLRN.Application;
    return true;
    }
    catch (Exception e)
    {
    MessageBox.Show(e.Message, "Problems starting PC-Dmis", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
    return false;
    }
    
    /// <summary>
    /// After PC-Dmis has started, this method is executed in the same thread that started PC-Dmis.
    /// This method exists to provide a convenient way of notifying the user and enabling various
    /// parts of the UI. There may be UI components that you may want disabled till PC-Dmis is
    /// up and running.
    /// </summary>
    /// <param name="cookie"></param>
    private void ConnectionDone(IAsyncResult cookie)
    {
    var target = (Func<Boolean>[emoticon:4191F5EE34E248A29FA0DBE8D975F74A]cookie.AsyncState;
    Boolean connectionResult = target.EndInvoke(cookie);
    
    if (connectionResult) // if connect() returns true
    {
    // If you want to see what a cross-threading error looks like, uncomment the following line.
    //UpdatePcdmisStatus();
    
    // This method is still a part of the new thread PC-Dmis was started in. The user interface
    // is executing in a different thread, thus, accessing the UI component from here, even
    // indirectly by calling a method (UpdatePcdmisStatus) is forbidden.
    
    // However, you can set local variables, or call methods which do not access UI objects.
    
    // While still in the PC-Dmis thread We need a way to create an action that will
    // execute in the application thread to update the application UI.
    // We can get around the cross-threading issue by using a delegate.
    
    // The next line creates an instance object (cb) of the ConnectionDelegate defined at
    // the top of this code. It's basically a pointer to the PCdmis_Connected method.
    ConnectionDelegate cb = new ConnectionDelegate(PCdmis_Connected);
    
    // In the following statement, 'this' is a reference to this form. Here we invoke the
    // form thread (which is the same thread that the UI is running) to execute the method
    // the delegate object (cb) points to, thus avoiding cross-threading issues.
    // The second parameter in the Invoke statement below is an anonymous object, or
    // an object without a name. The boolean value, connectionResult, becomes a property of
    // this new object. This anonymous object will become the required input parameter of
    // the method the delegate object points to.
    this.Invoke(cb, new object[] { connectionResult });
    }
    }
    
    /// <summary>
    /// This method calls a method to update the UI.
    /// </summary>
    /// <param name="IsConnected"></param>
    private void PCdmis_Connected(bool IsConnected)
    {
    btnViewPcdmis.Enabled = IsConnected; // Enable this button if PC-Dmis is connected
    
    UpdatePcdmisStatus();
    }
    
    /// <summary>Execute a PCDMIS program in different thread from calling program.</summary>
    /// <param name="program">Name of program without path or extension</param>
    /// <returns>Returns a boolean indicating whether or not the Pcdmis measurement program started
    /// successfully.</returns>
    /// <remarks>
    /// The execution of the Pcdmis measurement program is performed asynchronusly. This allows the user
    /// DotNet application interface to continue to function during part measurement.</remarks>
    public bool OpenPcdmisProgram(string program)
    {
    pcdProgram = null;
    
    pcdProgramList = pcdSession.PartPrograms;
    pcdProgram = pcdProgramList.Open(program, pcdDefaultMachine);
    if (pcdProgram is null)
    {
    return false;
    }
    else
    {
    return true;
    }
    }
    
    private void ReplaceToleranceValues(double plus, double minus)
    {
    int replacementCount = 0;
    PCDLRN.DimensionCmd dimCmd;
    
    pcdCommands = pcdProgram.Commands;
    
    int commandCount = pcdCommands.Count;
    
    for (int i = 1; i < commandCount; i++)
    {
    pcdCommand = pcdCommands.Item(i as object);
    
    if (pcdCommand is null) continue;
    
    if (pcdCommand.IsDimension)
    {
    dimCmd = pcdCommand.DimensionCommand;
    dimCmd.Plus = plus;
    dimCmd.Minus = minus;
    replacementCount++;
    }
    }
    lblTolCount.Text = replacementCount.ToString();
    }
    
    
    }
    }
    
Reply
  • Tolerance Test program continued

    Code from the PcdmisHelper.cs source file.
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace UpdateTolerances
    {
    
    public partial class MainForm : Form
    {
    //Global variable are declared here
    PCDLRN.Application pcdSession = null; // pcdSession will become the PC-Dmis Application session.
    PCDLRN.IPartPrograms pcdProgramList = null;
    PCDLRN.PartProgram pcdProgram = null;
    PCDLRN.Commands pcdCommands = null;
    PCDLRN.Command pcdCommand = null;
    
    // Name of CMM.
    private string pcdDefaultMachine = "CMM1";
    
    
    
    /// <summary>
    /// Define a delegate that points to a method which has as input, a boolean value.
    /// </summary>
    /// <param name="results">Indicates the true or false status of the connection to PCDLRN.
    /// A delegate is similar to a function pointer in C++. Delegates encapsulate both an object
    /// and a method.
    public delegate void ConnectionDelegate(Boolean results);
    
    /// <summary>
    /// This method is executed in a new thread created in the btnConnect_Click method.
    /// It performs the work of starting PC-Dmis.
    /// </summary>
    /// <returns>A connection status of true or false.</returns>
    private Boolean Connect()
    {
    try
    {
    Type pcdmisType = Type.GetTypeFromProgID("PCDLRN.Application");
    pcdSession = Activator.CreateInstance(pcdmisType) as PCDLRN.Application;
    return true;
    }
    catch (Exception e)
    {
    MessageBox.Show(e.Message, "Problems starting PC-Dmis", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
    return false;
    }
    
    /// <summary>
    /// After PC-Dmis has started, this method is executed in the same thread that started PC-Dmis.
    /// This method exists to provide a convenient way of notifying the user and enabling various
    /// parts of the UI. There may be UI components that you may want disabled till PC-Dmis is
    /// up and running.
    /// </summary>
    /// <param name="cookie"></param>
    private void ConnectionDone(IAsyncResult cookie)
    {
    var target = (Func<Boolean>[emoticon:4191F5EE34E248A29FA0DBE8D975F74A]cookie.AsyncState;
    Boolean connectionResult = target.EndInvoke(cookie);
    
    if (connectionResult) // if connect() returns true
    {
    // If you want to see what a cross-threading error looks like, uncomment the following line.
    //UpdatePcdmisStatus();
    
    // This method is still a part of the new thread PC-Dmis was started in. The user interface
    // is executing in a different thread, thus, accessing the UI component from here, even
    // indirectly by calling a method (UpdatePcdmisStatus) is forbidden.
    
    // However, you can set local variables, or call methods which do not access UI objects.
    
    // While still in the PC-Dmis thread We need a way to create an action that will
    // execute in the application thread to update the application UI.
    // We can get around the cross-threading issue by using a delegate.
    
    // The next line creates an instance object (cb) of the ConnectionDelegate defined at
    // the top of this code. It's basically a pointer to the PCdmis_Connected method.
    ConnectionDelegate cb = new ConnectionDelegate(PCdmis_Connected);
    
    // In the following statement, 'this' is a reference to this form. Here we invoke the
    // form thread (which is the same thread that the UI is running) to execute the method
    // the delegate object (cb) points to, thus avoiding cross-threading issues.
    // The second parameter in the Invoke statement below is an anonymous object, or
    // an object without a name. The boolean value, connectionResult, becomes a property of
    // this new object. This anonymous object will become the required input parameter of
    // the method the delegate object points to.
    this.Invoke(cb, new object[] { connectionResult });
    }
    }
    
    /// <summary>
    /// This method calls a method to update the UI.
    /// </summary>
    /// <param name="IsConnected"></param>
    private void PCdmis_Connected(bool IsConnected)
    {
    btnViewPcdmis.Enabled = IsConnected; // Enable this button if PC-Dmis is connected
    
    UpdatePcdmisStatus();
    }
    
    /// <summary>Execute a PCDMIS program in different thread from calling program.</summary>
    /// <param name="program">Name of program without path or extension</param>
    /// <returns>Returns a boolean indicating whether or not the Pcdmis measurement program started
    /// successfully.</returns>
    /// <remarks>
    /// The execution of the Pcdmis measurement program is performed asynchronusly. This allows the user
    /// DotNet application interface to continue to function during part measurement.</remarks>
    public bool OpenPcdmisProgram(string program)
    {
    pcdProgram = null;
    
    pcdProgramList = pcdSession.PartPrograms;
    pcdProgram = pcdProgramList.Open(program, pcdDefaultMachine);
    if (pcdProgram is null)
    {
    return false;
    }
    else
    {
    return true;
    }
    }
    
    private void ReplaceToleranceValues(double plus, double minus)
    {
    int replacementCount = 0;
    PCDLRN.DimensionCmd dimCmd;
    
    pcdCommands = pcdProgram.Commands;
    
    int commandCount = pcdCommands.Count;
    
    for (int i = 1; i < commandCount; i++)
    {
    pcdCommand = pcdCommands.Item(i as object);
    
    if (pcdCommand is null) continue;
    
    if (pcdCommand.IsDimension)
    {
    dimCmd = pcdCommand.DimensionCommand;
    dimCmd.Plus = plus;
    dimCmd.Minus = minus;
    replacementCount++;
    }
    }
    lblTolCount.Text = replacementCount.ToString();
    }
    
    
    }
    }
    
Children
No Data