在 Delphi 中,你可以通过改变TForm.Parent属性在另一个窗体中创建一个窗体。
有两种方法可以在另一个窗体中创建窗体
正规形式(fsNormal
)
下面是一个在表单中创建表单的示例
with TForm.Create(Self) do
begin
Parent := Self;
Caption := 'Test 1';
Width := 350;
Height := 200;
Show;
end;
字符串
问题是它们在与它们交互时不能正常工作。捕获焦点只能通过单击标题栏或使用Form.SetFocus来实现,它们包含的控件也是如此。表单将出现在表单可能包含的任何TWinControls或TGraphicControl之上。
的数据
MDI Forms('fsMDICild')
正确的方法是使用MDI表单。像这样:
Form.Style := fsMDIForm;
with TForm.Create(Self) do
begin
Parent := Self;
Caption := 'Test 1';
Width := 350;
Height := 200;
FormStyle := fsMDIChild;
Show;
end;
with TForm.Create(Self) do
begin
Parent := Self;
Caption := 'Test 2';
Width := 350;
Height := 200;
FormStyle := fsMDIChild;
Show;
end;
型
然后表单将正常运行。像这样:
问题是
MDI表单将完美地为我的用例工作,如果不是2个问题:
fsMDIForm
边界,称为“ClientEdge”
1.窗体内的控件显示在MDI窗体的上方
第一个问题可以通过覆盖ClientWndProc
轻松解决。过程如下:
procedure ShowMDIClientEdge(ClientHandle: THandle; ShowEdge: Boolean);
var
Style: NativeInt;
begin
if ClientHandle <> 0 then
begin
Style := GetWindowLong(ClientHandle, GWL_EXSTYLE);
if ShowEdge then
if Style and WS_EX_CLIENTEDGE = 0 then
Style := Style or WS_EX_CLIENTEDGE
else
Exit
else if Style and WS_EX_CLIENTEDGE <> 0 then
Style := Style and not WS_EX_CLIENTEDGE
else
Exit;
SetWindowLong(ClientHandle, GWL_EXSTYLE, Style);
SetWindowPos(ClientHandle, 0, 0, 0, 0, 0, SWP_FRAMECHANGED or SWP_NOACTIVATE or
SWP_NOMOVE or SWP_NOSIZE or SWP_NOZORDER);
end;
end;
procedure TForm1.ClientWndProc(var Message: TMessage);
begin
if Message.Msg = $3F then
begin
ShowMDIClientEdge(ClientHandle, false);
Exit;
end;
inherited;
end;
型
但是第二个问题是MDI表单出现在我认为的组件下面,这是无法解决的。这使得fsNormal
方法更有吸引力,如果表单能够正常工作并捕获焦点的话。
简而言之,我需要一个表单在另一个表单中,它可以:
- 保持在客户端区域内,因此它不能离开或被绘制到客户端之外
- 出现在窗体内的控件上方
- 专注
那么为什么fsNormal
表单无法捕获焦点呢?
1条答案
按热度按时间htrmnn0y1#
我首先使用Athens创建了
fsNormal
设置,然后使用Alexandria进行了测试。子窗体OnCreate过程我刚刚添加了代码,其中Form2 parent设置为Form1。
字符串
在Alexandria上关注表单在标题栏之外的地方点击的问题可以通过将其放在
OnMouseDown
事件的前面来解决。D12不再有这个问题。型
一个恼人的问题仍然存在,那就是当你直接移动窗体的标题栏,它将保持在其他子窗体下,直到你点击它.但我解决了这个问题在windows事件
WMMoving
通过添加BringToFront
在它.你也提到子窗体不应该走出Form1边界,它也可以很容易地解决在WMMoving
事件.型
当使用windows事件时,你也需要将其添加到Form类中。
型
例如,当在窗体内部单击按钮时,子窗体没有将其更改为顶部,而不是窗体本身仍然存在。一个选项是当鼠标进入窗体时,将窗体置于前面。
型
这些工作在D11和D12,我没有任何旧版本的测试。
这个旧的组件还在工作。
https://torry.net/components/forms/other/ttopmost
我希望这将有助于你推进你的项目。