Community
PowerShape and PowerMill API Forum
Welcome to Autodesk’s PowerShape and PowerMill API Forums. Share your knowledge, ask questions, and explore popular API topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to connect instance to specific window in C#?

1 REPLY 1
Reply
Message 1 of 2
ikims1126
441 Views, 1 Reply

How to connect instance to specific window in C#?

Hi everybody.

Prior to the text, I apologize for my lack of English.

 

Now I'm making some PowerMILL API program by C# which one runs as a independent program on windows, not plugin.

 

To make it, I referenced 'PowerSolutionDOTNetOLE'.

 

I made a feature to make list of windows of PowerMILL, select and connect to one of'em by using the function Interaction.GetObject().

 

pmObject = RuntimeHelpers.GetObjectValue(Interaction.GetObject(null, "PMILL.Document"));

command worked very well but this phrase can connect the first window of'em.

 

So, I changed the phrase as Interaction.GetObject(SPECIFIC_WINDOW_TITLE, "PMILL.Document"), but this one didn't.

 

The version of PM is 2016~.

 

Please let me know how to solve this problem.

 

Thank you.

1 REPLY 1
Message 2 of 2
barr.jarryd
in reply to: ikims1126

Hey so I ran into the same issue. Luckily I developed a bit of a work around that works.

 

In order for this method to work, you must build a macro that is executed in the session with this code:

 

CREATE PATTERN 'api_start'

ACTIVATE PATTERN 'api_start'

CD "YOUR API EXE LOCATION" // USUALLY IN THE DEBUG FOLDER

INFOBOX NEW "PowerMill Information"
INFOBOX STYLE "NORMAL"
INFOBOX APPEND "Loading Automation API... Please wait."

ole fileaction 'open' 'YOUR API.exe'

 

Once you have that you can add these methods to your C# script to look for that pattern and connect to that instance:

private void Form1_Load(object sender, EventArgs e)
{
    List<object> sessionList = PMAutomation.GetListOfPmComObjects();
    foreach (object obj in sessionList)
    {
        powerMill = new PMAutomation(obj);
        session = powerMill.ActiveProject;
        foreach (PMPattern pattern in session.Patterns)
        {
            if (pattern.Name == "api_start")
            {
                // Connect to the instance with the specific entity
                ConnectToInstance(obj);
                return; // Stop iterating if connected
            }
        }
    }
}
private void ConnectToInstance(object obj)
{
    powerMill = new PMAutomation(obj);
    session = powerMill.ActiveProject;
    session.Patterns.ActiveItem.Delete();
}

 

Unfortunately it is not the faster or cleanest way to do it (Drop down menu with instance list) but it does allow you to open a separate instance of the API and connect directly to the session that you'd.

As an added portion you can 'Dock' it to that instance so that it stays in the session like so:

// INCLUDE THESE IN THE CLASS METHOD BEFORE THE Form1() METHOD

// Import necessary user32.dll functions
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();

[DllImport("user32.dll")]
private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint processId);

[DllImport("user32.dll")]
private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

// ADD THIS TO THE TOP OF THE Form1_Load METHOD

SetParent(this.Handle, GetMainWindowHandleOfActiveProcess());

// ADD THESE METHODS AFTER THE Form1_Load METHOD

private IntPtr GetMainWindowHandleOfActiveProcess()
{
    // Get the active process
    Process activeProcess = GetActiveProcess();

    // Return the main window handle of the active process
    return activeProcess.MainWindowHandle;
}

private Process GetActiveProcess()
{
    // Get the process ID of the foreground window
    GetForegroundWindow();
    GetWindowThreadProcessId(GetForegroundWindow(), out uint processId);

    // Return the process associated with the process ID
    return Process.GetProcessById((int)processId);
}


This method will 'Dock' the API interface into the session so that the interface does not appear on the task bar, and does not send any commands to the wrong instance. You can have as many of these as you want running with a respective PowerMill session, and they will not conflict with each other.

Hope this helps you out a bit.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Technology Administrators