假设您要将模式窗口为主的桌面程序改成融合窗口,原子窗口为TForm类型窗口。

用到的组件:Raize 5.x (不要问我为什么不用TFrame)

目前流行用Raize的RzPageControl来做融合窗口,因为它自带TabSheet的关闭按钮和事件,所以大家都用这个了。

我的实现方法是放一个RzTabSheet当首页,上面显示一些通知通告、待办事项提醒的项目,然后所有子模块的窗口直接动态创建到RzPageControl里去,创建代码如下:

procedure TfrmMain.N13Click(Sender: TObject);

var

   f : TfrmCallTask;// 需要给子模块传递变量,所以这样定义

   TabCtrl : TRzTabSheet;// 容器

   i : Integer;

begin

   for i := 0 to RzPageControl1.PageCount - 1 do

      if RzPageControl1.Pages[i].Caption = '任务列表' then

      begin

         RzPageControl1.Pages[i].Show;

         exit;

      end;// 这里是根据子模块窗口的标题来区分有没有生成,有生成就激活显示

   TabCtrl := TRzTabSheet.Create(RzPageControl1);// 创建容器

   TabCtrl.PageControl := RzPageControl1;// 容器归属

   RzPageControl1.ActivePageIndex := TabCtrl.PageIndex;// 激活容器页

   f := TfrmCallTask.Create(TabCtrl);// 创建窗口

   // 我这里用的是TForm而不是TFrame,所以是有窗口标题这些属性的

   TabCtrl.Caption := f.Caption;// 用窗口标题当标签页名称

   f.ManualDock(TabCtrl);// 将窗口融合到容器里

   f.Align := alClient;// 窗口自适应

   f.vU := vU;// 这里是设置窗口模块里的变量,当然也可以操作组件

   f.vN := vN;

   f.Show;

   f.SetFocus;// 窗口显示后做个聚焦

end;

关于窗口中的按键事件,也就是onKeyPress,因为我用的是TForm,所以可以直接使用这个事件,只是切换组件时,需要以消息的形式来处理,代码如下:

procedure TfrmCallList.Edit1KeyPress(Sender: TObject; var Key: Char);

begin

   if (Key = #13) then

   begin

      Key := #0;

      PostMessage(Handle, WM_KEYDOWN, VK_TAB, 0);// 模拟按下Tab键

      // Perform(WM_NEXTDLGCTL, 1, 0);// 模式窗口时有效,融合窗口时无效

   end;

end;

关于融合窗口的关闭,也简单的,只要在RzPageControl的Close事件里设置AllowClose为真即可,代码如下:

procedure TfrmMain.RzPageControl1Close(Sender: TObject;var AllowClose: Boolean);

begin//因为我不想关闭“首页”这个RzTabSheet,所以这样判断就行。

   AllowClose := RzPageControl1.ActivePage.Caption <>'首页'

end;

其他事项呢,不要忘记设置RzPageControl的几个相关属性来显示标签页样式和关闭按钮就行了,比如ShowCloseButtonOnActiveTab为真,ShowCloseButton这个为假。

下面附上效果图: