tslediter/funcext/tvclib/tcustomcontrol.tsf

346 lines
11 KiB
Plaintext

type tcustomcontrol=class(TWinControl)
uses utslvclauxiliary,utslvclgdi;
{**
@explan(说明) 自绘制窗口控件 %%
**}
//20220908添加splitter功能
private
[weakref]FOnPaint:TNotifyEvent;
protected
procedure PaintWindow(DC:HDC);override;
begin
//odh := canvas.Handle;
Canvas.Handle := dc;
canvas.font := font;
canvas.brush.Color := Color;
Canvas.requiregdi();
Canvas.rcpaint := PAINTSTRUCT().rcpaint();
try
Paint();
finally
Canvas.Handle := 0;
end;
end
procedure Paint();override;
begin
inherited;
if iffuncptr(FOnPaint) then call(FOnPaint,self(true));
end
function ControlAppended(AControl);override;
begin
if AControl is class(tcustomsplitter) then
begin
fhassplitter++;
end
end
function ControlDeleted(AControl);override;
begin
if AControl is class(tcustomsplitter) then
begin
fhassplitter--;
end
end
public
function Create(AOwner:TComponent);override;
begin
inherited;
//FCanvas := new tcanvas();
end
function AfterConstruction();override;
begin
inherited;
includestate(FControlState,csCustomPaint);
fhassplitter := 0;
fsplitterwilldrag := true;
end
function CreateParams(p);override;
begin
inherited;
//p.style .|= WS_CLIPSIBLINGS .| WS_CLIPCHILDREN;
end
function Recycling();override;
begin
FOnPaint := nil;
fsplitercache := array();
fsplitterdragimglist := nil;
inherited;
end
function DoVScroll(o,e);virtual;
begin
end
function DoHScroll(o,e);virtual;
begin
end
public
function WMVScroll(o,e):LM_VScroll;virtual;
begin
return DoVScroll(o,e);
end
function WMHScroll(o,e):LM_HSCROLL;virtual;
begin
return DoHScroll(o,e);
end
function WMLButtonDown(o,e);override;//拖拽释放
begin
if fhassplitter<1 then return inherited;
if csDesigning in ComponentState then exit;
case fcurspltype of
alLeft,alRight:
begin
drgidx := 1;
end
alTop,alBottom:
begin
drgidx := 0;
end
else
begin
return inherited;
end
end ;
if fsplitterwilldrag then
begin
cimgst();
fsplitterwilldrag := false;
fsplitterdraging := true;
nxy := clienttowindow(e.xpos,e.ypos);
_wapi.ImageList_BeginDrag(fsplitterdragimglist.Handle,drgidx,12,12);
_wapi.ImageList_DragEnter(self.Handle,nxy[0],nxy[1]);
crect := clientrect;
ps := array(clienttoscreen(crect[0],crect[1]),clienttoscreen(crect[2],crect[3]));
_wapi.clipcursor(ps);
splitterenabled(false);
return ;
end
//end
inherited;
end
function WMLBUTTONUP(o,e);override;//拖拽实现
begin
if fhassplitter<1 then return inherited;
if csDesigning in ComponentState then return ;
if fsplitterdraging then
begin
cimgst();
_wapi.ImageList_DragLeave(self.Handle);
_wapi.ImageList_EndDrag();
splitterenabled(true);
fsplitterwilldrag := true;
fsplitterdraging := false;
sizeprive(e.pos);
_wapi.clipcursor(0);
return ;
end
return inherited;
end
function WMMouseMove(o,e);override; //移动
begin
if fhassplitter<1 then return inherited;
if csDesigning in ComponentState then return inherited;
if fsplitterdraging then
begin
cimgst();
nxy := clienttowindow(e.xpos,e.ypos);
_wapi.ImageList_DragMove(nxy[0],nxy[1]);
return ;
end else
begin
xy := e.pos();
fcurspltype := nil;
fcursplitterid := -1;
fcursplitter := nil;
for i,v in Controls.data do
begin
if (v is class(tcustomsplitter)) and (v.Visible) and (v.enabled) and pointinrect(xy,v.BoundsRect) and (v<>fcursplitter) then //拖拽
begin
va := v.Align;
if va in array(alLeft,alRight) then
begin
cursor := OCR_SIZEWE;
fcurspltype := va;
fcursplitter := v;
fcursplitterid := i;
return ;
end else
if va in array(alTop,alBottom) then
begin
cursor := OCR_SIZENS;
fcurspltype := va;
fcursplitter := v;
fcursplitterid := i;
return ;
end
end
end
cursor := OCR_NORMAL;
end
return inherited;
end
property OnPaint:eventhandler read FOnPaint write FOnPaint;
{**
@param(OnPaint)(function[TCustomControl,tuieventbase]) 窗口关闭消息回调 %%
**}
private
function getzybmp();
begin
r :="0502000000060400000074797065000203000000696D670006040000006461746
10002E300000089504E470D0A1A0A0000000D4948445200000018000000180806
000000E0773DF8000000017352474200AECE1CE90000000467414D410000B18F0
BFC6105000000097048597300000EC300000EC301C76FA8640000007849444154
484BED8FED09C0200C443B90C3B89CDB65174BC02B54134FA41F7FF220207AB98
7477D9910504240F94F2022EDC499654D812EE49C97242C3B08B0504A69371CCD
7A929B60A71C78924B80F294923BC07AC3F492EF7E0076245EB932081448AC851
E963505CA4A3998655DC1538480120242AD27B102A52F60A469C4000000004945
4E44AE42608200";
return r;
end
function getsxbmp();
begin
r := "0502000000060400000074797065000203000000696D670006040000006461746
100027801000089504E470D0A1A0A0000000D4948445200000018000000180806
000000E0773DF8000000017352474200AECE1CE90000000467414D410000B18F0
BFC6105000000097048597300000EC300000EC301C76FA8640000010D49444154
484BE5963D0A84400C853D8885BD585AD8D97802B11704AFA19D8D78053BAFE10
5AC0541F006361E204B86380CAC6322EC6EB31F04740CEF61327F0E08699A0682
2000C771A02C4B98E799BEDC2332288A42099B118621ECFB4E19765883BAAEDFC
4CF48D394B2ECB006499228B1388EB5705555FA79DB36CABC4654A2B66D615916
2D3A8E23F47DAF8243DC64C43490F26706BEEF2B83755D6984E79101CE986118E
84D8636388E43FDFA27629A2652350CA228D235FE44E05A417E67F0F5127D8B47
06B81F799EC7EE3F268F0CCEFA6219A4FC8101AE5CDB766DCE161BAC419EE74AF
4EAC0C18673B0067747669665946547D483AB435F228E889B7C5E5B5CD785AEEB
689403E005E8019174FBC7C7A70000000049454E44AE42608200";
return r;
end
function candosplitter(v);
begin
return (not(v is class(tcustomsplitter)) and (v.Visible) and (v.Align = fcurspltype));
end
function sizeprive(xy);
begin
id := fcursplitterid;
ctls := Controls;
rc := clientrect;
x := max(rc[0],xy[0]);
x := min(rc[2],x);
y := max(rc[1],xy[1]);
y:= min(rc[3],y);
case fcurspltype of
alLeft :
begin
for i:= id-1 downto 0 do
begin
v := ctls[i];
if candosplitter(v) then
begin
vL := v.Left;
sw := fcursplitter.Width;
nvl := max(x-vl-sw,sw);
v.Align := alNone;
v.Width := nvl;
v.Align := fcurspltype;
return ;
end
end
end
alTop:
begin
for i:= id-1 downto 0 do
begin
v := ctls[i];
if candosplitter(v) then
begin
vL := v.top;
sw := fcursplitter.Height;
nvl := max(y-vl-sw,sw);
v.Align := alNone;
v.Height := nvl;
v.Align := fcurspltype;
return ;
end
end
end
alRight:
begin
for i:= id-1 downto 0 do
begin
v := ctls[i];
if candosplitter(v) then
begin
vl := (v.BoundsRect)[2];
sw := fcursplitter.Width;
nvl := max(vl-x-sw*1.5,sw);
v.Align := alNone;
v.Width := nvl;
v.Align := fcurspltype;
return ;
end
end
end
alBottom:
begin
for i:= id-1 downto 0 do
begin
v := ctls[i];
if candosplitter(v) then
begin
vL := (v.BoundsRect)[3];
sw := fcursplitter.Height;
nvl := max(vl-y-sw*1.5,sw);
v.Align := alNone;
v.Height := nvl;
v.Align := fcurspltype;
return ;
end
end
end
end
end
function cimgst();
begin
if not fsplitterdragimglist then
begin
fsplitterdragimglist := new TCustomImageList(self);
fsplitterdragimglist.Width := 24;
fsplitterdragimglist.Height := 24;
bmp := new TcustomBitmap();
bmp.readvcon(HexFormatStrToTsl(getsxbmp()));
fsplitterdragimglist.addbmp(bmp);
bmp := new TcustomBitmap();
bmp.readvcon(HexFormatStrToTsl(getzybmp()));
fsplitterdragimglist.addbmp(bmp);
end
end
function splitterenabled(b);
begin
if not b then
begin
fsplitercache := array();
for i,v in controls.data do
begin
fsplitercache[i] := array(v,v.enabled);
v.enabled := false;
end
end else
begin
for i,v in fsplitercache do
begin
v[0].enabled := v[1];
end
fsplitercache := nil;
end
end
fsplitterdragimglist;
fsplitterwilldrag;
fsplitterdraging;
fcurspltype;
fcursplitter;
fcursplitterid;
fsplitercache;
fhassplitter;
end;