2010-08-10 46 views
1

我有一个面板可能或可能不在其他面板内。我正在努力解决该小组的可见范围。我认为GetWindowRectGetClientRect会做的伎俩,但没有喜悦。如何获得面板的可见边界

为了测试这个,我创建了一个带有面板和多行文本框的窗体。面板比表格大(即它伸展到表格底部以下)

所以如果我的表格是300的300.并且面板位于10,10并且是100的500 我想要一些会告诉我,可视面积是100,290(假设面板0,0的相对起点,这将是在10,10在所有。

难道这样的方法存在吗?

我曾尝试一些不同的方法,例如获得我感兴趣的面板的父母手柄并进行测试,但是我不能总是确定直接父母是确定可见性的那个人。

下面是测试应用程序的我写的测试GetWindowRect代码或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; 
    } 
} 
} 

编辑:发现了更多的信息:

我觉得行this.AutoScrollMinSize = new Size(250, 500); 被搞乱了我的结果。这似乎使面板500,即使它不显示500.将重做我的一些测试用例。我不会想到这条线会导致问题。

回答

0

这是我最终想出了:

WinSDK.RECT parentRect = new WinSDK.RECT(); 
      WinSDK.RECT intersectRect = new WinSDK.RECT(); 

      Rectangle parentRectangle = new Rectangle(); 
      Rectangle intersectRectangle = new Rectangle(); 

      // Get the current Handle. 
      IntPtr currentHandle = this.Handle; 

      // Get next Parent Handle. 
      IntPtr parentHandle = WinSDK.GetParent(this.Handle); 

      // Get the Rect for the current Window. 
      WinSDK.GetWindowRect(this.Handle, out intersectRect); 

      // Load Current Window Rect into a System.Drawing.Rectangle 
      intersectRectangle = new Rectangle(intersectRect.left, intersectRect.top, intersectRect.right - intersectRect.left, intersectRect.bottom - intersectRect.top); 

      // Itterate through all parent windows and get the overlap of the visible areas to find out what's actually visible. 
      while (parentHandle != IntPtr.Zero) 
      { 
       // Get the Rect for the Parent Window. 
       WinSDK.GetWindowRect(parentHandle, out parentRect); 
       parentRectangle = new Rectangle(parentRect.left, parentRect.top, parentRect.right - parentRect.left, parentRect.bottom - parentRect.top); 

       // Get the intersect between the current and parent window. 
       intersectRectangle.Intersect(parentRectangle); 

       // Set up for next loop. 
       currentHandle = parentHandle; 
       parentHandle = WinSDK.GetParent(currentHandle); 
      } 

      return intersectRectangle; 
2

您应该能够使用面板的DisplayRectangle属性来获取当前正在显示的矩形。该酒店在控制中实现,而是由ScrollableControl(System.Windows.Forms.Panel的母公司)重写

+0

是啊,我是TREID同样,它给了我与客户矩形相同的结果。所以这仍然太大。 – AidanO 2010-08-10 14:02:07