|
// --------------------------------------------------------------------------
// Copyright (c) MEMOS Software s.r.o. All rights reserved.
//
// Outlook Panel Demonstration
//
// File : PanelManager.cs
// Author : Lukas Neumann <lukas.neumann@memos.cz>
// Created : 080622
//
// --------------------------------------------------------------------------
using System;
using System.Drawing;
using System.Windows.Forms;
namespace OutlookPanel
{
/// <summary>
/// Class that manages nested panel control
/// </summary>
public class PanelManager : IDisposable
{
private PanelContainer _panelContainer;
private SubclassedWindow _subclassedSiblingWindow;
private bool _changingSize;
/// <summary>
/// Default constructor
/// </summary>
/// <param name="parentWindow">Parent window handle, most likely a main window of host application</param>
/// <param name="siblingWindow">Sibling window from which we will 'steal' the space to display our own panel</param>
public PanelManager(IntPtr parentWindow, IntPtr siblingWindow)
{
this._parentWindow = parentWindow;
this._siblingWindow = siblingWindow;
}
private readonly IntPtr _parentWindow;
/// <summary>
/// Parent window handle
/// </summary>
public IntPtr ParentWindow
{
get { return _parentWindow; }
}
private readonly IntPtr _siblingWindow;
/// <summary>
/// Sibling window handle
/// </summary>
public IntPtr SiblingWindow
{
get { return _siblingWindow; }
}
/// <summary>
/// Clean up method
/// </summary>
public void Dispose()
{
//Dispose the container (if it was initialised)
if (_panelContainer != null)
_panelContainer.Dispose();
//Dispose the subclassing wrapper (if it was initialised)
if (_subclassedSiblingWindow != null)
_subclassedSiblingWindow.ReleaseHandle();
}
/// <summary>
/// Show bar control
/// </summary>
/// <param name="nestedControl">Nested custom panel to show</param>
public void ShowBarControl(UserControl nestedControl)
{
//Create new container instance
_panelContainer = new PanelContainer();
//Set the parent window of the bar container
SafeNativeMethods.SetParent(_panelContainer.Handle, this.ParentWindow );
//Resize both sibling and our container
ResizePanels();
//Subclass sibling window to monitor SizeChange event
_subclassedSiblingWindow = new SubclassedWindow();
_subclassedSiblingWindow.AssignHandle(this.SiblingWindow);
_subclassedSiblingWindow.SizeChanged += new EventHandler(subclassedSiblingWindow_SizeChanged);
//Attach nested panel to our container
_panelContainer.AttachControl(nestedControl);
_panelContainer.Show();
}
/// <summary>
/// Resize original sibling window and our panel container window
/// </summary>
private void ResizePanels()
{
if (_changingSize)
return; //Prevent infinite loops
_changingSize = true;
try
{
//Get size of the sibling window and main parent window
Rectangle siblingRect = SafeNativeMethods.GetWindowRectange(this.SiblingWindow);
Rectangle parentRect = SafeNativeMethods.GetWindowRectange(this.ParentWindow);
//Calculate position of sibling window in screen coordinates
SafeNativeMethods.POINT topLeft = new SafeNativeMethods.POINT(siblingRect.Left, siblingRect.Top);
SafeNativeMethods.ScreenToClient(this.ParentWindow, ref topLeft);
//Decrease size of the sibling window
int newWidth = parentRect.Width - topLeft.X - _panelContainer.Width;
SafeNativeMethods.SetWindowPos(this.SiblingWindow, IntPtr.Zero, 0, 0, newWidth, siblingRect.Height, SafeNativeMethods.SWP_NOMOVE | SafeNativeMethods.SWP_NOZORDER);
//Move the bar to correct position
_panelContainer.Left = topLeft.X + newWidth;
_panelContainer.Top = topLeft.Y;
//Set correct height of the panel container
_panelContainer.Height = siblingRect.Height;
}
finally
{
_changingSize = false;
}
}
/// <summary>
/// Called when size of the sibling window has been changed
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void subclassedSiblingWindow_SizeChanged(object sender, EventArgs e)
{
//Since sibling has changed its size, we need to resize both windows again
ResizePanels();
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
I started developing software in Quick Basic on my very first PC running 8086 CPU @ 8MHz. Then I moved to Visual Basic, followed by MFC and for last 4 years i am stuck with C# and Microsoft .NET. Now I work as a senior developer for
MEMOS Software. My hobby is Office integration, especially Microsoft Outlook.
Check out my blog at
http://blog.memos.cz