C++ Builder XE4 > TeeChart > geometry > カスタムChartRectの使用例 + 図:ChartRectの領域 > はまりポイント: Appliction->ProcessMessage()の有無でChartRect.Topの値が変わる

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

### 概要

- ChartRectによるグラフ描画領域の変更
- ChartRectの定義が公式サイトなどでもはっきりしないため調べた


### ChartRect

- Top, Bottom, Left, Rightなどのプロパティを持つ
- 下記の手順でカスタムChartRectを設定可能
    - `Chart1->CustomChartRect = true;`
    - `Chart1->ChartRect = Rect(0, 100, 500, 300);`

### はまりポイント

上記記載の「カスタムChartRect」を実行しても、**グラフ描画領域がすぐに更新されるわけではない。**

グラフ描画領域の更新のためのイベントが必要になるようだ。

`Chart1->Update();`は試したが、描画が更新されなかった。

下記の実装例では、フォントサイズを変更し、戻す、という処理により描画を更新している。

## 実装 v0.1A > Appliction->ProcessMessage()がないとき

ボタンによりChartRectを変更する例。

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

#include <vcl.h>
#pragma hdrstop

#include <DateUtils.hpp>
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
	// グラフ描画用にダミーのデータを追加する
	//
	Chart1->Series[0]->XValues->DateTime = true;
	Chart1->BottomAxis->DateTimeFormat = L"nn:ss";
	//
	TDateTime dt;
	//
	dt = Now();
	//
	double yval;
	for (int idx=0; idx < 10; idx++) {
		yval = (1+ idx) % 2;
		Series1->AddXY(dt, yval, "", clRed);
		dt = IncSecond(dt, 1);
	}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
	// グラフ描画領域を上に

	Chart1->CustomChartRect = true;
	Chart1->ChartRect = Rect(0, 100, 500, 300);

	updateGraphView(Chart1);
	//
	Shape1->Top = Chart1->ChartRect.Top; // + Chart1->Title->Font->Height + 5;

}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
	// グラフ描画領域を中段に

	Chart1->CustomChartRect = true;
	Chart1->ChartRect = Rect(0, 0, 500, 300);

	updateGraphView(Chart1);
	//
	Shape1->Top = Chart1->ChartRect.Top; // + Chart1->Title->Font->Height + 5;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::updateGraphView(TChart *chrPtr)
{
	if (chrPtr == NULL) {
		return;
	}

	// グラフ描画の更新を促すため
	int pre = chrPtr->Title->Font->Size;
	chrPtr->Title->Font->Size = pre + 1;
	chrPtr->Title->Font->Size = pre;

	//
//	Application->ProcessMessages();
//	Sleep(100); // msec
}
```

### 実行例

Button3押下時 => ChartRect.Topを上に
![2019-02-19_09h53_05.png](https://qiita-image-store.s3.amazonaws.com/0/32870/89a3d59c-004d-c353-3690-fe9d77569fe6.png)

Button2押下時 => ChartRect.Topを中断に
![2019-02-19_09h53_12b.png](https://qiita-image-store.s3.amazonaws.com/0/32870/f9366d7f-dad9-dcb1-3a4b-fa078cb9b67e.png)


### 図:ChartRectの領域 (Application->ProcessMessage()がないとき)

ChartRectの領域を図示しておく。

Shape1のTop, LeftをChartRectのTop, Left, Bottom, Rightにあわせて確認をした。


![2019-02-19_14h48_41.png](https://qiita-image-store.s3.amazonaws.com/0/32870/0fb907f4-7da6-c4d5-7565-ae1658e5db32.png)


**Topというのは「タイトル文字列の上部」である。「グラフ描画領域の上部」ではない。**


### はまりポイント2 > Appliction->ProcessMessage()の有無でChartRect.Topの定義がｋと異なる

上記の実装をした後に気づいたのは、updateGraphView()の処理において下記があるかないかで動作が変わるということ。

```cpp
	Application->ProcessMessages();
	Sleep(100); // msec
```

## 実装 v0.1B > Appliction->ProcessMessage()があるとき

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

#include <vcl.h>
#pragma hdrstop

#include <DateUtils.hpp>
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
	// グラフ描画用にダミーのデータを追加する
	//
	Chart1->Series[0]->XValues->DateTime = true;
	Chart1->BottomAxis->DateTimeFormat = L"nn:ss";
	//
	TDateTime dt;
	//
	dt = Now();
	//
	double yval;
	for (int idx=0; idx < 10; idx++) {
		yval = (1+ idx) % 2;
		Series1->AddXY(dt, yval, "", clRed);
		dt = IncSecond(dt, 1);
	}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
	// グラフ描画領域を上に

	Chart1->CustomChartRect = true;
	Chart1->ChartRect = Rect(0, 100, 500, 300);

	updateGraphView(Chart1);
	//
	Shape1->Top = Chart1->ChartRect.Top; // + Chart1->Title->Font->Height + 5;

}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
	// グラフ描画領域を中段に

	Chart1->CustomChartRect = true;
	Chart1->ChartRect = Rect(0, 0, 500, 300);

	updateGraphView(Chart1);
	//
	Shape1->Top = Chart1->ChartRect.Top; // + Chart1->Title->Font->Height + 5;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::updateGraphView(TChart *chrPtr)
{
	if (chrPtr == NULL) {
		return;
	}

	// グラフ描画の更新を促すため
	int pre = chrPtr->Title->Font->Size;
	chrPtr->Title->Font->Size = pre + 1;
	chrPtr->Title->Font->Size = pre;

	//
	Application->ProcessMessages();
	Sleep(100); // msec
}
```

### 動作例

Button3押下後
![2019-02-19_13h07_50.png](https://qiita-image-store.s3.amazonaws.com/0/32870/92da4a6e-9d1f-5833-3151-4a6556afbe45.png)

Button2押下後
![2019-02-19_13h07_54.png](https://qiita-image-store.s3.amazonaws.com/0/32870/3480d0f8-356b-5e71-2351-6015bd5d3503.png)

### 図:ChartRectの領域 (Application->ProcessMessage()があるとき)

再度、ChartRectの領域を図示しておく。

Shape1のTop, LeftをChartRectのTop, Left, Bottom, Rightにあわせて確認をした。

![2019-02-19_14h51_54.png](https://qiita-image-store.s3.amazonaws.com/0/32870/a2fc206d-086d-b552-258c-7f11ae366159.png)

グラフの描画領域と一致した。

### まとめ

`Appliction->ProcessMessage()`を行うかどうかでChartRectの取得数値が変わる。