C# Windows窗体-客户端滚动条未按预期自动显示

C# Windows窗体-客户端滚动条未按预期自动显示,c#,winforms,scrollbars,mdiparent,mdichild,C#,Winforms,Scrollbars,Mdiparent,Mdichild,我正在用C#编写一个windows窗体应用程序,通过它可以启动一些windows实用程序(例如CMD提示符、注册表编辑器、事件查看器等),并将其放置在主窗体上的MdiClient控件中 除了当子窗口超出MdiClient的边界时,MdiClient控件中的滚动条不会自动出现外,其他一切都很正常。如果子窗口是windows窗体,那么我知道MdiClient的滚动条将按预期自动显示。我试过很多方法,包括一些复杂的解决方法。。我开始觉得一定有什么东西我完全忽略了 我在下面附上了一些示例代码: usin

我正在用C#编写一个windows窗体应用程序,通过它可以启动一些windows实用程序(例如CMD提示符、注册表编辑器、事件查看器等),并将其放置在主窗体上的MdiClient控件中

除了当子窗口超出MdiClient的边界时,MdiClient控件中的滚动条不会自动出现外,其他一切都很正常。如果子窗口是windows窗体,那么我知道MdiClient的滚动条将按预期自动显示。我试过很多方法,包括一些复杂的解决方法。。我开始觉得一定有什么东西我完全忽略了

我在下面附上了一些示例代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;
using System.Runtime.InteropServices;

namespace MdiClient
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            System.Windows.Forms.MdiClient mdiClient = new System.Windows.Forms.MdiClient();
            mdiClient.Dock = DockStyle.Fill;
            mdiClient.BackColor = Color.WhiteSmoke;
            this.Controls.Add(mdiClient);

            int processID = StartCMD();
            AddToMDIClient(processID, mdiClient.Handle);
        }

        private int StartCMD()
        {
            int processID = -1;

            using (Process process = new Process())
            {
                ProcessStartInfo startInfo = process.StartInfo;
                startInfo.FileName = "cmd.exe";

                try
                {
                    process.Start();
                    processID = process.Id;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }
            }

            return processID;
        }
        private void AddToMDIClient(int processID, IntPtr mdiClientHandle)
        {
            try
            {
                Process process = Process.GetProcessById(processID);

                int numberOfAttempts = 0;
                while (string.IsNullOrEmpty(process.MainWindowTitle) && numberOfAttempts < 30)//max of 3 seconds
                {
                    Thread.Sleep(100);
                    process.Refresh();

                    numberOfAttempts++;
                }

                if (!string.IsNullOrEmpty(process.MainWindowTitle))
                {
                    SetWindowPos(process.MainWindowHandle, HWND_TOPMOST, 1, 1, 0, 0, TOPMOST_FLAGS);

                    SetParent(process.MainWindowHandle, mdiClientHandle);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        [DllImport("user32.dll", SetLastError = true)]
        public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X,
            int Y, int cx, int cy, uint uFlags);

        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

        public static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
        public const UInt32 TOPMOST_FLAGS = /*SWP_NOMOVE | */SWP_NOSIZE;

        public const UInt32 SWP_NOSIZE = 0x0001;
    }
}
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用系统数据;
使用系统图;
使用系统文本;
使用System.Windows.Forms;
使用系统诊断;
使用系统线程;
使用System.Runtime.InteropServices;
命名空间MdiClient
{
公共部分类Form1:Form
{
公共表格1()
{
初始化组件();
}
私有void Form1\u加载(对象发送方、事件参数e)
{
System.Windows.Forms.MdiClient MdiClient=new System.Windows.Forms.MdiClient();
mdiClient.Dock=DockStyle.Fill;
mdiClient.BackColor=Color.WhiteSmoke;
this.Controls.Add(mdiClient);
int processID=StartCMD();
AddToMDIClient(processID,mdiClient.Handle);
}
私有int StartCMD()
{
int processID=-1;
使用(流程=新流程())
{
ProcessStartInfo startInfo=process.startInfo;
startInfo.FileName=“cmd.exe”;
尝试
{
process.Start();
processID=process.Id;
}
捕获(例外情况除外)
{
Show(例如ToString());
}
}
返回processID;
}
私有void AddToMDIClient(int-processID、IntPtr-mdiClientHandle)
{
尝试
{
Process=Process.GetProcessById(processID);
int numberofthresents=0;
while(string.IsNullOrEmpty(process.MainWindowTitle)&&numberOfAttempts<30)//最多3秒
{
睡眠(100);
process.Refresh();
尝试次数++;
}
如果(!string.IsNullOrEmpty(process.MainWindowTitle))
{
SetWindowPos(process.MainWindowHandle,HWND_最上面的、1、1、0、0、最上面的_标志);
SetParent(process.MainWindowHandle、mdiClientHandle);
}
}
捕获(例外情况除外)
{
Show(例如ToString());
}
}
[DllImport(“user32.dll”,SetLastError=true)]
公共静态外部布尔设置窗口位置(IntPtr hWnd、IntPtr hWndInsertAfter、int X、,
整数Y、整数cx、整数cy、整数uFlags);
[DllImport(“user32.dll”,SetLastError=true)]
公共静态外部IntPtr SetParent(IntPtr hWndChild、IntPtr hwndnnewparent);
公共静态只读IntPtr HWND_TOPMOST=新IntPtr(-1);
公共警察32最上面的旗帜=/*SWP\U NOMOVE*/SWP\U NOSIZE;
公共警察UInt32 SWP_NOSIZE=0x0001;
}
}
下面的屏幕截图显示,当移动CMD窗口使其边框位于MdiClient的边框之外时,没有滚动条:

