2007. november 16., péntek

Add a button to a TToolBar for each MDI child form created


Problem/Question/Abstract:

I want to create a TToolBar that will have corresponding buttons to the MDI children in my form, so that the user can switch between the children by clicking on the buttons - not going through the MDI menu. How do I do that ? Adding a button on MDI child creation, deleting the button when the corresponding window is closed, respond to CTRL+TAB, CTRL+F4 messages and so on.

Answer:

I did something like this. In my mdi parent form, I have three public procedures:

procedure addwindow(Sender: TForm; const Str: string);
procedure delwindow(Sender: TObject);
procedure activatewindow(Sender: TObject);

In the child form's oncreate, ondestroy, onformactivate, I call the corresponding parent's method sending self as the parameter. I store sender in the toolbutton's tag property so I know which button corresponds to which child window.

The code looks like this (TXnewsFrame is the mdi parent form; Taskbar is my toolbar).

{ str is window's caption }

procedure TXnewsFrame.AddWindow(Sender: TForm; const Str: string);
begin
  with TToolButton.Create(TaskBar) do
  begin
    AutoSize := true;
    Left := TaskBar.Width;
    Parent := TaskBar;
    Style := tbsCheck;
    Grouped := true;
    AllowAllUp := false;
    OnClick := TaskClick;
    Caption := Str;
    Hint := Str;
    Tag := Integer(Sender); { store form in button's tag }
    Down := true;
  end;
  TaskBar.Update;
end;

procedure TXnewsFrame.DelWindow(Sender: TObject);
var
  i: integer;
begin
  with TaskBar do
    for i := ButtonCount - 1 downto 0 do
      if TForm(Buttons[i].Tag) = Sender then
      begin
        Buttons[i].Free;
        break;
      end;
end;

procedure TXnewsFrame.ActivateWindow(Sender: TObject);
var
  i: integer;
begin
  with TaskBar do
    for i := ButtonCount - 1 downto 0 do
      with Buttons[i] do
        if TForm(Tag) = Sender then
        begin
          Down := true;
          break;
        end;
end;

{ taskbar's onclick event handler }

procedure TXnewsFrame.TaskBarClick(Sender: TObject);
var
  F: TForm;
  i: integer;
begin
  if (sender is TToolButton) then
  begin
    F := TForm(TComponent(Sender).Tag);
    with F do
      if (F <> Self.ActiveMDIChild) or not Visible then
      begin
        BringToFront;
        if WindowState = wsMinimized then
          ShowWindow(Handle, SW_RESTORE);
      end;
  end;
end;

Nincsenek megjegyzések:

Megjegyzés küldése