Sunday, August 15, 2010

C# .NET Active Windows Size Helper

I have several times found myself with a need to easily get window size information in windows. And I wanted the information available in a nice rounded tab associated with the currently active window. As the astute reader will point out is that every thing about doing this is indeed really simple the only challenge is to get the rounded corners on a windows form.

This proved to be much easier than expected.

The final result looks like this. The source code can be downloaded here WindowsSize.zip.


Here below we can find the main relevant parts of the code.
private void Form1_Load(object sender, EventArgs e)
{
 timer1.Start();
 this.Region = Region.FromHrgn(Win32.CreateRoundRectRgn(0, 0, 80, 80, 80, 23));
 ShowInTaskbar = false;
 this.Width = 80;
 this.Height = 23;
}

private void timer1_Tick(object sender, EventArgs e)
{
 const int nChars = 256;
 WINDOWINFO info = new WINDOWINFO();
 StringBuilder buffer = new StringBuilder(nChars);

 info.cbSize = (uint)Marshal.SizeOf(info);

 IntPtr activeWindowHandle = Win32.GetForegroundWindow();
 Win32.GetWindowInfo(activeWindowHandle, ref info);

 // Move this windows to front
 this.BringWindowToFront();

 // We need to get the current window to make sure that we are not trying to set the position of
 // our own window based on out own size then the windows will be moving over the screen
 if (this.Handle != activeWindowHandle)
 {
  this.Top = info.rcWindow.Top - this.Height;
  this.Left = info.rcWindow.Left + 10;

  int width = info.rcWindow.Right - info.rcWindow.Left;
  int height = info.rcWindow.Bottom - info.rcWindow.Top;
  lblWindowSize.Text = string.Format("{0} x {1}", width.ToString(), height.ToString());
 }
}

/// <summary>
/// Brings the window to front.
/// </summary>
private void BringWindowToFront()
{
 this.TopMost = true;
 this.Focus();
 this.BringToFront();
 this.TopMost = false;
}

And the relevant win32 api code
public struct RECT
{
 public int Left;       // Specifies the x-coordinate of the upper-left corner of the rectangle.
 public int Top;        // Specifies the y-coordinate of the upper-left corner of the rectangle.
 public int Right;      // Specifies the x-coordinate of the lower-right corner of the rectangle.
 public int Bottom;     // Specifies the y-coordinate of the lower-right corner of the rectangle.

}

[StructLayout(LayoutKind.Sequential)]
public struct WINDOWINFO
{
 public uint cbSize;
 public RECT rcWindow;
 public RECT rcClient;
 public uint dwStyle;
 public uint dwExStyle;
 public uint dwWindowStatus;
 public uint cxWindowBorders;
 public uint cyWindowBorders;
 public ushort atomWindowType;
 public ushort wCreatorVersion;

 public WINDOWINFO(Boolean? filler)
  : this()   // Allows automatic initialization of "cbSize" with "new WINDOWINFO(null/true/false)".
 {
  cbSize = (UInt32)(Marshal.SizeOf(typeof(WINDOWINFO)));
 }

}

class Win32
{
 /// <summary>
 /// Gets the foreground window.
 /// </summary>
 /// <returns></returns>
 [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
 public static extern IntPtr GetForegroundWindow();

 /// <summary>
 /// Gets the window info.
 /// </summary>
 /// <param name="hwnd">The HWND.</param>
 /// <param name="pwi">The pwi.</param>
 /// <returns></returns>
 [return: MarshalAs(UnmanagedType.Bool)]
 [DllImport("user32.dll", SetLastError = true)]
 public static extern bool GetWindowInfo(IntPtr hwnd, ref WINDOWINFO pwi);

 /// <summary>
 /// Gets the window text.
 /// </summary>
 /// <param name="hWnd">The h WND.</param>
 /// <param name="text">The text.</param>
 /// <param name="count">The count.</param>
 /// <returns></returns>
 [DllImport("user32.dll")]
 public static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);

 /// <summary>
 /// Creates the round rect RGN.
 /// </summary>
 /// <param name="nLeftRect">The n left rect.</param>
 /// <param name="nTopRect">The n top rect.</param>
 /// <param name="nRightRect">The n right rect.</param>
 /// <param name="nBottomRect">The n bottom rect.</param>
 /// <param name="nWidthEllipse">The n width ellipse.</param>
 /// <param name="nHeightEllipse">The n height ellipse.</param>
 /// <returns></returns>
 [DllImport("Gdi32.dll", EntryPoint = "CreateRoundRectRgn")]
 public static extern IntPtr CreateRoundRectRgn
 (
  int nLeftRect,
  int nTopRect, // y-coordinate of upper-left corner
  int nRightRect, // x-coordinate of lower-right corner
  int nBottomRect, // y-coordinate of lower-right corner
  int nWidthEllipse, // height of ellipse
  int nHeightEllipse // width of ellipse
 );
}

No comments: