Inventor 2010 Default Field Text Add-in

Inventor 2010 Default Field Text Add-in

AlexFielder
Advisor Advisor
2,674 Views
4 Replies
Message 1 of 5

Inventor 2010 Default Field Text Add-in

AlexFielder
Advisor
Advisor
This topic follows on my my other post here: http://bit.ly/2nZqqV

I also originally posted this over at http://theswamp.org but no-one has replied yet, so I'm reposting this here:
{code}Hi folks,

I am using Inventor 2010, VB.NET Express 2008, and Windows XP Pro (x86)
My problem is this: -

We create Inventor drawings (.idw) that we output to AutoCAD 2000 (.dwg) format.

I was hoping to be able to set up "default" entries for a lot of the Inventor-based attributes, and since we can't use Inventor fields* I was hoping to get some suggestions about a way forward.


Specifically:

what's the best storage format for the list of default values?
the best way of displaying these default values to the user?
is it worth having an "Admin" function capable of adding/editing default values built-into the resultant tool? (Would likely mean user authentication I think?)

Thanks in advance.

*Because exporting the .idw files to .dwg format loses any custom fields you setup in the .idw file (or at least it did in IV2009) - amongst other issues.{code}

Before asking for help I already had an idea of how I was going to store the data I collected, but didn't want to push the conversation one way or the other since there had been a rather heated discussion about what format to store data (XML/database etc.) in earlier posts over there.

So far (I think) I've figured out how to capture each of the "prompted entry" tags and strings, but am struggling with the correct terminology for what would commonly be called "thisapplication" on the userform I created.

Can anyone help me please?
Here's the code that loads the add-in, and captures/edits the right-click menu when working with a .idw file: -

(this code works fine provided you remember to change the subkey.version value below)
{code}Imports Inventor
Imports System.Runtime.InteropServices
Imports Microsoft.Win32

Namespace CH2MInventorAddIn
GuidAttribute("97e5aa08-2f2c-4d4d-b1e1-aa0462d7f9c1")> _
Public Class StandardAddInServer
Implements Inventor.ApplicationAddInServer

' Inventor application object.
Private m_inventorApplication As Inventor.Application
Private WithEvents m_PrintPDFsButtonDef As ButtonDefinition
Private WithEvents m_InputEvents As UserInputEvents
Private WithEvents m_EditFieldTextButtonDef As ButtonDefinition

#Region "ApplicationAddInServer Members"

Public Sub Activate(ByVal addInSiteObject As Inventor.ApplicationAddInSite, _
ByVal firstTime As Boolean) Implements Inventor.ApplicationAddInServer.Activate

' This method is called by Inventor when it loads the AddIn.
' The AddInSiteObject provides access to the Inventor Application object.
' The FirstTime flag indicates if the AddIn is loaded for the first time.

' Initialize AddIn members.
m_inventorApplication = addInSiteObject.Application
m_InputEvents = m_inventorApplication.CommandManager.UserInputEvents

' TODO: Add ApplicationAddInServer.Activate implementation.
' e.g. event initialization, command creation etc.

' Create the button definition.
Dim controldefs As ControlDefinitions
controldefs = m_inventorApplication.CommandManager.ControlDefinitions

m_PrintPDFsButtonDef = controldefs.AddButtonDefinition( _
"Print PDF Files", _
"CH2MPrintPDFs", _
CommandTypesEnum.kQueryOnlyCmdType, _
"{97e5aa08-2f2c-4d4d-b1e1-aa0462d7f9c1}", _
"Print PDFs to agreed standards!", _
"Print PDFs")
m_EditFieldTextButtonDef = controldefs.AddButtonDefinition( _
"Edit Field Text (CH2M)", _
"CH2MEditFieldText", _
CommandTypesEnum.kQueryOnlyCmdType, _
"{97e5aa08-2f2c-4d4d-b1e1-aa0462d7f9c1}", _
"Edits Field Text using a custom form", _
"Edit Field Text using our custom form")
If firstTime Then
' adds the button to the drawing annotation command bar.
Dim DWGcommandbar As Inventor.CommandBar
DWGcommandbar = m_inventorApplication.UserInterfaceManager.CommandBars.Item( _
"DLxDrawingAnnotationPanelCmdBar")
DWGcommandbar.Controls.AddButton(m_PrintPDFsButtonDef)
' Also creates a new command bar (toolbar) and makes it visible.
Dim Commandbars As CommandBars
Commandbars = m_inventorApplication.UserInterfaceManager.CommandBars

Dim CH2MCommandbar As CommandBar
CH2Mcommandbar = Commandbars.Add("CH2M Hill", _
"CH2MHillAddInMacros", , _
"{97e5aa08-2f2c-4d4d-b1e1-aa0462d7f9c1}")

' CH2Mcommandbar.Visible = True

CH2Mcommandbar.Controls.AddButton(m_PrintPDFsButtonDef)

End If

End Sub

Public Sub Deactivate() Implements Inventor.ApplicationAddInServer.Deactivate

' This method is called by Inventor when the AddIn is unloaded.
' The AddIn will be unloaded either manually by the user or
' when the Inventor session is terminated.

' TODO: Add ApplicationAddInServer.Deactivate implementation

' Release objects.
Marshal.ReleaseComObject(m_inventorApplication)
m_inventorApplication = Nothing

System.GC.WaitForPendingFinalizers()
System.GC.Collect()

End Sub

Public ReadOnly Property Automation() As Object Implements Inventor.ApplicationAddInServer.Automation

' This property is provided to allow the AddIn to expose an API
' of its own to other programs. Typically, this would be done by
' implementing the AddIn's API interface in a class and returning
' that class object through this property.

Get
Return Nothing
End Get

End Property

Public Sub ExecuteCommand(ByVal commandID As Integer) Implements Inventor.ApplicationAddInServer.ExecuteCommand

' Note:this method is now obsolete, you should use the
' ControlDefinition functionality for implementing commands.

End Sub

#End Region

#Region "COM Registration"

' Registers this class as an AddIn for Inventor.
' This function is called when the assembly is registered for COM.
_
Public Shared Sub Register(ByVal t As Type)

Dim clssRoot As RegistryKey = Registry.ClassesRoot
Dim clsid As RegistryKey = Nothing
Dim subKey As RegistryKey = Nothing

Try
clsid = clssRoot.CreateSubKey("CLSID\" + AddInGuid(t))
clsid.SetValue(Nothing, "CH2M Hill Inventor AddIn")
subKey = clsid.CreateSubKey("Implemented Categories\{39AD2B5C-7A29-11D6-8E0A-0010B541CAA8}")
subKey.Close()

subKey = clsid.CreateSubKey("Settings")
subKey.SetValue("AddInType", "Standard")
subKey.SetValue("LoadOnStartUp", "1")

'subKey.SetValue("SupportedSoftwareVersionLessThan", "")
subKey.SetValue("SupportedSoftwareVersionGreaterThan", "12..")
'subKey.SetValue("SupportedSoftwareVersionEqualTo", "")
'subKey.SetValue("SupportedSoftwareVersionNotEqualTo", "")
'subKey.SetValue("Hidden", "0")
'subKey.SetValue("UserUnloadable", "1")
' change the version below when making major changes otherwise Inventor will not load the newest version
subKey.SetValue("Version", 2)
subKey.Close()

subKey = clsid.CreateSubKey("Description")
subKey.SetValue(Nothing, "CH2M Inventor AddIn, read the help file for more details! Version: " & subKey.GetValue("Version"))

Catch ex As Exception
System.Diagnostics.Trace.Assert(False)
Finally
If Not subKey Is Nothing Then subKey.Close()
If Not clsid Is Nothing Then clsid.Close()
If Not clssRoot Is Nothing Then clssRoot.Close()
End Try

End Sub

' Unregisters this class as an AddIn for Inventor.
' This function is called when the assembly is unregistered.
_
Public Shared Sub Unregister(ByVal t As Type)

Dim clssRoot As RegistryKey = Registry.ClassesRoot
Dim clsid As RegistryKey = Nothing

Try
clssRoot = Microsoft.Win32.Registry.ClassesRoot
clsid = clssRoot.OpenSubKey("CLSID\" + AddInGuid(t), True)
clsid.SetValue(Nothing, "")
clsid.DeleteSubKeyTree("Implemented Categories\{39AD2B5C-7A29-11D6-8E0A-0010B541CAA8}")
clsid.DeleteSubKeyTree("Settings")
clsid.DeleteSubKeyTree("Description")
Catch
Finally
If Not clsid Is Nothing Then clsid.Close()
If Not clssRoot Is Nothing Then clssRoot.Close()
End Try

End Sub

' This property uses reflection to get the value for the GuidAttribute attached to the class.
Public Shared ReadOnly Property AddInGuid(ByVal t As Type) As String
Get
Dim guid As String = ""
Try
Dim customAttributes() As Object = t.GetCustomAttributes(GetType(GuidAttribute), False)
Dim guidAttribute As GuidAttribute = CType(customAttributes(0), GuidAttribute)
guid = "{" + guidAttribute.Value.ToString() + "}"
Finally
AddInGuid = guid
End Try
End Get
End Property

#End Region
#Region "The guts of this section"
Private Sub m_PrintPDFsButtonDef_OnExecute(ByVal Context As Inventor.NameValueMap) Handles m_PrintPDFsButtonDef.OnExecute
MsgBox("Latest Version = " & Now())
End Sub

Private Sub m_InputEvents_OnActivateCommand(ByVal CommandName As String, _
ByVal Context As Inventor.NameValueMap) Handles m_InputEvents.OnActivateCommand

If m_inventorApplication.ActiveDocumentType = DocumentTypeEnum.kDrawingDocumentObject Then
If CommandName = "DrawingEditFieldTextCmd" Then
Dim oDrawDoc As DrawingDocument
oDrawDoc = m_inventorApplication.ActiveDocument
MsgBox("we managed to figure out when the user wants to edit 'field text'!", _
MsgBoxStyle.Exclamation, _
"DrawingEditFieldTextCmd grabbed!")

End If
End If
End Sub

Private Sub m_InputEvents_OnContextMenu(ByVal SelectionDevice As Inventor.SelectionDeviceEnum, _
ByVal AdditionalInfo As Inventor.NameValueMap, _
ByVal CommandBar As Inventor.CommandBar) Handles m_InputEvents.OnContextMenu
Dim oCmdBarControl As CommandBarControl
oCmdBarControl = CommandBar.Controls.Item("DrawingEditFieldTextCmd")
If Not oCmdBarControl Is Nothing Then
' add our button before the normal "Edit Field Text" command!
' MsgBox("OnContextMenu: Commandbar Displayname= " & CommandBar.DisplayName) '& " AdditionalInfo Count= " & AdditionalInfo.Count)
CommandBar.Controls.AddButton(m_EditFieldTextButtonDef, oCmdBarControl.index)
Else
MsgBox("it didn't work!")
End If
End Sub

Private Sub m_EditFieldTextButtonDef_OnExecute(ByVal Context As Inventor.NameValueMap) Handles m_EditFieldTextButtonDef.OnExecute
Dim dbfrm As New frmDBEditFieldText
dbfrm.Show()

End Sub
#End Region
End Class

End Namespace

{code}
Oh and here's the code I've got so far on my userform

{code}Imports System.Data.SqlClient
Imports System.Data
Imports Inventor
Imports System.Runtime.InteropServices
Imports Microsoft.Win32
Imports System.Windows.Forms

Public Class frmDBEditFieldText

Inherits System.Windows.Forms.Form

'Create ADO.NET objects.
Private myConn As SqlConnection
Private myCmd As SqlCommand
Private results As String
Private myDA As SqlDataAdapter
Private myDataset As DataSet
'Create Inventor objects.
Private m_inventorApplication As Inventor.Application
'Create app-specific objects.
Private Project As String
Private FunctionName As String
' when the form loads, I want it to connect to the SQL database that's running the content center which it does below.
Private Sub frmDBEditFieldText_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles MyBase.Load
' password below removed for obvious reasons!
myConn = New SqlConnection("server=bas047\AUTODESKVAULT;uid=sa;pwd=;Database=DWGDetails;Integrated Security=SSPI")

Try
myConn.Open()
'opening the connection
myCmd = New SqlCommand("Select * from DETAILS;", myConn)
'executing the command and assigning it to connection
myDA = New SqlDataAdapter(myCmd)
Dim builder As SqlCommandBuilder = New SqlCommandBuilder(myDA)
' myDataset = New DataSet()
' myDA.Fill(myDataset, "DETAILS")
' DataGridView1.DataSource = myDataset.Tables("DETAILS").DefaultView
' not sure if we need to close the connection here?
' myReader.Close()
' myConn.Close()
MsgBox("Connected to: " & myConn.Database)
Catch ex As Exception
MessageBox.Show(ex.Message, "Connection to SQL Server or database failed!", MessageBoxButtons.OK)
End Try
End Sub

Private Sub ProcessButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ProcessButton.Click
FunctionName = "ProcessButton"
Try
Dim oDrgDoc As DrawingDocument = m_inventorApplication.ActiveDocument
Dim oSht As Sheet = oDrgDoc.ActiveSheet
Dim oBorderDef As BorderDefinition = oSht.Border.Definition
Dim oTag As String ' attribute tag
Dim oString As String ' attribute string

For Each oTextBox As Inventor.TextBox In oBorderDef.Sketch.TextBoxes
' here we would normally check the string to see if it matches a specific string we are looking for.
' but since we want to list all the prompted entries, we will need to modify what we've got and make it simply look for prompted entries!
If IsPromptField(oTextBox.FormattedText) Then
' we're working on a prompted entry!
' get the tag!
oTag = GetPromptField(oTextBox.FormattedText)
' and the string
oString = oSht.Border.GetResultText(oTextBox)
' now we should compare these results to the database!?
MsgBox(oBorderDef.Name, MsgBoxStyle.OkOnly)
End If
Next
Catch ex As Exception
MessageBox.Show(ex.Message, "Uh oh, something is broken with: " & FunctionName, MessageBoxButtons.OK)
End Try

End Sub

Private Sub CancelProcessButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CancelProcessButton.Click
Me.Hide()
End Sub
Private Function IsPromptField(ByVal FormattedText As String) As Boolean
' Verify that this is a prompt field.
If Strings.Left(FormattedText, 7) <> " IsPromptField = False
Exit Function
Else
IsPromptField = True
Exit Function
End If
End Function
Private Function GetPromptField(ByVal FormattedText As String) As String
FunctionName = "GetPromptfield!"
Try
' Verify that this is a prompt field.
If Strings.Left(FormattedText, 7) <> " GetPromptField = ""
Exit Function
End If
' Get the text that is to the right of the first ">" symbol
' and to the left of the last "<" symbol.
' Debug.Print FormattedText
GetPromptField = Strings.Right(FormattedText, Len(FormattedText) - InStr(FormattedText, ">"))
GetPromptField = Strings.Left(GetPromptField, InStr(GetPromptField, "<") - 1)
' Replace any < or > with < and > symbols.
If Project = "ALIQUOT" Then
GetPromptField = Replace(GetPromptField, "<", "<")
GetPromptField = Replace(GetPromptField, ">", ">")
End If
Exit Function
Catch ex As Exception
MessageBox.Show(ex.Message, "Uh oh, something is broken with: " & FunctionName, MessageBoxButtons.OK)
End Try

ErrorFound: GetPromptField = ""

End Function
End Class{code}

For reasons I can't work out, it fails (and properly breaks inventor) at the following line: -

{code}Dim oDrgDoc As DrawingDocument = m_inventorApplication.ActiveDocument{code}

Thanks in advance.

Alex.
0 Likes
2,675 Views
4 Replies
Replies (4)
Message 2 of 5

AlexFielder
Advisor
Advisor
It seems I was missing a couple of important points with my initialisation.

Thanks to the posters here: -

http://bit.ly/44Oakk

I have managed to fix it. see attached for a file that displays the tag and string for every prompted entry in the activesheet.

Now all I have to do is attach the code to the listview on the userform, and have it talk to the database.
0 Likes
Message 3 of 5

AlexFielder
Advisor
Advisor

I've recently found the time to return to this, and have been trying to capture and stop the Prompted Text Dialogue(s) from firing when a new template file is opened.

 

I'm using the Event Watcher tool provided with the SDK, but having captured the following:

 

 

FileUIEvents.OnFileNewDialog
     TemplateDir: "\\server\project\Templates\"
     ParentHWND: 133184
     TemplateFileName: Nothing
     Context: No context information
     HandlingCode: kEventNotHandled
	 
ApplicationEvents.OnNewDocument
     DocumentObject: Nothing
     Context:
          NewFileName = ""
          TemplateFileName = "\\server\project\Templates\Standard.idw"
     BeforeOrAfter: kBefore
     HandlingCode: kEventNotHandled
	 
ApplicationEvents.OnNewView
     ViewObject: Nothing
     Context: No context information
     BeforeOrAfter: kBefore
     HandlingCode: Uknown type specified.
	 
ApplicationEvents.OnInitializeDocument
     DocumentObject: Nothing
     FullDocumentName: ""
     Context: No context information
     BeforeOrAfter: kBefore
     HandlingCode: kEventNotHandled
	 
ApplicationEvents.OnInitializeDocument
     DocumentObject: Standard.idw (_DocumentClass)
     FullDocumentName: ""
     Context: No context information
     BeforeOrAfter: kAfter
     HandlingCode: kEventNotHandled
****** Prompted Text Dialogues appear at this point! ******	 
TransactionEvents.OnCommit
     TransactionObject: New Document (Transaction)
     Context: No context information
     BeforeOrAfter: kBefore
     HandlingCode: kEventHandled
	 
TransactionEvents.OnCommit
     TransactionObject: New Document (Transaction)
     Context: No context information
     BeforeOrAfter: kAfter
     HandlingCode: kEventHandled
	 
ApplicationEvents.OnNewDocument
     DocumentObject: Drawing14 (_DocumentClass)
     Context:
          NewFileName = ""
          TemplateFileName = "\\server\project\Templates\Standard.idw"
     BeforeOrAfter: kAfter
     HandlingCode: kEventNotHandled
	 
ApplicationEvents.OnNewView
     ViewObject: Drawing14 (View)
     Context: No context information
     BeforeOrAfter: kAfter
	 
ApplicationEvents.OnActivateDocument
     DocumentObject: Drawing14 (_DocumentClass)
     Context: No context information
     BeforeOrAfter: kBefore
     HandlingCode: kEventNotHandled
	 
ApplicationEvents.OnNewEditObject
     EditObject: 3XX-XXXXXX REV A - A3 DETAIL OR ASSEMBLY DRAWING:1 (Sheet)
     Context: No context information
     BeforeOrAfter: kBefore
     HandlingCode: kEventNotHandled
	 
ApplicationEvents.OnNewEditObject
     EditObject: 3XX-XXXXXX REV A - A3 DETAIL OR ASSEMBLY DRAWING:1 (Sheet)
     Context: No context information
     BeforeOrAfter: kAfter
     HandlingCode: kEventHandled
	 
ApplicationEvents.OnActivateDocument
     DocumentObject: Drawing14 (_DocumentClass)
     Context: No context information
     BeforeOrAfter: kAfter
     HandlingCode: kEventNotHandled

 I'm a bit stumped as to a)whether it's even possible to prevent these dialogues from displaying & b) exactly which event I should be watching out for.

 

