設計時に TTimer を描画するのは誰ですか?
Delphi IDE のフォーム デザイナを使用している場合、TTimer をフォームにドロップすると、コンポーネントは設計時に表示されます(もちろん、実行時には表示されません)。
TTimer クラスはユニット ExtCtrls で定義されているので、もちろんそのユニットで TTimer のソース コードを読みました。
私は次のようなものを見ることを期待していました:
procedure TTimer.Paint;
begin
if csDesigning in ComponentState then
with Canvas do
begin
// Paint the design-time appearance of TTimer here:
// ... code ...
end else begin end; // no painting at runtime.
end;
しかし、そのようなコードがないことに驚きました!
TTimer コンポーネントにはこのプライベート フィールドがあります:FWindowHandle: HWND;
が、これは Windows 自体から WM_Timer メッセージを受信するためにのみ使用されます。設計時であっても、何も描画するために使用されることはありません。そしてキャンバスもありません。
TTimer のソース コードを読んでいるときに、デザイン タイムの描画に関連するものは見つかりませんでした。
問題は、Delphi IDE 自体のフォーム デザイナで、TTimer のデザイン時の外観をフォームに描画するコードと場所です。
さて、なぜ私がこの質問をするのか不思議に思っている人のために、それに関する情報を以下に示します。
StackOverflow の別の場所で、誰かが実行時に .dfm ファイルをロードできるかどうか尋ねました。誰かが答えた:「いいえ、それは不可能です」 .
しかし、それは正確には真実ではありません。これを正確に行うためのコードをいくつか書きました。ディスクから「someform.dfm」をロードし、実行時にそのようなフォームを作成します。それは可能ですが、厄介なのは、次のようなコードを記述する必要があることです。
procedure RegisterNecessaryClasses;
begin
RegisterClass(TfrmDynaForm);
RegisterClass(TPanel);
RegisterClass(TMemo);
RegisterClass(TTimer);
RegisterClass(TListBox);
RegisterClass(TSplitter);
RegisterClass(TEdit);
RegisterClass(TCheckBox);
RegisterClass(TButton);
RegisterClass(TLabel);
RegisterClass(TRadioGroup);
end;
これは、特定のフォームをエラーなしで読み込んで表示できる最初の例にすぎません。ただし、TSpeedbutton などの他のフォームが含まれているとすぐに、上記の手順を編集して次の行を追加する必要があります。
RegisterClass(TSpeedbutton);
それをスキップすると、「class Txxx not found」という例外が発生します。
もう 1 つの問題は、ロードする dfm 内の TTimer コンポーネントを見つけるためのコードを追加し、その TTimer インスタンスの ComponentState で csDesigning を手動で設定した後でも、TTimer が非表示のままになることです。
では、Delphi IDE のフォーム デザイナで表示されるのと同じ方法で TTimer を表示するには、(他に) 何をする必要がありますか?