プロパティのデフォルト値を変更したい

201 views
Skip to first unread message

中村

unread,
Jan 18, 2022, 2:52:55 AM1/18/22
to Japan RAD Studio User Group
こんにちは、中村と申します。
カスタムコンポーネントについてお聞きしたいことがあります。

TEditを継承したTMyEditというカスタムコンポーネントを作るとします。
それをフォームに配置するときに毎回ImeModeを「imClose」にしておきたいので、コンポーネントのconstructorでImeModeにセットしてみたところその通りの動作になったのですが、それを設計時に「imHira」にしても実行時に「imClose」になってしまい期待した動作になりません。

どのようにしたらよろしいでしょうか。

Kuze

unread,
Jan 19, 2022, 4:55:39 AM1/19/22
to radstu...@googlegroups.com
中村さん

久世です。

constructorではなく、
TEditを継承したTMyEditで、
property ImeMode: TImeMode read FImeMode write FImeMode default imClose;

と記載すれば良いのではないでしょうか?

中村

unread,
Jan 19, 2022, 11:04:51 PM1/19/22
to Japan RAD Studio User Group
こんにちは、久世さん。中村です。

>  property ImeMode: TImeMode read FImeMode write FImeMode default imClose;

FImeModeがprivateで参照できないため以下のように試してみましたが、
property ImeMode default imClose;
配置したときにimCloseになってくれません。
default値のオーバーライドはできないでしょうか。

2022年1月19日水曜日 18:55:39 UTC+9 Kuze:

Kuze

unread,
Jan 19, 2022, 11:55:21 PM1/19/22
to radstu...@googlegroups.com
中村さん

久世です。

  TMyEdit = class(TEdit)
  private
    FImeMode: TImeMode;
  published

    property ImeMode: TImeMode read FImeMode write FImeMode default imClose;
  end;

で、駄目でしょうか?
FImeModeを再定義します。


細川淳

unread,
Jan 20, 2022, 12:14:11 AM1/20/22
to Japan RAD Studio User Group
こんにちは。
細川です。

property につける default は、値が設定されるわけではありません。
「default 値はこの値にしているから、この値の場合は保存しなくていいよ」という表明にすぎません。
component stream のサイズを小さくする手段です。


2022年1月20日(木) 13:55 Kuze <ku...@hi-ho.ne.jp>:
> --
> このメールは Google グループのグループ「Japan RAD Studio User Group」に登録しているユーザーに送られています。
> このグループから退会し、グループからのメールの配信を停止するには radstudio-jp...@googlegroups.com にメールを送信してください。
> このディスカッションをウェブ上で閲覧するには https://groups.google.com/d/msgid/radstudio-jp/212d13cd-88d5-4a72-a505-3019f012cf7d%40email.android.com にアクセスしてください。

中村

unread,
Jan 20, 2022, 1:19:55 AM1/20/22
to Japan RAD Studio User Group
久世さん、細川さん、こんにちは。

> FImeModeを再定義します。
試してみました。親のTEditが、再定義したFImeModeを参照してくれないようで、ImeMode自体が動作しなくなりました。

> property につける default は、値が設定されるわけではありません。
なるほど。値が無いときは「imClose」というのは、どのようにセットするのが正解でしょうか。

2022年1月20日木曜日 14:14:11 UTC+9 j...@serialgames.co.jp:

細川淳

unread,
Jan 20, 2022, 2:41:43 AM1/20/22
to Japan RAD Studio User Group
中村さん

細川です。

現在の Delphi にはフレームワークが2つ、VCL と FireMonkey
が搭載されているので、どちらのフレームワークなのか、また、どの OS なのか、というのを書いておくと良いかも知れません。
今回は恐らく VCL だと仮定しました。

初期化は基本的には constructor で設定するのが正しいです。

今回、オブジェクトインスペクタで値を設定しても設定値に変わらなかった、というのはコレが関係あるかもしれません。
https://docwiki.embarcadero.com/Support/ja/Windows_7%E3%81%A7TEdit/TMemo%E3%81%AA%E3%81%A9%E3%81%AE%E3%82%B3%E3%83%B3%E3%83%88%E3%83%AD%E3%83%BC%E3%83%AB%E3%81%AEImeMode%E3%81%8C%E5%8B%95%E4%BD%9C%E3%81%97%E3%81%AA%E3%81%84

2022年1月20日(木) 15:19 中村 <nakafu...@gmail.com>:
> このディスカッションをウェブ上で閲覧するには https://groups.google.com/d/msgid/radstudio-jp/858cba0b-0125-4b6f-968e-7a8a74c173b5n%40googlegroups.com にアクセスしてください。

Kuze

unread,
Jan 20, 2022, 5:42:01 AM1/20/22
to radstu...@googlegroups.com
中村さん、細川さん

久世です。

こんな感じでしょうか?

unit MyEditUnit;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TMyEdit = class(TEdit)
  public
    constructor Create(AOwner: TComponent); override;
    function  GetImeMode(): TImeMode;
    procedure SetImeMode(V: TImeMode);
  published
    property ImeMode: TImeMode read GetImeMode write SetImeMode default imClose;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Test', [TMyEdit]);
end;

constructor TMyEdit.Create(AOwner: TComponent);
begin
  inherited;
  ImeMode := imClose;
end;

function  TMyEdit.GetImeMode(): TImeMode;
begin
  Result := TEdit(Self).ImeMode;
end;

procedure TMyEdit.SetImeMode(V: TImeMode);
begin
  TEdit(Self).ImeMode := V;
