Bas Nederveen
Bas Nederveen

Reputation: 37

Avalonia window (textboxes) embedded in Autodesk Inventor not accepting input

I'm developing an Autodesk Inventor plug-in and I've chosen to use Avalonia for the UI.

Inventor exposes the ability to create a dockable window. I'm not completely sure how it works behind the scenes but you can add a winforms / WPF control to it, by adding the control's handle as child to the dockable window.

After looking at some samples I figured out how to add the avalonia control to the dockable window.

Everything seems to be working fine, only keypresses are not accepted. (Just backspace & delete) When I run the app from a button press in the ribbon, there are no such problems.

I've found some information on StackOverflow and on the Autodesk forum. I thought the problem might be related to Avalonia so I've used the sample here to embed the avalonia app in a WPF window, thinking this would fix the problem.

It didn't. This thread on the autodesk forum describes the same problem, but for a WPF window.

<Grid>
    <!--WPF input works-->
    <TextBox Text="Text"></TextBox>

    <!--Avalonia input does not work-->
    <interop:WpfAvaloniaHost  x:Name="AvaloniaHost" />
</Grid>

The fix in the autodesk thread:

public void Activate(ApplicationAddInSite addInSiteObject, bool firstTime)
{
    // Setup my WPF Window.
    var wpfWindow = new WpfWindow();
    wpfWindow.WindowStyle = System.Windows.WindowStyle.None;
    wpfWindow.ResizeMode = System.Windows.ResizeMode.NoResize;
    wpfWindow.Visibility = System.Windows.Visibility.Visible;

    // Get WPF Window's handle.
    var helper = new WindowInteropHelper(wpfWindow);
    helper.EnsureHandle();
    var handle = helper.Handle;

    // Create Dockable Window.
    var dockableWindow = InventorApplication.UserInterfaceManager.DockableWindows.Add(System.Guid.NewGuid().ToString(), "Test", "Test");
    dockableWindow.AddChild(handle);

    // Set key hook.
    HwndSource.FromHwnd(handle).AddHook(WndProc);
}

private const UInt32 DLGC_WANTARROWS = 0x0001;
private const UInt32 DLGC_WANTTAB = 0x0002;
private const UInt32 DLGC_WANTALLKEYS = 0x0004;
private const UInt32 DLGC_HASSETSEL = 0x0008;
private const UInt32 DLGC_WANTCHARS = 0x0080;
private const UInt32 WM_GETDLGCODE = 0x0087;

private static IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
    if (msg == WM_GETDLGCODE)
    {
        handled = true;
        return new IntPtr(DLGC_WANTCHARS | DLGC_WANTARROWS | DLGC_HASSETSEL | DLGC_WANTTAB | DLGC_WANTALLKEYS);
    }
    return IntPtr.Zero;
}

Fixes the problem for the input in WPF textboxes, but not yet for the embedded avalonia window.

This made me conclude that the problem lies elsewhere.

Somehow I need to pass the keypresses to the avalonia controls, but I have no clue how. Does anyone have any experience with this problem? Any advice is greatly appreciated!

Upvotes: 0

Views: 337

Answers (1)

Bas Nederveen
Bas Nederveen

Reputation: 37

Answered in the avalonia discussions but will copy-paste it here for future reference:

To handle the WM_GETDLGCODE message, you have two choices:

  • You're willing to use latest 11.1 nightly builds: use Win32SpecificOptions.AddWndProcHookCallback()
  • You're on stable 11.0.x: use the standard Win32 SetWindowLongPtr function with GWLP_WNDPROC to change the window procedure.

I chose for upgrading to the nightly build. After adding the avalonia window as child to the dockable window, call:

Win32SpecificOptions.AddWndProcHookCallback(TopLevel.GetTopLevel(MainWindow), WndProc);

Using WndProc from the original question.

Upvotes: 0

Related Questions