1

我正在用 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

任何帮助将非常感激!

谢谢, 谢迪

4

2 回答 2

1

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

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,我认为这不是一个好的组合。

于 2009-09-19T11:30:13.290 回答
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,让你在form中总是有滚动条小于设置的尺寸

希望有帮助

乔什

于 2009-10-07T15:15:17.373 回答