将控制添加到MDI客户端

时间:2009-12-02 10:37:39

标签: c#

请帮帮我,我有一个问题 我想知道如何向MDI Client添加像按钮或面板这样的控件 请帮我 感谢

4 个答案:

答案 0 :(得分:1)

如果我理解正确,您可以按照惯例在设计视图中创建表单,然后将这些表单作为子项加载到MDI Parent中。

// Create a new instance of the child form.
Form childForm = new Form1(); //where form1 is the form you designed
// Make it a child of this MDI form before showing it.
childForm.MdiParent = this;
childForm.Text = "Window " + childFormNumber++;
childForm.Show();

查看Using MDI

答案 1 :(得分:1)

我假设您正在尝试做与我相同的事情。我已经找到了如何将工具栏和状态栏放在mdi客户区中,但是找不到其他控件的任何信息。

这是我完成状态栏的方式;

在主窗口回调的WM_CREATE消息中,使用CreateWindowEx创建状态栏。数组statwidths []保存每个状态栏窗口的位置,出于某些原因,该位置是从每个窗口的右侧或末端进行测量的:

HWND hStatus;
int statwidths[] = { 50, 100, -1 };

hStatus = CreateWindowEx(
    0, STATUSCLASSNAME,
    NULL,
    WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP,
    0,0,0,0,
    hWnd,
    (HMENU)IDC_MAIN_STATUS,
    GetModuleHandle(NULL),
    NULL);

if (hStatus == NULL)
    MessageBox(hWnd, L"Could not create statusbar.", L"Error", MB_OK | MB_ICONERROR);

SendMessage(hStatus, SB_SETPARTS, sizeof(statwidths) / sizeof(int), (LPARAM)statwidths);
SendMessage(hStatus, SB_SETTEXT, 0, (LPARAM)L"Win32");
SendMessage(hStatus, SB_SETTEXT, 1, (LPARAM)L"MDI");

然后输入WM_SIZE:

HWND hStatusbar;
RECT rcStatusbar;
int iStatusbarHeight;

hStatusbar = GetDlgItem(hWnd, IDC_MAIN_STATUS);
SendMessage(hStatusbar, WM_SIZE, 0, 0);

GetWindowRect(hStatusbar, &rcStatusbar);
iStatusbarHeight = rcStatusbar.bottom - rcStatusbar.top;

对于工具栏,执行完全相同的操作,只需要一些代码即可为按钮填充工具栏。在WM_CREATE中:

HWND hToolbar;
TBBUTTON tbb[3];
TBADDBITMAP tbab;

hToolbar = CreateWindowEx(
    0,TOOLBARCLASSNAME,
    NULL,
    WS_CHILD | WS_VISIBLE,
    0,0,0,0,
    hWnd,
    (HMENU)IDC_MAIN_TOOL,
    GetModuleHandle(NULL),
    NULL);

if (hToolbar == NULL)
    MessageBox(hWnd, L"Could not create tool bar.", L"Error", MB_OK | MB_ICONERROR);

// Send the TB_BUTTONSTRUCTSIZE message, which is required for
// backward compatibility.
SendMessage(hToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);

tbab.hInst = HINST_COMMCTRL;
tbab.nID = IDB_STD_SMALL_COLOR;
SendMessage(hToolbar, TB_ADDBITMAP, 0, (LPARAM)&tbab);

ZeroMemory(tbb, sizeof(tbb));
tbb[0].iBitmap = STD_FILENEW;
tbb[0].fsState = TBSTATE_ENABLED;
tbb[0].fsStyle = TBSTYLE_BUTTON;
tbb[0].idCommand = ID_FILE_NEW;

tbb[1].iBitmap = STD_FILEOPEN;
tbb[1].fsState = TBSTATE_ENABLED;
tbb[1].fsStyle = TBSTYLE_BUTTON;
tbb[1].idCommand = ID_FILE_OPEN;

tbb[2].iBitmap = STD_FILESAVE;
tbb[2].fsState = TBSTATE_ENABLED;
tbb[2].fsStyle = TBSTYLE_BUTTON;
tbb[2].idCommand = ID_FILE_SAVEAS;

SendMessage(hToolbar, TB_ADDBUTTONS, sizeof(tbb) / sizeof(TBBUTTON), (LPARAM)&tbb);

,然后在WM_SIZE中执行与状态栏完全相同的操作

HWND hToolbar;
RECT rcToolbar;
int iToolbarHeight;

hToolbar = GetDlgItem(hWnd, IDC_MAIN_TOOL);
SendMessage(hToolbar, TB_AUTOSIZE, 0, 0);

