c++ builder > 指定の位置にヒントを表示する > v0.1,v0.2 > 3つのコンポーネントに対して順番にヒント表示

```txt:動作確認
C++ Builder XE4
```

### 仕様と参考情報

指定の位置にヒントを表示したい。

- 参考?にしたサイト
  - http://forum.sources.ru/index.php?showtopic=67609
  - ロシア語分からない。Delphiで書かれているのでbuilderに置き換えが分からない
  - google翻訳したら暴言が。。。
     - 「しかし、このがらくたが、作品」
  - Спасибі, сер
- 参考にしたサイト
  - http://www.gesource.jp/programming/bcb/96.html
  - いつも助けられています
  - こちらはbuilderなので分かりやすい

2つ目のサイトをメインに使って、1つ目のサイトのClientOriginを使ってみた。

## code v0.1 > ヒント表示だけ

### code

```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)
{
	FHintWin = new THintWindow(this);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button4Click(TObject *Sender)
{
	TPoint cp = Button1->ClientOrigin;

	UnicodeString hint = "表示するヒント";

	TRect rect = Bounds(0, 0, 0, 0);
	DrawText(FHintWin->Canvas->Handle, hint.c_str(), -1, &rect, DT_CALCRECT | DT_LEFT);
	OffsetRect(rect, cp.x, cp.y);
	//ヒントウィンドウの微調整
	rect.Right += 6;
	rect.Bottom += 2;
	//ヒントウィンドウを表示する
	FHintWin->ActivateHint(rect, hint);

}
//---------------------------------------------------------------------------
```

### 結果

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/025ab136-2550-f95b-e4e8-1c38160d7423.png)

Button1の真上に表示されたので、少し「コレジャナイ」感が出たけれど、それほど悪くはない。
使えそう。

### TButton.Top, .Leftでは失敗

TButtonのプロパティLeft, Topを上記のcp.x, cp.yの代わりに使った。

結果として、まったく違う場所にヒントが表示された。

Спасибі, сер (Thank you very much).

## code v0.2 > 時間差で表示する

3つのコンポーネントに対するヒントを時間差で表示する。

- TTimer実装
- 途中でフォームクローズされた時の対応を実装
   - 最善の手ではない

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

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <Vcl.ExtCtrls.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:	// IDE で管理されるコンポーネント
	TButton *Button1;
	TButton *Button2;
	TButton *Button3;
	TButton *Button4;
	TTimer *Timer1;
	void __fastcall Timer1Timer(TObject *Sender);
	void __fastcall Button4Click(TObject *Sender);
	void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
private:	// ユーザー宣言
	THintWindow* FHintWin;
	void __fastcall showHint(TControl *ctrlPtr, String hintstr);
	void __fastcall hideHint(void);
	bool __fastcall delay(int msec);

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;
//---------------------------------------------------------------------------

static bool bfStop = false; // ヒント表示中の停止処理用 (フォームクローズのみ対応)

__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
	FHintWin = new THintWindow(this);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::showHint(TControl *ctrlPtr, String hintstr)
{
	if (ctrlPtr == NULL) {
        return; // error
	}
	TPoint cp = ctrlPtr->ClientOrigin;
	int width = ctrlPtr->ClientRect.Width();

	TRect rect = Bounds(0, 0, 0, 0);
	DrawText(FHintWin->Canvas->Handle, hintstr.c_str(), -1, &rect, DT_CALCRECT | DT_LEFT);
	OffsetRect(rect, (cp.x + width), cp.y);
	//ヒントウィンドウの微調整
	rect.Right += 6;
	rect.Bottom += 2;

	//ヒントウィンドウを表示する
	FHintWin->ActivateHint(rect, hintstr);
	Application->ProcessMessages();
}

void __fastcall TForm1::hideHint(void)
{
	FHintWin->ReleaseHandle();
}

bool __fastcall TForm1::delay(int msec)
{
	int num = msec / 300;

	for(int loop=0; loop < num; loop++) {
		if (bfStop) {
			return false;
		}
		Application->ProcessMessages();
		Sleep(300);
	}
	return true;
}

void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
	Timer1->Enabled = false;

	showHint(Button1, L"表示するヒント1");
	if (delay(3000) == false) {
		hideHint();
		return;
	}
	hideHint();

	showHint(Button2, L"表示するヒント2");
	if (delay(3000) == false) {
		hideHint();
		return;
	}
	hideHint();

	showHint(Button3, L"表示するヒント3");
	if (delay(3000) == false) {
		hideHint();
		return;
	}
	hideHint();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button4Click(TObject *Sender)
{
	Timer1->Interval = 500; // msec
	Timer1->Enabled = true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
	bfStop = true;
}
//---------------------------------------------------------------------------
```

### 結果

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/6b579e58-5f51-c741-3ba0-93f0a1537973.png)

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/06e0cc27-714f-0ea8-4daa-28fc26c991d3.png)

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/d894d8b7-7405-7f94-6cc0-da50625f03b2.png)


http://qiita.com/7of9/items/9b53aae6c7712517a59d
の実装に利用した。