VSTO / Word 2003 events

We are working on a smart client / workflow solution with VSTO and Word 2003.  In our xml schema we have elements which are occurring subsequently. For example like this:< xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

<heading> Some heading</heading>

<text block>first block </text block>

<text block>second block </text block>

<text block>third block </text block>

<text block>fourth block </text block>

 

We cannot tell beforehand how many text blocks user would have. It would be handy if you could do so, that then user strikes enter key, the new text block and its placeholder would appear.

 

Problem:           Word 2003 + Enter
Description:       After InsertParagraph (=keypress Enter) add Tags outside Paragraph

How to: capture KeyDown event word 2003 or
capture InsertParagraph event  

 

If you could show some light that would be great.  Thanks,

~Brett



Answer this question

VSTO / Word 2003 events

  • Schakal

    Why wouldn't you add some UI (like button - "Click me to add another paragraph") to the programmable task pane (aka ActionsPane) to let the user drive the creation of the paragraphs rather than determining this automatically based on the enter key The enter keys may appear in places you would not  expect.

  • jim3891

    This could be done , but the question was how to automatically make this happen. The sample code I provided should be modified to make it more robust for an actual application, for example only check for new paragraphs if they are added to a particluar node.

    Paul

  • Pinball

    Hi,

    I have been looking into this question during the last week and may have found a workaround for your scenario. There is no way from withing Word to monitor the key press events. So I had to come up with another way. I have created some code that starts a timer and monitors the number of paragraphs in the document. When a new one is added it selects the previous paragraph.
     

    Paul Stubbs
    Program Manager
    Microsoft
    http://blogs.msdn.com/pstubbs/

     Here is the code.

    Public Class ThisDocument< xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

        Dim pcount As Integer

        Dim WithEvents timer As New System.Windows.Forms.Timer()

     

        Private Sub ThisDocument_Open() Handles Me.Open

            'count the number of paragraphs

            pcount = Me.Paragraphs.Count

     

            'set the timer interval

            timer.Interval = 750

            'start the timer

            timer.Start()

     

        End Sub

        Private Sub ThisDocument_Startup(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Startup

     

        End Sub

     

        Private Sub ThisDocument_Shutdown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shutdown

            'stop the timer

            timer.Stop()

        End Sub

     

        Private Sub timer_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles timer.Tick

            If (Me.Paragraphs.Count > pcount) Then

                'put the added paragraph in a bookmark

                Me.Paragraphs.Item(Me.Paragraphs.Count - 1).Range.Select()

                'Now that you have the range of the previous paragraph you

                'can wrap it in a bookmark or XMLNode.

     

                'set the new count

                pcount = Me.Paragraphs.Count

                'TODO: manage the deletion of paragraphs

            End If

     

        End Sub

    End Class



  • thelovebadger

    Hi Brett

    Here is some code that hooks a keyboard for Outlook and will work the same in word, you have to be careful to make sure callnexthook through,

    Appologies for layout, basically the Top part is the definitions, You can call HookKeyboard and Unhook as required, I would advise saving your work regularly whilst playing with this as the Keyboard Control is literal and can stop you being able to do anything in word :)

    Good Luck

    Mike Walker
    Visual Developer VSTO

            Private Declare Function GetFocus Lib "user32" Alias "GetFocus" () As Integer< xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

     

            Private Declare Function UnhookWindowsHookEx Lib "user32" _

        (ByVal hHook As Integer) As Integer

     

            Private Declare Function SetWindowsHookEx Lib "user32" _

              Alias "SetWindowsHookExA" (ByVal idHook As Integer, _

              ByVal lpfn As KeyboardHookDelegate, ByVal hmod As Integer, _

              ByVal dwThreadId As Integer) As Integer

     

            Private Declare Function GetAsyncKeyState Lib "user32" _

              (ByVal vKey As Integer) As Integer

     

            Private Declare Function CallNextHookEx Lib "user32" _

              (ByVal hHook As Integer, _

              ByVal nCode As Integer, _

              ByVal wParam As Integer, _

              ByVal lParam As KBDLLHOOKSTRUCT) As Integer

     

            Private Structure KBDLLHOOKSTRUCT

                Public vkCode As Integer

                Public scanCode As Integer

                Public flags As Integer

                Public time As Integer

                Public dwExtraInfo As Integer

            End Structure

     

            ' Low-Level Keyboard Constants

            Private Const HC_ACTION As Integer = 0

            Private Const LLKHF_EXTENDED As Integer = &H1

            Private Const LLKHF_INJECTED As Integer = &H10

            Private Const LLKHF_ALTDOWN As Integer = &H20

            Private Const LLKHF_UP As Integer = &H80

     

            ' Virtual Keys

            Private Const VK_TAB = &H9

            Private Const VK_CONTROL = &H11

            Private Const VK_ESCAPE = &H1B

            Private Const VK_DELETE = &H2E

            Private Const VK_ALT = &H12&

     

            Private Const WH_KEYBOARD_LL As Integer = 13&

            Private KeyboardHandle As Integer

     

     

            Private Delegate Function KeyboardHookDelegate( _

      ByVal Code As Integer, _

      ByVal wParam As Integer, ByRef lParam As KBDLLHOOKSTRUCT) _

                   As Integer

     

            <System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.FunctionPtr)> _

            Private callback As KeyboardHookDelegate

     

            ' Implement this function to block as many

            ' key combinations as you'd like

            Private Function IsHooked( _

              ByRef Hookstruct As KBDLLHOOKSTRUCT) As Boolean

     

                Debug.WriteLine("Hookstruct.vkCode: " & Hookstruct.vkCode & " - Time: " & Hookstruct.time.ToString() & " - Flags: " & Hookstruct.flags.ToString() & " - Extra:" & Hookstruct.dwExtraInfo.ToString())

     

     

                If (Hookstruct.vkCode = System.Windows.Forms.Keys.Enter And CBool(GetAsyncKeyState(VK_CONTROL))) Then

                    'CTRL + ENTER Pressed

                End If

                If (Hookstruct.vkCode = System.Windows.Forms.Keys.D And CBool(GetAsyncKeyState(VK_CONTROL))) Then

                    GoTo Delete

                End If

     

                If (Hookstruct.vkCode = System.Windows.Forms.Keys.S And CBool(GetAsyncKeyState(VK_CONTROL))) Then

                   ' CTRL S Pressed
               
    End If

     

                If (Hookstruct.vkCode = System.Windows.Forms.Keys.O And CBool(GetAsyncKeyState(VK_CONTROL))) Then

                    Dim cn As String = FWBS.Common.Functions.GetWindowClassName(GetFocus())

                    Debug.WriteLine(cn)

                    If cn = "SUPERGRID" Then

                        If (Session.OMS.IsLoggedIn) Then

                            _oms.RunCommand(_oms, "SYSTEM;OPEN")

                            Return True

                        End If

                    End If

                End If

     

                If Hookstruct.vkCode = VK_DELETE Then

                    If CBool(GetAsyncKeyState(VK_CONTROL)) = False And CBool(GetAsyncKeyState(VK_ALT)) = False Then

                    End If

                End If

     

                Return False

     

            End Function

     

            Private Sub HookedState(ByVal Text As String)

                Debug.WriteLine(Text)

            End Sub

     

            Private Function KeyboardCallback(ByVal Code As Integer, _

              ByVal wParam As Integer, _

              ByRef lParam As KBDLLHOOKSTRUCT) As Integer

     

                If (Code = HC_ACTION) Then

                    Debug.WriteLine("Calling IsHooked")

     

                    If (IsHooked(lParam)) Then

                        Return 1

                    End If

     

                End If

     

                Return CallNextHookEx(KeyboardHandle, _

                  Code, wParam, lParam)

     

            End Function

     

     

            Public Sub HookKeyboard()

                If (Hooked() = False) Then

     

                    callback = New KeyboardHookDelegate(AddressOf KeyboardCallback)

     

                    Dim m As System.Reflection.Module = System.Reflection.Assembly.GetExecutingAssembly.GetModules()(0)

                    KeyboardHandle = SetWindowsHookEx( _

                      WH_KEYBOARD_LL, callback, _

                    System.Runtime.InteropServices.Marshal.GetHINSTANCE(m).ToInt32, 0)

                    'System.Diagnostics.Process.GetCurrentProcess().MainModule.BaseAddress.ToInt32(), 0)

                End If

                Call CheckHooked()

            End Sub

     

            Private Sub CheckHooked()

                If (Hooked()) Then

                    Debug.WriteLine("Keyboard Hooked")

                Else

                    Debug.WriteLine("Keyboard hook failed: " & Err.LastDllError)

                End If

            End Sub

     

            Private Function Hooked()

                Hooked = KeyboardHandle <> 0

            End Function

     

            Private Sub UnhookKeyboard()

                If (Hooked()) Then

                    Call UnhookWindowsHookEx(KeyboardHandle)

                    KeyboardHandle = 0

                    Debug.WriteLine("Keyboard Unhooked")

                End If

            End Sub

     



  • VSTO / Word 2003 events