2010-08-10 8 views
1

J'ai un panneau qui peut ou peut ne pas être dans d'autres panneaux. J'essaye de travailler sur les limites visibles de ce panneau. Je pensais que le GetWindowRect ou le GetClientRect ferait l'affaire mais pas de joie.Comment obtenir les limites visibles d'un panneau

Pour tester cela, j'ai créé un formulaire avec un panneau et dans une zone de texte multiligne. Donc, si mon formulaire est 300 par 300. Et le panneau est situé à 10,10 et est 100 par 500 Je veux quelque chose qui me dire que la zone visible est de 100, 290 (en supposant que le 0,0 point de départ par rapport au panneau qui serait à 10,10 sur tout.

est-ce que cette méthode existe?

J'ai essayé quelques méthodes différentes comme obtenir le parent parent du panneau qui m'intéresse et le tester, mais je ne peux pas toujours être sûr que le parent direct sera celui qui détermine la visibilité

Voici le code de l'application de test je l'ai écrit pour tester GetWindowRect ou 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: plus d'informations trouvées:

Je pense que la ligne this.AutoScrollMinSize = new Size(250, 500); a été chambouler mes résultats. Cela a semblé rendre le panneau 500 même s'il n'en affichait pas 500. Je vais refaire certains de mes cas de test. Je n'aurais pas attendu cette ligne pour causer des problèmes.

Répondre

0

C'est ce que je suis venu avec à la fin:

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

Vous devriez pouvoir utiliser la propriété DisplayRectangle du panneau pour obtenir le rectangle actuellement affiché. Cette propriété est mise en œuvre dans le contrôle, mais est remplacée par les ScrollableControl (le parent de System.Windows.Forms.Panel)

+0

Oui, je treid que aussi, il m'a donné les mêmes résultats que le client Rectangle. donc c'est encore trop gros. – AidanO

Questions connexes