请帮帮我,我有一个问题 我想知道如何向MDI Client添加像按钮或面板这样的控件 请帮我 感谢
答案 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);
就是这样