0

I'm developing a VSTO Word addin. Is it possible for vsto add-in to detect if user click outside of document region.

Example like in the image below: Detect if I click anywhere inside the black box (ribbon area and the bottom area)

enter image description here

No need for me to know what control is being clicked... as long as that click happen inside those two black boxes.

Any way for me to that that? Thanks.

UPDATE:

Private Function MouseHookCallback(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
    If nCode = 0 Then
        Dim mouseHookStruct = CType(Marshal.PtrToStructure(lParam, GetType(SafeNativeMethods.MouseHookStructEx)), SafeNativeMethods.MouseHookStructEx)
        Dim message = CType(wParam, SafeNativeMethods.WindowMessages)
        Debug.WriteLine("{0} event detected at position {1} - {2}", message, mouseHookStruct.pt.X, mouseHookStruct.pt.Y)
        If message = WindowMessages.WM_LBUTTONDOWN Or message = WindowMessages.WM_MBUTTONDOWN Or message = WindowMessages.WM_RBUTTONDOWN Or _
            message = WindowMessages.WM_MOUSEHWHEEL Or message = WindowMessages.WM_MOUSEWHEEL Then
            'do something here
        End If
        If message = WindowMessages.WM_MOUSEMOVE Then
            Debug.WriteLine("mouse move!!!!!!!!!!!!!!!!!!a with ncode=> " & nCode)
        End If
    End If

    Return SafeNativeMethods.CallNextHookEx(_hookIdKeyboard, nCode, wParam, lParam)
End Function
azm
  • 31
  • 7

1 Answers1

0

VSTO doesn't provide anything for that. But you can try to set up a keyboard hook for that, see Low-Level Keyboard Hook in C# for more information.

 using System;
using System.Diagnostics;
using System.Windows.Forms;
using System.Runtime.InteropServices;

class InterceptKeys
{
    private const int WH_KEYBOARD_LL = 13;
    private const int WM_KEYDOWN = 0x0100;
    private static LowLevelKeyboardProc _proc = HookCallback;
    private static IntPtr _hookID = IntPtr.Zero;

    public static void Main()
    {
        _hookID = SetHook(_proc);
        Application.Run();
        UnhookWindowsHookEx(_hookID);
    }

    private static IntPtr SetHook(LowLevelKeyboardProc proc)
    {
        using (Process curProcess = Process.GetCurrentProcess())
        using (ProcessModule curModule = curProcess.MainModule)
        {
            return SetWindowsHookEx(WH_KEYBOARD_LL, proc,
                GetModuleHandle(curModule.ModuleName), 0);
        }
    }

    private delegate IntPtr LowLevelKeyboardProc(
        int nCode, IntPtr wParam, IntPtr lParam);

    private static IntPtr HookCallback(
        int nCode, IntPtr wParam, IntPtr lParam)
    {
        if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
        {
            int vkCode = Marshal.ReadInt32(lParam);
            Console.WriteLine((Keys)vkCode);
        }
        return CallNextHookEx(_hookID, nCode, wParam, lParam);
    }

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr SetWindowsHookEx(int idHook,
        LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool UnhookWindowsHookEx(IntPtr hhk);

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
        IntPtr wParam, IntPtr lParam);

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr GetModuleHandle(string lpModuleName);
}
Eugene Astafiev
  • 47,483
  • 3
  • 24
  • 45
  • THanks @Eugene. Ok, i've implemented a mouse hook (WH_MOUSE) instead of low level mouse hook (WH_MOUSE_LL). Managed to detect the click. But the problem now, how do I differentiate if the click happen in those 2 black box or the click is in the document region? – azm Aug 19 '21 at 03:17
  • It seems that doesn't matter where I click, the mouse hook callback will be called. Not sure how to detect which click happen in which region. – azm Aug 19 '21 at 03:21
  • You can try to subclass those two elements where you can handle the click events. Another approach is to check the mouse pointer location, see [Getting mouse position in c#](https://stackoverflow.com/questions/1316681/getting-mouse-position-in-c-sharp) for more information. – Eugene Astafiev Aug 19 '21 at 06:54