Quantcast
Channel: Manufacturing DevBlog
Viewing all articles
Browse latest Browse all 516

Handle Enter key from a MiniToolbar

$
0
0

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


Viewing all articles
Browse latest Browse all 516

Trending Articles