|
16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル
"D4,D5:障害対応版 Splitter"
【概要】
Delphi4 / Delphi5 の Splitter は、サイズ変更対象のコントロールの幅や
高さがゼロになるとサイズ変更対象コントロールを認識しなくなります。
Delphi5 で少し改善されたと思いきや、フォームのサイズ変更を行うと
Control が再配置(Control の作成順にも関係して、うまくいったりうまくい
かなかったりと不安定)されて、やっぱりサイズ変更できなくなります。原因
はサイズゼロの対象コントロールがスプリッタの Align方向とは逆の方向に(
要するにスプリッタの背面に)移動してしまうからです。
【対策】
問題を回避するスプリッタコンポーネントを記載します。
やっていることは特に複雑ではなく、マウス押下されたタイミングで背面側に
いると認識したサイズゼロのコントロールをスプリッタの前に引きずり出して
いるだけです。他の意図していなかったコントロールが引きずり出されないよ
うに、サイズゼロチェックと、スプリッタの Align 方向と同じ配置であるこ
とも検出の条件に含まれているので安全です。
【使用方法】
Delphi4/5 のどちらでも動作します。BugFixSplitter.pas と名前を付けて、
ライブラリ検索パスの通ったところに配置し、適当なパッケージに追加して
インストールして下さい。
Samples のパレットページに登録されます。
【ソース】
----------------------------------------------------------------------
unit BugfixSplitter;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs,
ExtCtrls;
type
TBugfixSplitter = class(TSplitter)
private
{ Private 宣言 }
function FindControl2(out RightPositioning: Boolean): TControl;
protected
{ Protected 宣言 }
procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer); override;
public
{ Public 宣言 }
published
{ Published 宣言 }
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Samples', [TBugfixSplitter]);
end;
{ TBugfixSplitter }
procedure TBugfixSplitter.MouseDown(Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
RightPos: Boolean;
C: TControl;
begin
// サイズゼロの隣り合わせたコントロールは、
// Parentのサイズ変更によってスプリッタの後ろに移動してしまうので
// まずはここでそのコントロールをスプリッタの前に持ってくる
C := FindControl2(RightPos);
if (not RightPos) and (C <> nil) then
begin
case Align of
alLeft: Left := C.Left+C.Width+1;
alTop: Top := C.Top+C.Height+1;
alRight: Left := C.Left-Width-1;
alBottom: Top := C.Top-Height-1;
end;
end;
inherited;
end;
function TBugfixSplitter.FindControl2(out RightPositioning: Boolean):
TControl;
var
P: TPoint;
I: Integer;
R: TRect;
begin
Result := nil;
RightPositioning := False;
P := Point(Left, Top);
case Align of
alLeft: Dec(P.X);
alRight: Inc(P.X, Width);
alTop: Dec(P.Y);
alBottom: Inc(P.Y, Height);
else
Exit;
end;
RightPositioning := True;
for I := 0 to Parent.ControlCount - 1 do
begin
Result := Parent.Controls[I];
if Result.Visible and Result.Enabled then
begin
R := Result.BoundsRect;
if (R.Right - R.Left) = 0 then
if Align in [alTop, alLeft] then
Dec(R.Left)
else
Inc(R.Right);
if (R.Bottom - R.Top) = 0 then
if Align in [alTop, alLeft] then
Dec(R.Top)
else
Inc(R.Bottom);
if PtInRect(R, P) then Exit;
end;
end;
// では、スプリッタの反対側にいるか?
RightPositioning := False;
P := Point(Left, Top);
case Align of
alLeft: Inc(P.X, Width);
alTop: Inc(P.Y, Height);
end;
for I := 0 to Parent.ControlCount - 1 do
begin
Result := Parent.Controls[I];
if Result.Visible and Result.Enabled and
(Result.Align = Align) and (not (Result is TSplitter)) then
begin
R := Result.BoundsRect;
case Align of
alLeft, alRight:
if R.Right-R.Left > 0 then continue;
alTop, alBottom:
if R.Bottom-R.Top > 0 then continue;
end;
if (R.Right - R.Left) = 0 then
if Align in [alTop, alLeft] then
Inc(R.Right)
else
Dec(R.Left);
if (R.Bottom - R.Top) = 0 then
if Align in [alTop, alLeft] then
Inc(R.Bottom)
else
Dec(R.Top);
if PtInRect(R, P) then Exit;
end;
end;
Result := nil;
end;
----------------------------------------------------------------------
▲● 2000/10/24 18:15 JDX06162(とんちんかんちんかとちん)
■ Inprise Delphi ... The Great Development Kit
uses D2Desktop, D3CSS, D4CSS, D5ENT;
- FDELPHI MES(16):玉石混淆みんなで作るSample蔵【見本蓄積】 00/10/27 -
Original document by かとちん 氏 ID:(JDX06162)
ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。
Copyright 1996-2002 Delphi Users' Forum
|