有关图像,请参见此链接:

任何帮助都将不胜感激

谢谢,
Shady

没有屏幕截图很难说,但我认为你创建MDIParanet的方式太复杂了

private void Form1_Load(object sender, EventArgs e)
    {
       // System.Windows.Forms.MdiClient mdiClient = new System.Windows.Forms.MdiClient();
       //  mdiClient.Dock = DockStyle.Fill;
       // mdiClient.BackColor = Color.WhiteSmoke;
       // this.Controls.Add(mdiClient);

       this.IsMdiContainer = true;

        int processID = StartCMD();
        AddToMDIClient(processID, mdiClient.Handle);
    }
如果需要客户端,可以从控件中筛选它


另一个问题可能是将MDIChild设置为TOP_MOST,我认为这不是一个好的组合

没有屏幕截图很难说,但我认为创建MDIParanet的方式太复杂了

private void Form1_Load(object sender, EventArgs e)
    {
       // System.Windows.Forms.MdiClient mdiClient = new System.Windows.Forms.MdiClient();
       //  mdiClient.Dock = DockStyle.Fill;
       // mdiClient.BackColor = Color.WhiteSmoke;
       // this.Controls.Add(mdiClient);

       this.IsMdiContainer = true;

        int processID = StartCMD();
        AddToMDIClient(processID, mdiClient.Handle);
    }
如果需要客户端,可以从控件中筛选它


另一个问题可能是将MDIChild设置为TOP_MOST,我认为这不是一个好的组合

我一直在做一些测试,只要表单属性中有Autoscroll=true,它就可以正常工作


此外,我注意到,如果您放大表单并移动命令窗口,使其显示右下角,它将不会显示滚动条,只有当您将表单最小化超过命令窗口时才会显示滚动条(请参见下面的屏幕截图)

截图1

截图2

另外,能否设置窗体的属性AutoScrollMinSize,以便窗体中的滚动条始终小于设置的大小

希望有帮助


Josh

我一直在做一些测试,只要表单属性中有Autoscroll=true,它就可以正常工作


此外,我注意到,如果您放大表单并移动命令窗口,使其显示右下角,它将不会显示滚动条,只有当您将表单最小化超过命令窗口时才会显示滚动条(请参见下面的屏幕截图)

截图1

截图2

另外,能否设置窗体的属性AutoScrollMinSize,以便窗体中的滚动条始终小于设置的大小

希望有帮助


Josh

屏幕截图链接已断开。链接现在已更新。屏幕截图链接已断开。链接现在已更新。下图:我尝试不使用HWND_TOPMOST,但在父窗口中仍然没有显示滚动条。我不知道如何理解你的代码摘录。如果MdiClient的代码被注释掉,并且添加了this.IsMdiContainer,那么我所看到的一切就是。我尝试添加此.IsMdiContainer,但没有成功