GetWindowRect(hToolbar, &rcToolbar);
iToolbarHeight = rcToolbar.bottom - rcToolbar.top;

最后调整主窗口工作区的大小;

HWND hMDI;
int iMDIHeight;
RECT rcClient;

GetClientRect(hWnd, &rcClient);
iMDIHeight = rcClient.bottom - iToolbarHeight - iStatusbarHeight;

hMDI = GetDlgItem(hWnd, IDC_MAIN_MDI);
SetWindowPos(hMDI, NULL, 0, iToolbarHeight, rcClient.right, iMDIHeight, SWP_NOZORDER);

我希望这就是你的追求。如果您发现如何将编辑控件放在状态栏顶部(例如Visual Studio中的输出窗口),请告诉我您的操作方式。

答案 2 :(得分:0)

据我所知,您只能将窗口(读取:表单)添加到MDI窗口。控件必须始终具有存在的父窗口。 astander的示例在技术上是正确的:如果您要“向MDI客户端添加按钮或面板”,那么在将该表单添加到MDI客户端之前,您需要在表单内托管该按钮或面板。

答案 3 :(得分:0)

这不是通常的建议,但是对于您来说,您可以编写简单的MDI应用程序。 我有一个样本。添加一个面板(docStyle = fill)[将其命名为panel_Container']到您的主表单。创建子表单并调用此方法。

 void MakeMDIChild_Simplest(Type thisForm)
    {
        FlowLayoutPanel panel_Bottom_flowLayout = null;
        if (null == Controls["panel_Bottom_flowLayout"])
        {
            panel_Bottom_flowLayout = new FlowLayoutPanel()
            {
                AutoSize = true,
                BackColor = System.Drawing.Color.Transparent,
                Dock = System.Windows.Forms.DockStyle.Bottom,
                Location = new System.Drawing.Point(0, 332),
                Name = "panel_Bottom_flowLayout",
                Size = new System.Drawing.Size(479, 0),
                TabIndex = 1
            };
            Controls.Add(panel_Bottom_flowLayout);
        }
        else
        {
            panel_Bottom_flowLayout = (FlowLayoutPanel)Controls["panel_Bottom_flowLayout"];
        }
        Form frm = (Form)Activator.CreateInstance(thisForm);
        const int GWL_STYLE = -16;
        const uint WS_POPUP = 0x80000000;
        const uint WS_CHILD = 0x40000000;
        uint style = GetWindowLong(frm.Handle, GWL_STYLE);
        style = (style & ~(WS_POPUP)) | WS_CHILD;

        SetWindowLong(frm.Handle, GWL_STYLE, style);
        SetParent(frm.Handle, panel_Container.Handle);

        int captionHeight = frm.Height - frm.ClientSize.Height;
        frm.Location = new Point(panel_Container.Width / 2 - frm.Width / 2, panel_Container.Height / 2 - frm.Height / 2 + captionHeight);
        frm.Show();
        frm.MouseDown += (sender, mea) =>
        {
            const int WM_NCLBUTTONDOWN = 0xA1;
            ReleaseCapture();
            PostMessage(frm.Handle, WM_NCLBUTTONDOWN, new IntPtr(2), IntPtr.Zero);
        };
        frm.Resize += (Sendder, rea) =>
        {
            if (frm.WindowState == FormWindowState.Minimized)
            {
                frm.SendToBack();
                Label lbl =
                new Label()
                {
                    AutoSize = true,
                    Text = frm.Text,
                    BackColor = Color.LightCoral,
                    BorderStyle = BorderStyle.FixedSingle,
                    Padding = new System.Windows.Forms.Padding(5),
                    Margin = new System.Windows.Forms.Padding(2)
                };
                lbl.Click += (sender, cea) =>
                {
                    frm.WindowState = FormWindowState.Normal;
                    frm.Location = lbl.Location;
                    frm.BringToFront();
                    panel_Bottom_flowLayout.Controls.Remove(lbl);
                };
                panel_Bottom_flowLayout.Controls.Add(lbl);
            }
        };
    }

用法:

 private void newToolStripMenuItem_Click(object sender, EventArgs e)
    {
        MakeMDIChild_Simplest(typeof(ChildForm));
    }

您还必须将以下内容添加到MainForm类

    [DllImport("user32.dll")]
    static extern int SetWindowLong(IntPtr hWnd, int nIndex, uint dwNewLong);

    [DllImport("user32.dll", SetLastError = true)]
    static extern uint GetWindowLong(IntPtr hWnd, int nIndex);

    [DllImport("user32.dll", SetLastError = true)]
    public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

就是这样