modal ejemplo dialogbox c# wpf ms-word vsto

c# - ejemplo - ¿Por qué mi diálogo Modal WPF se desliza detrás de MS Word?



showdialog c# ejemplo (1)

Tengo un complemento de aplicación de MS Word escrito con VSTO. Contiene un botón utilizado para crear nuevos documentos Carta. Cuando se presiona un documento se crea una instancia, se muestra un cuadro de diálogo WPF para capturar información y luego la información se inserta en el documento.

En raras ocasiones, el diálogo de WPF se desliza detrás de MS Word. Luego tengo que matar el proceso de Winword.exe porque el diálogo es modal. Uso el siguiente código para mi diálogo de WPF. La subclase OfficeDialog se usa para hacer que el diálogo se vea como un diálogo de MS-Word.

var view = new LetterDetailsView(ViewModel); view.ShowDialog(); public class OfficeDialog : Window { [DllImport("user32.dll")] static extern int GetWindowLong(IntPtr hwnd, int index); [DllImport("user32.dll")] static extern int SetWindowLong(IntPtr hwnd, int index, int newStyle); [DllImport("user32.dll")] static extern bool SetWindowPos(IntPtr hwnd, IntPtr hwndInsertAfter, int x, int y, int width, int height, uint flags); [DllImport("user32.dll")] static extern IntPtr SendMessage(IntPtr hwnd, uint msg, IntPtr wParam, IntPtr lParam); const int GWL_EXSTYLE = -20; const int WS_EX_DLGMODALFRAME = 0x0001; const int SWP_NOSIZE = 0x0001; const int SWP_NOMOVE = 0x0002; const int SWP_NOZORDER = 0x0004; const int SWP_FRAMECHANGED = 0x0020; const uint WM_SETICON = 0x0080; const int ICON_SMALL = 0; const int ICON_BIG = 1; public OfficeDialog() { this.ShowInTaskbar = false; } public new void ShowDialog() { try { var helper = new WindowInteropHelper(this); using (Process currentProcess = Process.GetCurrentProcess()) helper.Owner = currentProcess.MainWindowHandle; base.ShowDialog(); } catch (System.ComponentModel.Win32Exception ex) { Message.LogWarning(ex); var helper = new WindowInteropHelper(this); using (Process currentProcess = Process.GetCurrentProcess()) helper.Owner = currentProcess.MainWindowHandle; base.ShowDialog(); } } protected override void OnSourceInitialized(EventArgs e) { base.OnSourceInitialized(e); RemoveIcon(this); HideMinimizeAndMaximizeButtons(this); } public static void HideMinimizeAndMaximizeButtons(Window window) { const int GWL_STYLE = -16; IntPtr hwnd = new WindowInteropHelper(window).Handle; long value = GetWindowLong(hwnd, GWL_STYLE); SetWindowLong(hwnd, GWL_STYLE, (int)(value & -131073 & -65537)); } public static void RemoveIcon(Window w) { // Get this window''s handle IntPtr hwnd = new WindowInteropHelper(w).Handle; // Change the extended window style to not show a window icon int extendedStyle = OfficeDialog.GetWindowLong(hwnd, GWL_EXSTYLE); OfficeDialog.SetWindowLong(hwnd, GWL_EXSTYLE, extendedStyle | WS_EX_DLGMODALFRAME); // reset the icon, both calls important OfficeDialog.SendMessage(hwnd, WM_SETICON, (IntPtr)ICON_SMALL, IntPtr.Zero); OfficeDialog.SendMessage(hwnd, WM_SETICON, (IntPtr)ICON_BIG, IntPtr.Zero); // Update the window''s non-client area to reflect the changes OfficeDialog.SetWindowPos(hwnd, IntPtr.Zero, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); } static void SetCentering(Window win, IntPtr ownerHandle) { bool isWindow = IsWindow(ownerHandle); if (!isWindow) //Don''t try and centre the window if the ownerHandle is invalid. To resolve issue with invalid window handle error { //Message.LogInfo(string.Format("ownerHandle IsWindow: {0}", isWindow)); return; } //Show in center of owner if win form. if (ownerHandle.ToInt32() != 0) { var helper = new WindowInteropHelper(win); helper.Owner = ownerHandle; win.WindowStartupLocation = WindowStartupLocation.CenterOwner; } else win.WindowStartupLocation = WindowStartupLocation.CenterOwner; } [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] static extern bool IsWindow(IntPtr hWnd);

}


Un diálogo modal que no está en la parte superior es el resultado de un propietario configurado incorrectamente. Ya configuraste al propietario en MainWindowHandle del proceso actual; sin embargo, en particular con múltiples documentos de Word abiertos, esto podría no ser lo que desea.

Sugeriría confiar en la siguiente propiedad (presentada con Word 2013):

document.ActiveWindow.HWnd;

Aparte de eso, no debería existir la necesidad de matar el proceso de Word. Debería ser suficiente para minimizar todas las ventanas (por ejemplo, presionando Windows Key + M )