Win7 + XE2 の環境で Tedit + TSpeedButton を組み合わせた
コンポーネントを作っています。
どうしてもわからないのでどなたか教えてください。
現在の問題点、
作成したコンポーネントを設計時、マウスドラッグでPanelの上に
配置しても parent プロパティを正しく設定することができません。
配置時の Owner を確認すると Panel と Form どちらにドラッグし
ても Owner は Form になっています。
どうしたら Panel にドラッグしたことを感知することができますか。
>どうしたら Panel にドラッグしたことを感知することができますか。
設計時にですよね.
これは,かなり難しいと思います.
個人的には,素直に,切り取り,貼り付けがいいと思いますが.
ヒントだけを.
設計時にマウスイベントを受け取るには,DesignWndProc か CM_DESIGNHITTEST を実装します.
(Delphi XE2 なら使用可能です)
もちろん,コンポーネントにです.
以下のようなコンポーネントを作成して,フォームに配置すると,
すぐに赤い色になります.なぜなら,通常はマウスクリックでコンポを配置しますから,
当然マウスイベントが発生します (これは設計時の動作ですから,実行時は元に戻ります)
コンポーネントエディタ側でコーディングするのか,Parent プロパティのオーバライド
が必要なのか.やったことがないので,確実なことが言えません.申し訳ないです.
unit plMyPanel;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls;
type
TplMyPanel = class(TCustomPanel)
private
{ Private 宣言 }
protected
{ Protected 宣言 }
procedure CMDesignHitTest(var Message: TCMDesignHitTest);
message CM_DESIGNHITTEST;
public
{ Public 宣言 }
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('plXRAY', [TplMyPanel]);
end;
{ TplMyPanel }
procedure TplMyPanel.CMDesignHitTest(var Message: TCMDesignHitTest);
begin
inherited;
Self.ParentBackground := False;
Self.Color := clRed;
end;
end.
>作成したコンポーネントを設計時、マウスドラッグでPanelの上に
>配置しても parent プロパティを正しく設定することができません。
そもそも設計時に貼り付けるコンポーネントの parent は
自分で設定しないだろ?
フォーム上に配置してあるコンポーネントを
パネルの移動した場合にparentをフォームからパネルに
変更したいと言ってる?
>Win7 + XE2 の環境で Tedit + TSpeedButton を組み合わせた
Tedit か TSpeedButton どっちかが親で
もう片方を作るときのParentの設定が出来ないといってるのか・・・
Createした時点でParent はわからないからね
親Parent を設定された時に 個Parentを設定すればいい
XE2 なら
TLabeledEdit を見ればわかるだろ
> Mr.XRAY
CMDesignHitTest が何かよくわかりませんが書き込んでいただいた
内容で修正して実行してみました。
ドロップした時点ではこのメッセージは呼び出されないようです。
貼り付けた後にマウスカーソルをコンポーネントの上を通過時に
色が変わりました。
貼り付けた後にマウスカーソルをコンポーネント通過させる
という作業をすれば設定できそうですね。
>KHE00221 さんこんにちは
>そもそも設計時に貼り付けるコンポーネントの parent は
>自分で設定しないだろ?
通常のコンポーネントならおっしゃるとおりですだと思います。
今回のコンポは Tedit + TSpeedButton + ListView の合体で
TEdit 右のSppdButton をクリックすると ListView を表示させています。
>フォーム上に配置してあるコンポーネントを
>パネルの移動した場合にparentをフォームからパネルに
>変更したいと言ってる?
>Createした時点でParent はわからないからね
そうなんですね。それでこまっています。Left Top は RequestAlign
メソッドで取り出せたんですが、
>親Parent を設定された時に 個Parentを設定すればいい
親の SetParent で子供の Parent を設定するようにコーディング
してみましたが
そもそも親の Parent が未設定の状態で Create メソッドを
抜けると Parent が Null と怒られ、適当に Form なんかセット
しておくと Create を抜けた後も SetParent は呼ばれない
みたいで困ってしまいました。
次はCreate時点のマウス位置から下のコンポーネントを判断して
みたいと考えている最中です。
>TLabeledEdit を見ればわかるだろ
最初にソースを見てみましたが私の能力を超えていました。
>次はCreate時点のマウス位置から下のコンポーネントを判断して
>みたいと考えている最中です。
設計時のマウスイベントは,IDE が管理しています.
したがって,マウスのイベント,メッセージはとらえることはできません.
設計時にこれらの機能を使用するには,先に述べた CM_DESIGNHITTEST で
Result に 0 以外の値を返します.
ただし,そうすると,全てのマウス関係のメッセージを自前で処理しなければなりません.
自分自身が使うコンポーネントであれば,切り取り,貼り付けでいいのではないと思うのですが,
どうなんでしょう ?
実行時に Parent を変更するのであれば,比較的簡単ですけどね.
unit plMyPanel;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls;
type
TplMyPanel = class(TPanel)
private
{ Private 宣言 }
protected
{ Protected 宣言 }
procedure CMDesignHitTest(var Message: TCMDesignHitTest);
message CM_DESIGNHITTEST;
public
{ Public 宣言 }
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('plXRAY', [TplMyPanel]);
end;
{ TplMyPanel }
//-----------------------------------------------------------------------------------
// Resultに0以外の値を返すと,設計時にマウスメッセージの処理が可能
// ただし,IDE のメッセージは処理できなくなる
// つまり,設計時にマウスでのコントロールの移動もサイズ変更もできなくなる
//-----------------------------------------------------------------------------------
procedure TplMyPanel.CMDesignHitTest(var Message: TCMDesignHitTest);
begin
inherited;
Message.Result := 1;
end;
end.
>Result に 0 以外の値を返します.
>ただし,そうすると,全てのマウス関係のメッセージを自前で処理しなければなりません.
例外があります.以下の記事で確認してください.
[Vcl.Controls.TCMDesignHitTest]
http://docwiki.embarcadero.com/Libraries/XE3/ja/Vcl.Controls.TCMDesignHitTest
MK_LBUTTON マウスの左ボタンが押された。
等であれば,以下のように,CMDesignHitTest メッセージ内で処理可能です.
procedure TplMyPanel.CMDesignHitTest(var Message: TCMDesignHitTest);
begin
inherited;
if Parent = nil then exit;
if Message.Keys = MK_LBUTTON then begin
Self.ParentBackground := False;
Self.Color := clRed;
end;
end;
>ただし,そうすると,全てのマウス関係のメッセージを自前で処理しなければなりません.
スミマセン.情報が断片的で申し訳ないのですが.
このメッセージの処理は,WM_LBUTTONDOWN とかでなく,コンポーネント内部で
使用する MouseUp とか MouseDown メソッドを override して使います.例えば,以下のように
procedure TplMyPanel.MouseUp(Button: TMouseButton; Shift: TShiftState; X,
Y: Integer);
var
AForm : TForm;
begin
inherited;
if csDesigning in ComponentState then begin
AForm := TForm(GetParentForm(Self, False));
Self.ParentBackground := False;
Self.Color := clRed;
Self.Caption := AForm.Name;
end;
end;
の書き込みを参考にして AfterConstruction イベントを捕まえて
無理矢理 parent をセットしました。
簡単なテストでは問題はでていませんが、又何かでてきるかもしれません。
みなさんありがとうございました。
↓はコンポーネントから関係する部分だけを抜き出したものです。
//------------------------------------------
// TKELV AfterConstruction イベント
// ここで Parent プロパティをセット
//------------------------------------------
procedure TKELV.AfterConstruction;
var
WrkTPoint : TPoint; // マウス座標の下にあるコンポーネント取り出し
WrkTControl : TControl;
WrkTWincontrol : TWincontrol;
begin
inherited;
{
if Assigned( FDebugMemo ) = True then
FDebugMemo.Lines.Add( IntToStr( FDebugMemo.Lines.Count ) + 'AfterConstruction' );
Self.ParentBackground := False;
Self.Color := clBlue;
}
//----------------//
if ( csDesigning in Self.ComponentState ) = True then // 設計時はname プロパティの値はこのメソッドの後でセットされる。
begin
GetCursorPos( WrkTPoint ); // マウス座標の下にあるコンポーネント取り出し
WrkTControl := FindDragTarget( WrkTPoint, True );
if Assigned( WrkTControl ) = False then exit;
if ( WrkTControl is TWinControl ) = False then exit;
WrkTWincontrol := TWincontrol( WrkTControl );
if WrkTWincontrol <> Self.Parent then
Self.Parent := WrkTWincontrol;
end;
if Assigned( FDebugMemo ) = True then
FDebugMemo.Lines.Add( IntToStr( FDebugMemo.Lines.Count ) + 'AfterConstruction PA=' + Self.Parent.Name );
end;
ありゃ.
>の書き込みを参考にして AfterConstruction イベントを捕まえて
>無理矢理 parent をセットしました。
これって,設計時に,コンポーネントを貼り付ける時に,Parent を設定,
ということですか ?
勘違いしていました.
「設計時に,コンポーネントをドラッグして,Parentを設定できるコンポ」
という仕様だと勝手に解釈してしまいました.
何か意味のないレスになってしまい.スミマセンでした.
>今回のコンポは Tedit + TSpeedButton + ListView の合体で
普通こーゆうの作るときは 親を Panel にして
その上に TEdit TSpeedButton TListview 乗せるんだけどね・・・
いろいろ書いてしまい,掲示板をご覧の方々を混乱させてしまいました.
今回の snail さんの場合は特別な場合だと思いますが,普通は,以下のようにして
コントロール (コンポーネント) の親,つまり,Parent を変更できます.
[設計時に,コンポーネントの親 ( Parent) を変更する]
http://ht-deko.minim.ne.jp/delphiforum/?vasthtmlaction=viewtopic&t=1071.0
ツイート | ![]() |