Skip to content

Instantly share code, notes, and snippets.

@drewchapin
Last active September 26, 2022 06:38
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save drewchapin/787a03fc5bf084bfe23639e37eee9059 to your computer and use it in GitHub Desktop.
Save drewchapin/787a03fc5bf084bfe23639e37eee9059 to your computer and use it in GitHub Desktop.
IWin32Window implementation to allow VSTO addins to access Excel's main window.
using System.Reflection;
using System.Windows.Forms;
namespace MyExcelAddin
{
public partial class ThisAddIn
{
public Win32Window MainWindow { get; set; }
public string AssemblyTitle
{
get {
try
{
var attr = typeof(ThisAddIn)
.GetTypeInfo()
.Assembly
.GetCustomAttribute(typeof(AssemblyTitleAttribute))
as AssemblyTitleAttribute;
return attr?.Title ?? "Excel";
}
catch
{
return "Excel";
}
}
}
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
this.MainWindow = new Win32Window(Globals.ThisAddIn.Application.Hwnd);
}
}
}
using System;
using System.Runtime.InteropServices;
using System.Drawing;
namespace MyExcelAddin
{
public class Win32Window: System.Windows.Forms.IWin32Window
{
/// <summary>
/// Retrieves the dimensions of the bounding rectangle of the specified window.
/// The dimensions are given in screen coordinates that are relative to the upper-left corner of the screen.
/// </summary>
/// <see cref="https://msdn.microsoft.com/en-us/library/windows/desktop/ms633519(v=vs.85).aspx"/>
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetWindowRect( HandleRef hWnd, out RECT lpRect );
/// <summary>
/// The RECT structure defines the coordinates of the upper-left and lower-right corners of a rectangle.
/// </summary>
/// <see cref="https://msdn.microsoft.com/en-us/library/windows/desktop/dd162897(v=vs.85).aspx"/>
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
/// <summary>The x-coordinate of the upper-left corner of the rectangle.</summary>
public int Left;
/// <summary>The y-coordinate of the upper-left corner of the rectangle.</summary>
public int Top;
/// <summary>The x-coordinate of the lower-right corner of the rectangle.</summary>
public int Right;
/// <summary>The y-coordinate of the lower-right corner of the rectangle.</summary>
public int Bottom;
}
/// <summary>
/// Window Handle
/// </summary>
IntPtr _hwnd;
/// <summary>
/// Initializes a new instance of the Win32Window object.
/// </summary>
/// <param name="hwnd"></param>
public Win32Window( int hwnd )
{
this._hwnd = new IntPtr(hwnd);
}
/// <summary>
/// Gets the Y-coordinate of the bottom edge of the window.
/// </summary>
public int Bottom
{
get { return this.Rectangle.Bottom; }
}
/// <summary>
/// Window Handle
/// </summary>
public IntPtr Handle
{
get { return this._hwnd; }
}
/// <summary>
/// Window Handle Reference
/// </summary>
private HandleRef HandleRef
{
get { return new HandleRef(this,this.Handle); }
}
/// <summary>
/// Gets the height of the window.
/// </summary>
public int Height
{
get { return this.Rectangle.Width; }
}
/// <summary>
/// Gets the X-coordinate of the left edge of the window.
/// </summary>
public int Left
{
get { return this.Rectangle.Left; }
}
/// <summary>
/// Gets the Windows Rectangle
/// </summary>
public Rectangle Rectangle
{
get {
RECT rect;
GetWindowRect(this.HandleRef,out rect);
return new Rectangle(rect.Left,rect.Top,rect.Right-rect.Left,rect.Bottom-rect.Top);
}
}
/// <summary>
/// Gets the X-coordinate of the right edge of the window.
/// </summary>
public int Right
{
get { return this.Rectangle.Right; }
}
/// <summary>
/// Gets the Y-coordinate of the top edge of the window.
/// </summary>
public int Top
{
get { return this.Rectangle.Top; }
}
/// <summary>
/// Gets the width of the window.
/// </summary>
public int Width
{
get { return this.Rectangle.Width; }
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment