[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;
皆様のご参考になれば幸いです。
以下のコメントは、その投稿者が所有するものでサイト管理者はコメントに関する責任を負いません。
大変参考にさせていただいています。
公開頂いているソースをほぼそのまま利用すると(開発Delphi2007、実行Windows7 or 8.1)
1.親フォームに TPanel を継承したボタンを使用すると、スペースキーで押せない場合がある。
2.フォームを最小化すると、タスクボタンが消える場合がある。
という問題がありました。(私の環境だけかもしれません)
以下の様にすると解消されましたので、コメントさせていただきます。
1.FormClose 中の TForm(Owner).Show を削除する。
この行が無くても、特に他の動作におかしいと思われるところがなく、スペースキーの問題が解消されました。
2.FormActivate 中の AddTaskBarBtn(Handle); の実行位置を、関数の最後に移動する。
関数の先頭で、AddTaskBarBtn を実行すると、フォームを最小化した時にタスクバーボタンが消えてしまうことがあるようです。
※以前(かなり前です)、1.の問題をコメントさせてもらいました。その時は、何もわかっていない状態でのコメントでしたが、最近になってやっと解決しました。
くろねこです。 コメントいただきありがとうございます。
最近まったくプログラムを作れておりません