C++ Builder 10.2 Tokyo > FormShow後に一回だけ実行する > FormActivate()処理

```txt:動作環境
RAD Studio 10.2 Tokyo Update 3
秀丸エディタ Version 8.79
```

### 関連

- [C++ Builder 10.2 Tokyo > Forms > Height > Windows 10: 実行タイミングによって異なる | Windows 7, 8.1: 実行タイミングによらず同じ > FormShow時とFormShow後](https://qiita.com/7of9/items/fcd4e85d87857e513393)

Windows 10ではFormShow時にフォームのサイズを取得しようとすると希望の値を得られない。

FormShow後の処理をするにはどうするか。
いくつか方法があるだろう。

### FormActivate()処理

FormActivateでの処理としてみる。

- http://docwiki.embarcadero.com/Libraries/Tokyo/ja/Vcl.AppEvnts.TApplicationEvents.OnActivate
- [イベントの発生順序をみてみよう](http://kakinotane.s7.xrea.com/delphi/d2/s029.html) @ Seventh Delphi
    - 情報感謝です

```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 *Button1;
    void __fastcall Button1Click(TObject *Sender);
    void __fastcall FormShow(TObject *Sender);
    void __fastcall FormActivate(TObject *Sender);
private:	// ユーザー宣言
    void __fastcall getVisibleWindowSize(TForm *formPtr, TRect *rectPtr);
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)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::getVisibleWindowSize(TForm *formPtr, TRect *rectPtr)
{
    TRect arect_inv;
    RECT arect_nrm;

    if (formPtr == NULL || rectPtr == NULL) {
        return; // error
    }

    GetWindowRect(formPtr->Handle, &arect_nrm); // (1)
    DwmGetWindowAttribute(formPtr->Handle, DWMWA_EXTENDED_FRAME_BOUNDS, &arect_inv, sizeof(TRect)); // (2)

    // for Windows 7
    if (arect_inv.left == 0 && arect_inv.top == 0 && arect_inv.Bottom == 0 && arect_inv.right == 0) {
        // DwmGetWindowAttribute()が0を返すためGetWindowRect()の結果を使う
        rectPtr->left = arect_nrm.left;
        rectPtr->top = arect_nrm.top;
        rectPtr->right = arect_nrm.right;
        rectPtr->bottom = arect_nrm.bottom;
        return;
    }

    // for Windows 8.1, Windows 10
    //   Windows 8.1では(1)と(2)は同じ定義
    //   Windows 10ではinvisible borderにより(1)と(2)の結果が異なる
    //   invisible borderのサイズを含まない(2)の方を返す
    //
    // !!!ただしWindows 10の場合、FormShow時には正しい値を返さない!!!
    // FormShow後に実行すること
    rectPtr->left = arect_inv.left;
    rectPtr->top = arect_inv.top;
    rectPtr->right = arect_inv.right;
    rectPtr->bottom = arect_inv.bottom;
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    TRect arect;

    getVisibleWindowSize(this, &arect);

    int parhei = arect.Bottom - arect.top;
    String msg = IntToStr(parhei) + L" on Button1Click()";
    ShowMessage(msg);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormShow(TObject *Sender)
{
//    TRect arect;
//
//    getVisibleWindowSize(this, &arect);
//
//    int parhei = arect.Bottom - arect.top;
//    String msg = IntToStr(parhei) + L" on FormShow()";
//    ShowMessage(msg);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormActivate(TObject *Sender)
{
    static bool firstDraw = true; // FormShow後に一回だけ実行する

    if (firstDraw) {
        firstDraw = false;

        // ウィンドウHeightの取得
        TRect arect;

        getVisibleWindowSize(this, &arect);

        int parhei = arect.Bottom - arect.top;
        String msg = IntToStr(parhei) + L" on FormActivate()";
        ShowMessage(msg);
    }
}
//---------------------------------------------------------------------------
```

### 結果

- Windows 10
    - 336 on FormActivate()
    - 336 on Button1Click()

同じ値が得られた。