سؤال

لدي لوحة قد تكون أو لا تكون داخل لوحات أخرى. أحاول تحديد الحدود المرئية لتلك اللوحة. اعتقدت GetWindowRect أو ال GetClientRect سيفعل الخدعة ولكن لا فرح.

لاختبار هذا لقد قمت بإنشاء نموذج مع لوحة وفي مربع النص متعدد الأسلحة. اللوحة أكبر من النموذج (أي تمتد أسفل الجزء السفلي من النموذج)

لذا ، إذا كان النموذج الخاص بي هو 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. سيعيد بعض حالات الاختبار الخاصة بي. لم أكن قد استحوذت على هذا الخط للتسبب في مشاكل.

هل كانت مفيدة؟

المحلول 2

هذا ما توصلت إليه في النهاية:

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;

نصائح أخرى

يجب أن تكون قادرًا على استخدام خاصية DisplayRectangle للوحة للحصول على المستطيل الذي يتم عرضه حاليًا. يتم تنفيذ هذه الخاصية في السيطرة ، ولكن يتم تجاوزها بواسطة ScrollableControl (والد System.windows.forms.panel)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top