記事カテゴリ

ユーザー機能


 2024年4月26日(金) 05:22 JST

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

  • 投稿者:
  • 表示回数
    5,419

[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;

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

トラックバック

このエントリのトラックバックURL:
https://www.blackcat.xyz/trackback.php/ProgramingFAQ_del0082

以下のコメントは、その投稿者が所有するものでサイト管理者はコメントに関する責任を負いません。

  • [Delphi] MainFormOnTaskBarとタスクバーボタン2の問題&解決法
  • 投稿者:ゲストユーザー on 2015年7月13日(月) 17:13 JST
こんにちは。
大変参考にさせていただいています。
公開頂いているソースをほぼそのまま利用すると(開発Delphi2007、実行Windows7 or 8.1)
1.親フォームに TPanel を継承したボタンを使用すると、スペースキーで押せない場合がある。
2.フォームを最小化すると、タスクボタンが消える場合がある。

という問題がありました。(私の環境だけかもしれません)
以下の様にすると解消されましたので、コメントさせていただきます。

1.FormClose 中の TForm(Owner).Show を削除する。
この行が無くても、特に他の動作におかしいと思われるところがなく、スペースキーの問題が解消されました。
2.FormActivate 中の AddTaskBarBtn(Handle); の実行位置を、関数の最後に移動する。
関数の先頭で、AddTaskBarBtn を実行すると、フォームを最小化した時にタスクバーボタンが消えてしまうことがあるようです。

※以前(かなり前です)、1.の問題をコメントさせてもらいました。その時は、何もわかっていない状態でのコメントでしたが、最近になってやっと解決しました。
  • [Delphi] MainFormOnTaskBarとタスクバーボタン2の問題&解決法
  • 投稿者:くろねこ on 2015年7月14日(火) 07:45 JST

くろねこです。 コメントいただきありがとうございます。

最近まったくプログラムを作れておりません