Question

Denys W on Thu, 16 Aug 2012 14:00:32


I've created a Microsoft Office Word 2010 add-in which displays various WPF forms as dialogs when a user clicks on buttons in the ribbon, this is the code I use to create the custom windows and setting the owner of the window to MS Word:

            Window wrapperWindow = new Window();

            Process wordProcess = Process.GetProcessesByName("WINWORD").First();
            IntPtr wordWindow = wordProcess.MainWindowHandle;
            WindowInteropHelper wih = new WindowInteropHelper(wrapperWindow);
            wih.Owner = wordWindow;

            wrapperWindow.ShowInTaskbar = false;

It works well when one instance of Word is open but when there is more than one instance it freezes all the other Word windows when you open them from taskbar and the dialog is only displayed in one of the instances.

I want the behavior to be the same as the native Word Open dialog.The way it behaves is it will not let you edit any other Word instance until the Open dialog is dismissed.

You can easily recreate this scenario by doing the following:

1) Opening multiple instances of Word.

2) Click on Open in one of them to bring up the Open File dialog

3)Attempt opening any of the other Word instances from the taskbar.

Could you please suggest how I can ammend my current code to have the same functionality?




Sponsored



Replies

Cindy Meister MVP on Sun, 19 Aug 2012 09:24:57


Hi Denys

I suspect that the problem is that what you think are separate Word "instances" are actually multiple windows/documents of the same instance. If you look in the Windows task manager, under processes, how many entries of winword.exe do you see?

I'm guessing you're seeing one. Word is specifically designed to be "pseudo-SDI". It tries very hard to run only one instance of itself and associate all open document windows to that single instance. It is possible to force multiple instances to run, but a typical user working in a default installation environment isn't going to generate more than one instance.

So, since all the document window's are associated with a single instance, those windows are locked when you display a modal form, such as the Open dialog box.

I'm not really familiar with WPF forms, their windows, etc. But is there a way to display a WPF form as modal? (I know it's possible with a Windows Form.)

Denys W on Fri, 31 Aug 2012 07:34:27


Hello Cindy

Yes the WPF window can be displayed as a dialog by simply calling ShowDialog() on the window instance.

The problem I'm having is the following:

When one of my custom dialogs are displayed all open documents become "locked" until the dialog is dismissed(which is correct).But when I navigate to other documents the dialog remains in the Document it originated in.

I need the behavior to be exactly the same as the native Word open file dialog.

To replicate:

1) Open multiple Word documents

2) Click File-> Open. The open file dialog is displayed

3) Now try navigating to any other Word documents in the task pane, you will notice that the focus remains on the Window with the dialog and you're not allowed to select any other document until the dialog is dismissed.

I'm lookinhg for a way to make my dialogs have the same behavior, do you know what I could possible be missing?How can I keep the focus on the Word Document which has an active dialog and prevent users from navigating to any other documents?

Cindy Meister MVP on Fri, 31 Aug 2012 15:37:33


Hi Denys

I'm not following some of your scenario...

<<When one of my custom dialogs are displayed all open documents become "locked" until the dialog is dismissed(which is correct).But when I navigate to other documents the dialog remains in the Document it originated in.>>

How are you "navigating to other documents"? (Exact steps, please)

<<3) Now try navigating to any other Word documents in the task pane...>>

Word doesn't have a task pane that lists "other Word documents". Do you mean the Windows task bar, or do you have a task pane as part of your solution (which I wouldn't have, of course)?

Just in general terms: all documents open in the same instance of Word should be governed by the modal behavior. The only thing I can imagine is that the "other documents" are being opened in new instances of Word. Do you have code that's doing something like:
  Word.Application wdApp = new Word.Application();

That would start a new instance of Word every time it's called...

Denys W on Mon, 03 Sep 2012 10:03:28


Hello Cindy

Sorry for the confusion, yes I mean the Windows task bar.

Basically open multiple Word documents, then click Open on one of them:

-The Open file dialog pop's up.

Now try selecting any of the other open documents in the Windows task bar.

You will be prevented from doing so until the dialog is dismissed, I just want the same behavior on my custom dialogs...

And no, the other documents are not opened in new instances of Word









Cindy Meister MVP on Mon, 03 Sep 2012 13:08:25


Hi Denys

Yes, I know how Word functions. What I don't understand is this statement of yours:

"When one of my custom dialogs are displayed all open documents become "locked" until the dialog is dismissed(which is correct).But when I navigate to other documents the dialog remains in the Document it originated in."

You first say that all open document are locked. But then you say "navigate ot other documents". I don't understand how you're able to navigate to other documents when all documents are locked?

Or do you mean you navigate to other documents when the dialog box is NOT showing? And that when you try to display when you're in a different document the problem is occurring?

I'm not really good with the Windows API, but in that case, I believe the problem may be this:
  IntPtr wordWindow = wordProcess.MainWindowHandle

I know three ways to get the hWnd of a Word window, as follows. The third one returns the currently active document, which I believe is what you need:

    hWnd1 = FindWindow(vbNullString, applicationCaption)
    hWnd2 = FindWindow(wordClassName, applicationCaption)
    hWnd3 = FindWindow(wordClassName, vbNullString)

Denys W on Mon, 03 Sep 2012 13:46:22


Hello Cindy

"When one of my custom dialogs are displayed all open documents become "locked" until the dialog is dismissed(which is correct).But when I navigate to other documents the dialog remains in the Document it originated in."

What I mean by this is that when one of my dialogs are displayed I can still open other Word documents from the Windows task bar, and when those documents are displayed clicking anywhere in the Word document doesn't fire off any events:

E.g: clicking on any of the ribbon tabs, right clicking etc...

This is what I mean by "locked".

All I want is to prevent users from being able to navigate to any other open Word documents in the Windows task bar until the dialog is dismissed, that's all.

I will do some research on FindWindow(wordClassName, vbNullString)  will see if that solves my problem









Denys W on Tue, 04 Sep 2012 05:56:44


Hello Cindy

Tried the FindWindow method just now, still doesn't work.

I stepped through the code, the dialog is being displayed in the correct Word Document so the FindWindow method is clearly working but i can still navigate to other Word documents from the Windows task bar:

        [DllImport("user32.dll")]
        public static extern IntPtr FindWindow(String sClassName, String sAppName);

        [DllImport("user32.dll")]
        public static extern bool EnableWindow(IntPtr hwnd, bool bEnable);

        public bool? ShowDialog(IModalDialogViewModel dialogViewModel)
        {
                Window wrapperWindow = new Window();

                //dialogViewModel.WordWindowTitle = The title of the Word document in which the dialog is being displayed
                //E.g : Document1 - Microsoft Word
                IntPtr wordWindow = FindWindow(null, dialogViewModel.WordWindowTitle);
                
                //Some people suggested using FindWindow together with EnableWindow
                //Tried that as well, still doesn't work
                //http://msdn.microsoft.com/en-us/library/windows/desktop/ms633499(v=vs.85).aspx
                EnableWindow(wordWindow, false);

                WindowInteropHelper wih = new WindowInteropHelper(wrapperWindow);
                wih.Owner = wordWindow;
				
                wrapperWindow.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterOwner;
                wrapperWindow.ShowInTaskbar = false;

                dialogViewModel.onClose += delegate
                {
                    wrapperWindow.Dispatcher.Invoke((Action)wrapperWindow.Close);
                };

                dialogViewModel.Init();
                wrapperWindow.ShowDialog();
                wrapperWindow.Content = null;

            return dialogViewModel.DialogResult;
        }
Do you maybe have any other suggestions?


Cindy Meister MVP on Tue, 04 Sep 2012 10:35:24


Hi Denys

I don't know a lot about WPF, so I may be missing something.

But based on the knowledge I have, I'd say you may have to work with Word's DocumentChange or WindowActivate event (for the Application object). Your application could detect that and move focus back to your form?

sumits01 on Mon, 09 Mar 2015 11:51:33


I am also facing the same issue. Help me out here.

I am using custom modal dialog and when it is open my custome dialog in Document1 then I should not able to switch between Document1 to Document2.

I want my modal dialog to behave like:

1) Opening multiple instances of Word.
 
2) Click on Open in one of them to bring up the Open File dialog
 
3)Attempt opening any of the other Word instances from the taskbar.
 
Could you please suggest how I can ammend my current code to have the same functionality?