I have a panel that may or may not be within other panels. I'm trying to work out the visible bounds of that panel. I thought the GetWindowRect
or the GetClientRect
would do the trick but no joy.
To test this I've created a form with a panel and at multiline text box. The panel is bigger than the form (i.e. it stretches below the bottom of the form)
So if my form is 300 by 300. And the Panel is located at 10,10 and is 100 by 500 I want something that will tell me that the visible area is 100, 290 (assuming the 0,0 relative starting point for the panel which would be at 10,10 over all.
Does such a method exist?
I have tried a few different methods like getting the parent handle of the panel i'm interested in and testing that but I can't always be sure the direct parent will be the one that determines the visibility.
Here is the code of the test application I wrote to test GetWindowRect
or the GetClientRect
:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace clientRectTest
{
public partial class Form1 : Form
{
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public Int32 left;
public Int32 top;
public Int32 right;
public Int32 bottom;
public static RECT FromRectangle(Rectangle rectangle)
{
RECT win32rect = new RECT();
win32rect.top = rectangle.Top;
win32rect.bottom = rectangle.Bottom;
win32rect.left = rectangle.Left;
win32rect.right = rectangle.Right;
return win32rect;
}
}
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
[DllImport("user32.dll")]
public static extern IntPtr GetWindowDC(IntPtr hWnd);
public Form1()
{
InitializeComponent();
this.AutoScrollMinSize = new Size(250, 500);
}
protected override void OnMouseClick(MouseEventArgs e)
{
NewLine("Click Location: " + e.Location.ToString());
base.OnMouseClick(e);
}
protected override void OnResize(EventArgs e)
{
this.textBox1.Text = "Panel Size" + this.panel1.Size.ToString();
NewLine( "Form Size" + this.Size.ToString());
// NewLine("Panel PARENT Client Rectangle: " + getPanelClientRectangle(this.panel1.Parent.Handle));
NewLine("Panel Client Rectangle: " + getPanelClientRectangle(this.panel1.Handle));
NewLine("Panel Window Rectangle: " + getPanelWindowRectangle(this.panel1.Handle));
NewLine("Panel Window Bounts: " + this.panel1.Bounds.ToString());
NewLine("Panel DC Client Rectangle: " + getPanelDCClientRectangle(this.panel1.Handle));
NewLine("Panel DC Window Rectangle: " + getPanelDCWindowRectangle(this.panel1.Handle));
NewLine("Panel Location: " + this.panel1.Location.ToString());
base.OnResize(e);
}
private string getPanelDCClientRectangle(IntPtr handle)
{
string cr = string.Empty;
RECT r1 = new RECT();
IntPtr dc = GetWindowDC(handle);
GetClientRect(dc, out r1);
cr = r1.left.ToString() + ", " + r1.top.ToString() + ", " + r1.right.ToString()
+ ", " + r1.bottom.ToString();
Point thisLocation = this.Location;
return cr;
}
private string getPanelDCWindowRectangle(IntPtr handle)
{
string cr = string.Empty;
RECT r1 = new RECT();
IntPtr dc = GetWindowDC(handle);
GetWindowRect(dc, out r1);
cr = r1.left.ToString() + ", " + r1.top.ToString() + ", " + r1.right.ToString()
+ ", " + r1.bottom.ToString();
Point thisLocation = this.Location;
return cr;
}
private string getPanelWindowRectangle(IntPtr handle)
{
string cr = string.Empty;
RECT r1 = new RECT();
GetWindowRect(handle, out r1);
cr = r1.left.ToString() + ", " + r1.top.ToString() + ", " + r1.right.ToString()
+ ", " + r1.bottom.ToString();
Point thisLocation = this.Location;
return cr;
}
private string getPanelClientRectangle(IntPtr handle)
{
string cr = string.Empty;
RECT r1 = new RECT();
GetClientRect(handle, out r1);
cr = r1.left.ToString() + ", " + r1.top.ToString() + ", " + r1.right.ToString()
+ ", " + r1.bottom.ToString();
Point thisLocation = this.Location;
return cr;
}
private void NewLine(string p)
{
this.textBox1.Text += Environment.NewLine + p;
}
}
}
EDIT: more information found:
I think the line this.AutoScrollMinSize = new Size(250, 500);
was messing up my results. This seemed to make the panel 500 even though it wasn't displaying 500. Will redo some of my test cases. I wouldn't have expeced this line to cause problems.