Can anyone offer assistance?

 

Thanks,

 

Alex.

 

 

 

0 Likes
Message 4 of 5

AlexFielder
Advisor
Advisor

I have found a way to prevent the Field Text boxes from firing when you create a new drawing! It's not new or particularly novel but your template file needs to not have ANY borders or titleblocks inserted when you attempt to create a new drawing from it.

 

Below is my code for how I begin to deal with the insertion of the appropriate-sized border/titleblock:

 

 

Private Sub m_applicationEvents_OnNewDocument(ByVal DocumentObject As Inventor._Document, ByVal BeforeOrAfter As Inventor.EventTimingEnum, ByVal Context As Inventor.NameValueMap, ByRef HandlingCode As Inventor.HandlingCodeEnum) Handles m_applicationEvents.OnNewDocument
            'Dim i As Integer = 0
            Dim sContextName As String = ""
            Dim oContextValue As Object = Nothing
            Try

                If BeforeOrAfter = EventTimingEnum.kAfter Then
                    'System.Windows.MessageBox.Show(Context.Count)
                    If DocumentObject.DocumentType = DocumentTypeEnum.kDrawingDocumentObject Then
                        'System.Windows.MessageBox.Show("The .idw has finished opening!")
                        If Context.Count > 0 Then
                            For i As Integer = 1 To Context.Count
                                Dim contextval As Object = Context.Item(i)
                                If TypeOf contextval Is Array Then
                                    Dim temparray As Array
                                    temparray = CType(Context.Item(i), Array)
                                Else
                                    sContextName = Context.Name(i)
                                    oContextValue = Context.Item(i)
                                    'System.Windows.MessageBox.Show(sContextName & " " & oContextValue)
                                    If UCase(oContextValue) = UCase("\\myserver\myproject\Templates\Standard.idw") Then
                                        oIDWDoc = ThisApplication.ActiveDocument ' need to set this here or hilarity will ensue!
                                        ' we know we're using the correct template and can display a form to add borders etc!
                                        Dim dbform As New SQLConnectForm
                                        dbform.Show((New WindowWrapper(ThisApplication.MainFrameHWND)))
                                        'System.Windows.MessageBox.Show("Display the sheet size form here!")
                                        'System.Windows.MessageBox.Show("Then the form to pick default entries based on the previous selection!")
                                        'System.Windows.MessageBox.Show("Then finally we insert the block using osheet.addborder")
                                        Exit For
                                    ElseIf UCase(oContextValue) Like UCase("*STANDARD.IDW*") And Not UCase(oContextValue) = UCase("\\myserver\myproject\Templates\Standard.idw") Then
                                        System.Windows.MessageBox.Show("It looks like you're creating a new Inventor drawing that isn't based on our standard template!" & vbCrLf & _
                                                        "If you don't think you should be seeing this message, please let someone know!")
                                    End If
                                End If
                            Next
                        End If
                    End If
                End If
            Catch ex As Exception
                System.Windows.MessageBox.Show("There was an error in executing the form." & vbLf & "Error Message:" & ex.Message, "DB Form Error!")
            End Try
        End Sub

If anyone is interested I'll also post the userform, SQL Database and connection details I used to make this work.

 

 

Message 5 of 5

whamlin
Advocate
Advocate

I'm wondering if there is a method for Extracting Fields from AutoCAD and Importing them into Inventor for Title Block populating.

0 Likes