Q&A

  • 이미지 스크롤은 어떻게 하나요?


폼에 이미지 컴포넌트를 넣고

이미지를 불러 들였습니다만,



화면크기보다 이미지가 더 크기 때문에

아래 부분은 보이지 않습니다.



원본을 축소시키지 않고 보고싶기 때문에

스크롤을 사용하여 아래,좌우로 이동하여

보고 싶은데...



기본적으로 지원되는 컴포넌트를 이용하여

그림 스크롤을 만들수있는지요???

1  COMMENTS
  • Profile
    전철호 1999.06.07 20:06
    chobo 께서 말씀하시기를...

    >

    > 폼에 이미지 컴포넌트를 넣고

    > 이미지를 불러 들였습니다만,

    >

    > 화면크기보다 이미지가 더 크기 때문에

    > 아래 부분은 보이지 않습니다.

    >

    > 원본을 축소시키지 않고 보고싶기 때문에

    > 스크롤을 사용하여 아래,좌우로 이동하여

    > 보고 싶은데...

    >

    > 기본적으로 지원되는 컴포넌트를 이용하여

    > 그림 스크롤을 만들수있는지요???



    다음은 이미지를 스크롤하는 콤포넌트 소스입니다.

    참고하시면 위의 문제를 해결 하시는 데 도움이 될것입니다.



    [소스]

    unit ZImage;



    interface



    uses

    Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

    ExtCtrls;



    type

    TZImage = class(TGraphicControl)

    private

    FBitmap : TBitmap;

    PicRect : TRect;

    ShowRect : TRect;

    FShowBorder : boolean;

    FBorderWidth : integer;

    FForceRepaint : boolean;

    FMouse : (mNone, mDrag, mZoom);

    FProportional : boolean;

    FDblClkEnable : boolean;

    startx, starty,

    oldx, oldy : integer;

    procedure SetShowBorder(s:boolean);

    procedure SetBitmap(b:TBitmap);

    procedure SetBorderWidth(w:integer);

    procedure SetProportional(b:boolean);

    protected

    procedure Paint; override;

    procedure DblClick; override;

    procedure MouseDown(Button: TMouseButton; Shift: TShiftState;

    X, Y: Integer); override;

    procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;

    procedure MouseUp(Button: TMouseButton; Shift: TShiftState;

    X, Y: Integer); override;

    public

    constructor Create(AOwner:TComponent); override;

    destructor Destroy; override;

    published

    property ShowBorder : boolean

    read FShowBorder

    write SetShowBorder default true;

    property KeepAspect : boolean

    read FProportional

    write SetProportional default true;

    property Bitmap : TBitmap

    read FBitmap

    write SetBitmap;

    property BorderWidth : integer

    read FBorderWidth

    write SetBorderWidth default 7;

    property ForceRepaint : boolean

    read FForceRepaint

    write FForceRepaint default true;

    property DblClkEnable : boolean

    read FDblClkEnable

    write FDblClkEnable default False;

    property Align;

    property Width;

    property Height;

    property Top;

    property Left;

    property Visible;

    property Hint;

    property ShowHint;

    end;



    procedure Register;



    implementation



    constructor TZImage.Create(AOwner:TComponent);

    begin

    inherited;

    FShowBorder:=True;

    FBorderWidth:=7;

    FMouse:=mNone;

    FForceRepaint:=True;

    FDblClkEnable:=False;

    FProportional:=True;

    Width:=100; Height:=100;

    FBitmap:=TBitmap.Create;

    FBitmap.Width:=Width;

    FBitmap.Height:=Height;

    ControlStyle:=ControlStyle+[csOpaque];

    end;



    destructor TZImage.Destroy;

    begin

    FBitmap.Free;

    inherited;

    end;



    procedure TZImage.Paint;

    var buf:TBitmap;

    coef,asps,aspp:Double;

    sz,a : integer;

    begin

    buf:=TBitmap.Create;

    buf.Width:=Width;

    buf.Height:=Height;

    if not FShowBorder

    then ShowRect:=ClientRect

    else ShowRect:=Rect(ClientRect.Left,ClientRect.Top,

    ClientRect.Right-FBorderWidth,

    ClientRect.Bottom-FBorderWidth);

    with PicRect do begin

    if Right=0 then Right:=FBitmap.Width;

    if Bottom=0 then Bottom:=FBitmap.Height;

    end;

    if FProportional then begin

    asps:=ShowRect.Bottom/ShowRect.Right;

    //IF added in v.1.2 to avoid zero-divide

    if (PicRect.Right=PicRect.Left)

    then

    aspp := 1

    else

    aspp := (PicRect.Bottom-PicRect.Top)/(PicRect.Right-PicRect.Left);

    if asps>aspp then begin //PicRect is wider

    sz:=Round((PicRect.Bottom-PicRect.Top)/asps);

    a:=PicRect.Right-PicRect.Left;

    PicRect.Left:=PicRect.Left+(a-sz) div 2;

    PicRect.Right:=PicRect.Left+sz;

    end else begin //PicRect is taller

    sz:=Round((PicRect.Right-PicRect.Left)*asps);

    a:=PicRect.Bottom-PicRect.Top;

    PicRect.Top:=PicRect.Top+(a-sz) div 2;

    PicRect.Bottom:=PicRect.Top+sz;

    end;

    if PicRect.Left<0 then MessageBeep(0);

    if PicRect.Top<0 then MessageBeep(0);

    end;

    buf.Canvas.CopyMode:=cmSrcCopy;

    buf.Canvas.CopyRect(ShowRect,FBitmap.Canvas,PicRect);

    if FShowBorder then begin

    buf.Canvas.Brush.Color:=clWhite;

    buf.Canvas.Rectangle(Width-BorderWidth,0,Width,Height-BorderWidth);

    buf.Canvas.Rectangle(0,Height-BorderWidth,Width-BorderWidth,Height);

    buf.Canvas.Brush.Color:=clSilver;

    buf.Canvas.Rectangle(Width-BorderWidth-1,Height-BorderWidth-1,buf.Width,Height);

    //horizontal zoom indicator

    coef:=(Width-BorderWidth)/FBitmap.Width;

    buf.Canvas.Rectangle(

    Round(PicRect.Left*coef)+2, Height-BorderWidth+2,

    Round(PicRect.Right*coef)-2, Height-2);

    //vertical zoom indicator

    coef:=(Height-BorderWidth)/FBitmap.Height;

    buf.Canvas.Rectangle(

    Width-BorderWidth+2,Round(PicRect.Top*coef)+2,

    Width-2, Round(PicRect.Bottom*coef)-2);

    end;

    Canvas.CopyMode:=cmSrcCopy;

    Canvas.Draw(0,0,buf);

    buf.Free;

    end;



    procedure TZImage.MouseDown(Button: TMouseButton; Shift: TShiftState;

    X, Y: Integer);

    begin

    if not PtInRect(ShowRect,Point(X,Y)) and

    not PtInRect(Rect(ShowRect.Right,ShowRect.Bottom,

    Width,Height),Point(X,Y)) then Exit;

    if PtInRect(Rect(ShowRect.Right,ShowRect.Bottom,

    Width,Height),Point(X,Y)) then begin

    DblClick;

    Exit;

    end;



    startx:=x; oldx:=x;

    starty:=y; oldy:=y;

    if mbRight=Button then begin

    MouseCapture:=True;

    FMouse:=mZoom;

    Canvas.Pen.Mode:=pmNot;

    end else begin

    FMouse:=mDrag;

    Screen.Cursor:=crHandPoint;

    end;

    end;



    function Min(a,b:integer):integer;

    begin

    if a
    end;

    function Max(a,b:integer):integer;

    begin

    if a
    end;



    procedure TZImage.MouseMove(Shift: TShiftState; X, Y: Integer);

    var d,s:integer;

    coef:Double;

    begin

    if FMouse=mNone then Exit;

    if FMouse=mZoom then begin

    Canvas.DrawFocusRect(Rect(Min(startx,oldx),Min(starty,oldy),Max(startx,oldx),Max(starty,oldy)));

    oldx:=x; oldy:=y;

    Canvas.DrawFocusRect(Rect(Min(startx,oldx),Min(starty,oldy),Max(startx,oldx),Max(starty,oldy)));

    end;

    if FMouse=mDrag then begin

    //horizontal movement

    coef:=(PicRect.Right-PicRect.Left)/(ShowRect.Right-ShowRect.Left);

    d:=Round(coef*(x-oldx));

    s:=PicRect.Right-PicRect.Left;

    if d>0 then begin

    if PicRect.Left>=d then begin

    PicRect.Left:=PicRect.Left-d;

    PicRect.Right:=PicRect.Right-d;

    end else begin

    PicRect.Left:=0;

    PicRect.Right:=PicRect.Left+s;

    end;

    end;

    if d<0 then begin

    if PicRect.Right
    PicRect.Left:=PicRect.Left-d;

    PicRect.Right:=PicRect.Right-d;

    end else begin

    PicRect.Right:=FBitmap.Width;

    PicRect.Left:=PicRect.Right-s;

    end;

    end;



    //vertical movement

    coef:=(PicRect.Bottom-PicRect.Top)/(ShowRect.Bottom-ShowRect.Top);

    d:=Round(coef*(y-oldy));

    s:=PicRect.Bottom-PicRect.Top;

    if d>0 then begin

    if PicRect.Top>=d then begin

    PicRect.Top:=PicRect.Top-d;

    PicRect.Bottom:=PicRect.Bottom-d;

    end else begin

    PicRect.Top:=0;

    PicRect.Bottom:=PicRect.Top+s;

    end;

    end;



    if d<0 then begin

    if PicRect.Bottom
    PicRect.Top:=PicRect.Top-d;

    PicRect.Bottom:=PicRect.Bottom-d;

    end else begin

    PicRect.Bottom:=FBitmap.Height;

    PicRect.Top:=PicRect.Bottom-s;

    end;

    end;





    oldx:=x; oldy:=y;

    if FForceRepaint then Repaint

    else Invalidate;

    end;

    end;



    procedure TZImage.MouseUp(Button: TMouseButton; Shift: TShiftState;

    X, Y: Integer);

    var coef:Double;

    t:integer;

    begin

    if FMouse=mNone then Exit;

    if x>ShowRect.Right then x:=ShowRect.Right;

    if y>ShowRect.Bottom then y:=ShowRect.Bottom;

    if FMouse=mZoom then begin //calculate new PicRect

    t:=startx;

    startx:=Min(startx,x);

    x:=Max(t,x);

    t:=starty;

    starty:=Min(starty,y);

    y:=Max(t,y);

    FMouse:=mNone;

    MouseCapture:=False;

    if Abs(x-startx)<5 then Exit;



    if (PicRect.Right=PicRect.Left)

    then

    coef := 100000

    else

    coef:=ShowRect.Right/(PicRect.Right-PicRect.Left);

    PicRect.Left:=Round(PicRect.Left+startx/coef);

    PicRect.Right:=PicRect.Left+Round((x-startx)/coef);

    if (PicRect.Bottom=PicRect.Top)

    then

    coef := 100000

    else

    coef:=ShowRect.Bottom/(PicRect.Bottom-PicRect.Top);

    PicRect.Top:=Round(PicRect.Top+starty/coef);

    PicRect.Bottom:=PicRect.Top+Round((y-starty)/coef);

    end;

    if FMouse=mDrag then begin

    FMouse:=mNone;

    Canvas.Pen.Mode:=pmCopy;

    Screen.Cursor:=crDefault;

    end;

    Invalidate;

    end;



    procedure TZImage.DblClick;

    begin

    PicRect:=Rect(0,0,FBitmap.Width,FBitmap.Height);

    Invalidate;

    end;



    procedure TZImage.SetBitmap(b:TBitmap);

    begin

    FBitmap.Assign(b);

    PicRect:=Rect(0,0,b.Width, b.Height);

    Invalidate;

    end;



    procedure TZImage.SetBorderWidth(w:integer);

    begin

    FBorderWidth:=w;

    Invalidate;

    end;



    procedure TZImage.SetShowBorder(s:boolean);

    begin

    FShowBorder:=s;

    Invalidate;

    end;



    procedure TZImage.SetProportional(b:boolean);

    begin

    FProportional:=b;

    Invalidate;

    end;



    procedure Register;

    begin

    RegisterComponents('Custom', [TZImage]);

    end;