Monday, September 10, 2018

Excel as inlay frame in WPF has disabled ExcelWorksheet

Leave a Comment

I found a solution to setup Excel instance in WPF by using the SetParent() function of Windows.

Problem is, that mouse and keyboard is not reacting to the sheet but to the Workbook it does.

Full sample Project Download here

I also tried with WindowsFormsHost but it has the same effect.

XAML

<Window x:Class="ExcelEditor.SimpleWindow"     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"     xmlns:local="clr-namespace:ExcelEditor"     mc:Ignorable="d" Loaded="Window_Loaded" Closing="Window_Closing"     Title="SimpleWindow" Height="450" Width="800"> <Grid x:Name="LayoutRoot">  </Grid> 

C# code

    using System;     using System.Windows;   namespace ExcelEditor {     /// <summary>     /// Interaktionslogik für SimpleWindow.xaml     /// </summary>     public partial class SimpleWindow : Window     {         private Microsoft.Office.Interop.Excel.Application ExcelApplication;          public SimpleWindow()         {             InitializeComponent();         }          private void Window_Loaded(object sender, RoutedEventArgs e)         {             System.Windows.Forms.Integration.ElementHost.EnableModelessKeyboardInterop(this); // <- testing only (no success)             ExcelApplication = new Microsoft.Office.Interop.Excel.Application();             ExcelApplication.DisplayAlerts = false;             System.Windows.Interop.HwndSource hwnd = (System.Windows.Interop.HwndSource)System.Windows.Interop.HwndSource.FromVisual(this.LayoutRoot);             var excelWnd = Microsoft.Win32.Interop.FindWindow("XLMAIN", null);             GenerateTestData(ExcelApplication);             var successOfParentSetup = Microsoft.Win32.Interop.SetParent(excelWnd, hwnd.Handle);             var isMovedToLeftTop = Microsoft.Win32.Interop.MoveWindow(excelWnd, 10, 10, 800, 600, true);             ExcelApplication.Visible = true;         }          private void GenerateTestData(Microsoft.Office.Interop.Excel.Application excelApplication)         {             var excelWorkbook = excelApplication.Workbooks.Add();             var excelWorksheet = excelWorkbook.Worksheets[1] as Microsoft.Office.Interop.Excel.Worksheet;             excelWorksheet.Cells[1, 1] = "Today";             excelWorksheet.Cells[2, 1] = DateTime.Now.ToString();         }          private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)         {             if (ExcelApplication != null)             {                 ExcelApplication.ActiveWorkbook.Close();                 ExcelApplication.Visible = false;                 ExcelApplication.Quit();                 ExcelApplication = null;             }         }     } } 

Api calls

    [DllImport("user32.dll", EntryPoint = "SetWindowPos")]     public static extern bool SetWindowPos(         IntPtr hWnd,               // handle to window         IntPtr hWndInsertAfter,    // placement-order handle         int X,                  // horizontal position         int Y,                  // vertical position         int cx,                 // width         int cy,                 // height         uint uFlags             // window-positioning options     );      [DllImport("user32.dll", EntryPoint = "MoveWindow")]     public static extern bool MoveWindow(         IntPtr hWnd,         int X,         int Y,         int nWidth,         int nHeight,         bool bRepaint     );     [DllImport("USER32.DLL", SetLastError = true)]     public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);      //Sets a window to be a child window of another window     [DllImport("USER32.DLL", SetLastError = true)]     public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent); 

Question is, how to enable the mouse and keyboard handling in Excel to allow editing the worksheet?

Excel not working propert as parent

*Tested at: Windows 10 x64, Single screen (optional dual screen) Excel 2016 MSO 32-Bit (16.0.10325.20082) out of Office 365

This issue is also reported on Microsoft Forum to check if there is a solution.

In the following video you see how the click sometimes will select cells and sometimes it will not recognize the mouse.

Excel

1 Answers

Answers 1

You need to make sure Excel has been shown once before you can call SetParent. Of course, it looks ugly, so you also need to hide Excel UI somehow from the end-user. For example:

    private void Window_Loaded(object sender, RoutedEventArgs e)     {         ...         // get excel window         var excelWnd = Microsoft.Win32.Interop.FindWindow("XLMAIN", null);          // move excel somewhere outside the screen (of course you should compute it, not hardcode it)         Microsoft.Win32.Interop.MoveWindow(excelWnd, -10000, -10000, 800, 600, true);          // show it so it's initialized properly         ExcelApplication.Visible = true;         GenerateTestData(ExcelApplication);          // now call SetParent         Microsoft.Win32.Interop.SetParent(excelWnd, hwnd.Handle);          // move it to parent         Microsoft.Win32.Interop.MoveWindow(excelWnd, 10, 10, 800, 600, true);     } 
If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment