お知らせ

電子会議

ライブラリ

パレット

Delphi FAQ検索

Delphi FAQ一覧

サンプル蔵





FDelphi FAQ
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