我正在用C#编写一个Windows窗体应用程序,可以启动一些Windows实用程序(例如CMD提示符,注册表编辑器,事件查看器等),并放在主窗体上的MdiClient控件中。
除了当子窗口超出MdiClient的边界时,MdiClient控件中的滚动条不会自动出现,所以一切都很好。如果子窗口是窗体,那么我知道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;
}
}
下面的屏幕截图显示,当移动CMD窗口使其边框位于MdiClient的边框之外时,没有滚动条:
请参阅此链接以获取图片:http://picasaweb.google.com/lh/photo/75rMVJMCWRg_s_DFF6LmNg?authkey=Gv1sRgCIKRlsu8xuDh8AE&feat=directlink
非常感谢任何帮助!
谢谢, 黑幕
答案 0 :(得分:1)
没有屏幕截图很难说,但我认为你创建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,我不认为这是一个很好的组合。
答案 1 :(得分:0)
我一直在做一些测试,只要我在表单属性中有Autoscroll = true,它就可以正常工作。
另外,我注意到如果你放大窗体并移动命令窗口说右下角它将不会显示滚动条,它只会在你通过命令窗口最小化窗体时显示(见下面的截图)
截屏1 http://picasaweb.google.com/lh/photo/rfwm-S8y06Fl3HFNshgj3g?feat=directlink
截图2 http://picasaweb.google.com/lh/photo/y6qkN9Jj19vDGFNkTuL4FQ?feat=directlink
另外,您可以在Form的属性AutoScrollMinSize上进行设置,这样您在表单中的滚动条总是小于设置的大小
希望有所帮助
约什