2010-12-28 20 views
2

私はは、TPageControlコンポーネントの特定の領域に対してと「0nMouseLeave」「OnMouseEnter」をキャッチする必要があります。その特定の領域で私は全体の "タブヘッダー"の矩形を意味します。は、TPageControlのタブ領域

問題はページコントロールがメッセージ「空」スペース(私は内部制御メッセージCM_MOUSEENTERとCM_MOUSELEAVEをキャッチしています)をキャッチしていないこと、です。

screenshot

私のための目的は、ユーザーが赤いフレーム化領域に置いたときに右の空の側にある小さな矢印を描画(描画ケーキのちょうど一部である)、このエリアを離れると、それを消去することです。そして、私はタブのオーバーフロー(スクロールするダブルボタンを描く)を気にしません - それは決して起こりません。

コードの作業部分はですが、それは明確な解決策ではなく、私はそれを好きではありません。それを行うには別の(よりクリーンな)方法が必要です。

type 
    TPageControl = class(ComCtrls.TPageControl) 
    protected 
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE; 
    procedure WMNCHitTest(var Message: TWMNCHitTest); message WM_NCHITTEST; 
    end; 

procedure TPageControl.CMMouseLeave(var Message: TMessage); 
begin 
    inherited; 
    Canvas.TextOut(Width - 130, 5, 'CMMouseLeave'); // display result 
end; 

procedure TPageControl.WMNCHitTest(var Message: TWMNCHitTest); 
var TabHeaderRect: TRect; 
begin 
    if Message.Result = 0 then // if Message.Result = HTNOWHERE ... 
    begin 
     TabHeaderRect := ClientRect; 
     TabHeaderRect.Bottom := Top + 21; 

     if PtInRect(TabHeaderRect, ScreenToClient(Point(Message.XPos, Message.YPos))) then 
     Canvas.TextOut(Width - 130, 5, 'WMNCHitTest '); // display result 

     Message.Result := HTCLIENT; 
    end 
    else 
    inherited; 
end; 
+0

私はそれが確実に可能であることを知っています。パネルコントロールの下に適切な高さのパネルを配置し、ページコントロールのOnMouseEnterとOnMouseLeaveとパネルの同じイベントを共有しますが、これを真剣に1つのコンポーネントで囲む必要があります。 –

答えて

1

明らかに、空白はコントロールのクライアント領域に属していないため、コントロールはその領域のマウス関連のWindowsメッセージを取得しません。フォームのマウスイベントを使用する必要があります。または、ページコントロールをパネル内に配置し(alClientを使用)、パネルのマウスイベントを使用します。

これを複数回使用する必要がある場合は、必要な動作を実現するためにパネルとページコントロールを組み合わせて、正確に新しいコンポーネントを作成できます。

+0

どういうわけか可能です。多分WM_NCHITTESTか何かを使用しています。私がテストした限り、WindowFromPoint関数は空の領域であってもTPageControlハンドルを返します。そのため、この領域にページコントロール自体がキャッチしたメッセージがあることを願っています。空のスペースはページコントロールのクライアントエリアに属しますね。私はバックグラウンドメッセージを消去しているので透明だと思った。 –

+2

@daemon - いいえ、それがクライアントエリアだった場合、あなたはマウスの出入りメッセージを得るでしょう。ヒットテストがHTTRANSPARENTの場合はWM_NCHITTESTハンドラでHTCLIENTに変更し、VCLのleave/enterイベントが発生しているかどうかを確認してください。あなたのために+1 –

+0

+1。このWM_NCHITTESTメッセージは私を怒らせます。唯一の問題は、マウスを捕捉して解放する時期がわからないことです。上のコードでは、マウスをキャプチャしていないので動作します。私の視点からは、カーソルがページコントロールに入ったときにマウスを見る(キャプチャ)必要がありますが、空の部分にカーソルを置いたかどうかわかりません。だから私は決して言うことができない、はい、私の空きスペースの下にいる。それが私がこの答えを受け入れた理由です。 TPageControlを作成してパネル上に配置し、OnMouseEnterと0nMouseLeaveを割り当てます。あなたの時間はありがたい。 –

0

ページコントロール自体のOnMouseEnter/OnMouseLeaveを処理していて、それに含まれているTTabSheetインスタンスではないですか?

+0

ヨップ。私はCM_MOUSEENTERとCM_MOUSELEAVEをオーバーライドされたTPageControlクラスで処理しています。 –