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:
<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
[2709 byte] By [
BRJ2k5] at [2008-2-7]
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
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
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
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