views:

590

answers:

1

I'm writing a windows forms application in C# whereby some windows utilities can be launched (e.g. CMD prompt, Registry editor, Events Viewer etc) and placed in an MdiClient control on the main form.

Everything is working great except that the scroll bars in the MdiClient control aren't automatically appearing when a child window falls beyond the MdiClient's borders. If the child windows were windows forms then I know that the MdiClient's scroll bars would automatically appear as expected. I've tried many things, including some complex workarounds.. and i'm beginning to think there must be something i'm completely overlooking.

I have attached some sample code below:

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;
    }
}

The screenshot below shows that when the CMD window is moved so its borders are outside the borders of the MdiClient there are no scroll bars:

Please see this link for the image: http://picasaweb.google.com/lh/photo/75rMVJMCWRg%5Fs%5FDFF6LmNg?authkey=Gv1sRgCIKRlsu8xuDh8AE&amp;feat=directlink

Any help would be much appreciated!

Thanks, Shady

A: 

Hi Shady,

I have been doing some testing and it work ok for me was long as I have Autoscroll = true in the forms properties.

Also, I noticed if you enlarge the form and move the command window to say the bottom right it will not show the scroll bars, it will only when you minimize the form past the command windows (see screenshots below)

Screenshot 1 http://picasaweb.google.com/lh/photo/rfwm-S8y06Fl3HFNshgj3g?feat=directlink

Screenshot 2 http://picasaweb.google.com/lh/photo/y6qkN9Jj19vDGFNkTuL4FQ?feat=directlink

Also, can you set on the Form's properties AutoScrollMinSize, so that you always have scroll bars in the form is smaller than the size set

Hope that helps

Josh

jj.matthews
"Also, I noticed if you enlarge the form and move the command window to say the bottom right it will not show the scroll bars, it will only when you minimize the form past the command windows (see screenshots below)"This is what my problem is. I've been trying to find a solution using AutoScollMinSize but it's not easy..Any other tips would be greatly appreciated.
Shady
Hi Shady, been thinking and have a few ideas, just wanted to check to see what you are trying to achieve? Do you want the scrollbars to appear as soon as the bottom right of the child form goes past the bottom right of the parent form?Josh
jj.matthews
I would like the scroll bars to appear whenever the child form goes beyond any border of the parent form (top, right, left and bottom). Currently I have a timer that resizes the parent form twice a second (increments width by 1px then decrements width by 1px) and this forces the scroll bars to appear. But this is not what i was hoping to have to do of course.
Shady