none
add mouseclick event handler RRS feed

  • Question

  • I would like to display a Word document in a WebBrowser control disabling almost all user interaction - no default function key behavior, accelerator key behavior - and also have no GUI components - menus, ribbons etc. Users should only be able to select text and copy to clipboard - kind of like a PDF "image" of a document. So far I have been able to get pretty close to this behavior. However, I need one more critical bit of functionality: I must be able to react to mouse clicks and key down events.

    Is there a way to add/override/customize the default mouse and key events for a Word document?


    • Edited by Fetter Doubt Thursday, November 14, 2013 9:01 AM
    Thursday, November 14, 2013 9:00 AM

All replies

  • Hi Fetter,

    According to your description, you want to display the Word document in a WebBrowser control and disabling all user interaction and react to mouse clicks and key down events.

    If I misunderstand, please feel free to correct me.

    As far as I know, when we display the Word document in a webBroswer control it used ActiveX document(Refer to How to use the WebBrowser control to open an Office document).

    When you create an ActiveX document-based project, you are creating a Visual Basic "document" that can be contained in an ActiveX container (such as Internet Explorer). Compiling the ActiveX document creates both a Visual Basic Document file (with the extension .vbd) and its corresponding server — which can be an ActiveX .dll, or ActiveX .exe file. In other words, the .vbd file is to the .exe or .dll file what the .doc file is to the Winword.exe file. (Refer to What Is an ActiveX Document)

    I didn’t find there is a way we can add/override/customize the default mouse key events for the Word document.

    Hope this is helpful.

    Best regards

    Fei


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Friday, November 15, 2013 12:47 PM
    Moderator
  • Fei Xue

    I sincerely appreciate your helpful response. However, even though I learned a few things about ActiveX "documents" my problem remains unsolved.

    The logic of using a container document has proven useful to me with respect to HTML documents. As the code below shows I am able to get access to the HTML document in the WebBrowser control once it has completed loading. At that point I am able to make use of the AddHandler VB statement to associate an event with a handler at runtime. In this manner I can solve my problem for HTML document by customizing the event handler code. And it works pretty reliably so far. What I need is a way to do the same thing for Word, Excel and PowerPoint documents. However, unlike the HtmlDocument class, the Office Interop documents don't seem to expose a KeyUp or Click or MouseClick event.

    It's hard to imagine a more straightforward question than the one I'm posing and yet there are no responses. I don't know what to make of this. Either it is not possible or it is extremely difficult I guess.

       Private Sub wbrPreview_DocumentCompleted(sender As System.Object, e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles wbrPreview.DocumentCompleted
            Dim objDocument As Object
            'MessageBox.Show("DocumentCompleted")
    
            If e.Url.ToString.EndsWith(".html") Or e.Url.ToString.EndsWith(".htm") Then
                Dim htmlDocument As HtmlDocument = wbrPreview.Document
                'Attach KeyDown event handler
                AddHandler htmlDocument.Body.KeyUp, New HtmlElementEventHandler(AddressOf wbrPreview_KeyUp)
                'Attach Click event handler
                AddHandler htmlDocument.Body.Click, New HtmlElementEventHandler(AddressOf wbrPreview_Click)
            ElseIf e.Url.ToString.EndsWith(".docx") Or e.Url.ToString.EndsWith(".doc") Then
                Dim objIE As InternetExplorer = wbrPreview.ActiveXInstance
                objIE.ExecWB(OLECMDID.OLECMDID_HIDETOOLBARS, OLECMDEXECOPT.OLECMDEXECOPT_DONTPROMPTUSER)
                objDocument = objIE.Document
                Dim wordDocument As Word.Document = objDocument
    
                wordDocument.Application.ActiveDocument.Protect(3)
                wordDocument.ActiveWindow.View.Zoom.PageFit = 2
            ElseIf e.Url.ToString.EndsWith(".xlsx") Or e.Url.ToString.EndsWith(".xls") Then
                Dim objIE As InternetExplorer = wbrPreview.ActiveXInstance
                objDocument = objIE.Document
                Dim excelDocument As Excel.Workbook = objDocument
                For Each excelWorksheet As Excel.Worksheet In excelDocument.Worksheets
                    excelWorksheet.Protect()
                Next
            End If
    
            wbrPreview.Visible = True
            wbrPreview.Focus()
            blnOverHyperlink = False
        End Sub


    Monday, November 18, 2013 5:12 AM
  • Hi FD

    <<It's hard to imagine a more straightforward question than the one I'm posing and yet there are no responses. I don't know what to make of this. Either it is not possible or it is extremely difficult I guess.>>

    That pretty much sums it up, yes. In contrast to an HTML document, which is the object actually being handled by the browser, an Office document is in a "container" - it's Office application - which in turn is in an ActiveX container - the thing that makes it possible for the Office application to be "in" the browser.

    So the events that work fine on an HTML document aren't going to work the same way with these "container" layers. And, in fact, the Office applications have an increasing tendancy to block a number of Windows API events so that they don't interfere with the applications' internal functioning.

    In addition, the Office applications are not intended to be hosted in a browser window. It's quite possible you might be able to get something to work with one (an older) version of an Office application, but the same thing might not work with another application or version of the same application. And it would be totally unsupported by Microsoft.

    Add to this the underlying philosophy concerning Office applications: they're licensed to the user, are meant to run stand-alone, not embedded and Microsoft doesn't want the developer using them in a third-party application - and you're looking at a very difficult proposal.


    Cindy Meister, VSTO/Word MVP, my blog

    Tuesday, November 19, 2013 3:59 PM
    Moderator
  • It has been written in a few places that the way to achieve this is by subclassing the active window and overriding the WndProc. This seems like the best solution to me (hooks are the other). However, I can't get it to pick up any messages. Here is my NativeWindow based class:

    Friend Class OfficeWindow
        Inherits NativeWindow
        Implements IDisposable
    
        Public Sub New(handle As IntPtr)
            Me.AssignHandle(handle)
        End Sub
    
        <System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.Demand, Name:="FullTrust")> _
        Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
            Console.WriteLine(m.Msg)
            Select Case m.Msg
                Case &H200
                    Console.WriteLine("WM_MOUSEMOVE")
            End Select
            MyBase.WndProc(m)
        End Sub
    
        ' Flag: Has Dispose already been called? 
        Dim disposed As Boolean = False
    
        ' Public implementation of Dispose pattern callable by consumers. 
        Public Sub Dispose() Implements IDisposable.Dispose
            Dispose(True)
            GC.SuppressFinalize(Me)
        End Sub
    
        ' Protected implementation of Dispose pattern. 
        Protected Overridable Sub Dispose(disposing As Boolean)
            If disposed Then Return
    
            If disposing Then
                ' Free any other managed objects here. 
                ' 
                Me.DestroyHandle()
            End If
    
            ' Free any unmanaged objects here. 
            '
            disposed = True
        End Sub
    
        Protected Overrides Sub Finalize()
            Dispose(False)
        End Sub
    
    End Class
    

    Then in my test app:

                wordDocument.Application.ActiveDocument.ActiveWindow.SetFocus()
                hWndOffice = GetFocus()
                officeWindow = New OfficeWindow(hWndOffice)
    

    Any reason why this doesn't work? How do I know I have the correct window handle (seems the most pertinent question)?

    Tuesday, July 29, 2014 9:55 AM