Set parent (Word) window for MessageBox & Help

D

David Thielen

Hi;

When poping up a message box you need to pass in a IWin32Window as the
parent. For Help.ShowHelp you need to pass in a Control as the parent.

In an add-in it is important that these have the main Word window as the
parent so the windows show up properly, on top of Word. (For the MessageBox
it is critical as otherwise they can end up under Word and the user doesn't
know they are there and Word appears hung.)

How can I do this as Word is not a .NET application?
 
F

Fredrik Wahlgren

David Thielen said:
Hi;

When poping up a message box you need to pass in a IWin32Window as the
parent. For Help.ShowHelp you need to pass in a Control as the parent.

In an add-in it is important that these have the main Word window as the
parent so the windows show up properly, on top of Word. (For the MessageBox
it is critical as otherwise they can end up under Word and the user doesn't
know they are there and Word appears hung.)

How can I do this as Word is not a .NET application?

I haven't done any .NET programming so I really don't know much about it.
However, I googled IWin32Window and found it was a handle. Therefore, I
think it should be possible to use something like FindWindow("OpusApp", 0);
Using Spy++, I found that OpusApp is the class name for the main Word
window. I had to do this for some reason when I made an xll add-in for
Excel.

/ Fredrik
 
D

David Thielen

Hi;

I thought of that. The problem is, if there are two instances of Word
running, you may not get the hwnd to the copy of Word that made the call in
to the add-in.

thanks - dave
 
D

David Thielen

Hi;

I thought of that but the problem is, if there are two instances of Word,
how do you get the instance that called you? Also, if Word is being started
inside Outlook, there is no visible Word window yet and you need the handle
to the Outlook window.

Any idea how to get around these issues?

thanks - dave
 
F

Fredrik Wahlgren

Hi

Well, I remember I had the same problem with my xll. I should have mentioned
that. One thing I thought was if there was a way to get the ProcessID from
a Handle. I never found anything useful. My other idea was that maybe
there's a way to get the WindowHandle from an IDispatch pointer.
Unfortunately, I had to leave the company before I had a chance to
investigate any of these ideas.
/ Fredrik
 
P

Peter Huang

Hi

Here is a link about how to get the office program's window when automation.

Find the Window Handle for an Application That Can Have Multiple Instances

How To Obtain the Window Handle for an Office Automation Server
http://support.microsoft.com/kb/258511/EN-US/

Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 
D

David Thielen

Hi;

What a hack. Are sure there isn't another way? I dislike this because the
user sees the caption change and that is not good.

I tried doing this and this works:
FindWindow("OpusApp", null);

But this does not work:
FindWindow("OpusApp", ThisApplication.Caption);

I noticed that while the Caption property has the string I gave it ("blah
blah blah") the actual title was "Document - blah blah blah".

Any idea how to get this to work? I can't use null because a user could have
multiple instances of Word running.

thanks - dave
 
P

Peter Huang

Hi

So far this is the recommend way to do the job, I did not find any other
way.
As for you concern, I think we may just set the caption and find window and
then set it back immediately, what we need to do is to stored the window
handle, so that we do not need to keep the title in changed state.

Also here is code you may have a try which will build the caption.
public void Test2()
{
Word.Application wdApp =new Word.ApplicationClass();
wdApp.Visible=true;
object oMissing = System.Reflection.Missing.Value;
Word.Document oDoc = wdApp.Documents.Add(ref oMissing, ref oMissing,ref
oMissing, ref oMissing);
wdApp.Caption = "fasdfsadf";
Console.WriteLine(wdApp.Caption);
int handle = FindWindow("OpusApp", oDoc.Name +" - "+wdApp.Caption);
wdApp.Caption=string.Empty;
Console.WriteLine(handle.ToString());
wdApp.Quit(ref oMissing,ref oMissing,ref oMissing);
}

Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 
D

David Thielen

Hello;

You use
FindWindow("OpusApp", oDoc.Name +" - "+wdApp.Caption);

Is this something that you know will work 100% of the time, or just a guess
as to what will match? If your answer is it will work 100% of the time you
are incorrect because when Word is started by Outlook, wdApp.Caption alone
works correctly.

So my question is, what is the correct way to do this that will work for all
situations? This includes starting Word stand-alone, starting it in Outlook,
starting it in Internet Explorer (to display a .doc file), starting it in ???

thanks - dave
 
F

Fredrik Wahlgren

I think the suggested way should work 100% of the time there is a window.
It's not nice it's just the Microsoft API. i'm ot sure the code will work as
it is if you start Word from something like IE. If FindWindow doesn't
returna naything you may have to find the top IE window and dig your way
down.

David,
I remember you wrote that you had worked for MS for a couple of years. What
software were you responsible for?

/ Fredrik
 
D

David Thielen

Hi;

I worked on the Win95 team.

Does anyone at MS know if there is a solution that will work for all
situations? It seems like such a simple and widely needed request (as almost
all add-ins will have a MessageBox somewhere).

thanks - dave
 
D

David Thielen

And another interesting question. For U.S. Offoce it is:

document - caption

but is it that for all countries/locales? Or in some is the order switched
or a different character used? And if so, how do I get it for those locales?

thanks - dave
 
P

Peter Huang

Hi

Based on my test, in other language e.g, chinese, the document name will be
changed.
But I think you may try to use the code below to retrieve the window with
similar title.
We can get the current active document and get its name as the evidence to
retrieve the window.

How To Get a Window Handle Without Specifying an Exact Title
http://support.microsoft.com/?id=147659

Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 
M

Matt Fletcher

I don't know whether this will work for Word, but for Outlook Inspectors and
Explorers you can get the window handle by casting to IOleWindow and calling
GetWindow - e.g. I use the code below to identify whether I am dealing with
the same Explorer.

HTH
Matt Fletcher

STDMETHODIMP CExplorerHandler::MatchExplorerWindow(IDispatch * pExplorer,
WINDOWTEST * pResult)
{
CComQIPtr<IOleWindow> spThisWindow = m_spExplorer;
CComQIPtr<IOleWindow> spThatWindow = pExplorer;

if (spThisWindow && spThatWindow)
{
HWND hwndThis;
HWND hwndThat;

if (SUCCEEDED(spThisWindow->GetWindow(&hwndThis)) &&
SUCCEEDED(spThatWindow->GetWindow(&hwndThat)))
{
if (hwndThis == NULL)
*pResult = windowNull;
else if (hwndThis == hwndThat)
*pResult = windowMatch;
else
*pResult = windowDiffer;
}
}

return S_OK;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top