end;

end.
---------- 転送メッセージ ----------
From: 細川淳 <j...@serialgames.co.jp>
日付: 2022/01/20 16:41
件名: Re: [radstudio-jp:260] Re: プロパティのデフォルト値を変更したい
To: Japan RAD Studio User Group <radstu...@googlegroups.com>
Cc:

このメールは Google グループのグループ「Japan RAD Studio User Group」の登録者に送られています。
このグループから退会し、グループからのメールの配信を停止するには radstudio-jp...@googlegroups.com にメールを送信してください。
このディスカッションをウェブ上で閲覧するには、https://groups.google.com/d/msgid/radstudio-jp/CAEcB0P7ZD6DhzSa9iQ61yo6a-g_NQD7Yi25C8RAC8t-Qs90L7Q%40mail.gmail.com にアクセスしてください。


細川淳

unread,
Jan 20, 2022, 8:47:21 PM1/20/22
to Japan RAD Studio User Group
久世さん
細川です。

default 値を変えるだけだったら reader / writer を再宣言する必用はないです。
↓こんな感じで書けます。

type
TMyEdit = class(TEdit)
public
constructor Create(AOwner: TComponent); override;
published
property ImeMode default imClose;
end;

implementation

{ TMyEdit }

constructor TMyEdit.Create(AOwner: TComponent);
begin
inherited;
ImeMode := imClose;
end;

2022年1月20日(木) 19:42 Kuze <ku...@hi-ho.ne.jp>:
> このディスカッションをウェブ上で閲覧するには https://groups.google.com/d/msgid/radstudio-jp/f6627a6f-77ab-42a9-8f65-c19c89a63e0e%40email.android.com にアクセスしてください。

kuze

unread,
Jan 21, 2022, 1:31:50 AM1/21/22
to radstu...@googlegroups.com

細川さん

久世です。

ありがとうございます。

中村さん
お役に立てずすみません。

少し前の中村さんの投稿で

> FImeModeがprivateで参照できないため以下のように試してみましたが、
> property ImeMode default imClose;
> 配置したときにimCloseになってくれません。

というのは、コンストラクタ部分の記載を削除してしまったからなんですね。
最初の議論に戻るのですが、

> それを設計時に「imHira」にしても実行時に「imClose」になってしまい
> 期待した動作になりません。

の原因は、Delphiのバージョンと、Winのバージョンの組み合わせの可能性が高
いんですね。
実行時に「imHira」にならないのは間違いで、実行時にMyEdit1.ImeModeは
imHiraになっているが、動作が、imCloseになっているということなんですね。

中村

unread,
Jan 21, 2022, 2:36:40 AM1/21/22
to Japan RAD Studio User Group
久世さん、細川さん、こんにちは。
もっと単純な話かと思っていたのですが意外と奥が深いようで。

> 実行時に「imHira」にならないのは間違いで、実行時にMyEdit1.ImeModeは
> imHiraになっているが、動作が、imCloseになっているということなんですね。

constructorでimCloseにすると、フォーム設計時にセットした値が反映してくれないようで、
たぶんconstructorより前にフォームのプロパティが読まれていて、そのあとにconstructorで上書きされているような気がします。
もう少しウェブを探してみたところ、ズバリな回答を見つけました。

中村の里さん
自作コンポーネントの順序型と集合型のプロパティの初期化の仕方
#こちらにはずいぶん昔からお世話になっています。NkPrinter現役です!

2022年1月21日金曜日 15:31:50 UTC+9 kuze:

kuze

unread,
Jan 21, 2022, 3:39:27 AM1/21/22
to radstu...@googlegroups.com
中村さん

久世です。

解決したようでよかったです。

細川淳

unread,
Jan 21, 2022, 4:13:40 AM1/21/22
to Japan RAD Studio User Group
中村さん

細川です。
Component Stream からコンポーネントが復元される順序は、該当コンポーネントを生成→プロパティ値の読み込み、となります。
なので constructor で設定した値は上書きされます。

今回の場合は

type
TMyEdit = class(TEdit)
public
constructor Create(AOwner: TComponent);
published
property ImeMode default imClose;
end;

constructor TMyEdit.Create(AOwner: TComponent);
begin
inherited;
ImeMode := imClose;
end;

で上手くいきませんでしたか?
中村の里の中村さんの記事は、default 指定されている値を、RTTI を使って値を取得し、初期値とする、というものです。
default 値を把握できている場合は、RTTI を使う必要は無いと思います。

2022年1月21日(金) 16:36 中村 <nakafu...@gmail.com>:
> --
> このメールは Google グループのグループ「Japan RAD Studio User Group」に登録しているユーザーに送られています。
> このグループから退会し、グループからのメールの配信を停止するには radstudio-jp...@googlegroups.com にメールを送信してください。
> このディスカッションをウェブ上で閲覧するには https://groups.google.com/d/msgid/radstudio-jp/6c6177cf-1fa4-4fc2-b05f-256eee942101n%40googlegroups.com にアクセスしてください。

中村

unread,
Jan 23, 2022, 8:00:29 PM1/23/22
to Japan RAD Studio User Group
細川さん、こんにちは。

仰るとおり、defaultを再定義した上でconstructorでImeModeにセットすることで意図する動作になりました。
ありがとうございました。

2022年1月21日金曜日 18:13:40 UTC+9 j...@serialgames.co.jp:
Reply all
Reply to author
Forward
0 new messages