2010-08-10 61 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