マウス動作を追跡するためのフィールドのフォームへの追加
ラバー バンドの例 への移動
マウス ボタンが押されたかを追跡するには、フォーム オブジェクトに、オブジェクト フィールドを追加する必要があります。 コンポーネントをフォームに追加すると、Delphi は、そのコンポーネントを表すフィールドをフォーム オブジェクトに追加することで、そのフィールドの名前を使用して、そのコンポーネントを参照できるようにします。 また、フォーム ユニットの ヘッダー ファイルで型宣言を編集することで、独自にフィールドをフォームに追加することもできます。
以下の例では、フォームは、ユーザーがマウス ボタンを押したかどうかを追跡する必要があります。 これを行うには、Boolean フィールドを追加し、ユーザーがマウス ボタンを押した際に、その値を設定します。
オブジェクトにフィールドを追加するには、オブジェクトの型宣言を編集します。具体的には、宣言の一番下で public 指令の後ろに、フィールド識別子と型を指定します。
Delphi/C++Builder は、public 指令より前の宣言をいずれも「所有」しており、 コントロールを表すフィールドや、イベントに応答するメソッドは、この部分に生成していきます。
次のコードでは、フォーム オブジェクトの宣言部分で、フォームに、Drawing という bool
型のフィールドを追加しています。 また、点を保存するための 2 つのフィールド、Origin と MovePt も TPoint 型で追加しています。
class TForm1 : public TForm {
__published: // IDE-managed Components
void __fastcall FormMouseDown(TObject *Sender, TMouseButton Button,
TShiftState Shift, int X, int Y);
void __fastcall FormMouseMove(TObject *Sender, TShiftState Shift,
int X, int Y);
void __fastcall FormMouseUp(TObject *Sender, TMouseButton Button,
TShiftState Shift, int X, int Y);
private: // User declarations
public: // User declarations
__fastcall TForm1(TComponent* Owner);
bool Drawing; // field to track whether button was pressed
TPoint Origin, MovePt; // fields to store points
};
描画するかどうか追跡するための Drawing フィールドの準備ができたら、それに対して、ユーザーがマウス ボタンを押した場合には True、ユーザーが離した場合には False を設定します:
void __fastcall TForm1::FormMouseDown(TObject *Sender, TMouseButton Button,
TShiftState Shift, int X, int Y) {
Drawing = true; // set the Drawing flag
Canvas->MoveTo(X, Y); // set pen position
}
void __fastcall TForm1::FormMouseUp(TObject *Sender, TMouseButton Button,
TShiftState Shift, int X, int Y) {
Canvas->LineTo(X, Y); // draw line from PenPos to (X, Y)
Drawing = false; // clear the Drawing flag
}
次に、OnMouseMove イベント ハンドラを編集して、Drawing が true の場合にのみ描画するようにできます:
void __fastcall TForm1::FormMouseMove(TObject *Sender, TMouseButton Button,
TShiftState Shift, int X, int Y) {
if (Drawing)
Canvas->LineTo(X, Y); // only draw if mouse is down }
この結果、マウス ボタンの押下、解放イベントの間のみ描画しますが、それでも、直線の代わりにマウスの移動を追跡した軌跡の線は残ります。
問題は、マウスを動かすたびに、マウス移動イベント ハンドラは LineTo を呼び出し、これがペンの位置を移動させ、ボタンを離した時点では、直線を開始したはずの点を失っていることです。