【问题标题】:Windows Forms - MdiClient scroll bars not automatically appearing as expectedWindows 窗体 - MdiClient 滚动条未按预期自动显示
【发布时间】:2009-09-18 22:20:15
【问题描述】:

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

任何帮助将不胜感激!

谢谢, 阴暗的

【问题讨论】:

  • 截图链接失效了。
  • 链接已更新。

标签: c# winforms scrollbars mdiparent mdichild


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

【讨论】:

  • 这是图像:picasaweb.google.com/lh/photo/… 我尝试不使用 HWND_TOPMOST,但父窗口中仍然没有出现滚动条。我不确定如何处理您的代码摘录。我所看到的是否是 MdiClient 的代码被注释掉并且 this.IsMdiContainer 被添加了。我尝试添加 this.IsMdiContainer 没有成功。
  • 我的代码不完整,只是以正常方式“设置”MDI 更安全。请注意,当您设置 Cmd Windows 的父级时,它们可能不会出现在客户端的控件列表中。如果部分 MDI 逻辑由 WinForms 处理,那么这可能就是问题所在。
  • 如果有人可以提供一个工作示例,说明 CMD 窗口是 Windows 窗体的子窗口,并且父窗口中的滚动条按预期运行,将不胜感激。滚动条是我唯一遇到的问题。
【解决方案2】:

我一直在做一些测试,只要我在表单属性中有 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中总是有滚动条小于设置的尺寸

希望有帮助

乔什

【讨论】:

  • "另外,我注意到如果你放大表单并移动命令窗口,说右下角它不会显示滚动条,只有当你最小化表单通过命令窗口时才会显示(参见下面的屏幕截图)“这就是我的问题。我一直在尝试使用 AutoScollMinSize 找到解决方案,但这并不容易。任何其他提示将不胜感激。
  • 嗨,Shady,一直在思考并有一些想法,只是想看看您想要实现什么?您是否希望子窗体的右下角越过父窗体的右下角时立即出现滚动条?乔什
  • 我希望每当子窗体超出父窗体的任何边框(顶部、右侧、左侧和底部)时出现滚动条。目前我有一个计时器,它每秒两次调整父窗体的大小(将宽度增加 1px,然后将宽度减少 1px),这会强制滚动条出现。但这当然不是我希望做的。
猜你喜欢
  • 2019-11-23
  • 2011-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多