TAQSkinScrollBar 类美化滚动条再讨论

时间:2024-03-27 16:36:44

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

滚动的改善方法:

TAQSkinScrollBar 类美化滚动条再讨论

unit AQSkinScrollBar;
(*
说明:本单元提取自TdsaSkinAdapter控件,版权归原作者所有。 提取:www.138soft.com *)
{$R Scroll.RES} interface
uses
ComCtrls,
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms; const
// Billenium Effects messages
BE_ID = $41A2;
BE_BASE = CM_BASE + $0C4A;
CM_BENCPAINT = BE_BASE + ;
CM_SENCPAINT = CM_BASE + ; 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 = );
procedure HDrawScroll(DC: HDC = );
// 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 + ;
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; implementation function 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 = ) or
(RBPt.Y - LTPt.Y = ) 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 := to XCnt do
begin
if NewLTPt.X + X * w + w > NewRTPt.X
then XO := NewLTPt.X + X * w + w - NewRTPt.X else XO := ;
CopyRect(Rect(NewLTPt.X + X * w, , 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, , 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(, , 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 := to XCnt do
begin
if NewLBPt.X + X * w + w > NewRBPt.X
then XO := NewLBPt.X + X * w + w - NewRBPt.X else XO := ;
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(, , 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 := to YCnt do
begin
if NewLTPt.Y + Y * h + h > NewLBPt.Y
then YO := NewLTPt.Y + Y * h + h - NewLBPt.Y else YO := ;
CopyRect(Rect(, 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(, 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(, , 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 := to YCnt do
begin
if NewRTPt.Y + Y * h + h > NewRBPt.Y
then YO := NewRTPt.Y + Y * h + h - NewRBPt.Y else YO := ;
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(, , Buffer.Width, Buffer.Height);
Buffer.Canvas.CopyRect(R3, SB.Canvas, R2);
StretchDraw(R1, Buffer);
Buffer.Free;
end; // Draw corners
// lefttop CopyRect(Rect(, , NewLTPt.X, NewClRect.Top),
SB.Canvas, Rect(R.Left, R.Top,
R.Left + LTPt.X, R.Top + ClRect.Top)); CopyRect(Rect(, 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, , 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(, 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(, , 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) > ) and (RectHeight(NewClRect) > ) 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(, , Buffer2.Width, Buffer2.Height), Buffer);
XCnt := RectWidth(NewClRect) div Buffer2.Width;
for X := 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(, , Buffer2.Width, Buffer2.Height), Buffer);
YCnt := RectHeight(NewClRect) div Buffer2.Height;
for Y := 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 := to XCnt do
for Y := to YCnt do
begin
if X * w + w > rw then XO := X * W + W - rw else XO := ;
if Y * h + h > rh then YO := Y * h + h - rh else YO := ;
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 <> then
CopyRect(Rect(, , LO, B.Height), SB.Canvas,
Rect(R.Left, R.Top, R.Left + LO, R.Bottom));
if RO <> then
CopyRect(Rect(B.Width - RO, , 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 = then w := ;
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(, , Buffer.Width, Buffer.Height),
SB.Canvas, R);
R1 := Rect(LO, , B.Width - RO, B.Height);
B.Canvas.StretchDraw(R1, Buffer);
Buffer.Free;
end
else
for X := to XCnt do
begin
if LO + X * w + w > B.Width - RO
then XO := LO + X * w + w - (B.Width - RO)
else XO := ;
B.Canvas.CopyRect(Rect(LO + X * w, , 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 <> then
CopyRect(Rect(, , B.Width, TpO), SB.Canvas,
Rect(R.Left, R.Top, R.Right, R.Top + TpO));
if BO <> then
CopyRect(Rect(, 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 <>
then
YCnt := (B.Height - TpO - BO) div h
else
YCnt := ;
if AStretch
then
begin
Buffer := TBitMap.Create;
Buffer.Width := RectWidth(R);
Buffer.Height := RectHeight(R);
Buffer.Canvas.CopyRect(Rect(, , Buffer.Width, Buffer.Height),
SB.Canvas, R);
R1 := Rect(, TpO, B.Width, B.Height - BO);
B.Canvas.StretchDraw(R1, Buffer);
Buffer.Free;
end
else
for Y := to YCnt do
begin
if TpO + Y * h + h > B.Height - BO
then YO := TpO + Y * h + h - (B.Height - BO)
else YO := ;
B.Canvas.CopyRect(
Rect(, 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 - ), , gw * FGlyphNum, gh);
B.Canvas.CopyRect(Rect(, , 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 > ) and (h > ) and (RTPt.X - LTPt.X > ) 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, , NewRTPt.X, h);
TB.Width := RectWidth(TR);
TB.Height := RectHeight(TR);
TB.Canvas.CopyRect(Rect(, , TB.Width, TB.Height),
SB.Canvas, TR);
TopB.Canvas.StretchDraw(TR1, TB);
TB.Free;
end
else
for X := to XCnt do
begin
if X * w + w > TopB.Width
then XO := X * w + w - TopB.Width else XO := ;
with TopB.Canvas do
begin
CopyRect(Rect(X * w, , 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(, , NewLTPt.X, h), SB.Canvas,
Rect(R.Left, R.Top, R.Left + LTPt.X, R.Top + h));
CopyRect(Rect(NewRTPt.X, , 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 > ) and (h > ) and (RBPt.X - LBPt.X > )
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, , NewRBPt.X, h);
TB.Width := RectWidth(TR);
TB.Height := RectHeight(TR);
TB.Canvas.CopyRect(Rect(, , TB.Width, TB.Height),
SB.Canvas, TR);
BottomB.Canvas.StretchDraw(TR1, TB);
TB.Free;
end
else
for X := to XCnt do
begin
if X * w + w > BottomB.Width
then XO := X * w + w - BottomB.Width else XO := ;
with BottomB.Canvas do
begin
CopyRect(Rect(X * w, , 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(, , NewLBPt.X, h), SB.Canvas,
Rect(R.Left, R.Bottom - h, R.Left + LBPt.X, R.Bottom));
CopyRect(Rect(NewRBPt.X, , 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 > ) and (h > ) and (LBPt.Y - LTPt.Y > )
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(, LTPt.Y - ClRect.Top, w,
LeftB.Height - (ClRect.Bottom - LBPt.Y));
TB.Width := RectWidth(TR);
TB.Height := RectHeight(TR);
TB.Canvas.CopyRect(Rect(, , TB.Width, TB.Height),
SB.Canvas, TR);
LeftB.Canvas.StretchDraw(TR1, TB);
TB.Free;
end
else
for Y := to YCnt do
begin
if Y * h + h > LeftB.Height
then YO := Y * h + h - LeftB.Height else YO := ;
with LeftB.Canvas do
CopyRect(Rect(, 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 >
then
CopyRect(Rect(, , 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 > then
CopyRect(Rect(, 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 > ) and (h > ) and (RBPt.Y - RTPt.Y > ) 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(, RTPt.Y - ClRect.Top, w,
RightB.Height - (ClRect.Bottom - RBPt.Y));
TB.Width := RectWidth(TR);
TB.Height := RectHeight(TR);
TB.Canvas.CopyRect(Rect(, , TB.Width, TB.Height),
SB.Canvas, TR);
RightB.Canvas.StretchDraw(TR1, TB);
TB.Free;
end
else
for Y := to YCnt do
begin
if Y * h + h > RightB.Height
then YO := Y * h + h - RightB.Height else YO := ;
with RightB.Canvas do
CopyRect(Rect(, 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 > then
CopyRect(Rect(, , 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 > then
CopyRect(Rect(, 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(, , , );
end; function IsNullRect(R: TRect): Boolean;
begin
Result := (R.Right - R.Left <= ) or (R.Bottom - R.Top <= )
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
:
begin
X := R.Left + RectWidth(R) div - ;
Y := R.Top + RectHeight(R) div ;
for i := to do
begin
MoveTo(X + i, Y - i);
LineTo(X + i, Y + i + );
end;
end;
:
begin
X := R.Left + RectWidth(R) div + ;
Y := R.Top + RectHeight(R) div ;
for i := downto do
begin
MoveTo(X - i, Y + i);
LineTo(X - i, Y - i - );
end;
end;
:
begin
X := R.Left + RectWidth(R) div ;
Y := R.Top + RectHeight(R) div - ;
for i := to do
begin
MoveTo(X - i, Y + i);
LineTo(X + i + , Y + i);
end;
end;
:
begin
X := R.Left + RectWidth(R) div ;
Y := R.Top + RectHeight(R) div + ;
for i := downto do
begin
MoveTo(X - i, Y - i);
LineTo(X + i + , Y - i);
end;
end;
: begin
X := R.Left + RectWidth(R) div ;
Y := R.Top + RectHeight(R) div ;
MoveTo(X - , Y - );
LineTo(X + , Y - );
MoveTo(X - , Y);
LineTo(X + , Y);
//
MoveTo(X - , Y - );
LineTo(X - , Y + );
MoveTo(X, Y - );
LineTo(X, Y + );
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 = 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 := ;
end; procedure TWinScroll.WMNCHitTest(var Msg: TWMNCHitTest);
begin
Msg.Result := HTTRANSPARENT;
end; { TAQSkinScrollBar } const
BUTCOUNT = ;
THUMB = ;
UPBUTTON = ;
DOWNBUTTON = ;
TRACK = ;
CLIENT = ;
SBUTTONW = ; procedure TAQSkinScrollBar.CMBENCPaint(var Message: TMessage);
begin
if (Message.LParam = BE_ID) then
begin
if (Message.wParam <> ) 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 <> ) 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 := ;
FOldWinProc := nil; with FVScrollCtrl do
begin
skinrect := Rect(, , , );
LTPoint := point(, );
RTPoint := point(, );
LBPoint := point(, );
RBPoint := point(, );
ClRect := Rect(, , , );
LeftStretch := False;
topstretch := False;
rightstretch := False;
bottomstretch := False;
stretcheffect := False;
stretchtype := stfull;
trackarea := Rect(, , , );
upbuttonrect := Rect(, , , );
activeupbuttonrect := Rect(, , , );
downupbuttonrect := Rect(, , , );
downbuttonrect := Rect(, , , );
activedownbuttonrect := Rect(, , , );
downdownbuttonrect := Rect(, , , );
thumbrect := Rect(, , , );
activethumbrect := Rect(, , , );
downthumbrect := Rect(, , , );
thumboffset1 := ;
thumboffset2 := ;
thumbtransparent := False;
thumbtransparentcolor := ;
thumbstretcheffect := False;
thumbminsize := ;
thumbminpagesize := ;
glyphrect := Rect(, , , );
activeglyphrect := Rect(, , , );
downglyphrect := Rect(, , , );
glyphtransparent := False;
glyphtransparentcolor := ;
end; with FHScrollCtrl do
begin
skinrect := Rect(, , , );
LTPoint := point(, );
RTPoint := point(, );
LBPoint := point(, );
RBPoint := point(, );
ClRect := Rect(, , , );
LeftStretch := False;
topstretch := False;
rightstretch := False;
bottomstretch := False;
stretcheffect := False;
stretchtype := stfull;
trackarea := Rect(, , , );
upbuttonrect := Rect(, , , );
activeupbuttonrect := Rect(, , , );
downupbuttonrect := Rect(, , , );
downbuttonrect := Rect(, , , );
activedownbuttonrect := Rect(, , , );
downdownbuttonrect := Rect(, , , );
thumbrect := Rect(, , , );
activethumbrect := Rect(, , , );
downthumbrect := Rect(, , , );
thumboffset1 := ;
thumboffset2 := ;
thumbtransparent := False;
thumbtransparentcolor := ;
thumbstretcheffect := False;
thumbminsize := ;
thumbminpagesize := ;
glyphrect := Rect(, , , );
activeglyphrect := Rect(, , , );
downglyphrect := Rect(, , , );
glyphtransparent := False;
glyphtransparentcolor := ;
end; FBtnFace := ; 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 = then Exit; Canvas := TCanvas.Create;
if not AUseExternalDC
then Canvas.Handle := GetWindowDC(Handle)
else Canvas.Handle := ADC; P := Point(, );
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, );
if not AUseExternalDC then ReleaseDC(Handle, Canvas.Handle); Canvas.Handle := ;
Canvas.Free;
end; procedure TAQSkinScrollBar.DrawButton(Cnvs: TCanvas; i: Integer);
const
SP_XP_BTNFRAMECOLOR = ;
SP_XP_BTNACTIVECOLOR = ;
SP_XP_BTNDOWNCOLOR = ;
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(, , Bmp_skinrect_V.Width, Bmp_skinrect_V.Height);
ActiveUpButtonRect := Rect(, , Bmp_activeupbuttonrect_V.Width, Bmp_activeupbuttonrect_V.Height);
ActiveDownButtonRect := Rect(, , Bmp_activedownbuttonrect_V.Width, Bmp_activedownbuttonrect_V.Height);
ThumbRect := Rect(, , Bmp_thumbrect_V.Width, Bmp_thumbrect_V.Height);
ActiveThumbRect := Rect(, , Bmp_activethumbrect_V.Width, Bmp_activethumbrect_V.Height);
end;
end
else
begin
SkinCtrl := FHScrollCtrl;
with SkinCtrl do
begin
SkinRect := Rect(, , Bmp_skinrect_H.Width, Bmp_skinrect_H.Height);
ActiveUpButtonRect := Rect(, , Bmp_activeupbuttonrect_H.Width, Bmp_activeupbuttonrect_H.Height);
ActiveDownButtonRect := Rect(, , Bmp_activedownbuttonrect_H.Width, Bmp_activedownbuttonrect_H.Height);
ThumbRect := Rect(, , Bmp_thumbrect_H.Width, Bmp_thumbrect_H.Height);
ActiveThumbRect := Rect(, , Bmp_activethumbrect_H.Width, Bmp_activethumbrect_H.Height);
end;
end; FPageSize := ; { Offset }
if FKind = sbVertical then
begin
R := VTrackRect;
if RectWidth(SkinCtrl.SkinRect) < RectWidth(R) then
MoveWindowOrg(Cnvs.Handle, RectWidth(R) - RectWidth(SkinCtrl.SkinRect), );
end
else
begin
R := HTrackRect;
if RectHeight(SkinCtrl.SkinRect) < RectHeight(R) then
MoveWindowOrg(Cnvs.Handle, , 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 := -
else if (RBPoint.X <> ) and (RBPoint.Y <> ) then
ResizeMode :=
else if (RTPoint.X <> ) or (RTPoint.Y <> ) then
ResizeMode :=
else if (LBPoint.X <> ) or (LBPoint.Y <> ) then
ResizeMode :=
else
ResizeMode := ; if RectWidth(R) * RectHEight(R) > 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
:
begin
B.Canvas.CopyRect(Rect(, , B.Width, B.Height), Bmp_r1.Canvas, R1);
end;
: 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); : CreateHSkinImage(LTPoint.X, RectWidth(SkinRect) - RTPoint.X,
B, Bmp_r1, R1, B.Width, B.Height, StretchEffect);
: 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) = 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 );
R.Top := TrackR.Top + Round(((R.Top - VTrackRect.Top) / RectHeight(VTrackRect)) * RectHeight(TrackR)) + ;
R.Bottom := TrackR.Top + Round(((R.Bottom - VTrackRect.Top) / RectHeight(VTrackRect)) * RectHeight(TrackR)) + ; MinH := RectHeight(SkinCtrl.ThumbRect);
if SkinCtrl.ThumbMinSize > then MinH := SkinCtrl.ThumbMinSize; if RectHeight(R) < MinH then
begin
X := ((R.Top + R.Bottom) div );
R.Top := X - (MinH div );
R.Bottom := X + (MinH div );
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) = 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 );
R.Left := TrackR.Left + Round(((R.Left - HTrackRect.Left) / RectWidth(HTrackRect)) * RectWidth(TrackR)) + ;
R.Right := TrackR.Left + Round(((R.Right - HTrackRect.Left) / RectWidth(HTrackRect)) * RectWidth(TrackR)) + ; MinW := RectWidth(SkinCtrl.ThumbRect);
if SkinCtrl.ThumbMinSize > then MinW := SkinCtrl.ThumbMinSize; if RectWidth(R) < MinW then
begin
X := ((R.Left + R.Right) div );
R.Left := X - (MinW div );
R.Right := X + (MinW div );
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) > then
begin
ThumbB := TBitMap.Create;
ThumbB.Width := RectWidth(R);
ThumbB.Height := RectHeight(R);
if FPageSize = then
ThumbB.Canvas.CopyRect(Rect(, , 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 - RectWidth(R1) div ,
ThumbB.Height div - RectHeight(R1) div ,
ThumbB.Width div - RectWidth(R1) div + RectWidth(R1),
ThumbB.Height div - RectHeight(R1) div + RectHeight(R1));
if SkinCtrl.GlyphTransparent then
begin
GlyphB := TBitMap.Create;
GlyphB.Width := RectWidth(R1);
GlyphB.Height := RectHeight(R1);
GlyphB.Canvas.CopyRect(Rect(, , 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)), );
end
else
begin
R := HTrackRect;
if RectHeight(SkinCtrl.SkinRect) < RectHeight(R) then
MoveWindowOrg(Cnvs.Handle, , -(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(, ); PWnd := GetParent(Handle);
CP := Point(, );
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(, , , );
Exit;
end; if FControl <> nil then
Result := Rect(FControl.Left, FControl.Top, FControl.Left + FControl.Width, FControl.Top + FControl.Height)
else
if FHandle <> then
Windows.GetWindowRect(Handle, Result)
else
Result := Rect(, , , );
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 := ;
Exit;
end; if FControl <> nil then
Result := FControl.Height
else
if FHandle <> then
begin
Windows.GetClientRect(Handle, R);
Result := R.Bottom;
end
else
Result := ;
end; function TAQSkinScrollBar.GetWidth: Integer;
var
R: TRect;
begin
if (Control <> nil) and (Control is TGraphicControl) and
(Control.Parent = nil) then
begin
Result := ;
Exit;
end; if FControl <> nil then
Result := FControl.Width
else
if FHandle <> then
begin
Windows.GetClientRect(Handle, R);
Result := R.Right;
end
else
Result := ;
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) > then
begin
Result.Left := Result.Right - RectHeight(Result);
end
else
Result := Rect(, , , );
end; procedure TAQSkinScrollBar.HDrawScroll(DC: HDC);
var
// R: TRect;
Canvas: TCanvas;
// P: TPoint;
i: Integer;
// X, Y: Integer;
begin
if Handle = then Exit;
if DC = then Exit; Canvas := TCanvas.Create;
Canvas.Handle := DC; { Fill back } Canvas.Brush.Color := FBtnFace;
Canvas.FillRect(Rect(, , Width, Height)); { Draw Hscroll }
if RectHeight(HScrollRect) > then
begin
FKind := sbHorizontal;
DrawButton(Canvas, CLIENT);
for i := to BUTCOUNT - do
DrawButton(Canvas, i);
if not HScrollDisabled then
DrawButton(Canvas, THUMB);
end; Canvas.Handle := ;
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[] = 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[] <> then
Result := Rect(, , , )
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[] <> then
Result := Rect(, , , )
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 - ;
Result.Right := Offset + BarInfo.xyThumbBottom - ;
end;
end; function TAQSkinScrollBar.HTrackRect: TRect;
begin
Result := HScrollRect;
if RectWidth(Result) > then
begin
Result.Left := Result.Left + RectHeight(Result);
Result.Right := Result.Right - RectHeight(Result);
end
else
Result := Rect(, , , );
end; function TAQSkinScrollBar.HUpButtonRect: TRect;
begin
Result := HScrollRect;
if RectHeight(Result) > then
begin
Result.Right := Result.Left + RectHeight(Result);
end
else
Result := Rect(, , , );
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 + ;
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);
begin end; 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(, );
RTPoint := Point(, );
LBPoint := Point(, );
RBPoint := Point(, ); SkinRect := rect(, , , ); ClRect := rect(, , , );
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(, , 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(, , TopB);
Canvas.Draw(, TopB.Height, LeftB);
Canvas.Draw(FControl.Width - RightB.Width, TopB.Height, RightB);
Canvas.Draw(, 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 - , Height - GripSize - , Width - , Height - ))
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 := ; 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);
begin end; 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) > then
begin
Result.Top := Result.Bottom - RectWidth(Result);
end
else
Result := Rect(, , , );
end; procedure TAQSkinScrollBar.VDrawScroll(DC: HDC);
var
// R: TRect;
Canvas: TCanvas;
// P: TPoint;
i: Integer;
// X, Y: Integer;
begin
if Handle = then Exit;
if DC = then Exit; Canvas := TCanvas.Create;
if DC <> then
Canvas.Handle := DC;
begin
{ Fill back }
Canvas.Brush.Color := FBtnFace;
Canvas.FillRect(Rect(, , Width, Height)); { Draw Vscroll }
if RectWidth(VScrollRect) > then
begin
FKind := sbVertical;
DrawButton(Canvas, CLIENT);
for i := to BUTCOUNT - do
DrawButton(Canvas, i);
if not VScrollDisabled then
DrawButton(Canvas, THUMB);
end;
end; Canvas.Handle := ;
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[] = 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[] <> then
Result := Rect(, , , )
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[] <> then
Result := Rect(, , , )
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 - ;
Result.Bottom := Offset + BarInfo.xyThumbBottom - ;
end;
end; function TAQSkinScrollBar.VTrackRect: TRect;
begin
Result := VScrollRect;
if RectWidth(Result) > then
begin
Result.Top := Result.Top + RectWidth(Result);
Result.Bottom := Result.Bottom - RectWidth(Result);
end
else
Result := Rect(, , , )
end; function TAQSkinScrollBar.VUpButtonRect: TRect;
begin
Result := VScrollRect;
if RectWidth(Result) > then
begin
Result.Bottom := Result.Top + RectWidth(Result);
end
else
Result := Rect(, , , );
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, );
Exit;
end; if HSliderState = bsasbPressed then
begin
ReleaseCapture;
lbtndown := False;
HSliderState := bsasbNormal;
PaintScroll;
Handled := True;
SendMessage(Handle, WM_HSCROLL, SB_ENDSCROLL, );
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))), ); 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), );
end
else
begin
SetScrollPos(Handle, SB_HORZ, Round(FCurPos), False);
PostMessage(Handle, WM_HSCROLL, Integer(SmallPoint(SB_THUMBPOSITION, Round(FCurPos))), );
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(, Round((FCurPos - OldCurPos)));
end
else
begin
PostMessage(Handle, WM_VSCROLL, Integer(SmallPoint(SB_THUMBPOSITION, Round(FCurPos))), );
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), );
end
else
PostMessage(Handle, WM_HSCROLL, Integer(SmallPoint(SB_THUMBPOSITION, Round(FCurPos))), );
PaintScroll;
Handled := True;
Exit;
end; FOldWinProc(TMessage(Msg));
PaintScroll;
Handled := True;
end; procedure TAQSkinScrollBar.WMNCPaint(var Msg: TWMNCPaint);
begin
FOldWinProc(TMessage(Msg));
DrawBorder(, 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(, 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;