[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;
皆様のご参考になれば幸いです。