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