Entry No.
103
|
VCL - 一般 - コントロール - TWinControl
RecreateWnd は、ウィンドウハンドルを信頼する API ルーチンにとって危険である
|
1.02 |
2.01 |
3.0 |
3.01 |
3.02 |
4.0 |
4.01 |
4.02 |
4.03 |
5.0 |
5.01 |
6.0 |
6.01 |
6.02 |
Kylix 1.0 |
Gotcha |
Gotcha |
Gotcha |
Gotcha |
Gotcha |
Gotcha |
Gotcha |
Gotcha |
Gotcha |
Gotcha |
Gotcha |
Gotcha |
Gotcha |
Gotcha |
N/A |
|
|
解説
|
|
TWinControl から派生する全てのコンポーネントは、カレントウィンドウを破棄して再生成するメソッド RecreateWnd を持っています。これは特定の状況、例えば生成された後にウィンドウのスタイルが変更されたような場合に必要とされます。しかしながら、ある種の Windows の関数はウィンドウハンドルに依存しており、ウィンドウの再生成はそのような関数が正しく動作することを妨げます。例えば、関数 DragAcceptFiles はウィンドウハンドルを受け取り、ファイルマネージャからのファイルのドロップを受け取れるように、そのウィンドウを登録します。もしそのウィンドウが再生成されてしまうと、DragAcceptFiles に渡したハンドルは無効になってしまいます。
|
|
解決策 / 回避方法
|
これは、非常に大きな gotcha、というほどのバグではありません。私の考える最良の解決方法は、RecreateWnd メソッドをオーバーライドする新しい派生コンポーネントを作成し、inherited が呼ばれた後にウィンドウハンドルを再登録することです。この回避策の明らかな欠点は、問題が発生するかもしれない全てのコンポーネントに対してこれを行わなければならないことです。
もう1つの候補は、単純に、コンポーネントウィンドウの再生成が必要になるようなことは何もしないことです。ウィンドウを再生成しなければならない状況:
ボーダースタイル(BorderStyle)の変更
エディットコントロールのプロパティ CharCase または HideSelection または OEMConvert の変更
メモコントロールのプロパティ Alignment または ScrollBars の変更
リストボックスコントロールのプロパティ Sorted または Style の変更
リストボックスコントロールのプロパティ Alignment の変更
チェックボックスコントロールのプロパティ Ctl3D の変更
これを完全なリストだとは思わないでください。これは私が STDCTRLS.PAS から見つけたもののおよそ半分にすぎません。このことは、これらの状況を避けるよりも、RecreateWnd をオーバーライドする新しい派生コンポーネントを作るべきだということを、良く表していると思います。
|
|