首页 > 代码库 > TAQSkinScrollBar 类美化滚动条再讨论

TAQSkinScrollBar 类美化滚动条再讨论

再说:TAQSkinScrollBar 类美化滚动条,http://www.138soft.com/?p=156  里面有人提到不可以滚动

滚动的改善方法:

技术分享

 

技术分享
unit AQSkinScrollBar;(* 说明:本单元提取自TdsaSkinAdapter控件,版权归原作者所有。 提取:www.138soft.com*){$R Scroll.RES}interfaceuses  ComCtrls,  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms;const  // Billenium Effects messages  BE_ID = $41A2;  BE_BASE = CM_BASE + $0C4A;  CM_BENCPAINT = BE_BASE + 1;  CM_SENCPAINT = CM_BASE + 457;type  TStretchType = (stFull, stHorz, stVert);  TAQSkinScrollBarControl = record    SkinRect: TRect;    //============================    LTPoint, RTPoint, LBPoint, RBPoint: TPoint;    ClRect: TRect;    StretchEffect: Boolean;    LeftStretch, TopStretch, RightStretch, BottomStretch: Boolean;    StretchType: TStretchType;    //============================    TrackArea: TRect;    UpButtonRect, ActiveUpButtonRect, DownUpButtonRect: TRect;    DownButtonRect, ActiveDownButtonRect, DownDownButtonRect: TRect;    ThumbRect, ActiveThumbRect, DownThumbRect: TRect;    ThumbOffset1, ThumbOffset2: Integer;    GlyphRect, ActiveGlyphRect, DownGlyphRect: TRect;    GlyphTransparent: Boolean;    GlyphTransparentColor: TColor;    ThumbTransparent: Boolean;    ThumbTransparentColor: TColor;    ThumbStretchEffect: Boolean;    ThumbMinSize: Integer;    ThumbMinPageSize: Integer;  end;type  TScrollButtonDrawState = (    bsasbNormal,    bsasbPressed,    bsasbHot,    bsasbDisabled    );type  TAQSkinScrollBar = class(TObject)  private    FControl: TControl;    FHandle: THandle;    FHandled: Boolean;    FOldWinProc: TWndMethod;    SMouseInControl: Boolean;    lbtndown: Boolean;    procedure SetControl(Value: TControl);    procedure NewWindowProc(var Message: TMessage);  private    FKind: TScrollBarKind;    procedure DrawBorder(ADC: HDC; AUseExternalDC: Boolean);    procedure DrawButton(Cnvs: TCanvas; i: Integer);    function GetBoundsRect: TRect;    function GetBorderTopLeft: TPoint;    function HaveBorder: Boolean;    function GetHeight: Integer;    function GetWidth: Integer;    function GetEnabled: Boolean;  protected    FOldPos: Integer;    FCurPos, LVOldCurPos: single;    VScrollWnd, HScrollWnd: TWinControl;    VSliderState, VUpState, VDownState: TScrollButtonDrawState;    HSliderState, HUpState, HDownState: TScrollButtonDrawState;    function VScrollDisabled: Boolean;    function HScrollDisabled: Boolean;    function VDownButtonRect: TRect;    function VScrollRect: TRect;    function VSliderRect: TRect;    function VTrackRect: TRect;    function VUpButtonRect: TRect;    function HDownButtonRect: TRect;    function HScrollRect: TRect;    function HSliderRect: TRect;    function HTrackRect: TRect;    function HUpButtonRect: TRect;    procedure VDrawScroll(DC: HDC = 0);    procedure HDrawScroll(DC: HDC = 0);    // Billenium    procedure CMBENCPaint(var Message: TMessage); //message CM_BENCPAINT;    // SmartEffects    procedure CMSENCPaint(var Message: TMessage); //message CM_SENCPAINT;    //    procedure WMLButtonDown(var Msg: TWMMouse); //message WM_LBUTTONDOWN;    procedure WMLButtonUp(var Msg: TWMMouse); //message WM_LBUTTONUP;    procedure WMNCLButtonDblClk(var Msg: TWMMouse); //message WM_NCLBUTTONDBLCLK;    procedure WMNCLButtonDown(var Msg: TWMMouse); //message WM_NCLBUTTONDOWN;    procedure WMNCMouseMove(var Msg: TWMNCHitMessage); //message WM_NCMOUSEMOVE;    procedure WMNCLButtonUp(var Msg: TWMMouse); //message WM_NCLBUTTONUP;    procedure WMMouseMove(var Msg: TWMMouse); //message WM_MOUSEMOVE;    procedure WMNCPaint(var Msg: TWMNCPaint); //message WM_NCPAINT;    procedure WMEraseBkgnd(var Msg: TMessage); //message WM_ERASEBKGND;    procedure WMMouseWheel(var Msg: TMessage); //message WM_MOUSEWHEEL;    procedure WMVScroll(var Msg: TMessage); //message WM_VSCROLL;    procedure WMHScroll(var Msg: TMessage); //message WM_HSCROLL;    procedure WMSize(var Msg: TMessage); //message WM_SIZE;    procedure WMKeyDown(var Msg: TMessage); //message WM_KEYDOWN;    procedure WMCAPTURECHANGED(var Msg: TMessage); //message WM_CAPTURECHANGED;    procedure WMVTChangeState(var Msg: TMessage); message WM_APP + 32;    procedure CMVisibleChanged(var Msg: TMessage); //message CM_VISIBLECHANGED;    procedure CMMouseEnter(var Msg: TMessage); //message CM_MOUSEENTER;    procedure CMMouseLeave(var Msg: TMessage); //message CM_MOUSELEAVE;    procedure EMLINEINDEX(var Msg: TMessage); //message EM_LINEINDEX;    procedure WMWindowPosChanging(var Msg: TWMWindowPosChanged); //message WM_WINDOWPOSCHANGING;    procedure WMWindowPosChanged(var Msg: TWMWindowPosChanged); //message WM_WINDOWPOSCHANGED;    procedure OnContextPopupAction(var Message: TMessage);    procedure PaintBorder(Canvas: TCanvas; R: TRect); //override;    function IsPopupWindow: Boolean;    procedure PaintScroll;    procedure UpdateScroll;    procedure Paint(Canvas: TCanvas); //override;    procedure SetHandle(const Value: HWnd); //override;  private    FBmp_Border: TBitmap;    FBmp_skinrect_V: TBitmap;    FBmp_activeupbuttonrect_V: TBitmap;    FBmp_activedownbuttonrect_V: TBitmap;    FBmp_thumbrect_V: TBitmap;    FBmp_activethumbrect_V: TBitmap;    FBmp_skinrect_H: TBitmap;    FBmp_activeupbuttonrect_H: TBitmap;    FBmp_activedownbuttonrect_H: TBitmap;    FBmp_thumbrect_H: TBitmap;    FBmp_activethumbrect_H: TBitmap;    FVScrollCtrl, FHScrollCtrl: TAQSkinScrollBarControl;    FBtnFace: TColor;  public    constructor Create;    destructor Destroy; override;  published    property Control: TControl read FControl write SetControl;    property Handle: THandle read FHandle;    property Handled: Boolean read FHandled write FHandled;    property Width: Integer read GetWidth;    property Height: Integer read GetHeight;    property Enabled: Boolean read GetEnabled;  end;  TWinScroll = class(TCustomControl)  public    FSubclass: TAQSkinScrollBar;    FVertical: Boolean;  private  protected    procedure WMNCHitTest(var Msg: TWMNCHitTest); message WM_NCHITTEST;    procedure WMEraseBkgnd(var Msg: TMessage); message WM_ERASEBKGND;    procedure Paint; override;    procedure CreateParams(var Params: TCreateParams); override;  public  end;implementationfunction RectWidth(R: TRect): Integer;begin  Result := R.Right - R.Left;end;function RectHeight(R: TRect): Integer;begin  Result := R.Bottom - R.Top;end;type  //  TStretchType = (stFull, stHorz, stVert);  TButtonLayout = (blGlyphLeft, blGlyphRight, blGlyphTop, blGlyphBottom);procedure CreateSkinImage(LtPt, RTPt, LBPt, RBPt: TPoint; ClRect: TRect;  NewLTPt, NewRTPt, NewLBPt, NewRBPt: TPoint; NewClRect: TRect;  B, SB: TBitMap; R: TRect; AW, AH: Integer; ADrawClient: Boolean;  ALeftStretch, ATopStretch, ARightStretch, ABottomStretch,  AClientStretch: Boolean; AStretchType: TStretchType);var  w, h, rw, rh: Integer;  X, Y, XCnt, YCnt: Integer;  XO, YO: Integer;  R1, R2, R3: TRect;  Buffer, Buffer2: TBitMap;  SaveIndex: Integer;begin  B.Width := AW;  B.Height := AH;  if (RBPt.X - LTPt.X = 0) or    (RBPt.Y - LTPt.Y = 0) or SB.Empty then Exit;  with B.Canvas do  begin    // Draw lines    // top    if not ATopStretch      then    begin      w := RTPt.X - LTPt.X;      XCnt := (NewRTPt.X - NewLTPt.X) div (RTPt.X - LTPt.X);      for X := 0 to XCnt do      begin        if NewLTPt.X + X * w + w > NewRTPt.X          then XO := NewLTPt.X + X * w + w - NewRTPt.X else XO := 0;        CopyRect(Rect(NewLTPt.X + X * w, 0, NewLTPt.X + X * w + w - XO, NewClRect.Top),          SB.Canvas, Rect(R.Left + LTPt.X, R.Top,          R.Left + RTPt.X - XO, R.Top + ClRect.Top));      end;    end    else    begin      R1 := Rect(NewLTPt.X, 0, NewRTPt.X, NewClRect.Top);      R2 := Rect(R.Left + LTPt.X, R.Top, R.Left + RTPt.X, R.Top + ClRect.Top);      Buffer := TBitMap.Create;      Buffer.Width := RectWidth(R2);      Buffer.Height := RectHeight(R2);      R3 := Rect(0, 0, Buffer.Width, Buffer.Height);      Buffer.Canvas.CopyRect(R3, SB.Canvas, R2);      StretchDraw(R1, Buffer);      Buffer.Free;    end;    // bottom    if not ABottomStretch      then    begin      w := RBPt.X - LBPt.X;      XCnt := (NewRBPt.X - NewLBPt.X) div (RBPt.X - LBPt.X);      for X := 0 to XCnt do      begin        if NewLBPt.X + X * w + w > NewRBPt.X          then XO := NewLBPt.X + X * w + w - NewRBPt.X else XO := 0;        CopyRect(Rect(NewLBPt.X + X * w, NewClRect.Bottom, NewLBPt.X + X * w + w - XO, AH),          SB.Canvas, Rect(R.Left + LBPt.X, R.Top + ClRect.Bottom,          R.Left + RBPt.X - XO, R.Bottom));      end;    end    else    begin      R1 := Rect(NewLBPt.X, NewClRect.Bottom, NewRBPt.X, AH);      R2 := Rect(R.Left + LBPt.X, R.Top + ClRect.Bottom, R.Left + RBPt.X, R.Bottom);      Buffer := TBitMap.Create;      Buffer.Width := RectWidth(R2);      Buffer.Height := RectHeight(R2);      R3 := Rect(0, 0, Buffer.Width, Buffer.Height);      Buffer.Canvas.CopyRect(R3, SB.Canvas, R2);      StretchDraw(R1, Buffer);      Buffer.Free;    end;    // left    if not ALeftStretch      then    begin      w := NewClRect.Left;      h := LBPt.Y - LTPt.Y;      YCnt := (NewLBPt.Y - NewLTPt.Y) div h;      for Y := 0 to YCnt do      begin        if NewLTPt.Y + Y * h + h > NewLBPt.Y          then YO := NewLTPt.Y + Y * h + h - NewLBPt.Y else YO := 0;        CopyRect(Rect(0, NewLTPt.Y + Y * h, w, NewLTPt.Y + Y * h + h - YO),          SB.Canvas,          Rect(R.Left, R.Top + LTPt.Y, R.Left + w, R.Top + LBPt.Y - YO));      end    end    else    begin      R1 := Rect(0, NewLTPt.Y, NewClRect.Left, NewLBPt.Y);      R2 := Rect(R.Left, R.Top + LtPt.Y, R.Left + ClRect.Left, R.Top + LBPt.Y);      Buffer := TBitMap.Create;      Buffer.Width := RectWidth(R2);      Buffer.Height := RectHeight(R2);      R3 := Rect(0, 0, Buffer.Width, Buffer.Height);      Buffer.Canvas.CopyRect(R3, SB.Canvas, R2);      StretchDraw(R1, Buffer);      Buffer.Free;    end;    // right    if not ARightStretch      then    begin      h := RBPt.Y - RTPt.Y;      YCnt := (NewRBPt.Y - NewRTPt.Y) div h;      for Y := 0 to YCnt do      begin        if NewRTPt.Y + Y * h + h > NewRBPt.Y          then YO := NewRTPt.Y + Y * h + h - NewRBPt.Y else YO := 0;        CopyRect(Rect(NewClRect.Right, NewRTPt.Y + Y * h,          AW, NewRTPt.Y + Y * h + h - YO),          SB.Canvas,          Rect(R.Left + ClRect.Right, R.Top + RTPt.Y,          R.Right, R.Top + RBPt.Y - YO));      end    end    else    begin      R1 := Rect(NewClRect.Right, NewRTPt.Y, AW, NewRBPt.Y);      R2 := Rect(R.Left + ClRect.Right, R.Top + RtPt.Y, R.Right, R.Top + RBPt.Y);      Buffer := TBitMap.Create;      Buffer.Width := RectWidth(R2);      Buffer.Height := RectHeight(R2);      R3 := Rect(0, 0, Buffer.Width, Buffer.Height);      Buffer.Canvas.CopyRect(R3, SB.Canvas, R2);      StretchDraw(R1, Buffer);      Buffer.Free;    end;    // Draw corners    // lefttop    CopyRect(Rect(0, 0, NewLTPt.X, NewClRect.Top),      SB.Canvas, Rect(R.Left, R.Top,      R.Left + LTPt.X, R.Top + ClRect.Top));    CopyRect(Rect(0, NewClRect.Top, NewClRect.Left, NewLTPt.Y),      SB.Canvas, Rect(R.Left, R.Top + ClRect.Top,      R.Left + ClRect.left, R.Top + LTPT.Y));    //topright    CopyRect(Rect(NewRTPt.X, 0, AW, NewClRect.Top), SB.Canvas,      Rect(R.Left + RTPt.X, R.Top, R.Right, R.Top + ClRect.Top));    CopyRect(Rect(NewClRect.Right, NewClRect.Top, AW, NewRTPt.Y), SB.Canvas,      Rect(R.Left + ClRect.Right, R.Top + ClRect.Top,      R.Right, R.Top + RTPt.Y));    //leftbottom    CopyRect(Rect(0, NewLBPt.Y, NewClRect.Left, AH), SB.Canvas,      Rect(R.Left, R.Top + LBPt.Y, R.Left + ClRect.Left, R.Bottom));    CopyRect(Rect(NewClRect.Left, NewClRect.Bottom, NewLBPt.X, AH), SB.Canvas,      Rect(R.Left + ClRect.Left, R.Top + ClRect.Bottom, R.Left + LBPt.X, R.Bottom));    //rightbottom    CopyRect(Rect(NewRBPt.X, NewClRect.Bottom, AW, AH), SB.Canvas,      Rect(R.Left + RBPt.X, R.Top + ClRect.Bottom, R.Right, R.Bottom));    CopyRect(Rect(NewClRect.Right, NewRBPt.Y, AW, NewClRect.Bottom), SB.Canvas,      Rect(R.Left + ClRect.Right, R.Top + RBPt.Y,      R.Right, R.Top + ClRect.Bottom));    //Draw client    if ADrawClient      then      if AClientStretch        then      begin        Buffer := TBitMap.Create;        Buffer.Width := RectWidth(ClRect);        Buffer.Height := RectHeight(ClRect);        Buffer.Canvas.CopyRect(Rect(0, 0, Buffer.Width, Buffer.Height),          SB.Canvas, Rect(R.Left + ClRect.Left, R.Top + ClRect.Top,          R.Left + ClRect.Right, R.Top + ClRect.Bottom));        if (RectWidth(NewClRect) > 0) and (RectHeight(NewClRect) > 0) then          case AStretchType of            stFull:              StretchDraw(NewClRect, Buffer);            stHorz:              begin                SaveIndex := SaveDC(B.Canvas.Handle);                IntersectClipRect(B.Canvas.Handle,                  NewCLRect.Left, NewCLRect.Top, NewCLRect.Right, NewClRect.Bottom);                //                Buffer2 := TBitMap.Create;                Buffer2.Width := Buffer.Width;                Buffer2.Height := RectHeight(NewClRect);                Buffer2.Canvas.StretchDraw(Rect(0, 0, Buffer2.Width, Buffer2.Height), Buffer);                XCnt := RectWidth(NewClRect) div Buffer2.Width;                for X := 0 to XCnt do                  B.Canvas.Draw(NewClRect.Left + X * Buffer2.Width, NewClRect.Top, Buffer2);                Buffer2.Free;                //                RestoreDC(B.Canvas.Handle, SaveIndex);              end;            stVert:              begin                SaveIndex := SaveDC(B.Canvas.Handle);                IntersectClipRect(B.Canvas.Handle,                  NewCLRect.Left, NewCLRect.Top, NewCLRect.Right, NewClRect.Bottom);                //                Buffer2 := TBitMap.Create;                Buffer2.Width := RectWidth(NewClRect);                Buffer2.Height := Buffer.Height;                Buffer2.Canvas.StretchDraw(Rect(0, 0, Buffer2.Width, Buffer2.Height), Buffer);                YCnt := RectHeight(NewClRect) div Buffer2.Height;                for Y := 0 to YCnt do                  B.Canvas.Draw(NewClRect.Left, NewClRect.Top + Y * Buffer2.Height, Buffer2);                Buffer2.Free;                //                RestoreDC(B.Canvas.Handle, SaveIndex);              end;          end;        Buffer.Free;      end      else      begin        w := RectWidth(ClRect);        h := RectHeight(ClRect);        rw := RectWidth(NewClRect);        rh := RectHeight(NewClRect);        // Draw client area        XCnt := rw div w;        YCnt := rh div h;        for X := 0 to XCnt do          for Y := 0 to YCnt do          begin            if X * w + w > rw then XO := X * W + W - rw else XO := 0;            if Y * h + h > rh then YO := Y * h + h - rh else YO := 0;            CopyRect(Rect(NewClRect.Left + X * w, NewClRect.Top + Y * h,              NewClRect.Left + X * w + w - XO,              NewClRect.Top + Y * h + h - YO),              SB.Canvas,              Rect(R.Left + ClRect.Left, R.Top + ClRect.Top,              R.Left + ClRect.Right - XO,              R.Top + ClRect.Bottom - YO));          end;      end;  end;end;procedure CreateStretchImage(B: TBitMap; SB: TBitMap; R: TRect; ClRect: TRect;  ADrawClient: Boolean);var  LTPt, RTPt, LBPt, RBPt: TPoint;  NewLTPt, NewRTPt, NewLBPt, NewRBPt: TPoint;  NewClRect: TRect;begin  LtPt := Point(ClRect.Left, ClRect.Top);  RtPt := Point(ClRect.Right, ClRect.Top);  LBPt := Point(ClRect.Left, ClRect.Bottom);  RBPt := Point(ClRect.Right, ClRect.Bottom);  NewClRect := ClRect;  NewClRect.Right := B.Width - (RectWidth(R) - ClRect.Right);  NewClRect.Bottom := B.Height - (RectHeight(R) - ClRect.Bottom);  NewLtPt := Point(NewClRect.Left, NewClRect.Top);  NewRtPt := Point(NewClRect.Right, NewClRect.Top);  NewLBPt := Point(NewClRect.Left, NewClRect.Bottom);  NewRBPt := Point(NewClRect.Right, NewClRect.Bottom);  CreateSkinImage(LtPt, RTPt, LBPt, RBPt, ClRect,    NewLTPt, NewRTPt, NewLBPt, NewRBPt, NewClRect,    B, SB, R, B.Width, B.Height, ADrawClient,    True, True, True, True, True, stFull);end;procedure CreateHSkinImage(LO, RO: Integer;  B, SB: TBitMap; R: TRect; AW, AH: Integer; AStretch: Boolean);var  X, XCnt, w, XO: Integer;  R1: TRect;  Buffer: TBitMap;begin  B.Width := AW;  B.Height := RectHeight(R);  with B.Canvas do  begin    if LO <> 0 then      CopyRect(Rect(0, 0, LO, B.Height), SB.Canvas,        Rect(R.Left, R.Top, R.Left + LO, R.Bottom));    if RO <> 0 then      CopyRect(Rect(B.Width - RO, 0, B.Width, B.Height),        SB.Canvas,        Rect(R.Right - RO, R.Top, R.Right, R.Bottom));    Inc(R.Left, LO);    Dec(R.Right, RO);    w := RectWidth(R);    if w = 0 then w := 1;    XCnt := (B.Width - LO - RO) div w;    if AStretch      then    begin      Buffer := TBitMap.Create;      Buffer.Width := RectWidth(R);      Buffer.Height := RectHeight(R);      Buffer.Canvas.CopyRect(Rect(0, 0, Buffer.Width, Buffer.Height),        SB.Canvas, R);      R1 := Rect(LO, 0, B.Width - RO, B.Height);      B.Canvas.StretchDraw(R1, Buffer);      Buffer.Free;    end    else      for X := 0 to XCnt do      begin        if LO + X * w + w > B.Width - RO          then XO := LO + X * w + w - (B.Width - RO)        else XO := 0;        B.Canvas.CopyRect(Rect(LO + X * w, 0, LO + X * w + w - XO,          B.Height),          SB.Canvas,          Rect(R.Left, R.Top, R.Right - XO, R.Bottom));      end;  end;end;procedure CreateVSkinImage(TpO, BO: Integer;  B, SB: TBitMap; R: TRect; AW, AH: Integer; AStretch: Boolean);var  Y, YCnt, h, YO: Integer;  R1: TRect;  Buffer: TBitMap;begin  B.Width := RectWidth(R);  B.Height := AH;  with B.Canvas do  begin    if TpO <> 0 then      CopyRect(Rect(0, 0, B.Width, TpO), SB.Canvas,        Rect(R.Left, R.Top, R.Right, R.Top + TpO));    if BO <> 0 then      CopyRect(Rect(0, B.Height - BO, B.Width, B.Height),        SB.Canvas,        Rect(R.Left, R.Bottom - BO, R.Right, R.Bottom));    Inc(R.Top, TpO);    Dec(R.Bottom, BO);    h := RectHeight(R);    if H <> 0      then      YCnt := (B.Height - TpO - BO) div h    else      YCnt := 0;    if AStretch      then    begin      Buffer := TBitMap.Create;      Buffer.Width := RectWidth(R);      Buffer.Height := RectHeight(R);      Buffer.Canvas.CopyRect(Rect(0, 0, Buffer.Width, Buffer.Height),        SB.Canvas, R);      R1 := Rect(0, TpO, B.Width, B.Height - BO);      B.Canvas.StretchDraw(R1, Buffer);      Buffer.Free;    end    else      for Y := 0 to YCnt do      begin        if TpO + Y * h + h > B.Height - BO          then YO := TpO + Y * h + h - (B.Height - BO)        else YO := 0;        B.Canvas.CopyRect(          Rect(0, TpO + Y * h, B.Width, TpO + Y * h + h - YO),          SB.Canvas,          Rect(R.Left, R.Top, R.Right, R.Bottom - YO));      end;  end;end;procedure DrawGlyph(Cnvs: TCanvas; X, Y: Integer; FGlyph: TBitMap;  FNumGlyphs, FGlyphNum: Integer);var  B: TBitMap;  gw, gh: Integer;  GR: TRect;begin  if FGlyph.Empty then Exit;  gw := FGlyph.Width div FNumGlyphs;  gh := FGlyph.Height;  B := TBitMap.Create;  B.Width := gw;  B.Height := gh;  GR := Rect(gw * (FGlyphNum - 1), 0, gw * FGlyphNum, gh);  B.Canvas.CopyRect(Rect(0, 0, gw, gh), FGlyph.Canvas, GR);  B.Transparent := True;  Cnvs.Draw(X, Y, B);  B.Free;end;procedure CreateSkinBorderImages(LtPt, RTPt, LBPt, RBPt: TPoint; ClRect: TRect;  NewLTPt, NewRTPt, NewLBPt, NewRBPt: TPoint; NewClRect: TRect;  LeftB, TopB, RightB, BottomB, SB: TBitMap; R: TRect; AW, AH: Integer;  LS, TS, RS, BS: Boolean);var  XCnt, YCnt, i, X, Y, XO, YO, w, h: Integer;  TB: TBitMap;  TR, TR1: TRect;begin  // top  w := AW;  h := NewClRect.Top;  if (w > 0) and (h > 0) and (RTPt.X - LTPt.X > 0) then  begin    TopB.Width := w;    TopB.Height := h;    w := RTPt.X - LTPt.X;    XCnt := TopB.Width div w;    if TS then    begin      TB := TBitMap.Create;      TR := Rect(R.Left + LTPt.X, R.Top,        R.Left + RTPt.X, R.Top + h);      TR1 := Rect(NewLTPt.X, 0, NewRTPt.X, h);      TB.Width := RectWidth(TR);      TB.Height := RectHeight(TR);      TB.Canvas.CopyRect(Rect(0, 0, TB.Width, TB.Height),        SB.Canvas, TR);      TopB.Canvas.StretchDraw(TR1, TB);      TB.Free;    end    else      for X := 0 to XCnt do      begin        if X * w + w > TopB.Width          then XO := X * w + w - TopB.Width else XO := 0;        with TopB.Canvas do        begin          CopyRect(Rect(X * w, 0, X * w + w - XO, h),            SB.Canvas,            Rect(R.Left + LTPt.X, R.Top,            R.Left + RTPt.X - XO, R.Top + h));        end;      end;    with TopB.Canvas do    begin      CopyRect(Rect(0, 0, NewLTPt.X, h), SB.Canvas,        Rect(R.Left, R.Top, R.Left + LTPt.X, R.Top + h));      CopyRect(Rect(NewRTPt.X, 0, TopB.Width, h), SB.Canvas,        Rect(R.Left + RTPt.X, R.Top, R.Right, R.Top + h));    end;  end;  // bottom  w := AW;  h := AH - NewClRect.Bottom;  if (w > 0) and (h > 0) and (RBPt.X - LBPt.X > 0)    then  begin    BottomB.Width := w;    BottomB.Height := h;    w := RBPt.X - LBPt.X;    XCnt := BottomB.Width div w;    if BS then    begin      TB := TBitMap.Create;      TR := Rect(R.Left + LBPt.X, R.Bottom - h,        R.Left + RBPt.X, R.Bottom);      TR1 := Rect(NewLBPt.X, 0, NewRBPt.X, h);      TB.Width := RectWidth(TR);      TB.Height := RectHeight(TR);      TB.Canvas.CopyRect(Rect(0, 0, TB.Width, TB.Height),        SB.Canvas, TR);      BottomB.Canvas.StretchDraw(TR1, TB);      TB.Free;    end    else      for X := 0 to XCnt do      begin        if X * w + w > BottomB.Width          then XO := X * w + w - BottomB.Width else XO := 0;        with BottomB.Canvas do        begin          CopyRect(Rect(X * w, 0, X * w + w - XO, h),            SB.Canvas,            Rect(R.Left + LBPt.X, R.Bottom - h,            R.Left + RBPt.X - XO, R.Bottom));        end;      end;    with BottomB.Canvas do    begin      CopyRect(Rect(0, 0, NewLBPt.X, h), SB.Canvas,        Rect(R.Left, R.Bottom - h, R.Left + LBPt.X, R.Bottom));      CopyRect(Rect(NewRBPt.X, 0, BottomB.Width, h), SB.Canvas,        Rect(R.Left + RBPt.X, R.Bottom - h, R.Right, R.Bottom));    end;  end;  // draw left  h := AH - BottomB.Height - TopB.Height;  w := NewClRect.Left;  if (w > 0) and (h > 0) and (LBPt.Y - LTPt.Y > 0)    then  begin    LeftB.Width := w;    LeftB.Height := h;    h := LBPt.Y - LTPt.Y;    YCnt := LeftB.Height div h;    if LS then    begin      TB := TBitMap.Create;      TR := Rect(R.Left, R.Top + LTPt.Y,        R.Left + w, R.Top + LBPt.Y);      TR1 := Rect(0, LTPt.Y - ClRect.Top, w,        LeftB.Height - (ClRect.Bottom - LBPt.Y));      TB.Width := RectWidth(TR);      TB.Height := RectHeight(TR);      TB.Canvas.CopyRect(Rect(0, 0, TB.Width, TB.Height),        SB.Canvas, TR);      LeftB.Canvas.StretchDraw(TR1, TB);      TB.Free;    end    else      for Y := 0 to YCnt do      begin        if Y * h + h > LeftB.Height          then YO := Y * h + h - LeftB.Height else YO := 0;        with LeftB.Canvas do          CopyRect(Rect(0, Y * h, w, Y * h + h - YO),            SB.Canvas,            Rect(R.Left, R.Top + LTPt.Y, R.Left + w, R.Top + LBPt.Y - YO));      end;    with LeftB.Canvas do    begin      YO := LTPt.Y - ClRect.Top;      if YO > 0        then        CopyRect(Rect(0, 0, w, YO), SB.Canvas,          Rect(R.Left, R.Top + ClRect.Top,          R.Left + w, R.Top + LTPt.Y));      YO := ClRect.Bottom - LBPt.Y;      if YO > 0 then        CopyRect(Rect(0, LeftB.Height - YO, w, LeftB.Height),          SB.Canvas,          Rect(R.Left, R.Top + LBPt.Y,          R.Left + w, R.Top + ClRect.Bottom));    end;  end;  // draw right  h := AH - BottomB.Height - TopB.Height;  w := AW - NewClRect.Right;  if (w > 0) and (h > 0) and (RBPt.Y - RTPt.Y > 0) then  begin    RightB.Width := w;    RightB.Height := h;    h := RBPt.Y - RTPt.Y;    YCnt := RightB.Height div h;    if RS then    begin      TB := TBitMap.Create;      TR := Rect(R.Left + ClRect.Right, R.Top + RTPt.Y,        R.Right, R.Top + RBPt.Y);      TR1 := Rect(0, RTPt.Y - ClRect.Top, w,        RightB.Height - (ClRect.Bottom - RBPt.Y));      TB.Width := RectWidth(TR);      TB.Height := RectHeight(TR);      TB.Canvas.CopyRect(Rect(0, 0, TB.Width, TB.Height),        SB.Canvas, TR);      RightB.Canvas.StretchDraw(TR1, TB);      TB.Free;    end    else      for Y := 0 to YCnt do      begin        if Y * h + h > RightB.Height          then YO := Y * h + h - RightB.Height else YO := 0;        with RightB.Canvas do          CopyRect(Rect(0, Y * h, w, Y * h + h - YO),            SB.Canvas,            Rect(R.Left + ClRect.Right, R.Top + RTPt.Y,            R.Right, R.Top + RBPt.Y - YO));      end;    with RightB.Canvas do    begin      YO := RTPt.Y - ClRect.Top;      if YO > 0 then        CopyRect(Rect(0, 0, w, YO), SB.Canvas,          Rect(R.Left + ClRect.Right, R.Top + ClRect.Top,          R.Right, R.Top + RTPt.Y));      YO := ClRect.Bottom - RBPt.Y;      if YO > 0 then        CopyRect(Rect(0, RightB.Height - YO, w, RightB.Height),          SB.Canvas,          Rect(R.Left + ClRect.Right, R.Top + RBPt.Y,          R.Right, R.Top + ClRect.Bottom));    end;  end;end;function NullRect: TRect;begin  Result := Rect(0, 0, 0, 0);end;function IsNullRect(R: TRect): Boolean;begin  Result := (R.Right - R.Left <= 0) or (R.Bottom - R.Top <= 0)end;procedure DrawArrowImage(Cnvs: TCanvas; R: TRect; Color: TColor; Code: Integer);var  i: Integer;  X, Y: Integer;begin  with Cnvs do  begin    Pen.Color := Color;    case Code of      1:        begin          X := R.Left + RectWidth(R) div 2 - 2;          Y := R.Top + RectHeight(R) div 2;          for i := 0 to 3 do          begin            MoveTo(X + i, Y - i);            LineTo(X + i, Y + i + 1);          end;        end;      2:        begin          X := R.Left + RectWidth(R) div 2 + 2;          Y := R.Top + RectHeight(R) div 2;          for i := 3 downto 0 do          begin            MoveTo(X - i, Y + i);            LineTo(X - i, Y - i - 1);          end;        end;      3:        begin          X := R.Left + RectWidth(R) div 2;          Y := R.Top + RectHeight(R) div 2 - 2;          for i := 0 to 3 do          begin            MoveTo(X - i, Y + i);            LineTo(X + i + 1, Y + i);          end;        end;      4:        begin          X := R.Left + RectWidth(R) div 2;          Y := R.Top + RectHeight(R) div 2 + 2;          for i := 3 downto 0 do          begin            MoveTo(X - i, Y - i);            LineTo(X + i + 1, Y - i);          end;        end;      5: begin          X := R.Left + RectWidth(R) div 2;          Y := R.Top + RectHeight(R) div 2;          MoveTo(X - 4, Y - 1);          LineTo(X + 4, Y - 1);          MoveTo(X - 4, Y);          LineTo(X + 4, Y);          //          MoveTo(X - 1, Y - 4);          LineTo(X - 1, Y + 4);          MoveTo(X, Y - 4);          LineTo(X, Y + 4);        end;    end;  end;end;{ TWinScroll }procedure TWinScroll.CreateParams(var Params: TCreateParams);begin  inherited;  Params.Style := Params.Style or WS_CHILDWINDOW or WS_CLIPCHILDREN or WS_CLIPSIBLINGS;  Params.ExStyle := Params.ExStyle or WS_EX_NOPARENTNOTIFY;  Params.WindowClass.style := Params.WindowClass.style;end;procedure TWinScroll.Paint;begin  if Width * Height = 0 then Exit;  if FSubclass <> nil then  begin    if FVertical then    begin      with FSubclass.VScrollRect do        MoveWindowOrg(Canvas.Handle, -Left, -Top);      FSubclass.VDrawScroll(Canvas.Handle);      with FSubclass.VScrollRect do        MoveWindowOrg(Canvas.Handle, Left, Top);    end    else    begin      with FSubclass.HScrollRect do        MoveWindowOrg(Canvas.Handle, -Left, -Top);      FSubclass.HDrawScroll(Canvas.Handle);      with FSubclass.HScrollRect do        MoveWindowOrg(Canvas.Handle, Left, Top);    end;  end;end;procedure TWinScroll.WMEraseBkgnd(var Msg: TMessage);begin  Msg.Result := 1;end;procedure TWinScroll.WMNCHitTest(var Msg: TWMNCHitTest);begin  Msg.Result := HTTRANSPARENT;end;{ TAQSkinScrollBar }const  BUTCOUNT = 3;  THUMB = 0;  UPBUTTON = 1;  DOWNBUTTON = 2;  TRACK = 3;  CLIENT = 4;  SBUTTONW = 16;procedure TAQSkinScrollBar.CMBENCPaint(var Message: TMessage);begin  if (Message.LParam = BE_ID) then  begin    if (Message.wParam <> 0) then      DrawBorder(Message.wParam, True);    Message.Result := BE_ID;    Handled := True;  end  else  begin    Handled := False;    FOldWinProc(TMessage(Message));  end;end;procedure TAQSkinScrollBar.CMMouseEnter(var Msg: TMessage);begin  FOldWinProc(TMessage(Msg));  SMouseInControl := True;  PaintScroll;  Handled := True;end;procedure TAQSkinScrollBar.CMMouseLeave(var Msg: TMessage);begin  FOldWinProc(TMessage(Msg));  SMouseInControl := False;  PaintScroll;  Handled := True;end;procedure TAQSkinScrollBar.CMSENCPaint(var Message: TMessage);begin  FOldWinProc(TMessage(Message));  if (Message.wParam <> 0) then  begin    DrawBorder(Message.wParam, True);    if HScrollWnd <> nil then      HScrollWnd.PaintTo(Message.wParam,        HScrollWnd.Left - Control.Left, HScrollWnd.Top - Control.Top);    if VScrollWnd <> nil then      VScrollWnd.PaintTo(Message.wParam,        VScrollWnd.Left - Control.Left, VScrollWnd.Top - Control.Top);  end;end;procedure TAQSkinScrollBar.CMVisibleChanged(var Msg: TMessage);begin  if (Control <> nil) and (Control.Visible) then    ShowWindow(VScrollWnd.Handle, SW_SHOW);  if (Control <> nil) and (not Control.Visible) then    ShowWindow(VScrollWnd.Handle, SW_HIDE);  if (Control <> nil) and (Control.Visible) then    ShowWindow(HScrollWnd.Handle, SW_SHOW);  if (Control <> nil) and (not Control.Visible) then    ShowWindow(HScrollWnd.Handle, SW_HIDE);end;constructor TAQSkinScrollBar.Create;begin  FControl := nil;  FHandle := 0;  FOldWinProc := nil;  with FVScrollCtrl do  begin    skinrect := Rect(225, 25, 240, 89);    LTPoint := point(7, 14);    RTPoint := point(0, 0);    LBPoint := point(8, 50);    RBPoint := point(0, 0);    ClRect := Rect(0, 15, 15, 49);    LeftStretch := False;    topstretch := False;    rightstretch := False;    bottomstretch := False;    stretcheffect := False;    stretchtype := stfull;    trackarea := Rect(0, 13, 15, 51);    upbuttonrect := Rect(0, 51, 15, 64);    activeupbuttonrect := Rect(241, 36, 256, 49);    downupbuttonrect := Rect(0, 0, 0, 0);    downbuttonrect := Rect(0, 0, 15, 13);    activedownbuttonrect := Rect(241, 25, 256, 38);    downdownbuttonrect := Rect(0, 0, 0, 0);    thumbrect := Rect(245, 2, 255, 16);    activethumbrect := Rect(228, 2, 238, 16);    downthumbrect := Rect(0, 0, 0, 0);    thumboffset1 := 5;    thumboffset2 := 5;    thumbtransparent := False;    thumbtransparentcolor := 0;    thumbstretcheffect := False;    thumbminsize := 10;    thumbminpagesize := 14;    glyphrect := Rect(0, 0, 0, 0);    activeglyphrect := Rect(0, 0, 0, 0);    downglyphrect := Rect(0, 0, 0, 0);    glyphtransparent := False;    glyphtransparentcolor := 0;  end;  with FHScrollCtrl do  begin    skinrect := Rect(153, 132, 217, 147);    LTPoint := point(14, 5);    RTPoint := point(49, 7);    LBPoint := point(0, 0);    RBPoint := point(0, 0);    ClRect := Rect(16, 1, 48, 14);    LeftStretch := False;    topstretch := False;    rightstretch := False;    bottomstretch := False;    stretcheffect := False;    stretchtype := stfull;    trackarea := Rect(14, 0, 50, 15);    upbuttonrect := Rect(51, 0, 64, 15);    activeupbuttonrect := Rect(164, 148, 177, 163);    downupbuttonrect := Rect(0, 0, 0, 0);    downbuttonrect := Rect(0, 0, 13, 15);    activedownbuttonrect := Rect(153, 148, 166, 163);    downdownbuttonrect := Rect(0, 0, 0, 0);    thumbrect := Rect(133, 151, 147, 161);    activethumbrect := Rect(133, 134, 147, 144);    downthumbrect := Rect(0, 0, 0, 0);    thumboffset1 := 4;    thumboffset2 := 4;    thumbtransparent := False;    thumbtransparentcolor := 0;    thumbstretcheffect := False;    thumbminsize := 10;    thumbminpagesize := 14;    glyphrect := Rect(0, 0, 0, 0);    activeglyphrect := Rect(0, 0, 0, 0);    downglyphrect := Rect(0, 0, 0, 0);    glyphtransparent := False;    glyphtransparentcolor := 0;  end;  FBtnFace := 15852243;  FBmp_Border := TBitmap.Create;  FBmp_Border.LoadFromResourceName(HInstance, memo_skinrect);  FBmp_skinrect_V := TBitmap.Create;  FBmp_activeupbuttonrect_V := TBitmap.Create;  FBmp_activedownbuttonrect_V := TBitmap.Create;  FBmp_thumbrect_V := TBitmap.Create;  FBmp_activethumbrect_V := TBitmap.Create;  FBmp_skinrect_V.LoadFromResourceName(HInstance, v_skinrect);  FBmp_activeupbuttonrect_V.LoadFromResourceName(HInstance, v_activeupbuttonrect);  FBmp_activedownbuttonrect_V.LoadFromResourceName(HInstance, v_activedownbuttonrect);  FBmp_thumbrect_V.LoadFromResourceName(HInstance, v_thumbrect);  FBmp_activethumbrect_V.LoadFromResourceName(HInstance, v_activethumbrect);  FBmp_skinrect_H := TBitmap.Create;  FBmp_activeupbuttonrect_H := TBitmap.Create;  FBmp_activedownbuttonrect_H := TBitmap.Create;  FBmp_thumbrect_H := TBitmap.Create;  FBmp_activethumbrect_H := TBitmap.Create;  FBmp_skinrect_H.LoadFromResourceName(HInstance, h_skinrect);  FBmp_activeupbuttonrect_H.LoadFromResourceName(HInstance, h_activeupbuttonrect);  FBmp_activedownbuttonrect_H.LoadFromResourceName(HInstance, h_activedownbuttonrect);  FBmp_thumbrect_H.LoadFromResourceName(HInstance, h_thumbrect);  FBmp_activethumbrect_H.LoadFromResourceName(HInstance, h_activethumbrect);end;destructor TAQSkinScrollBar.Destroy;begin  if (FControl <> nil) and (@FOldWinProc <> nil) then FControl.WindowProc := FOldWinProc;  if VScrollWnd <> nil then  begin    TWinScroll(VScrollWnd).FSubclass := nil;    FreeAndNil(VScrollWnd);  end;  if HScrollWnd <> nil then  begin    TWinScroll(HScrollWnd).FSubclass := nil;    FreeAndNil(HScrollWnd);  end;  FBmp_skinrect_V.Free;  FBmp_activeupbuttonrect_V.Free;  FBmp_activedownbuttonrect_V.Free;  FBmp_thumbrect_V.Free;  FBmp_activethumbrect_V.Free;  FBmp_skinrect_H.Free;  FBmp_activeupbuttonrect_H.Free;  FBmp_activedownbuttonrect_H.Free;  FBmp_thumbrect_H.Free;  FBmp_activethumbrect_H.Free;  FBmp_Border.Free;  inherited;end;procedure TAQSkinScrollBar.DrawBorder(ADC: HDC; AUseExternalDC: Boolean);var  R: TRect;  Canvas: TCanvas;  P: TPoint;begin  if Handle = 0 then Exit;  Canvas := TCanvas.Create;  if not AUseExternalDC    then Canvas.Handle := GetWindowDC(Handle)  else Canvas.Handle := ADC;  P := Point(0, 0);  Windows.ClientToScreen(Handle, P);  Windows.GetWindowRect(Handle, R);  P.X := P.X - R.Left;  P.Y := P.Y - R.Top;  Windows.GetClientRect(Handle, R);  ExcludeClipRect(Canvas.Handle, P.X, P.Y, R.Right - R.Left + P.X, R.Bottom - R.Top + P.Y);  Windows.GetWindowRect(Handle, R);  OffsetRect(R, -R.Left, -R.Top);  PaintBorder(Canvas, R);  SelectClipRgn(Canvas.Handle, 0);  if not AUseExternalDC then ReleaseDC(Handle, Canvas.Handle);  Canvas.Handle := 0;  Canvas.Free;end;procedure TAQSkinScrollBar.DrawButton(Cnvs: TCanvas; i: Integer);const  SP_XP_BTNFRAMECOLOR = 8388608;  SP_XP_BTNACTIVECOLOR = 13811126;  SP_XP_BTNDOWNCOLOR = 11899781;var  R1, R2: TRect;  C: TColor;  ThumbB: TBitMap;  B1: TBitMap;  kf: Double;  FPageSize: Integer;  SkinCtrl: TAQSkinScrollBarControl;  TrackR, R: TRect;  B: TBitmap;  x, ResizeMode: Integer;  NewLTPoint, NewRTPoint, NewLBPoint, NewRBPoint: TPoint;  NewClRect: TRect;  MinW, MinH: Integer;  GlyphB: TBitMap;  //==============================================  Bmp_skinrect_V: TBitmap;  Bmp_activeupbuttonrect_V: TBitmap;  Bmp_activedownbuttonrect_V: TBitmap;  Bmp_thumbrect_V: TBitmap;  Bmp_activethumbrect_V: TBitmap;  Bmp_r1: TBitmap;  Bmp_skinrect_H: TBitmap;  Bmp_activeupbuttonrect_H: TBitmap;  Bmp_activedownbuttonrect_H: TBitmap;  Bmp_thumbrect_H: TBitmap;  Bmp_activethumbrect_H: TBitmap;begin  Bmp_skinrect_V := FBmp_skinrect_V;  Bmp_activeupbuttonrect_V := FBmp_activeupbuttonrect_V;  Bmp_activedownbuttonrect_V := FBmp_activedownbuttonrect_V;  Bmp_thumbrect_V := FBmp_thumbrect_V;  Bmp_activethumbrect_V := FBmp_activethumbrect_V;  Bmp_skinrect_H := FBmp_skinrect_H;  Bmp_activeupbuttonrect_H := FBmp_activeupbuttonrect_H;  Bmp_activedownbuttonrect_H := FBmp_activedownbuttonrect_H;  Bmp_thumbrect_H := FBmp_thumbrect_H;  Bmp_activethumbrect_H := FBmp_activethumbrect_H;  if FKind = sbVertical then  begin    SkinCtrl := FVScrollCtrl;    with SkinCtrl do    begin      SkinRect := Rect(0, 0, Bmp_skinrect_V.Width, Bmp_skinrect_V.Height);      ActiveUpButtonRect := Rect(0, 0, Bmp_activeupbuttonrect_V.Width, Bmp_activeupbuttonrect_V.Height);      ActiveDownButtonRect := Rect(0, 0, Bmp_activedownbuttonrect_V.Width, Bmp_activedownbuttonrect_V.Height);      ThumbRect := Rect(0, 0, Bmp_thumbrect_V.Width, Bmp_thumbrect_V.Height);      ActiveThumbRect := Rect(0, 0, Bmp_activethumbrect_V.Width, Bmp_activethumbrect_V.Height);    end;  end  else  begin    SkinCtrl := FHScrollCtrl;    with SkinCtrl do    begin      SkinRect := Rect(0, 0, Bmp_skinrect_H.Width, Bmp_skinrect_H.Height);      ActiveUpButtonRect := Rect(0, 0, Bmp_activeupbuttonrect_H.Width, Bmp_activeupbuttonrect_H.Height);      ActiveDownButtonRect := Rect(0, 0, Bmp_activedownbuttonrect_H.Width, Bmp_activedownbuttonrect_H.Height);      ThumbRect := Rect(0, 0, Bmp_thumbrect_H.Width, Bmp_thumbrect_H.Height);      ActiveThumbRect := Rect(0, 0, Bmp_activethumbrect_H.Width, Bmp_activethumbrect_H.Height);    end;  end;  FPageSize := 20;  { Offset }  if FKind = sbVertical then  begin    R := VTrackRect;    if RectWidth(SkinCtrl.SkinRect) < RectWidth(R) then      MoveWindowOrg(Cnvs.Handle, RectWidth(R) - RectWidth(SkinCtrl.SkinRect), 0);  end  else  begin    R := HTrackRect;    if RectHeight(SkinCtrl.SkinRect) < RectHeight(R) then      MoveWindowOrg(Cnvs.Handle, 0, RectHeight(R) - RectHeight(SkinCtrl.SkinRect));  end;  if I = CLIENT then  begin    if FKind = sbVertical then      R := VScrollRect    else      R := HScrollRect;    with SkinCtrl do    begin      if IsNullRect(SkinRect) then        ResizeMode := -1      else if (RBPoint.X <> 0) and (RBPoint.Y <> 0) then        ResizeMode := 1      else if (RTPoint.X <> 0) or (RTPoint.Y <> 0) then        ResizeMode := 2      else if (LBPoint.X <> 0) or (LBPoint.Y <> 0) then        ResizeMode := 3      else        ResizeMode := 0;      if RectWidth(R) * RectHEight(R) > 0 then      begin        B := TBitmap.Create;        B.Width := RectWidth(R);        B.Height := RectHeight(R);        R1 := SkinRect;        if FKind = sbVertical then          Bmp_r1 := Bmp_skinrect_V        else          Bmp_r1 := Bmp_skinrect_H;        case ResizeMode of          0:            begin              B.Canvas.CopyRect(Rect(0, 0, B.Width, B.Height), Bmp_r1.Canvas, R1);            end;          1: CreateSkinImage(LTPoint, RTPoint, LBPoint, RBPoint, CLRect,              NewLtPoint, NewRTPoint, NewLBPoint, NewRBPoint, NewCLRect,              B, Bmp_r1, R1, B.Width, B.Height, True,              LeftStretch, TopStretch, RightStretch, BottomStretch,              StretchEffect, StretchType);          2: CreateHSkinImage(LTPoint.X, RectWidth(SkinRect) - RTPoint.X,              B, Bmp_r1, R1, B.Width, B.Height, StretchEffect);          3: CreateVSkinImage(LTPoint.Y, RectHeight(SkinRect) - LBPoint.Y,              B, Bmp_r1, R1, B.Width, B.Height, StretchEffect);        end;        Cnvs.Draw(R.Left, R.Top, B);        B.Free;      end;    end; //end for "with SkinCtrl do"  end; //end for "if I = CLIENT then"  if I = THUMB then  begin    if FKind = sbVertical then    begin      if RectHeight(VTrackRect) = 0 then Exit;      R := VSliderRect;      if (VSliderState = bsasbPressed) and (not IsNullRect(SkinCtrl.DownThumbRect)) then      begin        R1 := SkinCtrl.DownThumbRect;        Bmp_r1 := Bmp_skinrect_V; //Add      end      else if (VSliderState = bsasbHot) and sMouseInControl and (not IsNullRect(SkinCtrl.ActiveThumbRect)) then      begin        R1 := SkinCtrl.ActiveThumbRect;        Bmp_r1 := Bmp_activethumbrect_V; //Add      end      else      begin        R1 := SkinCtrl.ThumbRect;        Bmp_r1 := Bmp_thumbrect_V; //Add      end;      TrackR := SkinCtrl.TrackArea;      TrackR.Bottom := RectHeight(VScrollRect) - (RectHeight(SkinCtrl.SkinRect) - SkinCtrl.TrackArea.Bottom);      OffsetRect(TrackR, VScrollRect.Left, VScrollRect.Top);      R.Left := R.Left + SkinCtrl.TrackArea.Left + ((RectWidth(SkinCtrl.TrackArea) - RectWidth(SkinCtrl.ThumbRect)) div 2);      R.Top := TrackR.Top + Round(((R.Top - VTrackRect.Top) / RectHeight(VTrackRect)) * RectHeight(TrackR)) + 1;      R.Bottom := TrackR.Top + Round(((R.Bottom - VTrackRect.Top) / RectHeight(VTrackRect)) * RectHeight(TrackR)) + 1;      MinH := RectHeight(SkinCtrl.ThumbRect);      if SkinCtrl.ThumbMinSize > 0 then MinH := SkinCtrl.ThumbMinSize;      if RectHeight(R) < MinH then      begin        X := ((R.Top + R.Bottom) div 2);        R.Top := X - (MinH div 2);        R.Bottom := X + (MinH div 2);        if R.Bottom > VScrollRect.Bottom - (MinH - SkinCtrl.TrackArea.Bottom) then        begin          R.Bottom := VScrollRect.Bottom - (MinH - SkinCtrl.TrackArea.Bottom);          R.Top := R.Bottom - MinH;        end;        if R.Top < VScrollRect.Top + SkinCtrl.TrackArea.Top then        begin          R.Top := VScrollRect.Top + SkinCtrl.TrackArea.Top;          R.Bottom := R.Top + MinH;        end;      end;    end //end for "if FKind = sbVertical then"    else    begin      R := HSliderRect;      if RectWidth(HTrackRect) = 0 then Exit;      if (HSliderState = bsasbPressed) and (not IsNullRect(SkinCtrl.DownThumbRect)) then      begin        R1 := SkinCtrl.DownThumbRect;        Bmp_r1 := Bmp_skinrect_H; //Add      end      else if (HSliderState = bsasbHot) and sMouseInControl and (not IsNullRect(SkinCtrl.ActiveThumbRect)) then      begin        R1 := SkinCtrl.ActiveThumbRect;        Bmp_r1 := Bmp_activethumbrect_H; //Add      end      else      begin        R1 := SkinCtrl.ThumbRect;        Bmp_r1 := Bmp_thumbrect_H; //Add      end;      TrackR := SkinCtrl.TrackArea;      TrackR.Right := RectWidth(HScrollRect) - (RectWidth(SkinCtrl.SkinRect) - SkinCtrl.TrackArea.Right);      OffsetRect(TrackR, HScrollRect.Left, HScrollRect.Top);      R.Top := R.Top + SkinCtrl.TrackArea.Top + ((RectHeight(SkinCtrl.TrackArea) - RectHeight(SkinCtrl.ThumbRect)) div 2);      R.Left := TrackR.Left + Round(((R.Left - HTrackRect.Left) / RectWidth(HTrackRect)) * RectWidth(TrackR)) + 1;      R.Right := TrackR.Left + Round(((R.Right - HTrackRect.Left) / RectWidth(HTrackRect)) * RectWidth(TrackR)) + 1;      MinW := RectWidth(SkinCtrl.ThumbRect);      if SkinCtrl.ThumbMinSize > 0 then MinW := SkinCtrl.ThumbMinSize;      if RectWidth(R) < MinW then      begin        X := ((R.Left + R.Right) div 2);        R.Left := X - (MinW div 2);        R.Right := X + (MinW div 2);        if R.Right > HScrollRect.Right - (MinW - SkinCtrl.TrackArea.Right) then        begin          R.Right := HScrollRect.Right - (MinW - SkinCtrl.TrackArea.Right);          R.Left := R.Right - MinW;        end;        if R.Left < HScrollRect.Left + SkinCtrl.TrackArea.Left then        begin          R.Left := HScrollRect.Left + SkinCtrl.TrackArea.Left;          R.Right := R.Left + MinW;        end;      end;    end;    if RectHeight(R) * RectWidth(R) > 0 then    begin      ThumbB := TBitMap.Create;      ThumbB.Width := RectWidth(R);      ThumbB.Height := RectHeight(R);      if FPageSize = 0 then        ThumbB.Canvas.CopyRect(Rect(0, 0, ThumbB.Width, ThumbB.Height), Bmp_r1.Canvas, R1)      else        case FKind of          sbHorizontal:            CreateHSkinImage(SkinCtrl.ThumbOffset1, SkinCtrl.ThumbOffset2, ThumbB, Bmp_r1, R1,              ThumbB.Width, ThumbB.Height, SkinCtrl.ThumbStretchEffect);          sbVertical:            CreateVSkinImage(SkinCtrl.ThumbOffset1, SkinCtrl.ThumbOffset2, ThumbB, Bmp_r1, R1,              ThumbB.Width, ThumbB.Height, SkinCtrl.ThumbStretchEffect);        end;      // draw glyph      if FKind = sbVertical then      begin        if (VSliderState = bsasbPressed) and sMouseInControl and (not IsNullRect(SkinCtrl.DownGlyphRect)) then        begin          R1 := SkinCtrl.DownGlyphRect;          Bmp_r1 := Bmp_skinrect_V; //Add        end        else if (VSliderState = bsasbHot) and sMouseInControl and (not IsNullRect(SkinCtrl.ActiveGlyphRect)) then        begin          R1 := SkinCtrl.ActiveGlyphRect;          Bmp_r1 := Bmp_skinrect_V; //Add        end        else        begin          R1 := SkinCtrl.GlyphRect;          Bmp_r1 := Bmp_skinrect_V; //Add        end;      end      else      begin        if (HSliderState = bsasbPressed) and sMouseInControl and (not IsNullRect(SkinCtrl.DownGlyphRect)) then        begin          R1 := SkinCtrl.DownGlyphRect;          Bmp_r1 := Bmp_skinrect_H; //Add        end        else          if (HSliderState = bsasbHot) and sMouseInControl and (not IsNullRect(SkinCtrl.ActiveGlyphRect)) then          begin            R1 := SkinCtrl.ActiveGlyphRect;            Bmp_r1 := Bmp_skinrect_H; //Add          end          else          begin            R1 := SkinCtrl.GlyphRect;            Bmp_r1 := Bmp_skinrect_H; //Add          end;      end;      if not IsNullRect(R1) then      begin        R2 := Rect(ThumbB.Width div 2 - RectWidth(R1) div 2,          ThumbB.Height div 2 - RectHeight(R1) div 2,          ThumbB.Width div 2 - RectWidth(R1) div 2 + RectWidth(R1),          ThumbB.Height div 2 - RectHeight(R1) div 2 + RectHeight(R1));        if SkinCtrl.GlyphTransparent then        begin          GlyphB := TBitMap.Create;          GlyphB.Width := RectWidth(R1);          GlyphB.Height := RectHeight(R1);          GlyphB.Canvas.CopyRect(Rect(0, 0, GlyphB.Width, GlyphB.Height),            Bmp_r1.Canvas, R1);          GlyphB.Transparent := True;          GlyphB.TransparentMode := tmFixed;          GlyphB.TransparentColor := SkinCtrl.GlyphTransparentColor;          ThumbB.Canvas.Draw(R2.Left, R2.Top, GlyphB);          GlyphB.Free;        end        else          ThumbB.Canvas.CopyRect(R2, Bmp_r1.Canvas, R1);      end;      //      if SkinCtrl.ThumbTransparent then      begin        ThumbB.Transparent := True;        ThumbB.TransparentMode := tmFixed;        ThumbB.TransparentColor := SkinCtrl.ThumbTransparentColor;      end;      Cnvs.Draw(R.Left, R.Top, ThumbB);      ThumbB.Free;    end;  end  else  begin    R1 := NullRect;    if FKind = sbVertical then      Bmp_r1 := Bmp_skinrect_V //Add    else      Bmp_r1 := Bmp_skinrect_H; //Add    if FKind = sbVertical then    begin      case I of        UPBUTTON:          begin            if (VUpState = bsasbPressed) and sMouseInControl then            begin              R1 := SkinCtrl.DownUpButtonRect;              Bmp_r1 := Bmp_skinrect_V; //Add              if IsNullRect(R1) then              begin                R1 := SkinCtrl.ActiveUpButtonRect;                Bmp_r1 := Bmp_activeupbuttonrect_V; //Add              end;            end            else              if (VUpState = bsasbHot) and sMouseInControl and (not IsNullRect(SkinCtrl.ActiveUpButtonRect)) then              begin                R1 := SkinCtrl.ActiveUpButtonRect;                Bmp_r1 := Bmp_activeupbuttonrect_V; //Add              end              else              begin                R1 := SkinCtrl.UpButtonRect;                Bmp_r1 := Bmp_skinrect_V; //Add                OffsetRect(R1, SkinCtrl.SkinRect.Left, SkinCtrl.SkinRect.Top);              end;            R := VDownButtonRect;            OffsetRect(R, SkinCtrl.UpButtonRect.Left, RectHeight(R) - (RectHeight(SkinCtrl.SkinRect) - SkinCtrl.UpButtonRect.Top));          end;        DOWNBUTTON:          begin            if (VDownState = bsasbPressed) and sMouseInControl then            begin              R1 := SkinCtrl.DownDownButtonRect;              Bmp_r1 := Bmp_skinrect_V; //Add              if IsNullRect(R1) then              begin                R1 := SkinCtrl.ActiveDownButtonRect;                Bmp_r1 := Bmp_activedownbuttonrect_V; //Add              end;            end            else if (VDownState = bsasbHot) and sMouseInControl and (not IsNullRect(SkinCtrl.ActiveUpButtonRect)) then            begin              R1 := SkinCtrl.ActiveDownButtonRect;              Bmp_r1 := Bmp_activedownbuttonrect_V; //Add            end            else            begin              R1 := SkinCtrl.DownButtonRect;              Bmp_r1 := Bmp_skinrect_V; //Add              OffsetRect(R1, SkinCtrl.SkinRect.Left, SkinCtrl.SkinRect.Top);            end;            R := VUpButtonRect;            OffsetRect(R, SkinCtrl.DownButtonRect.Left, SkinCtrl.DownButtonRect.Top);          end      end;    end    else    begin      case I of        UPBUTTON:          begin            if (HUpState = bsasbPressed) and sMouseInControl then            begin              R1 := SkinCtrl.DownUpButtonRect;              Bmp_r1 := Bmp_skinrect_H; //Add              if IsNullRect(R1) then              begin                R1 := SkinCtrl.ActiveUpButtonRect;                Bmp_r1 := Bmp_activeupbuttonrect_H; //Add              end;            end            else              if (HUpState = bsasbHot) and sMouseInControl and (not IsNullRect(SkinCtrl.ActiveUpButtonRect)) then              begin                R1 := SkinCtrl.ActiveUpButtonRect;                Bmp_r1 := Bmp_activeupbuttonrect_H; //Add              end              else              begin                R1 := SkinCtrl.UpButtonRect;                Bmp_r1 := Bmp_skinrect_H; //Add                OffsetRect(R1, SkinCtrl.SkinRect.Left, SkinCtrl.SkinRect.Top);              end;            R := HDownButtonRect;            OffsetRect(R, RectWidth(R) - (RectWidth(SkinCtrl.SkinRect) - SkinCtrl.UpButtonRect.Left), SkinCtrl.UpButtonRect.Top);          end;        DOWNBUTTON:          begin            if (HDownState = bsasbPressed) and sMouseInControl then            begin              R1 := SkinCtrl.DownDownButtonRect;              Bmp_r1 := Bmp_skinrect_H; //Add              if IsNullRect(R1) then              begin                R1 := SkinCtrl.ActiveDownButtonRect;                Bmp_r1 := Bmp_activedownbuttonrect_H; //Add              end;            end            else              if (HDownState = bsasbHot) and sMouseInControl and (not IsNullRect(SkinCtrl.ActiveUpButtonRect)) then              begin                R1 := SkinCtrl.ActiveDownButtonRect;                Bmp_r1 := Bmp_activedownbuttonrect_H; //Add              end              else              begin                R1 := SkinCtrl.DownButtonRect;                Bmp_r1 := Bmp_skinrect_H; //Add                OffsetRect(R1, SkinCtrl.SkinRect.Left, SkinCtrl.SkinRect.Top);              end;            R := HUpButtonRect;            OffsetRect(R, SkinCtrl.DownButtonRect.Left, SkinCtrl.DownButtonRect.Top);          end      end;    end;    if not IsNullRect(R1) then      BitBlt(Cnvs.Handle, R.Left, R.Top, RectWidth(R1), RectHeight(R1), Bmp_r1.Canvas.Handle,        R1.Left, R1.Top, SRCCOPY);  end;  { Restore Offset }  if FKind = sbVertical then  begin    R := VTrackRect;    if RectWidth(SkinCtrl.SkinRect) < RectWidth(R) then      MoveWindowOrg(Cnvs.Handle, -(RectWidth(R) - RectWidth(SkinCtrl.SkinRect)), 0);  end  else  begin    R := HTrackRect;    if RectHeight(SkinCtrl.SkinRect) < RectHeight(R) then      MoveWindowOrg(Cnvs.Handle, 0, -(RectHeight(R) - RectHeight(SkinCtrl.SkinRect)));  end;end;procedure TAQSkinScrollBar.EMLINEINDEX(var Msg: TMessage);begin  FOldWinProc(TMessage(Msg));  PaintScroll;end;function TAQSkinScrollBar.GetBorderTopLeft: TPoint;var  PWnd: HWnd;  CP, PP: TPoint;begin  Result := Point(0, 0);  PWnd := GetParent(Handle);  CP := Point(0, 0);  ClientToScreen(Handle, CP);  with GetBoundsRect do    PP := Point(Left, Top);  ClientToScreen(PWnd, PP);  Result := Point(CP.X - PP.X, CP.Y - PP.Y);end;function TAQSkinScrollBar.GetBoundsRect: TRect;begin  if (Control <> nil) and (Control is TGraphicControl) and    (Control.Parent = nil) then  begin    Result := Rect(0, 0, 0, 0);    Exit;  end;  if FControl <> nil then    Result := Rect(FControl.Left, FControl.Top, FControl.Left + FControl.Width, FControl.Top + FControl.Height)  else    if FHandle <> 0 then      Windows.GetWindowRect(Handle, Result)    else      Result := Rect(0, 0, 0, 0);end;function TAQSkinScrollBar.GetEnabled: Boolean;begin  if FControl <> nil then    Result := FControl.Enabled  else    Result := True;end;function TAQSkinScrollBar.GetHeight: Integer;var  R: TRect;begin  if (Control <> nil) and (Control is TGraphicControl) and    (Control.Parent = nil) then  begin    Result := 0;    Exit;  end;  if FControl <> nil then    Result := FControl.Height  else    if FHandle <> 0 then    begin      Windows.GetClientRect(Handle, R);      Result := R.Bottom;    end    else      Result := 0;end;function TAQSkinScrollBar.GetWidth: Integer;var  R: TRect;begin  if (Control <> nil) and (Control is TGraphicControl) and    (Control.Parent = nil) then  begin    Result := 0;    Exit;  end;  if FControl <> nil then    Result := FControl.Width  else    if FHandle <> 0 then    begin      Windows.GetClientRect(Handle, R);      Result := R.Right;    end    else      Result := 0;end;function TAQSkinScrollBar.HaveBorder: Boolean;var  S, ExS: Cardinal;begin  S := GetWindowLong(Handle, GWL_STYLE);  ExS := GetWindowLong(Handle, GWL_EXSTYLE);  if S and WS_BORDER = WS_BORDER then    Result := True  else    Result := False;  if ExS and WS_EX_CLIENTEDGE = WS_EX_CLIENTEDGE then    Result := True  else    Result := False;end;function TAQSkinScrollBar.HDownButtonRect: TRect;begin  Result := HScrollRect;  if RectHeight(Result) > 0 then  begin    Result.Left := Result.Right - RectHeight(Result);  end  else    Result := Rect(0, 0, 0, 0);end;procedure TAQSkinScrollBar.HDrawScroll(DC: HDC);var  //  R: TRect;  Canvas: TCanvas;  //  P: TPoint;  i: Integer;  //  X, Y: Integer;begin  if Handle = 0 then Exit;  if DC = 0 then Exit;  Canvas := TCanvas.Create;  Canvas.Handle := DC;  { Fill back }  Canvas.Brush.Color := FBtnFace;  Canvas.FillRect(Rect(0, 0, Width, Height));  { Draw Hscroll }  if RectHeight(HScrollRect) > 0 then  begin    FKind := sbHorizontal;    DrawButton(Canvas, CLIENT);    for i := 1 to BUTCOUNT - 1 do      DrawButton(Canvas, i);    if not HScrollDisabled then      DrawButton(Canvas, THUMB);  end;  Canvas.Handle := 0;  Canvas.Free;end;function TAQSkinScrollBar.HScrollDisabled: Boolean;var  //  P: TPoint;  BarInfo: TScrollBarInfo;begin  BarInfo.cbSize := SizeOf(BarInfo);  GetScrollBarInfo(Handle, integer(OBJID_HSCROLL), BarInfo);  if STATE_SYSTEM_UNAVAILABLE and BarInfo.rgstate[0] = STATE_SYSTEM_UNAVAILABLE then    Result := True  else    Result := False;end;function TAQSkinScrollBar.HScrollRect: TRect;var  P: TPoint;  BarInfo: TScrollBarInfo;begin  BarInfo.cbSize := SizeOf(BarInfo);  GetScrollBarInfo(Handle, integer(OBJID_HSCROLL), BarInfo);  if STATE_SYSTEM_INVISIBLE and BarInfo.rgstate[0] <> 0 then    Result := Rect(0, 0, 0, 0)  else  begin    P := BarInfo.rcScrollBar.TopLeft;    Windows.ScreenToClient(Handle, P);    Result.TopLeft := P;    P := BarInfo.rcScrollBar.BottomRight;    Windows.ScreenToClient(Handle, P);    Result.BottomRight := P;    with GetBorderTopLeft do      OffsetRect(Result, X, Y);  end;end;function TAQSkinScrollBar.HSliderRect: TRect;var  Offset: Integer;  P: TPoint;  BarInfo: TScrollBarInfo;begin  BarInfo.cbSize := SizeOf(BarInfo);  GetScrollBarInfo(Handle, integer(OBJID_HSCROLL), BarInfo);  if STATE_SYSTEM_INVISIBLE and BarInfo.rgstate[0] <> 0 then    Result := Rect(0, 0, 0, 0)  else  begin    P := BarInfo.rcScrollBar.TopLeft;    Windows.ScreenToClient(Handle, P);    Result.TopLeft := P;    P := BarInfo.rcScrollBar.BottomRight;    Windows.ScreenToClient(Handle, P);    Result.BottomRight := P;    with GetBorderTopLeft do      OffsetRect(Result, X, Y);    Offset := Result.Left;    Result.Left := Offset + BarInfo.xyThumbTop - 1;    Result.Right := Offset + BarInfo.xyThumbBottom - 1;  end;end;function TAQSkinScrollBar.HTrackRect: TRect;begin  Result := HScrollRect;  if RectWidth(Result) > 0 then  begin    Result.Left := Result.Left + RectHeight(Result);    Result.Right := Result.Right - RectHeight(Result);  end  else    Result := Rect(0, 0, 0, 0);end;function TAQSkinScrollBar.HUpButtonRect: TRect;begin  Result := HScrollRect;  if RectHeight(Result) > 0 then  begin    Result.Right := Result.Left + RectHeight(Result);  end  else    Result := Rect(0, 0, 0, 0);end;function TAQSkinScrollBar.IsPopupWindow: Boolean;begin  Result := (GetWindowLong(Handle, GWL_EXSTYLE) and WS_EX_TOOLWINDOW = WS_EX_TOOLWINDOW) or    (GetWindowLong(Handle, GWL_STYLE) and WS_POPUP = WS_POPUP);end;procedure TAQSkinScrollBar.NewWindowProc(var Message: TMessage);const  WM_VTChangeState = WM_APP + 32;begin  case Message.Msg of    CM_BENCPAINT: CMBENCPaint(Message);    CM_SENCPAINT: CMSENCPaint(Message);    WM_LBUTTONDOWN: WMLButtonDown(TWMMouse(Message));    WM_LBUTTONUP: WMLButtonUp(TWMMouse(Message));    WM_NCLBUTTONDBLCLK: WMNCLButtonDblClk(TWMMouse(Message));    WM_NCLBUTTONDOWN: WMNCLButtonDown(TWMMouse(Message));    WM_NCMOUSEMOVE: WMNCMouseMove(TWMNCHitMessage(Message));    WM_NCLBUTTONUP: WMNCLButtonUp(TWMMouse(Message));    WM_MOUSEMOVE: WMMouseMove(TWMMouse(Message));    WM_NCPAINT: WMNCPaint(TWMNCPaint(Message));    WM_ERASEBKGND: WMEraseBkgnd(message);    WM_MOUSEWHEEL: WMMouseWheel(message);    WM_VSCROLL: WMVScroll(message);    WM_HSCROLL: WMHScroll(message);    WM_SIZE: WMSize(message);    WM_KEYDOWN: WMKeyDown(message);    WM_CAPTURECHANGED: WMCAPTURECHANGED(message);    WM_VTChangeState: WMVTChangeState(message);    CM_VISIBLECHANGED: CMVisibleChanged(message);    CM_MOUSEENTER: CMMouseEnter(message);    CM_MOUSELEAVE: CMMouseLeave(message);    EM_LINEINDEX: EMLINEINDEX(message);    WM_WINDOWPOSCHANGING: WMWindowPosChanging(TWMWindowPosChanged(Message));    WM_WINDOWPOSCHANGED: WMWindowPosChanged(TWMWindowPosChanged(Message));    WM_UNDO, WM_CUT, WM_PASTE, WM_CLEAR, EM_REPLACESEL: OnContextPopupAction(Message);  else    FOldWinProc(Message);  end;end;procedure TAQSkinScrollBar.OnContextPopupAction(var Message: TMessage);begin  FOldWinProc(Message);  PaintScroll;end;procedure TAQSkinScrollBar.Paint(Canvas: TCanvas);beginend;procedure TAQSkinScrollBar.PaintBorder(Canvas: TCanvas; R: TRect);var //这些是叼毛  LTPoint, RTPoint, LBPoint, RBPoint: TPoint;  SkinRect, ClRect: TRect;  LeftStretch, TopStretch, RightStretch, BottomStretch: Boolean;var  //  R1, R2: TRect;  Picture: TBitmap;  //  SkinCtrl: TDataSkinMemoControl;  //  FIndex: Integer;  NewClRect: TRect;  NewLTPoint, NewRTPoint, NewLBPoint, NewRBPoint: TPoint;  LeftB, TopB, RightB, BottomB: TBitMap;  OffX, OffY: Integer;  //  X, Y: Integer;var  GripSize: Integer;begin  LTPoint := Point(6, 5);  RTPoint := Point(52, 6);  LBPoint := Point(4, 46);  RBPoint := Point(53, 45);  SkinRect := rect(224, 347, 283, 399);  ClRect := rect(1, 1, 57, 51);  LeftStretch := False;  TopStretch := False;  RightStretch := False;  BottomStretch := False;  (*    LTPoint:=    RTPoint:=    LBPoint:=leftbottompoint=4,46  RBPoint:=rightbottompoint=53,45    skinrect=   clientrect=   leftstretch=0  topstretch=0  rightstretch=0  bottomstretch=0  *)  SkinRect := rect(0, 0, FBmp_Border.Width, FBmp_Border.Height);  Picture := FBmp_Border;  LeftB := TBitMap.Create;  TopB := TBitMap.Create;  RightB := TBitMap.Create;  BottomB := TBitMap.Create;  OffX := FControl.Width - RectWidth(SkinRect);  OffY := FControl.Height - RectHeight(SkinRect);  NewLTPoint := LTPoint;  NewRTPoint := Point(RTPoint.X + OffX, RTPoint.Y);  NewLBPoint := Point(LBPoint.X, LBPoint.Y + OffY);  NewRBPoint := Point(RBPoint.X + OffX, RBPoint.Y + OffY);  NewClRect := Rect(ClRect.Left, ClRect.Top,    ClRect.Right + OffX, ClRect.Bottom + OffY);  CreateSkinBorderImages(LTPoint, RTPoint, LBPoint, RBPoint, CLRect,    NewLtPoint, NewRTPoint, NewLBPoint, NewRBPoint, NewCLRect,    LeftB, TopB, RightB, BottomB, Picture, SkinRect, Width, Height,    LeftStretch, TopStretch, RightStretch, BottomStretch);  Canvas.Draw(0, 0, TopB);  Canvas.Draw(0, TopB.Height, LeftB);  Canvas.Draw(FControl.Width - RightB.Width, TopB.Height, RightB);  Canvas.Draw(0, FControl.Height - BottomB.Height, BottomB);  TopB.Free;  LeftB.Free;  RightB.Free;  BottomB.Free;  //===============================  Canvas.Brush.Color := FBtnFace;  GripSize := GetSystemMetrics(SM_CXVSCROLL);  if Self.HaveBorder then    Canvas.FillRect(Rect(Width - GripSize - 2, Height - GripSize - 2, Width - 2, Height - 2))  else    Canvas.FillRect(Rect(Width - GripSize, Height - GripSize, Width, Height));end;procedure TAQSkinScrollBar.PaintScroll;begin  { Paint scrollbars }  if VScrollWnd <> nil then  begin    VScrollWnd.Invalidate;  end;  if HScrollWnd <> nil then  begin    HScrollWnd.Invalidate;  end;end;procedure TAQSkinScrollBar.SetControl(Value: TControl);begin  if FControl <> nil then  begin    if @FOldWinProc <> nil then FControl.WindowProc := FOldWinProc;  end;  FControl := Value;  FOldWinProc := FControl.WindowProc;  FControl.WindowProc := NewWindowProc;  if (FControl is TWinControl) then    FHandle := TWinControl(FControl).Handle  else    FHandle := 0;  if VScrollWnd <> nil then FreeAndNil(VScrollWnd);  VScrollWnd := TWinScroll.CreateParented(Control.Parent.Handle);  VScrollWnd.DoubleBuffered := True;  TWinScroll(VScrollWnd).FSubclass := Self;  TWinScroll(VScrollWnd).FVertical := True;  with VScrollRect do    if IsPopupWindow      then      SetWindowPos(VScrollWnd.Handle, HWND_TOPMOST, Control.Left + Left, Control.Top + Top, Right - Left, Bottom - Top, SWP_NOREDRAW)    else      SetWindowPos(VScrollWnd.Handle, HWND_TOP, Control.Left + Left, Control.Top + Top, Right - Left, Bottom - Top, SWP_NOREDRAW);  if IsRectEmpty(VScrollRect) then    ShowWindow(VScrollWnd.Handle, SW_HIDE)  else    ShowWindow(VScrollWnd.Handle, SW_SHOW);  if HScrollWnd <> nil then FreeAndNil(HScrollWnd);  HScrollWnd := TWinScroll.CreateParented(Control.Parent.Handle);  HScrollWnd.DoubleBuffered := True;  TWinScroll(HScrollWnd).FSubclass := Self;  TWinScroll(HScrollWnd).FVertical := False;  with HScrollRect do    if IsPopupWindow      then      SetWindowPos(HScrollWnd.Handle, HWND_TOPMOST, Control.Left + Left, Control.Top + Top, Right - Left, Bottom - Top, SWP_NOREDRAW)    else      SetWindowPos(HScrollWnd.Handle, HWND_TOP, Control.Left + Left, Control.Top + Top, Right - Left, Bottom - Top, SWP_NOREDRAW);  if IsRectEmpty(HScrollRect) then    ShowWindow(HScrollWnd.Handle, SW_HIDE)  else    ShowWindow(HScrollWnd.Handle, SW_SHOW);end;procedure TAQSkinScrollBar.SetHandle(const Value: HWnd);beginend;procedure TAQSkinScrollBar.UpdateScroll;begin  { Paint scrollbars }  if (VScrollWnd <> nil) and (VScrollWnd.HandleAllocated) then  begin    with VScrollRect do      if IsPopupWindow then        SetWindowPos(VScrollWnd.Handle, HWND_TOPMOST,          Control.Left + Left, Control.Top + Top,          Right - Left, Bottom - Top, SWP_SHOWWINDOW)      else        SetWindowPos(VScrollWnd.Handle, HWND_TOP,          Control.Left + Left, Control.Top + Top,          Right - Left, Bottom - Top, SWP_SHOWWINDOW);  end;  if (HScrollWnd <> nil) and (HScrollWnd.HandleAllocated) then  begin    with HScrollRect do      if IsPopupWindow then        SetWindowPos(HScrollWnd.Handle, HWND_TOPMOST,          Control.Left + Left, Control.Top + Top,          Right - Left, Bottom - Top, SWP_SHOWWINDOW)      else        SetWindowPos(HScrollWnd.Handle, HWND_TOP,          Control.Left + Left, Control.Top + Top,          Right - Left, Bottom - Top, SWP_SHOWWINDOW);  end;  PaintScroll;end;function TAQSkinScrollBar.VDownButtonRect: TRect;begin  Result := VScrollRect;  if RectWidth(Result) > 0 then  begin    Result.Top := Result.Bottom - RectWidth(Result);  end  else    Result := Rect(0, 0, 0, 0);end;procedure TAQSkinScrollBar.VDrawScroll(DC: HDC);var  //  R: TRect;  Canvas: TCanvas;  //  P: TPoint;  i: Integer;  //  X, Y: Integer;begin  if Handle = 0 then Exit;  if DC = 0 then Exit;  Canvas := TCanvas.Create;  if DC <> 0 then    Canvas.Handle := DC;  begin    { Fill back }    Canvas.Brush.Color := FBtnFace;    Canvas.FillRect(Rect(0, 0, Width, Height));    { Draw Vscroll }    if RectWidth(VScrollRect) > 0 then    begin      FKind := sbVertical;      DrawButton(Canvas, CLIENT);      for i := 1 to BUTCOUNT - 1 do        DrawButton(Canvas, i);      if not VScrollDisabled then        DrawButton(Canvas, THUMB);    end;  end;  Canvas.Handle := 0;  Canvas.Free;end;function TAQSkinScrollBar.VScrollDisabled: Boolean;var  BarInfo: TScrollBarInfo;begin  BarInfo.cbSize := SizeOf(BarInfo);  GetScrollBarInfo(Handle, integer(OBJID_VSCROLL), BarInfo);  if STATE_SYSTEM_UNAVAILABLE and BarInfo.rgstate[0] = STATE_SYSTEM_UNAVAILABLE then    Result := True  else    Result := False;end;function TAQSkinScrollBar.VScrollRect: TRect;var  P: TPoint;  BarInfo: TScrollBarInfo;begin  BarInfo.cbSize := SizeOf(BarInfo);  GetScrollBarInfo(Handle, integer(OBJID_VSCROLL), BarInfo);  if STATE_SYSTEM_INVISIBLE and BarInfo.rgstate[0] <> 0 then    Result := Rect(0, 0, 0, 0)  else  begin    P := BarInfo.rcScrollBar.TopLeft;    Windows.ScreenToClient(Handle, P);    Result.TopLeft := P;    P := BarInfo.rcScrollBar.BottomRight;    Windows.ScreenToClient(Handle, P);    Result.BottomRight := P;    with GetBorderTopLeft do      OffsetRect(Result, X, Y);  end;end;function TAQSkinScrollBar.VSliderRect: TRect;var  Offset: Integer;  P: TPoint;  BarInfo: TScrollBarInfo;begin  BarInfo.cbSize := SizeOf(BarInfo);  GetScrollBarInfo(Handle, integer(OBJID_VSCROLL), BarInfo);  if STATE_SYSTEM_INVISIBLE and BarInfo.rgstate[0] <> 0 then    Result := Rect(0, 0, 0, 0)  else  begin    P := BarInfo.rcScrollBar.TopLeft;    Windows.ScreenToClient(Handle, P);    Result.TopLeft := P;    P := BarInfo.rcScrollBar.BottomRight;    Windows.ScreenToClient(Handle, P);    Result.BottomRight := P;    with GetBorderTopLeft do      OffsetRect(Result, X, Y);    Offset := Result.Top;    Result.Top := Offset + BarInfo.xyThumbTop - 1;    Result.Bottom := Offset + BarInfo.xyThumbBottom - 1;  end;end;function TAQSkinScrollBar.VTrackRect: TRect;begin  Result := VScrollRect;  if RectWidth(Result) > 0 then  begin    Result.Top := Result.Top + RectWidth(Result);    Result.Bottom := Result.Bottom - RectWidth(Result);  end  else    Result := Rect(0, 0, 0, 0)end;function TAQSkinScrollBar.VUpButtonRect: TRect;begin  Result := VScrollRect;  if RectWidth(Result) > 0 then  begin    Result.Bottom := Result.Top + RectWidth(Result);  end  else    Result := Rect(0, 0, 0, 0);end;procedure TAQSkinScrollBar.WMCAPTURECHANGED(var Msg: TMessage);begin  if VUpState = bsasbPressed then  begin    VUpState := bsasbNormal;    PaintScroll;  end;  if VDownState = bsasbPressed then  begin    VDownState := bsasbNormal;    PaintScroll;  end;  if HUpState = bsasbPressed then  begin    HUpState := bsasbNormal;    PaintScroll;  end;  if HDownState = bsasbPressed then  begin    HDownState := bsasbNormal;    PaintScroll;  end;  FOldWinProc(TMessage(Msg));  Handled := True;end;procedure TAQSkinScrollBar.WMEraseBkgnd(var Msg: TMessage);begin  FOldWinProc(TMessage(Msg));  if (Self.Control.ClassName = TRichView) or    (Self.Control.ClassName = TRichViewEdit)    then    PaintScroll;end;procedure TAQSkinScrollBar.WMHScroll(var Msg: TMessage);begin  FOldWinProc(TMessage(Msg));  PaintScroll;  Handled := True;end;procedure TAQSkinScrollBar.WMKeyDown(var Msg: TMessage);begin  FOldWinProc(TMessage(Msg));  PaintScroll;end;procedure TAQSkinScrollBar.WMLButtonDown(var Msg: TWMMouse);begin  FOldWinProc(TMessage(Msg));  PaintScroll;  Handled := True;end;procedure TAQSkinScrollBar.WMLButtonUp(var Msg: TWMMouse);begin  if VSliderState = bsasbPressed then  begin    ReleaseCapture;    lbtndown := False;    VSliderState := bsasbNormal;    PaintScroll;    Handled := True;    SendMessage(Handle, WM_VSCROLL, SB_ENDSCROLL, 0);    Exit;  end;  if HSliderState = bsasbPressed then  begin    ReleaseCapture;    lbtndown := False;    HSliderState := bsasbNormal;    PaintScroll;    Handled := True;    SendMessage(Handle, WM_HSCROLL, SB_ENDSCROLL, 0);    Exit;  end;  if VUpState = bsasbPressed then  begin    VUpState := bsasbNormal;  end;  if VDownState = bsasbPressed then  begin    VDownState := bsasbNormal;  end;  if HUpState = bsasbPressed then  begin    HUpState := bsasbNormal;  end;  if HDownState = bsasbPressed then  begin    HDownState := bsasbNormal;  end;  FOldWinProc(TMessage(Msg));  lbtndown := False;  PaintScroll;  Handled := True;end;procedure TAQSkinScrollBar.WMMouseMove(var Msg: TWMMouse);var  SF: TScrollInfo;  OldCurPos: single;begin  if VSliderState = bsasbPressed then  begin    SF.fMask := SIF_ALL;    SF.cbSize := SizeOf(SF);    GetScrollInfo(Handle, SB_VERT, SF);    OldCurPos := FCurPos;    FCurPos := FCurPos + (SF.nMax - SF.nMin) * ((Mouse.CursorPos.Y - FOldPos) / RectHeight(VTrackRect));    if FCurPos < SF.nMin then FCurPos := SF.nMin;    if FCurPos > SF.nMax then FCurPos := SF.nMax;    FOldPos := Mouse.CursorPos.Y;    SetScrollPos(Handle, SB_VERT, Round(FCurPos), False);    PostMessage(Handle, WM_VSCROLL, Integer(SmallPoint(SB_THUMBPOSITION, Round(FCurPos))), 0);    PaintScroll;    Handled := True;    Exit;  end;  if HSliderState = bsasbPressed then  begin    SF.fMask := SIF_ALL;    SF.cbSize := SizeOf(SF);    GetScrollInfo(Handle, SB_HORZ, SF);    OldCurPos := FCurPos;    FCurPos := FCurPos + (SF.nMax - SF.nMin) * ((Mouse.CursorPos.X - FOldPos) / RectWidth(HTrackRect));    if FCurPos < SF.nMin then FCurPos := SF.nMin;    if FCurPos > SF.nMax then FCurPos := SF.nMax;    FOldPos := Mouse.CursorPos.X;    if Control is TCustomListView then    begin      TCustomListView(FControl).Scroll(Round(FCurPos - OldCurPos), 0);    end    else    begin      SetScrollPos(Handle, SB_HORZ, Round(FCurPos), False);      PostMessage(Handle, WM_HSCROLL, Integer(SmallPoint(SB_THUMBPOSITION, Round(FCurPos))), 0);    end;    PaintScroll;    Handled := True;    Exit;  end;  if (HSliderState <> bsasbPressed) and (HSliderState = bsasbHot) then  begin    HSliderState := bsasbNormal;    PaintScroll;  end;  if (VSliderState <> bsasbPressed) and (VSliderState = bsasbHot) then  begin    VSliderState := bsasbNormal;    PaintScroll;  end;  if (HUpState <> bsasbPressed) and (HUpState = bsasbHot) then  begin    HUpState := bsasbNormal;    PaintScroll;  end;  if (HDownState <> bsasbPressed) and (HDownState = bsasbHot) then  begin    HDownState := bsasbNormal;    PaintScroll;  end;  if (VUpState <> bsasbPressed) and (VUpState = bsasbHot) then  begin    VUpState := bsasbNormal;    PaintScroll;  end;  if (VDownState <> bsasbPressed) and (VDownState = bsasbHot) then  begin    VDownState := bsasbNormal;    PaintScroll;  end;  FOldWinProc(TMessage(Msg));  if lbtndown then    PaintScroll;  Handled := True;end;procedure TAQSkinScrollBar.WMMouseWheel(var Msg: TMessage);begin  FOldWinProc(TMessage(Msg));  PaintScroll;  Handled := True;end;procedure TAQSkinScrollBar.WMNCLButtonDblClk(var Msg: TWMMouse);begin  WMNCLButtonDown(Msg);end;procedure TAQSkinScrollBar.WMNCLButtonDown(var Msg: TWMMouse);var  P: TPoint;  SF: TScrollInfo;  VEnabled, HEnabled: Boolean;begin  P := Point(Msg.XPos, Msg.YPos);  ScreenToClient(Handle, P);  with GetBorderTopLeft do  begin    P.X := P.X + X;    P.Y := P.Y + Y;  end;  VEnabled := not VScrollDisabled;  HEnabled := not HScrollDisabled;  if PtInRect(VSliderRect, P) then  begin    lbtndown := True;    SF.fMask := SIF_ALL;    SF.cbSize := SizeOf(SF);    GetScrollInfo(Handle, SB_VERT, SF);    FCurPos := SF.nPos;    FOldPos := Mouse.CursorPos.Y;    VSliderState := bsasbPressed;    Handled := True;    PaintScroll;    SetCapture(Handle);    Exit;  end;  if PtInRect(HSliderRect, P) then  begin    lbtndown := True;    SF.fMask := SIF_ALL;    SF.cbSize := SizeOf(SF);    GetScrollInfo(Handle, SB_HORZ, SF);    FCurPos := SF.nPos;    FOldPos := Mouse.CursorPos.X;    HSliderState := bsasbPressed;    PaintScroll;    SetCapture(Handle);    Handled := True;    Exit;  end;  if PtInRect(VDownButtonRect, P) and VEnabled then  begin    VUpState := bsasbPressed;  end;  if PtInRect(VUpButtonRect, P) and VEnabled then  begin    VDownState := bsasbPressed;  end;  if PtInRect(HDownButtonRect, P) and HEnabled then  begin    HUpState := bsasbPressed;  end;  if PtInRect(HUpButtonRect, P) and HEnabled then  begin    HDownState := bsasbPressed;  end;  FOldWinProc(TMessage(Msg));  PaintScroll;  Handled := True;end;procedure TAQSkinScrollBar.WMNCLButtonUp(var Msg: TWMMouse);begin  if VSliderState = bsasbPressed then  begin    lbtndown := False;    VSliderState := bsasbNormal;    PaintScroll;    Handled := True;    Exit;  end;  if HSliderState = bsasbPressed then  begin    lbtndown := False;    HSliderState := bsasbNormal;    PaintScroll;    Handled := True;    Exit;  end;  if VUpState = bsasbPressed then  begin    VUpState := bsasbNormal;  end;  if VDownState = bsasbPressed then  begin    VDownState := bsasbNormal;  end;  if HUpState = bsasbPressed then  begin    HUpState := bsasbNormal;  end;  if HDownState = bsasbPressed then  begin    HDownState := bsasbNormal;  end;  FOldWinProc(TMessage(Msg));  PaintScroll;  Handled := True;end;procedure TAQSkinScrollBar.WMNCMouseMove(var Msg: TWMNCHitMessage);var  SF: TScrollInfo;  OldCurPos: single;  P: TPoint;  VEnabled, HEnabled: Boolean;begin  P := Point(Msg.XCursor, Msg.YCursor);  ScreenToClient(Handle, P);  with GetBorderTopLeft do  begin    P.X := P.X + X;    P.Y := P.Y + Y;  end;  VEnabled := not VScrollDisabled;  HEnabled := not HScrollDisabled;  if VSliderState <> bsasbPressed then  begin    if PtInRect(VSliderRect, P) then      VSliderState := bsasbHot    else      VSliderState := bsasbNormal;  end;  if HSliderState <> bsasbPressed then  begin    if PtInRect(HSliderRect, P) then      HSliderState := bsasbHot    else      HSliderState := bsasbNormal;  end;  if (VUpState <> bsasbPressed) and VEnabled then  begin    if PtInRect(VDownButtonRect, P) then      VUpState := bsasbHot    else      VUpState := bsasbNormal;  end;  if (HUpState <> bsasbPressed) and HEnabled then  begin    if PtInRect(HDownButtonRect, P) then      HUpState := bsasbHot    else      HUpState := bsasbNormal;  end;  if (VDownState <> bsasbPressed) and VEnabled then  begin    if PtInRect(VUpButtonRect, P) then      VDownState := bsasbHot    else      VDownState := bsasbNormal;  end;  if (HDownState <> bsasbPressed) and HEnabled then  begin    if PtInRect(HUpButtonRect, P) then      HDownState := bsasbHot    else      HDownState := bsasbNormal;  end;  if VSliderState = bsasbPressed then  begin    SF.fMask := SIF_ALL;    SF.cbSize := SizeOf(SF);    GetScrollInfo(Handle, SB_VERT, SF);    OldCurPos := FCurPos;    FCurPos := FCurPos + (SF.nMax - SF.nMin) * ((Mouse.CursorPos.Y - FOldPos) / RectHeight(VTrackRect));    if FCurPos < SF.nMin then FCurPos := SF.nMin;    if FCurPos > SF.nMax then FCurPos := SF.nMax;    FOldPos := Mouse.CursorPos.Y;    if Control is TCustomListView then    begin      TCustomListView(FControl).Scroll(0, Round((FCurPos - OldCurPos)));    end    else    begin      PostMessage(Handle, WM_VSCROLL, Integer(SmallPoint(SB_THUMBPOSITION, Round(FCurPos))), 0);    end;    PaintScroll;    Handled := True;    Exit;  end;  if HSliderState = bsasbPressed then  begin    SF.fMask := SIF_ALL;    SF.cbSize := SizeOf(SF);    GetScrollInfo(Handle, SB_HORZ, SF);    OldCurPos := FCurPos;    FCurPos := FCurPos + (SF.nMax - SF.nMin) * ((Mouse.CursorPos.X - FOldPos) / RectWidth(HTrackRect));    if FCurPos < SF.nMin then FCurPos := SF.nMin;    if FCurPos > SF.nMax then FCurPos := SF.nMax;    FOldPos := Mouse.CursorPos.X;    if Control is TCustomListView then    begin      TCustomListView(FControl).Scroll(Round(FCurPos - OldCurPos), 0);    end    else      PostMessage(Handle, WM_HSCROLL, Integer(SmallPoint(SB_THUMBPOSITION, Round(FCurPos))), 0);    PaintScroll;    Handled := True;    Exit;  end;  FOldWinProc(TMessage(Msg));  PaintScroll;  Handled := True;end;procedure TAQSkinScrollBar.WMNCPaint(var Msg: TWMNCPaint);begin  FOldWinProc(TMessage(Msg));  DrawBorder(0, False);  Handled := True;end;procedure TAQSkinScrollBar.WMSize(var Msg: TMessage);begin  FOldWinProc(TMessage(Msg));  UpdateScroll;  Handled := True;end;procedure TAQSkinScrollBar.WMVScroll(var Msg: TMessage);begin  FOldWinProc(TMessage(Msg));  PaintScroll;  Handled := True;end;procedure TAQSkinScrollBar.WMVTChangeState(var Msg: TMessage);begin  FOldWinProc(TMessage(Msg));  PaintScroll;  Handled := True;end;procedure TAQSkinScrollBar.WMWindowPosChanged(var Msg: TWMWindowPosChanged);begin  FOldWinProc(TMessage(Msg));  if Msg.WindowPos.Flags and SWP_HIDEWINDOW = SWP_HIDEWINDOW then  begin    if VScrollWnd <> nil then      ShowWindow(VScrollWnd.Handle, SW_HIDE);    if HScrollWnd <> nil then      ShowWindow(HScrollWnd.Handle, SW_HIDE);  end  else    if IsWindowVisible(Handle) then    begin      UpdateScroll;      DrawBorder(0, False);    end;  Handled := True;end;procedure TAQSkinScrollBar.WMWindowPosChanging(var Msg: TWMWindowPosChanged);begin  if (Control is TScrollBox) and IsWindowVisible(Handle) then  begin    UpdateScroll;  end;  FOldWinProc(TMessage(Msg));end;end.
unit AQSkinScrollBar;

 

TAQSkinScrollBar 类美化滚动条再讨论