<p>以前だと、フォームからフォームを表示しても、タスクバーにはアプリケーションのウィンドウのボタンが表示されていたため、何の変化もありませんでした。<br />
しかし、今はメインフォームのボタンが表示されます。<br />
これがどういうことかもう少しブレイクダウンします。</p>
<p>Form1 から Form2 を表示するアプリケーションを作ります。<br />
Form1 のボタンをクリックすると Form2 を表示することとします。<br />
このコードは下記のようになります。</p>
<pre class="brush: delphi">
procedure TForm1.Button1Click(Sender: TObject);
begin
  TForm2.Create(Self).Show;
end;</pre>
<p>このアプリケーションを実行すると、タスクバーにはメインフォームである Form1 のボタンが表示されます。<br />
Form2を表示しても同じです。</p>
<p>今度は、Form1 のボタンをクリックすると Form2 を表示し、Form1 はハイドすることとします。<br />
以下のようなコードになります。</p>
<pre class="brush: delphi">
procedure TForm1.Button1Click(Sender: TObject);
begin
  TForm2.Create(Self).Show;
  Hide;
end;</pre>
<p>このアプリケーションを実行して確認してみると、Form1 の表示時は先ほどと変わりないですが、Form2 を表示するとタスクバーから表示が消えてしまいます。メインフォームが消えてしまったからだと思われます。</p>
<p>これはちょっとまずいと思いました。くろねこ的には、現在アクティブなフォームのアイコンとキャプションを持ったタスクバーアイコンにしたいわけです。とりあえず、この内容を <strong>ActiveFormOnTaskBar</strong> と名づけます。Delphi で標準対応してほしいところですが、出来ないのでやり方を考えて見ます。</p>
<p>SetWindowLong と SetParent を使用します。</p>
<pre class="brush: delphi; title='タスクバーに現在のフォームのタスクバーボタンを表示する'">
procedure TForm2.ShowTaskbarButton;
begin
  Windows.SetWindowLong(Handle, GWL_EXSTYLE, 
    Windows.GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_APPWINDOW);
  Windows.SetParent(Handle, GetDesktopWindow);
end;
</pre>
<p>Form1を非表示にしない場合のタスクバーボタンのみ非表示にする関数</p>
<pre class="brush: delphi; title='現在のフォームのタスクバーボタンを非表示にする'">
procedure TForm1.HideTaskBarButton;
begin
  ShowWindow(Handle, SW_HIDE);
  SetWindowLong(Handle, GWL_EXSTYLE,
    GetWindowLong(Handle, GWL_EXSTYLE) and not WS_EX_APPWINDOW or WS_EX_TOOLWINDOW);
  ShowWindow(Handle, SW_SHOW);
end;
</pre>
<p>Form2を閉じたときにForm1のタスクバーボタンを元に戻す関数</p>
<pre class="brush: delphi; title='Form2を閉じたときにForm1のタスクバーボタンを元に戻す'">
// Form1側 ---
procedure TForm1.RestoreTaskBarButton;
begin
  Windows.SetWindowLong(Handle, GWL_EXSTYLE, FExStyle);
  Windows.SetParent(Handle, GetDesktopWindow);
end;
// FExStyle は、FormCreate で退避
procedure TForm1.FormCreate(Sender: TObject);
begin
  FExStyle := GetWindowLong(Handle, GWL_EXSTYLE);
end;

// Form2側 ---
procedure TForm2.FormDestroy(Sender: TObject);
begin
  if (Owner is TForm1) then
    with TForm1(Owner) do
    begin
      if not Visible then
        Show;
      RestoreTaskBarButton;
      Refresh;
    end;
end;
</pre>
<p>現在、だいたいいけるようになりましたが、Form2を表示している際のForm1のタイトルバーが変更されてしまっているのが気になります。外観の変更を伴わずに何とかならないですかね？</p>
<p>■参考：</p>
<ul>
    <li><a href="http://edn.embarcadero.com/article/33747">Delphiで、Windows Vista Readyアプリケーションを作る</a></li>
</ul>