[Delphi] MainFormOnTaskBarとタスクバーボタン2

[Delphi] MainFormOnTaskBarとタスクバーボタンで完成できていなかったActiveFormOnTaskBarの動きがようやく完成です。
サポートの方にもご協力いただいて...実現しました。

ウィンドウスタイルを変更すると概観にも変化が起きてしまうので、今度はタスクバーそのものを直接いじってます。
このため、今回はComObjectを利用することになりました。
よって、uses にComObj, ShlObjを追加しておいてください。

タスクバーにタスクバーボタンを追加する関数と削除する関数です。

procedure AddTaskBarBtn(hnd: THandle);
var
  TaskbarList: ITaskbarList;
begin
  TaskbarList := CreateComObject(CLSID_TaskbarList) as ITaskbarList;
  TaskbarList.HrInit;
  TaskbarList.AddTab(hnd);
  TaskbarList.ActivateTab(hnd);
end;

procedure DelTaskBarBtn(hnd: THandle);
var
  TaskbarList: ITaskbarList;
begin
  TaskbarList := CreateComObject(CLSID_TaskbarList) as ITaskbarList;
  TaskbarList.HrInit;
  TaskbarList.DeleteTab(hnd);
end;

これを実際のプログラムに組み込んで行きます。
子フォームを生成する側/生成される側両方に組み込む必要があること、その両方の立場になるフォームが出来ることが予想されますから、テンプレートのフォームを作って組み込んでおき、そこから派生して行くのがいいかと思います。
組み込むイベントは、OnActivate/Deactivate/FormCloseの3ヶ所です

procedure TForm1.FormActivate(Sender: TObject);
var
  i: integer;
begin
  AddTaskBarBtn(Handle);

  if (fsModal in FormState) then
    for i := 1 to Screen.FormCount - 1 do
      DelTaskBarBtn(Screen.Forms[i].Handle);
end;

procedure TForm1.FormDeactivate(Sender: TObject);
begin
  DelTaskBarBtn(Handle);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  // ダイアログ(モード付き)の場合には、
  // ...CALL元でダイアログ情報を参照する可能性があるので破棄しない
  if not(fsModal in FormState) then
    Action := caFree;
  if (not Application.Terminated) and (Owner <> nil) and (Owner is TForm) then
  begin
    TForm(Owner).Show;
    if (fsModal in FormState) then
      AddTaskBarBtn(TForm(Owner).Handle);
  end;
end;

テストは、Showのみ、ShowModalのみ、ShowとHide、ShowModalとHideの4種類で確認しました。

procedure TForm1.btnShowClick(Sender: TObject);
begin
  with TForm1.Create(Self) do
  begin
    Show;
  end;
end;

procedure TForm1.btnShowHideClick(Sender: TObject);
begin
  with TForm1.Create(Self) do
  begin
    Self.Hide;
    Show;
  end;
end;

procedure TForm1.btnShowModalClick(Sender: TObject);
begin
  with TForm1.Create(Self) do
  begin
    ShowModal;
    Release;
  end;
end;

procedure TForm1.btnShowModalHideClick(Sender: TObject);
begin
  with TForm1.Create(Self) do
  begin
    Self.Hide;
    ShowModal;
    Release;
  end;
end;

なお、実際のテストは複数フォームを作成するのがめんどくさいので1つのフォームでまとめてやりました。
なので、何個目のフォームか簡単に識別するためにOnCreateでキャプションの変更をしています。

procedure TForm1.FormCreate(Sender: TObject);
begin
  Caption := Format('Form%d', [Screen.FormCount]);
end;

皆様のご参考になれば幸いです。

コメント (2件)


くろねこ研究所
https://www.blackcat.xyz/article.php/ProgramingFAQ_del0082