Help: floating modeless dialog in Word add-in (C#)

A

Alex

Hello,

I am writing a Word add-in in C#.
I am trying to create a dialog window that will behave similarly to the "Find" dialog in Word or Visual Studio
(actually, I try to mimic the Visual Studio "find" as it does not appear on the taskbar).
That is:
- The dialog is modeless (the user can continue working in the application when it is open).
- The dialog is always on top of the application window (but not on top of other applications).

So far I am failing miserably.

What am I doing wrong?

Here are the relevant parts of the code:

////////// code begins //////////

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using Extensibility;
using Microsoft.Office.Core;
using Word = Microsoft.Office.Interop.Word;

[GuidAttribute("3C6ED867-A0F7-4747-BBAA-34D1D8FA2E3E"), ProgId("MyAddin1.Connect")]
public class Connect : Object, Extensibility.IDTExtensibility2 {
public void OnConnection(object application, Extensibility.ext_ConnectMode connectMode, object addInInst, ref System.Array custom)
{
applicationObject = (Word.Application)application;
addInInstance = addInInst;
if (connectMode != Extensibility.ext_ConnectMode.ext_cm_Startup) {
OnStartupComplete(ref custom);
}
}

public void OnStartupComplete(ref System.Array custom)
{
applicationObject.CustomizationContext = applicationObject.ActiveDocument;
CommandBar commandBar = applicationObject.CommandBars.Add("My Command Bar", MsoBarPosition.msoBarTop, false, false);
CommandBarButton button = (CommandBarButton) commandBar.Controls.Add(MsoControlType.msoControlButton, missing, missing, missing, true);
button.Tag = "Launch Panel";
button.Click += new _CommandBarButtonEvents_ClickEventHandler(LaunchPanel);
commandBar.Visible = true;
}

private void LaunchPanel(CommandBarButton button, ref bool cancel)
{
string caption = applicationObject.ActiveWindow.Caption + " - " + applicationObject.Caption;
Form1 form = new Form1(ref caption);
form.Show();
}

private Word.Application applicationObject;
private object addInInstance;
static object missing = System.Reflection.Missing.Value;
}

public class Form1 : System.Windows.Forms.Form
{
public Form1(ref string caption)
{
InitializeComponent();

IntPtr hwnd = Win32.FindWindow("OpusApp", caption);
Win32.SetParent(Handle, hwnd);
int style = Win32.GetWindowLong(Handle, Win32.GWL_STYLE);
Win32.SetWindowLong(Handle, Win32.GWL_STYLE, style | Win32.WS_CHILD);
MaximizeBox = false;
MinimizeBox = false;
ControlBox = false;
ShowInTaskbar = false;
FormBorderStyle = FormBorderStyle.FixedToolWindow;
}
}

public class Win32
{
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

[DllImport("user32.dll", SetLastError = true)]
public static extern int GetWindowLong(IntPtr hWnd, int nIndex);

[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

[DllImport("user32.dll", SetLastError = true)]
public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

public const int GWL_EXSTYLE = -20;
public const int WS_CHILD = 0x40000000;
}

////////// code ends //////////

Thnank you,
Alex.
 
A

Alex

Problem solved.

Here are the relevant parts of the code:

////////// code begins //////////

public class Connect : Object, Extensibility.IDTExtensibility2
{
public void OnConnection(object application, Extensibility.ext_ConnectMode connectMode, object addInInst, ref System.Array custom)
{
applicationObject = (Word.Application)application;
addInInstance = addInInst;
if (connectMode != Extensibility.ext_ConnectMode.ext_cm_Startup)
OnStartupComplete(ref custom);
}

public void OnDisconnection(Extensibility.ext_DisconnectMode disconnectMode, ref System.Array custom)
{
if (disconnectMode != Extensibility.ext_DisconnectMode.ext_dm_HostShutdown)
OnBeginShutdown(ref custom);
}

public void OnStartupComplete(ref System.Array custom)
{
applicationObject.CustomizationContext = applicationObject.ActiveDocument;
CommandBar commandBar = applicationObject.CommandBars.Add("My Command Bar", MsoBarPosition.msoBarTop, false, false);
CommandBarButton button = (CommandBarButton) commandBar.Controls.Add(MsoControlType.msoControlButton, missing, missing, missing, true);
button.Tag = "Launch Panel"; button.FaceId = 9528;
button.Click += new _CommandBarButtonEvents_ClickEventHandler(LaunchPanel);
commandBar.Visible = true;
applicationObject.ActiveDocument.Saved = true;
}

private void LaunchPanel(CommandBarButton button, ref bool cancel)
{
string caption = applicationObject.ActiveWindow.Caption + " - " + applicationObject.Caption;
Form1 form = new Form1(ref caption);
form.Show();
}

private Word.Application applicationObject;
private object addInInstance;
static object missing = System.Reflection.Missing.Value;
}

public class Form1 : System.Windows.Forms.Form
{
public Form1(ref string caption)
{
// Required for Windows Form Designer support
InitializeComponent();

MaximizeBox = false;
MinimizeBox = false;
ControlBox = false;
ShowInTaskbar = false;
FormBorderStyle = FormBorderStyle.FixedToolWindow;

IntPtr hwnd = Win32.FindWindow("OpusApp", caption);
if (hwnd == IntPtr.Zero)
Win32.ThrowLastError();

if (Win32.SetParent(Handle, hwnd) == IntPtr.Zero)
Win32.ThrowLastError();
}
}

public class Win32
{
public static void ThrowLastError()
{
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
}

[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
}

////////// code ends //////////
 
R

Roberto Huezo

Hello Alex,

but by using Word.Application you are binding to the Word version which is
referenced in your project...if it is Word 2003, will it work in a machine
with Word 2000 or Word XP?

Roberto

Problem solved.

Here are the relevant parts of the code:

////////// code begins //////////

public class Connect : Object, Extensibility.IDTExtensibility2
{
public void OnConnection(object application,
Extensibility.ext_ConnectMode connectMode, object addInInst, ref
System.Array custom)
{
applicationObject = (Word.Application)application;
addInInstance = addInInst;
if (connectMode != Extensibility.ext_ConnectMode.ext_cm_Startup)
OnStartupComplete(ref custom);
}

public void OnDisconnection(Extensibility.ext_DisconnectMode
disconnectMode, ref System.Array custom)
{
if (disconnectMode !=
Extensibility.ext_DisconnectMode.ext_dm_HostShutdown)
OnBeginShutdown(ref custom);
}

public void OnStartupComplete(ref System.Array custom)
{
applicationObject.CustomizationContext =
applicationObject.ActiveDocument;
CommandBar commandBar = applicationObject.CommandBars.Add("My
Command Bar", MsoBarPosition.msoBarTop, false, false);
CommandBarButton button = (CommandBarButton)
commandBar.Controls.Add(MsoControlType.msoControlButton, missing, missing,
missing, true);
button.Tag = "Launch Panel"; button.FaceId = 9528;
button.Click += new
_CommandBarButtonEvents_ClickEventHandler(LaunchPanel);
commandBar.Visible = true;
applicationObject.ActiveDocument.Saved = true;
}

private void LaunchPanel(CommandBarButton button, ref bool cancel)
{
string caption = applicationObject.ActiveWindow.Caption + " - "
+ applicationObject.Caption;
Form1 form = new Form1(ref caption);
form.Show();
}

private Word.Application applicationObject;
private object addInInstance;
static object missing = System.Reflection.Missing.Value;
}

public class Form1 : System.Windows.Forms.Form
{
public Form1(ref string caption)
{
// Required for Windows Form Designer support
InitializeComponent();

MaximizeBox = false;
MinimizeBox = false;
ControlBox = false;
ShowInTaskbar = false;
FormBorderStyle = FormBorderStyle.FixedToolWindow;

IntPtr hwnd = Win32.FindWindow("OpusApp", caption);
if (hwnd == IntPtr.Zero)
Win32.ThrowLastError();

if (Win32.SetParent(Handle, hwnd) == IntPtr.Zero)
Win32.ThrowLastError();
}
}

public class Win32
{
public static void ThrowLastError()
{
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
}

[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindow(string lpClassName, string
lpWindowName);

[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr
hWndNewParent);
}

////////// code ends //////////
 
A

Alex

Roberto Huezo said:
Hello Alex,

but by using Word.Application you are binding to the Word version which is
referenced in your project...if it is Word 2003, will it work in a machine
with Word 2000 or Word XP?

I have no idea.
I'm new at this...
 
C

Cindy M -WordMVP-

Hi Roberto,
but by using Word.Application you are binding to the Word version which is
referenced in your project...if it is Word 2003, will it work in a machine
with Word 2000 or Word XP?
If you want a single project to support more than one version of Word, then
you should develop it in the earliest version, with that versions PIAs. And
you then probably need to distribute these PIAs as part of the solution.

Microsoft recommends that you develop a separate solution for each version.

Cindy Meister
INTER-Solutions, Switzerland
http://homepage.swissonline.ch/cindymeister (last update Jun 8 2004)
http://www.word.mvps.org

This reply is posted in the Newsgroup; please post any follow question or
reply in the newsgroup and not by e-mail :)
 

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