C++ Builder > TForm > タイトルバーのないウィンドウ(サイズ変更可能)の実装 > ボタン押下による表示、非表示

```txt:動作環境
C++ Builder XE4
```

### 概要

- [C++ Builder > TForm > タイトルバーのないウィンドウ(サイズ変更可能)の実装 > ソフト起動時](https://qiita.com/7of9/items/280e3c9a817ac6d97336)

- 以下の実装に変更する
    - ボタン押下時にタイトルバー非表示
    - ボタン押下時にタイトルバー表示

### 情報

- [Show/hide titlebar of a form](http://delphimagic.blogspot.com/2008/08/showhide-titlebar-of-form.html) @ Delphi Magic
- [Unityでデスクトップマスコットのためにタイトルバー非表示した](https://qiita.com/gatosyocora/items/b9bc12b4d56ac763e8c0) by @gatosyocora 様

情報感謝です。

### 実装

```Unit1.h
//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:	// IDE で管理されるコンポーネント
	TButton *B_hide;
	TButton *B_show;
	void __fastcall B_hideClick(TObject *Sender);
	void __fastcall B_showClick(TObject *Sender);
private:	// ユーザー宣言
public:		// ユーザー宣言
	__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
```

```Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
	this->Position = poScreenCenter; // 画面中央に表示
}
//---------------------------------------------------------------------------
void __fastcall TForm1::B_hideClick(TObject *Sender)
{
	DWORD astyle;

	astyle = GetWindowLong(this->Handle, GWL_STYLE);
	SetWindowLong(this->Handle, GWL_STYLE, astyle & ~WS_CAPTION);

	// SetWindowLongの変更適用
	SetWindowPos(this->Handle, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::B_showClick(TObject *Sender)
{
	DWORD astyle;

	// this->BorderStyle = bsSingle;

	astyle = GetWindowLong(this->Handle, GWL_STYLE);
	SetWindowLong(this->Handle, GWL_STYLE, astyle | WS_CAPTION);

	// SetWindowLongの変更適用
	SetWindowPos(this->Handle, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED);
}
//---------------------------------------------------------------------------
```

### 備考

SetWindowPos()をコールすることでSetWindowLong()の内容が適用されるというのは @gatosyocora さんの[記事](https://qiita.com/gatosyocora/items/b9bc12b4d56ac763e8c0)で知りました。

情報感謝です。

### SetWindowPos()

SetWindowPos()の各種パラメータについては以下に詳しい。

- [SetWindowPos](https://msdn.microsoft.com/ja-jp/library/cc411206.aspx) @ MSDN

### 動作例

タイトルバーないときー (B_hide押下後)

![2018-11-09_16h03_14.png](https://qiita-image-store.s3.amazonaws.com/0/32870/0880bf8c-e927-5233-c296-ca652a5ca1fb.png)


タイトルバーあるときー (B_show押下後)

![2018-11-09_16h03_08.png](https://qiita-image-store.s3.amazonaws.com/0/32870/ed77fafd-bf8c-ed02-a194-f3b0ae99ab50.png)


### 備考 > Windows 10: 表示位置のずれ

```
動作環境: Windows 10 Pro (64bit) バージョン 1803 (April 2018 Update)
```

- タイトルバー非表示からタイトルバー表示に戻った時、ウィンドウの位置が下にずれる
- 他のウィンドウをクリックすると、ずれていたウィンドウが元の位置に戻る

Windows 10の処理でおかしな部分があるのだろう。
(対処は検討が必要）

モニタの解像度によっても症状の有無が異なるようだ。

- FullHD: ずれは起きない
- 4K UHD: ずれが起きる

ずれの原因は下記に記載した。

- [Windows 10 > bug > geometry > ウィンドウのタイトルバー非表示、表示にてウィンドウの位置がずれる > Windows 10にて「テキスト、アプリ、その他の項目のサイズ」が100%でない時に発生する | 対処: Hide(), Show()する](https://qiita.com/7of9/items/0009ff02bb6da1e9dd9e)