By Adam Nagy
In case of built-in commands like the Extrude command when the user presses the Enter key it has the same effect as if the Apply button was clicked - the changes will be applied and the mini toolbar gets dismissed.
However, when using the MiniToolbar class of the API the Enter key does not dismiss the mini toolbar and there does not seem to be a way to catch the Enter key being pressed either, so that we could dismiss it ourselves. This seems to be an oversight which will be solved in the future, I hope.
In the meantime you can use a keyboard hook to watch out for the Enter key. You could use solutions like this: http://blogs.msdn.com/b/toub/archive/2006/05/03/589423.aspx
I used the MiniToolbar sample from the API Help file and then added the keyboard hook to it:
Imports Inventor
Imports System.Windows.Forms
Imports System.Runtime.InteropServices
PublicClassInterceptKeys
PrivateConst WH_KEYBOARD_LL AsInteger = 13
PrivateConst WM_KEYDOWN AsInteger = &H100
PrivateShared _proc AsLowLevelKeyboardProc =
NewLowLevelKeyboardProc(AddressOf HookCallback)
PrivateShared _hookID AsIntPtr = IntPtr.Zero
PrivateShared _mini AsMyMiniToolbar
PublicSharedSub SetHook(mini AsMyMiniToolbar)
_mini = mini
_hookID = SetHook(_proc)
EndSub
PublicSharedSub UnhookWindowsHookEx()
UnhookWindowsHookEx(_hookID)
EndSub
PrivateSharedFunction SetHook(
proc AsLowLevelKeyboardProc) AsIntPtr
Using curProcess AsProcess = Process.GetCurrentProcess()
Using curModule AsProcessModule = curProcess.MainModule
Return SetWindowsHookEx(WH_KEYBOARD_LL, proc,
GetModuleHandle(curModule.ModuleName), 0)
EndUsing
EndUsing
EndFunction
PrivateDelegateFunctionLowLevelKeyboardProc(
nCode AsInteger, wParam AsIntPtr, lParam AsIntPtr) AsIntPtr
PrivateSharedFunction HookCallback(
nCode AsInteger, wParam AsIntPtr, lParam AsIntPtr) AsIntPtr
If nCode >= 0 AndAlso wParam = NewIntPtr(WM_KEYDOWN) Then
Dim vkCode AsInteger = Marshal.ReadInt32(lParam)
Dim key AsKeys = DirectCast(vkCode, Keys)
System.Diagnostics.Debug.WriteLine(key)
If key = Keys.Enter Then
_mini.m_MiniToolbar_OnOK()
EndIf
EndIf
Return CallNextHookEx(_hookID, nCode, wParam, lParam)
EndFunction
<DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
PrivateSharedFunction SetWindowsHookEx(
idHook AsInteger, lpfn AsLowLevelKeyboardProc,
hMod AsIntPtr, dwThreadId AsUInteger) AsIntPtr
EndFunction
<DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
PrivateSharedFunction UnhookWindowsHookEx(hhk AsIntPtr) _
As<MarshalAs(UnmanagedType.Bool)> Boolean
EndFunction
<DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
PrivateSharedFunction CallNextHookEx(
hhk AsIntPtr, nCode AsInteger, wParam AsIntPtr, lParam AsIntPtr) _
AsIntPtr
EndFunction
<DllImport("kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
PrivateSharedFunction GetModuleHandle(lpModuleName AsString) AsIntPtr
EndFunction
EndClass
PublicClassMyMiniToolbar
'*************************************************************
' The declarations and functions below need to be copied into
' a class module whose name is "clsMiniToolbarEvents". The name can be
' changed but you'll need to change the declaration in the
' calling function "CreateSketchSlotSample" to use the new name.
PrivateWithEvents m_EndCenterOneX AsMiniToolbarValueEditor
PrivateWithEvents m_EndCenterOneY AsMiniToolbarValueEditor
PrivateWithEvents m_EndCenterTwoX AsMiniToolbarValueEditor
PrivateWithEvents m_EndCenterTwoY AsMiniToolbarValueEditor
PrivateWithEvents m_Width AsMiniToolbarValueEditor
PrivateWithEvents m_MiniToolbar AsMiniToolbar
Private m_DisplayCenterline AsMiniToolbarCheckBox
Private m_Sketch AsSketch
Private bCenterline AsBoolean
Private bStop AsBoolean
Private ThisApplication As Inventor.Application
PublicSub Init(app As Inventor.Application)
ThisApplication = app
Dim oActiveEnv AsEnvironment =
ThisApplication.UserInterfaceManager.ActiveEnvironment
If oActiveEnv.InternalName <> "PMxPartSketchEnvironment"And
oActiveEnv.InternalName <> "AMxAssemblySketchEnvironment"And
oActiveEnv.InternalName <> "DLxDrawingSketchEnvironment"Then
MsgBox("Please activate a sketch environment first!")
Exit Sub
EndIf
m_MiniToolbar = ThisApplication.CommandManager.CreateMiniToolbar
m_MiniToolbar.ShowOK = True
m_MiniToolbar.ShowApply = True
m_MiniToolbar.ShowCancel = True
Dim oControls AsMiniToolbarControls
oControls = m_MiniToolbar.Controls
oControls.Item("MTB_Options").Visible = False
Dim oDescriptionLabel AsMiniToolbarControl
oDescriptionLabel = oControls.AddLabel(
"Description",
"This toolbar is to create sketch slot:",
"MiniToolbar sample to show how to create sketch slot.")
oControls.AddNewLine()
' Define the first center position.
Dim oEndCenterOne AsMiniToolbarButton
oEndCenterOne = oControls.AddButton(
"FirstCenter: ",
"First Center: ",
"Specify the first center of sketch slot")
m_EndCenterOneX = oControls.AddValueEditor(
"FirstCenterX", "", ValueUnitsTypeEnum.kLengthUnits, "", "X:")
m_EndCenterOneX.Expression = "0"
m_EndCenterOneX.SetFocus()
m_EndCenterOneY = oControls.AddValueEditor(
"FirstCenterY", "", ValueUnitsTypeEnum.kLengthUnits, "", "Y:")
m_EndCenterOneY.Expression = "0"
oControls.AddNewLine()
' Define the second center position.
Dim oEndCenterTwo AsMiniToolbarButton
oEndCenterTwo = oControls.AddButton(
"SecondCenter:", "Second Center:",
"Specify the second center of sketch slot")
m_EndCenterTwoX = oControls.AddValueEditor(
"SecondCenterX", "", ValueUnitsTypeEnum.kLengthUnits, "", "X:")
m_EndCenterTwoX.Expression = "3"
m_EndCenterTwoY = oControls.AddValueEditor(
"SecondCenterY", "", ValueUnitsTypeEnum.kLengthUnits, "", "Y:")
m_EndCenterTwoY.Expression = "0"
oControls.AddNewLine()
' Define the width of sketch slot.
m_Width = oControls.AddValueEditor(
"WidthValue", "", ValueUnitsTypeEnum.kLengthUnits, "", "Width:")
m_Width.Expression = "1"
' Define if display the center line of sketch slot.
m_DisplayCenterline = oControls.AddCheckBox(
"DisplayCenterline", "Display center line",
"Check this to display center line of slot", True)
' the position of mini-toolbar
Dim oPosition AsPoint2d
oPosition = ThisApplication.TransientGeometry.CreatePoint2d(
ThisApplication.ActiveView.Left, ThisApplication.ActiveView.Top)
m_MiniToolbar.Position = oPosition
m_MiniToolbar.Visible = True
m_MiniToolbar = m_MiniToolbar
m_Sketch = ThisApplication.ActiveEditObject
bStop = False
InterceptKeys.SetHook(Me)
Do
ThisApplication.UserInterfaceManager.DoEvents()
LoopUntil bStop
InterceptKeys.UnhookWindowsHookEx()
EndSub
PrivateSub m_MiniToolbar_OnApply() Handles m_MiniToolbar.OnApply
CreateSlot()
EndSub
PrivateSub m_MiniToolbar_OnCancel() Handles m_MiniToolbar.OnCancel
bStop = True
EndSub
PublicSub m_MiniToolbar_OnOK() Handles m_MiniToolbar.OnOK
bStop = True
CreateSlot()
m_MiniToolbar.Delete()
EndSub
PrivateSub CreateSlot()
IfNot (m_EndCenterOneX.IsExpressionValid And
m_EndCenterOneY.IsExpressionValid And
m_EndCenterTwoX.IsExpressionValid And
m_EndCenterTwoY.IsExpressionValid) Then
MsgBox("Invalid values for end center positions!")
Exit Sub
EndIf
bCenterline = m_DisplayCenterline.Checked
Dim oTG AsTransientGeometry
oTG = ThisApplication.TransientGeometry
Dim oEndCenterOne AsPoint2d
Dim oEndCenterTwo AsPoint2d
Dim oEndArcOne AsSketchArc
Dim oEndArcTwo AsSketchArc
' Start transaction for creating slot.
Dim oTransaction AsTransaction =
ThisApplication.TransactionManager.StartTransaction(
ThisApplication.ActiveDocument, "Create slot")
' If the two centers are vertical
IfMath.Abs(
m_EndCenterOneX.Value - m_EndCenterTwoX.Value) < 0.000001 Then
If (m_EndCenterOneY.Value > m_EndCenterTwoY.Value) Then
oEndCenterOne = oTG.CreatePoint2d(
m_EndCenterOneX.Value, m_EndCenterOneY.Value)
oEndCenterTwo = oTG.CreatePoint2d(
m_EndCenterTwoX.Value, m_EndCenterTwoY.Value)
Else
oEndCenterOne = oTG.CreatePoint2d(
m_EndCenterTwoX.Value, m_EndCenterTwoY.Value)
oEndCenterTwo = oTG.CreatePoint2d(
m_EndCenterOneX.Value, m_EndCenterOneY.Value)
EndIf
If oEndCenterOne.IsEqualTo(oEndCenterTwo, 0.000001) Then
MsgBox("The two centers are coincident!")
Exit Sub
EndIf
' Create the top arc
oEndArcOne = m_Sketch.SketchArcs.AddByCenterStartEndPoint(
oEndCenterOne,
oTG.CreatePoint2d(oEndCenterOne.X + 0.1, oEndCenterOne.Y),
oTG.CreatePoint2d(oEndCenterOne.X - 0.1, oEndCenterOne.Y))
' Create the bottom arc
oEndArcTwo = m_Sketch.SketchArcs.AddByCenterStartEndPoint(
oEndCenterTwo,
oTG.CreatePoint2d(oEndCenterTwo.X - 0.1, oEndCenterTwo.Y),
oTG.CreatePoint2d(oEndCenterTwo.X + 0.1, oEndCenterTwo.Y))
'If the two centers are not vertical
Else
If m_EndCenterOneX.Value < m_EndCenterTwoX.Value Then
oEndCenterOne = oTG.CreatePoint2d(
m_EndCenterOneX.Value, m_EndCenterOneY.Value)
oEndCenterTwo = oTG.CreatePoint2d(
m_EndCenterTwoX.Value, m_EndCenterTwoY.Value)
ElseIf m_EndCenterOneX.Value > m_EndCenterTwoX.Value Then
oEndCenterOne = oTG.CreatePoint2d(
m_EndCenterTwoX.Value, m_EndCenterTwoY.Value)
oEndCenterTwo = oTG.CreatePoint2d(
m_EndCenterOneX.Value, m_EndCenterOneY.Value)
EndIf
If oEndCenterOne.IsEqualTo(oEndCenterTwo, 0.000001) Then
MsgBox("The two centers are coincident!")
Exit Sub
EndIf
oEndArcOne = m_Sketch.SketchArcs.AddByCenterStartEndPoint(
oEndCenterOne,
oTG.CreatePoint2d(
m_EndCenterOneX.Value, m_EndCenterOneY.Value + 0.1),
oTG.CreatePoint2d(
m_EndCenterOneX.Value, m_EndCenterOneY.Value - 0.1))
oEndArcTwo = m_Sketch.SketchArcs.AddByCenterStartEndPoint(
oEndCenterTwo,
oTG.CreatePoint2d(
m_EndCenterTwoX.Value, m_EndCenterTwoY.Value + 0.1),
oTG.CreatePoint2d(
m_EndCenterTwoX.Value, m_EndCenterTwoY.Value - 0.1),
False)
EndIf
Dim dWidth AsDouble
dWidth = m_Width.Value
' Create center line if required
If bCenterline Then
Dim oCenterline AsSketchLine
oCenterline = m_Sketch.SketchLines.AddByTwoPoints(
oEndArcOne.CenterSketchPoint, oEndArcTwo.CenterSketchPoint)
oCenterline.Construction = True
EndIf
Dim oGround1 AsGroundConstraint
Dim oGround2 AsGroundConstraint
oGround1 = m_Sketch.GeometricConstraints.AddGround(
oEndArcOne.CenterSketchPoint)
oGround2 = m_Sketch.GeometricConstraints.AddGround(
oEndArcTwo.CenterSketchPoint)
' Create sketch lines of slot
Dim oLine1 AsSketchLine
Dim oLine2 AsSketchLine
oLine1 = m_Sketch.SketchLines.AddByTwoPoints(
oEndArcOne.StartSketchPoint, oEndArcTwo.EndSketchPoint)
oLine2 = m_Sketch.SketchLines.AddByTwoPoints(
oEndArcOne.EndSketchPoint, oEndArcTwo.StartSketchPoint)
' Add geometric constraints to the sketch entities
Call m_Sketch.GeometricConstraints.AddEqualRadius(
oEndArcOne, oEndArcTwo)
Call m_Sketch.GeometricConstraints.AddTangent(
oLine1, oEndArcOne)
Call m_Sketch.GeometricConstraints.AddTangent(
oLine1, oEndArcTwo)
Call m_Sketch.GeometricConstraints.AddTangent(
oLine2, oEndArcOne)
Call m_Sketch.GeometricConstraints.AddTangent(
oLine2, oEndArcTwo)
' Add dimensional constraints to the sketch entities
Dim oDiameter AsDiameterDimConstraint
oDiameter = m_Sketch.DimensionConstraints.AddDiameter(
oEndArcOne, oEndArcOne.CenterSketchPoint.Geometry)
oDiameter.Parameter.Value = dWidth
ThisApplication.ActiveDocument.Update()
oDiameter.Delete()
oGround1.Delete()
oGround2.Delete()
oTransaction.End()
EndSub
EndClass
And then you can use it like this from your command's event handler:
ProtectedOverridesSub ButtonDefinition_OnExecute(
ByVal context As Inventor.NameValueMap)
Dim mtb AsNewMyMiniToolbar
mtb.Init(InventorApplication)
EndSub