tslediter/funcext/tvclib/utslvclgdi.tsf

3418 lines
91 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

unit utslvclgdi;
{**
@explan(˵Ã÷) gdi ¶ÔÏó¿â %%
@date(20220507)
**}
interface
uses cstructurelib,utslvclmemstruct,utslvclauxiliary,utslvclbase;
function GetTextWidthAndHeightWidthFont(s,f,mul);
function getdrawablebitmap(w,h,bmp);
function GetGdipStatus(v);
type TGdi = class(TSLUIBASE)
private
static GDICache;
[weakref]FCanvas;
function SetCanvas(c);
begin
FCanvas := c;
Onchange();
end
protected FHandle; //gdi¾ä±ú
FGdistate;
FGDIstruct;
class function sinit();override;
begin
if not GDICache then
begin
inherited;
if _wapi then
GDICache := new TResourcescache(_wapi);
end
end
public
function HandleAllocated();virtual;
begin
return FHandle <> 0 and ifnumber(FHandle);
end
function HandleNeeded();virtual;
begin
return FHandle;
end
function DestroyHandle();virtual;
begin
if HandleAllocated()then
begin
unreference();
FHandle := 0;
end
end
function GetGDIinfo();virtual;
begin
if not FGDIstruct then
begin
FGDIstruct := 1;
end
//return array();
end
function Onchange();virtual;
begin
end
function GetFormatGdiStr();
begin
v := gdiformatstr();
if ifstring(v)then return getmsgd_Crc32(v);
return "";
end
function reference();virtual;
begin
return GDICache.reference(GetFormatGdiStr());
end
function addsource(v);virtual;
begin
GDICache.addsource(GetFormatGdiStr(),v);
end
function unreference();virtual;
begin
GDICache.unreference(GetFormatGdiStr());
end
function destroyresource();virtual;
begin
GDICache.destroyresource(GetFormatGdiStr());
end
function gdiformatstr();virtual;
begin
return 0;
end
function create();override;
begin
inherited;
FGdistate := array();
end
function Recycling();override;
begin
FCanvas := nil;
DestroyHandle();
inherited;
end
property Canvas read FCanvas write SetCanvas;
property Handle read HandleNeeded;
end
type Tcustomfont = class(tgdi)
private
fdwfacename;
FHeight;
FWidth;
Fescapement;
Forientation;
Fweight;
Fitalic;
Funderline;
Fstrikeout;
Fcharset;
Foutprecision;
Fclipprecision;
Fquality;
Fpitchandfamily;
Ffacename;
FColor;
FBKColor;
FBkmode;
static LOGSTRUCT;
static LOGSTRUCTarray;
class function sinit();override;
begin
inherited;
if not LOGSTRUCTarray then
begin
LOGSTRUCTarray := array(
("height","int",15),
("width","int",0),
("escapement","int",0),
("orientation","int",0),
("weight","int",400),
("italic","byte",0),
("underline","byte",0),
("strikeout","byte",0),
("charset","byte",134),
("outprecision","byte",3),
("clipprecision","byte",2),
("quality","byte",1),
("pitchandfamily","byte",FIXED_PITCH),
("facename","char[32]","ÐÂËÎÌå"));
dt := MemoryAlignmentCalculate(LOGSTRUCTarray,1,nil,nil);
LOGSTRUCT := new tslcstructureobj(dt,nil);
end
end
function SetColor(c);
begin
if ifnumber(c)and c <> FColor then
begin
FColor := c;
if Canvas then Canvas.OnFontColorChange();
end
end
function SetbkColor(c);
begin
if ifnumber(c)and c <> FBKColor then
begin
FBKColor := c;
if Canvas then Canvas.OnFontbkColorChange();
end
end
function SetbkMode(c);
begin
nc :=(c=OPAQUE)?OPAQUE:TRANSPARENT;
if FBkmode <> nc then
begin
FBkmode := nc;
if Canvas then Canvas.OnFontbkmodeChange();
end
end
function Setheight(v)
begin
if ifnumber(v)and v <> Fheight then
begin
Fheight := v;
onchange();
end
end
function Setwidth(v)
begin
if ifnumber(v)and v <> Fwidth then
begin
Fwidth := v;
onchange();
end
end
function Setescapement(v)
begin
if ifnumber(v)and v <> Fescapement then
begin
Fescapement := v;
onchange();
end
end
function Setorientation(v)
begin
if ifnumber(v)and v <> Forientation then
begin
Forientation := v;
onchange();
end
end
function Setweight(v)
begin
if not(v=400 or v=700)then return;
if v <> Fweight then
begin
Fweight := v;
onchange();
end
end
function Setitalic(v)
begin
nv := v?true:false;
if nv <> Fitalic then
begin
Fitalic := nv;
onchange();
end
end
function Setunderline(v)
begin
nv := v?true:false;
if nv <> Funderline then
begin
Funderline := nv;
onchange();
end
end
function Setstrikeout(v)
begin
nv := v?true:false;
if nv <> Fstrikeout then
begin
Fstrikeout := nv;
onchange();
end
end
function Setcharset(v)
begin
if ifnumber(v)and v <> Fcharset then
begin
Fcharset := v;
onchange();
end
end
function Setoutprecision(v)
begin
if not(v in array(OUT_DEFAULT_PRECIS,OUT_DEVICE_PRECIS,OUT_OUTLINE_PRCIS,OUT_RASTER_PRECIS,
OUT_STRING_PRECIS,OUT_STROKE_PRECIS,OUT_TT_ONLY_PRECIS,OUT_TT_PRECIS))then return;
if v <> Foutprecision then
begin
Foutprecision := v;
onchange();
end
end
function Setclipprecision(v)
begin
if not ifnumber(v)then return;
if(v .&(CLIP_DEFAULT_PRECIS .| CLIP_STROKE_PRECIS .| CLIP_MASK .| CLIP_LH_ANGLES .| CLIP_TT_ALWAYS))and v <> Fclipprecision then
begin
Fclipprecision := v;
onchange();
end
end
function Setquality(v)
begin
if not(v in array(DEFAULT_QUALITY,DRAFT_QUALITY,PROOF_QUALITY))then return;
if v <> Fquality then
begin
Fquality := v;
onchange();
end
end
function Setpitchandfamily(v)
begin
if not(v in array(DEFAULT_PITCH,FIXED_PITCH,VARIABLE_PITCH,
FF_DECORATIVE,FF_MODERN,FF_ROMAN,FF_SCRIPT,FF_SWISS))then return;
if v <> Fpitchandfamily then
begin
Fpitchandfamily := v;
onchange();
end
end
function Setfacename(v)
begin
{$ifdef linux}
{$else}
if not(v in fdwfacename) then
begin
return ;
end
{$endif}
if ifstring(v)and v <> Ffacename and length(v)<= 32 then
begin
Ffacename := v;
onchange();
end
end
protected
function gdiformatstr();override;
begin
s := "";
for i,v in LOGSTRUCTarray do
begin
v0 := v[0];
s += v0;
s += ":";
if v0="facename" then
begin
s += invoke(self,"f"+v0);
end else
vvi := invoke(self,"f"+v0);
if ifnumber(vvi)then s += inttostr(vvi);
else s += "0";
s += ";";
end
r := "class:font;"+s;
return r;
end
public
function HandleNeeded();override;
begin
if not HandleAllocated()then
begin
hp := reference();
if not hp then
begin
for i,v in LOGSTRUCTarray do
begin
v0 := v[0];
LOGSTRUCT._setvalue_(v0,invoke(self,"f"+v0));
end
hp := _wapi.CreateFontIndirectA(LOGSTRUCT._getptr_);
addsource(hp);
end
FHandle := hp;
end
return FHandle;
end
function fontinfo();
begin
{**
@explan(˵Ã÷) »ñµÃ×ÖÌåÐÅÏ¢ %%
**}
r := array();
for i,v in LOGSTRUCTarray do
begin
r[v[0]]:= invoke(self,v[0]);
end
r["color"]:= color;
r["bkcolor"]:= bkcolor;
return r;
end
function create();override;
begin
inherited;
fdwfacename := array( "ÐÂËÎÌå","ËÎÌå","Courier New");
fheight := 15;
fwidth := 7;
fescapement := 0;
forientation := 0;
fweight := 400;
fitalic := 0;
funderline := 0;
fstrikeout := 0;
fcharset := 134;
foutprecision := 3;
fclipprecision := 2;
fquality := 1;
fpitchandfamily := FIXED_PITCH;
ffacename := "ÐÂËÎÌå";
FColor := 0;
Onchange();
end
function Onchange();override;
begin
if Canvas then Canvas.OnFontChange();
DestroyHandle();
end
function copyfont(f);virtual;
begin
{**
@explan(˵Ã÷) ×ÖÌåÐÅÏ¢¿½±´ %%
@param(f)(Tcostmtont)
**}
if not(f is class(Tcustomfont))then exit;
return SetValues(f.fontinfo());
val := array();
for i,v in LOGSTRUCTarray do
begin
v0 := v[0];
fvi := invoke(f,v0);
val[v0]:= fvi;
end
val["color"]:= f.color;
val["bkcolor"]:= f.bkcolor;
return SetValues(val);
end
function SetValues(vs);virtual;
begin
{**
@explan(˵Ã÷) ͨ¹ýÊý×éÉèÖÃ×ÖÌåÊôÐÔ %%
@param(vs)(array)×ÖÌåÐÅÏ¢Êý¾Ý %%
**}
if not ifarray(vs)then exit;
for i,v in LOGSTRUCTarray do
begin
v0 := v[0];
vsv := vs[v0];
{$ifdef linux}
{$else}
if v0="facename" and not(vsv in fdwfacename ) then
begin
continue;
end
{$endif}
if not ifnil(vsv)then
begin
ovi := invoke(self,"f"+v0);
if ovi <> vsv then
begin
invoke(self,"f"+v0,1,vsv);
cg := true;
end
end
end
vsc := vs["color"];
if ifnumber(vsc) and (FColor<>vsc) then
begin
cg := true;
SetColor(vsc);
end
if cg then Onchange();
return cg;
end
function GetFontWidth();
begin
if FWidth>0 then return FWidth;
return abs(FHeight)/2;
end
property height read Fheight write Setheight;
property width read Fwidth write Setwidth;
property escapement read Fescapement write Setescapement;
property orientation read Forientation write Setorientation;
property weight read Fweight write Setweight;
property italic read Fitalic write Setitalic;
property underline read Funderline write Setunderline;
property strikeout read Fstrikeout write Setstrikeout;
property charset read Fcharset write Setcharset;
property outprecision read Foutprecision write Setoutprecision;
property clipprecision read Fclipprecision write Setclipprecision;
property quality read Fquality write Setquality;
property pitchandfamily read Fpitchandfamily write Setpitchandfamily;
property facename read Ffacename write Setfacename;
property Color read FColor write SetColor;
property bkColor read FBKColor Write SetBkColor;
property bkmode read FBkmode Write SetBkMode;
end
type TFontControl=class(Tcustomfont)
{**
@explan(˵Ã÷) ¿Ø¼þ×ÖÌå %%
**}
private
[weakref]FControl;
Function SetControl(v);
begin
if(v <> FControl)and(v is class(tcontrol))then
begin
FControl := v;
end
end
protected
function Onchange();override;
begin
inherited;
if FControl then
begin
FControl.FontChanged();
end
end
public
function create();override;
begin
inherited;
end
function Recycling();override;
begin
FControl := nil;
inherited;
end
property Control read FControl write SetControl;
end
type tcustompen=class(tgdi)
private
FStyle;
FColor;
FWidth;
static LOGSTRUCT;
class function sinit();override;
begin
inherited;
if not LOGSTRUCT then
begin
LOGSTRUCTarray := array(("lopenstyle","int",0),
("lopnwidth","int",1),
("lopnwidth2","int",0),
("lopncolor","int",0));
dt := MemoryAlignmentCalculate(LOGSTRUCTarray,1,nil,nil);
LOGSTRUCT := new tslcstructureobj(dt,nil);
end
end
function HandleNeeded();override;
begin
if not HandleAllocated()then
begin
hp := reference();
if not hp then
begin
if fStyle in array(PS_NULL,PS_SOLID,PS_INSIDEFRAME)then
begin
w := FWidth;
end else
w := 0;
hp := _wapi.CreatePen(FStyle,w,FColor);
addsource(hp);
end
FHandle := hp;
end
return FHandle;
end
function gdiformatstr();override;
begin
return format("class:pen;style:%d;color:%d;width:%d",FStyle,FColor,FWidth);
end
function Onchange();override;
begin
if Canvas then Canvas.OnPenChange();
DestroyHandle();
end
function SetColor(c);
begin
if ifnumber(c)and c <> FColor then
begin
Onchange();
FColor := c;
end
end
function SetStyle(s);
begin
if(s in array(0,1,2,3,4,5,6)) and s <> FStyle then
begin
Onchange();
FStyle := s;
end
end
function SetWidth(w);
begin
if w >= 0 and w<20 and c <> FWidth then
begin
Onchange();
FWidth := w;
end
end
function copypen(p);
begin
{**
@explan(˵Ã÷)¿½±´penÊôÐÔ %%
@param(p)(tcustompen) Ô´ %%
**}
if p is class(tcustompen)then
begin
ps := p.style;
wd := p.width;
cl := p.color;
if ps <> FStyle or wd <> FWidth or cl <> FColor then
begin
Onchange();
FStyle := ps;
FWidth := wd;
FColor := cl;
end
end
end
public
function create();
begin
inherited;
FStyle := PS_SOLID;
FWidth := 1;
FColor := 0;
end
property Color read FColor write SetColor;
property Width read FWidth write SetWidth;
property Style read FStyle write SetStyle;
end
type tcustombrush=class(tgdi)
private
FStyle;
FColor;
FHatch;
static LOGSTRUCT;
function SetColor(c);
begin
if ifnumber(c)and c <> FColor then
begin
onchange();
FColor := c;
end
end
public
class function sinit();override;
begin
inherited;
if not LOGSTRUCT then
begin
LOGSTRUCTarray := array(("lbstyle","int",BS_SOLID),
("lbcolor","int",0),
("lbhatch","intptr",0));
dt := MemoryAlignmentCalculate(LOGSTRUCTarray,1,nil,nil);
LOGSTRUCT := new tslcstructureobj(dt,nil);
end
end
function onchange();override;
begin
if Canvas then Canvas.OnBrushChange();
DestroyHandle();
end
function HandleNeeded();override;
begin
if not HandleAllocated()then
begin
hp := reference();
if not hp then
begin
//LOGSTRUCT._setvalue_("lbstyle",FStyle);
//LOGSTRUCT._setvalue_("lbcolor",FColor);
//LOGSTRUCT._setvalue_("lbhatch",FHatch);
//hp := _wapi.CreateBrushIndirect(LOGSTRUCT._getptr_);
hp := _wapi.CreateSolidBrush(FColor);
addsource(hp);
end
FHandle := hp;
end
return FHandle;
end
function gdiformatstr();override;
begin
return format("class:brush;style:%d;color:%d;hatch:%d",FStyle,FColor,FHatch);
end
function create();override;
begin
inherited create();
sinit();
FStyle := BS_SOLID;
FHatch := 0;
FColor := 0;
end
function copybrush(b);
begin
if b is class(tcustombrush)then
begin
if FColor <> b.color then
begin
onchange();
FColor := b.color;
end
end
end
//property Style read FStyle write SetStyle;
property Color read FColor write SetColor;
//property Hatch read FHatch write SetHatch;
end
type TRgn = class(TSLUIBASE)
{**
@explan(˵Ã÷) ÇøÓò %%
**}
private
FHandle;
function GetHandle();
begin
if not HandleAllocated()then FHandle := CreateRgn();
return FHandle;
end
function SetHandle(v);
begin
if v <> FHandle then
begin
DestroyHandle();
if ifnumber(v)and v then FHandle := v;
end
end
public
function Create();override;
begin
inherited;
end
function HandleAllocated();
begin
return FHandle and ifnumber(FHandle);
end
function DestroyHandle();
begin
if HandleAllocated()then _wapi.DeleteObject(FHandle);
FHandle := 0;
end
function CreateRgn();virtual;
begin
return _wapi.createrectrgn(0,0,0,0);
end
class function CombineRgn(rgn1,rgn2,f,rgn);
begin
{**
@explan(˵Ã÷)rgnºÏ²¢%%
@param(rgn1)(trgn) ÇøÓò1 %%
@param(rgn2)(trgn) ÇøÓò2 %%
@param(rgn)(trgn) ·µ»ØºÏ²¢ºóµÄÇøÓò %%
@param(f)(integer) ºÏ²¢·½Ê½ RGN_AND RGN_COPY RGN_DIFF RGN_OR RGN_XOR %%
@param(integer) ·µ»Ø NULLREGION COMPLEXREGION SIMPLEREGION ERROR
**}
if(rgn1 is class(TRGN))and(rgn2 is class(TRGN))then
begin
rgn := new TRgn();
return _wapi.CombineRgn(rgn.Handle,s1.Handle,rgn2.Handle,f);
end
end
function Recycling();override;
begin
DestroyHandle();
inherited;
end
property Handle read GetHandle write SetHandle;
end
type TRGNELLIP=class(TRGN) //ÍÖÔ²
{**
@explan(˵Ã÷)ÍÖÔ²rgn
**}
private
FRect;
function SetRect(v);
begin
if v <> FRect and ifarray(v) and ifnumber(v[0])and ifnumber(v[1])and v[2]>v[0]and v[3]>v[1] then
begin
FRect := v;
DestroyHandle();
end
end
public
function create();override;
begin
inherited;
FRect := array(0,0,0,0);
end
function CreateRgn();override;
begin
return _wapi.CreateEllipticRgn(FRect[0],FRect[1],FRect[2],FRect[3]);
end
property Rect read FRect write SetRect;
end
type TRGNRECT=class(TRGNELLIP)
{**
@explan(˵Ã÷)¾ØÐÎÇøÓò%%
**}
function create();override;
begin
inherited;
end
function CreateRgn();override;
begin
rec := Rect;
return _wapi.CreateRectRgn(rec[0],rec[1],rec[2],rec[3]);
end
end
type TRGNRoundRect=class(TRGNELLIP)
{**
@explan(˵Ã÷) RoundRect rgn %%
**}
private
FEllipseWidth;
FEllipseHeight;
function SetEllipseWidth(v);
begin
if v >= 0 and v <> FEllipseWidth then
begin
FEllipseWidth := v;
DestroyHandle();
end
end
function SetEllipseHeight();
begin
if v >= 0 and v <> FEllipseHeight then
begin
FEllipseHeight := v;
DestroyHandle();
end
end
public
function Create(AOwner);override;
begin
inherited;
FEllipseHeight := 1;
FEllipseWidth := 1;
end
function CreateRgn();override;
begin
rec := Rect;
return _wapi.CreateRoundRectRgn(rec[0],rec[1],rec[2],rec[3],FEllipseWidth,FEllipseHeight);
end
property EllipseWidth:integer read FEllipseWidth write SetEllipseWidth;
property EllipseHeight:integer read FEllipseHeight write SetEllipseHeight;
end
type TRGNPOLY=class(TRGN) //¶à±ßÐÎ
{**
@explan(˵Ã÷)¶à±ßÐÎÇøÓò%%
**}
private
FPoints;
FImode;
function pointtovector(pts); //µãת»»ÎªÊý×é
begin
t := array();
lt := 0;
if not ifarray(pts)then return array();
for i,v in pts do
begin
if ifarray(v)and ifnumber(v[0])and ifnumber(v[1])then
begin
t[lt++]:= v[0];
t[lt++]:= v[1];
end
end
return t;
end
function SetImode(v);
begin
if(v in array(1,2))and v <> FImode then
begin
FImode := v;
DestroyHandle();
end
end
function SetPoints(v);
begin
if v <> FPoints then
begin
FPoints := v;
DestroyHandle();
end
end
public
function create(); //µã ºÍÌî³äģʽ
begin
inherited;
FImode := ALTERNATE;
end
function CreateRgn();override;
begin
t := pointtovector(FPoints);
len := length(t);
if len>5 then return _wapi.CreatePolygonRgn(t,len/2,FImode);
end
property Points read FPoints write SetPoints;
property Imode read FImode write SetImode;
end
type tcustomimage=class(TSLUIBASE)
{**
@explan(˵Ã÷)imageÀà²ÉÓÃgdiflat·â×° %%
**}
private
FHandle;
FGdi;
Static FImageTypes;
class function GetFileType(t_);
begin
if not(t_ and ifstring(t_))then t := "png";
else t := lowercase(t_);
if not(t in array("png","jpeg","bmp","gif","tiff"))then exit;
vp := FImageTypes[t];
if vp then return vp;
dt := MemoryAlignmentCalculate(array((0,"byte[20]",array())),1,nil,nil);
vp := new tslcstructureobj(dt,nil);
//messagebox("image/"+t,"123",0);
nt := _wapi.AnsiToWidChar("image/"+t);
vvp := _wapi.GetEncoderClsid(nt,vp._getptr_);
if vvp <>-1 then
begin
FImageTypes[t]:= vp;
end
return vp;
end
function IFhandle(h);
begin
return ifnumber(h)and h;
end
private
function ImageToStream(t);
begin
{**
@ignore(ºöÂÔ) %%
@explan(˵Ã÷) image ת»»Îªstream %%
**}
if not FHandle then exit;
vp := GetFileType(t);
_wapi.CreateStreamOnHGlobal(0,true,st);
r := gdi.GdipSaveImageToStream(FHandle,st,vp._getptr_,0);
if r <> 0 then exit;
return st;
end
public
class function sinit();override;
begin
inherited;
if not ifarray(FImageTypes)then
begin
//return ;
FImageTypes := array();
for i,v in array("png","jpeg","bmp","gif","tiff") do
begin
GetFileType(v);
end
end
end
function create();
begin
inherited;
FHandle := 0;
FGdi := new TGdiplusflat();
end
function DestroyHandle();
begin
{**
@explan(˵Ã÷) Ïú»Ù¾ä±ú %%
**}
if IFhandle(FHandle)then
begin
gdi.GdipDisposeImage(FHandle);
end
FHandle := 0;
end
function Recycling();override;
begin
{**
@explan(˵Ã÷) »ØÊÕ %%
**}
DestroyHandle();
inherited;
end
function Destroy();override;
begin
inherited;
end
function LoadFromstr(p);
begin
if not(ifstring(p) and p) then return -1 ;
if fileexists("",p) then return LoadFromFile(p);
return StringToImage(p);
end
function LoadFromFile(path);
begin
{**
@explan(˵Ã÷)´ò¿ªÎļþ %%
@param(path)(string) ·¾¶ %%
**}
if not ifstring(path)then exit;
size := filesize("",path); //»ñÈ¡Îļþ´óС
r :=-1;
if readFile(rwraw(),"",path,0,size,data)then
begin
r := StringToImage(data);
end
return r;
//***********GdipLoadImageFromFile ±¨´í****************
fn := _wapi.AnsiToWidChar(path);
r := gdi.GdipLoadImageFromFile(fn,hd);
if hd then
begin
DestroyHandle();
FHandle := hd;
end
return r;
end
function SavetoFile(p,t);
begin
{**
@explan(˵Ã÷) ±£´æµ½Îļþ%%
@param(p)(string)·¾¶ %%
@param(t)(string)ÀàÐÍ ,"png" "bmp" "gif"
**}
if not ifstring(p)then return -1;
if not ifstring(t)then t := "png";
if not FHandle then return -1;
vp := GetFileType(t);
fn := _wapi.AnsiToWidChar(p);
return Gdi.GdipSaveImageToFile(FHandle,fn,vp._getptr_(),0);
end
function ImageToString(t);
begin
{**
@explan(˵Ã÷) µÃµ½Í¼Æ¬ÄÚ´æ%%
@param(t)(string) png bmp %%
**}
if not FHandle then exit;
/////////ÕûÀíimagetostring//////////
vp := GetFileType(t);
s := gdi.imagetostring(FHandle,vp);
return s;
end
function StringToImage(b);
begin
{**
@explan(˵Ã÷) ´Ó×Ö·û´®µ½Í¼Æ¬ %%
@param(b)(string) ÄÚ´æ %%
**}
if not(b and ifstring(b))then return 3;
////////ÕûÀí//////////////////////
r := gdi.stringtoimage(b,hd);
if hd then
begin
DestroyHandle();
FHandle := hd;
end
return r;
end
function ToHbitmap();
begin
{**
@explan(˵Ã÷) ת»»Îªbitmap %%
@return(pointer)
**}
if not FHandle then exit;
gdi.GdipCreateHBITMAPFromBitmap(FHandle,fhbmp,0xffffff);//rgb(255,255,255)
return fhbmp;
end
function FromHBitmap(bmp);
begin
{**
@explan(˵Ã÷) ´ÓbitmapµÃµ½Í¼Æ¬ %%
@param(bmp)(pointer) hbitmap
**}
if not(IFhandle(bmp))then exit;
if bmp=FHandle then exit;
gdi.GdipCreateBitmapFromHBITMAP(bmp,0,hd);
if hd then
begin
DestroyHandle();
FHandle := hd;
end
end
function FromHIcon(ico);
begin
{**
@explan(˵Ã÷) ´ÓhiconµÃµ½Í¼Æ¬ %%
@param(ico)(pointer) hicon %%
**}
if not(ifnumber(ico)and ico)then exit;
if bmp=ico then exit;
gdi.GdipCreateBitmapFromHICON(ico,hd);
if hd then
begin
DestroyHandle();
FHandle := hd;
end
end
function tohicon();
begin
{**
@explan(˵Ã÷) µÃµ½hcion %%
@return(pointer)hicon
**}
if not FHandle then exit;
gdi.GdipCreateHICONFromBitmap(FHandle,hd);
return hd;
end
property Gdi read FGdi;
property Handle Read FHandle;
{**
@param(gdi)(TGdiplusflat) gdi¶ÔÏó %%
@param(handle)(pointer) ¾ä±ú %%
**}
end
type TPicturebase=class(TSLUIBASE)
{**
@explan(˵Ã÷)bitmap,ico»ùÀà %%
**}
private
FImage;
public
function Create();override;
begin
inherited;
try
FImage := new tcustomimage();
except
raise "^~^ gdi support err!";
FImage := 0;
end;
end
function Recycling();override;
begin
FImage := nil;
inherited;
end
property Image read FImage;
end
type TcustomBitmap = class(TPicturebase)
{**
@explan(˵Ã÷) bitmap Àà %%
**}
private
FHandle;
FId;
FDestroy;
FBytes;
FDIBites;
FBitmap;
static FsysBitmaps;
static FSHDC;
static FSHDC2;
class function sinitdc();
begin
if not FSHDC then
begin
FSHDC := _wapi.CreateCompatibleDC(0);
FSHDC2 := _wapi.CreateCompatibleDC(0);
end
end
function getvalue(n);
begin
case n of
"bmtype":return FBitmap.bmtype;
"bmwidth":return FBitmap.bmwidth;
"bmheight":return FBitmap.bmheight;
"bmwidthbytes":return FBitmap.bmwidthbytes;
"bmplanes":return FBitmap.bmplanes;
"bmbitspixel":return FBitmap.bmbitspixel;
end
end
function setvalue(n,v);
begin
case n of
"bmtype" : FBitmap.bmtype :=v ;
"bmwidth" : FBitmap.bmwidth :=v ;
"bmheight" : FBitmap.bmheight :=v ;
"bmwidthbytes" : FBitmap.bmwidthbytes:=v ;
"bmplanes" : FBitmap.bmplanes :=v ;
"bmbitspixel" : FBitmap.bmbitspixel :=v ;
end ;
end
function SetHandle(h);
begin
{**
@explan(˵Ã÷) ÉèÖþä±ú %%
**}
if h=FHandle then exit;
if HandleAllocated()then DestroyHandle();
FDIBites := FBytes := "";
FHandle := h;
ReadhInfo();
end
Function ReadhInfo();
begin
{**
@explan(˵Ã÷) »ñÈ¡ÐÅÏ¢ %%
**}
if HandleAllocated()and FBitmap then
begin
_wapi.GetObjectA(FHandle,FBitmap._size_(),FBitmap._getptr_());
end
end
function setid(aid);virtual;
begin
{**
@explan(˵Ã÷) ÉèÖÃid %%;
**}
if aid <> FId then
begin
Fid := aid;
DestroyHandle();
if ifnumber(aid)then h := loadsysbmp(aid);
if h then
begin
AutoDestroy := false; //²»É¾³ý
end else
begin
//h := getresourcebyid(aid,array("type":"bmp"));
if not h then
begin
if Image then
begin
//echo "\r\nloadok:",
Image.LoadFromstr(aid);
//echo "\r\n=================readhandle:",Image.Handle;
h := Image.ToHbitmap();
end
end
AutoDestroy := true; //ɾ³ý
end
if h then
begin
SetHandle(H);
end
end
end
protected
class function loadsysbmp(aid);virtual;
begin
{**
@explan(˵Ã÷) »ñȡϵͳµÄbitmap¾ä±ú %%
@param(aid)(menuber of TSystemBitmap) id %%
@return(hbitmap) ¾ä±ú %%
**}
if not ifarray(FsysBitmaps)then FsysBitmaps := array();
r := FsysBitmaps[aid];
if r then return r;
else
begin
r := _wapi.LoadBitmapA2(nil,aid);
FsysBitmaps[aid]:= r;
end
return r;
end
function DestroyHandle();virtual;
begin
{**
@explan(˵Ã÷) Îö¹¹¾ä±ú %%
**}
if HandleAllocated()and FDestroy then _wapi.DeleteObject(FHandle);
FHandle := 0;
FBytes := "";
end
public
function HandleAllocated();
begin
{**
@explan(˵Ã÷) ÅжÏÊÇÓоä±ú %%
@return(bool)
**}
return ifnumber(FHandle)and(FHandle <> 0);
end
function create();override;
begin
inherited;
FBitmap := new TSHBMP(nil);
FDestroy := true;
end
function draw(dc,x,y,flag,rect);
begin
{**
@explan(˵Ã÷) Õ³Ìùµ½hdc %%
@param(dc)(tcustomcanvas) canvas ¶ÔÏó%%
@param(x)(integer) canvas ÖеÄxλÖÃ%%
@param(y)(integer) canvas ÖеÄyλÖÃ%%
@param(rect)(array) bimap µÄ·¶Î§ array(×óÉÏÓÒÏÂ)%%
@param(flag)(member of TRasterOperationConst) ¹âÕ¤²Ù×÷Âë %%
**}
if(dc is class(tcustomcanvas))and dc.HandleAllocated()and HandleAllocated()then
begin
sinitdc();
bw1 := FBitmap.bmwidth;
bh1 := FBitmap.bmheight;
rc := array(0,0,bw1,bh1);
if ifarray(rect)then
begin
if intersectrect(rc,rect,irect)then rc := irect;
end
return _wapi.drawbitmaptodc(FHandle,dc.Handle,x,y,rc,flag,FSHDC);
oldmp := _wapi.SelectObject(FSHDC,FHandle);
if not flag then flag := SRCCOPY;
r := _wapi.BitBlt(dc.handle,x,y,rc[2]-rc[0],rc[3]-rc[1],FSHDC,rc[0],rc[1],flag);
if oldmp then _wapi.SelectObject(FSHDC,oldmp);
return r;
end
end
function StretchDraw(dc,drect,flag,brect);
begin
{**
@explan(˵Ã÷) Õ³Ìùµ½hdc %%
@param(dc)(tcustomcanvas) canvas ¶ÔÏó%%
@param(drect)(array) canvas µÄ·¶Î§ array(×óÉÏÓÒÏÂ)%%
@param(brect)(array) bimap µÄ·¶Î§ array(×óÉÏÓÒÏÂ)%%
@param(flag)(member of TRasterOperationConst) ¹âÕ¤²Ù×÷Âë %%
**}
if not(ifarray(drect))then return-1;
if(dc is class(tcustomcanvas))and dc.HandleAllocated()and HandleAllocated()then
begin
sinitdc();
bw1 := FBitmap.bmwidth;
bh1 := FBitmap.bmheight;
rc := array(0,0,bw1,bh1);
if ifarray(brect)then if intersectrect(rc,brect,irect)then rc := irect;
return _wapi.drawbitmapstretchtodc(FHandle,dc.Handle,drect,rc,flag,FSHDC);
oldmp := _wapi.SelectObject(FSHDC,FHandle);
if not flag then flag := SRCCOPY;
r := _wapi.StretchBlt(dc.handle,drect[0],drect[1],drect[2]-drect[0],drect[3]-drect[1],FSHDC,rc[0],rc[1],rc[2]-rc[0],rc[3]-rc[1],flag);
if oldmp then _wapi.SelectObject(FSHDC,oldmp);
end
return r;
end
function Readvcon(d);override;
begin
{**
@expaln(˵Ã÷)¶ÁÈ¡¶þ½øÖÆÐÅÏ¢ %%
**}
if Image and ifarray(d)and d["type"]="img" then
begin
Image.StringToImage(d["data"]);
bthandle := Image.ToHbitmap();
SetHandle(bthandle);
AutoDestroy := true;
return;
end
end
function tovcon();override;
begin
{**
@expaln(˵Ã÷)ת»»ÎªÊý¾Ý %%
**}
r := nil;
if Image and HandleAllocated()then
begin
r := array();
r["type"]:= "bmp";
Image.FromHBitmap(FHandle);
r["type"]:= "img";
r["data"]:= Image.ImageToString("png");
end
return r;
end
function CopyRect(x,y,w,h);
begin
{**
@explan(˵Ã÷) ¿½±´Î»Í¼ %%
**}
r := nil;
if HandleAllocated()then
begin
if x<0 or y<0 or w<0 or h<0 then return r;
if x+wd>FBitmap.bmwidth then return r;
if y+h>FBitmap.bmheight then return r;
wd1 := FBitmap.bmwidthbytes/FBitmap.bmwidth;
r := array();
r["type"]:= "bmp";
r["width"]:= w;
r["bmwidthbytes"]:= wd1 * w;
r["bmplanes"]:= FBitmap.bmplanes;
r["bmbitspixel"]:= FBitmap.bmbitspixel;
r["height"]:= h;
sbt := BmpBits;
sbt2 := "";
setlength(sbt2,wd1 * w * h * 2);
hr := FBitmap.bmwidthbytes;
jj := 1;
sx := x * wd1;
ex := sx+w * wd1-1; //(x+w)*wd1-1;
for ri := y to y+h-1 do
begin
for ci := sx to ex do
begin
if ri * hr+ci+1>length(sbt)then break;
v := sbt[ri * hr+ci+1];
sbt2[jj++]:= v;
end
end
r["bytes"]:= sbt2[1:(wd1 * w * h)];
rt := new tcustombitmap();
rt.readvcon(r);
return rt;
end
return r;
end
function ToBMPFileString();
begin
if Image and HandleAllocated()then
begin
r := array();
Image.FromHBitmap(FHandle);
return Image.ImageToString("bmp");
end
return "";
end
function ToIcon();
begin
{**
@explan(˵Ã÷)½«Î»Í¼×ª»»Îªicon %%
@return(ticon|nil) ³É¹¦·µ»ØÍ¼±ê %%
**}
if HandleAllocated()then
begin
Image.FromHBitmap(FHandle);
thandle := Image.tohicon(); //²ÉÓÃgdi+
if not thandle then return 0;
r := new tcustomicon();
r.Handle := tHandle;
return r;
end
return nil;
end
function Recycling();override;
begin
DestroyHandle();
FBitmap := nil;
inherited;
end
property id read FId write SetID;
property Handle:pointer read FHandle write SetHandle;
property AutoDestroy:bool read FDestroy write FDestroy;
//property BmpBits read GetBits;
//property DIBits read GetDIBits;
property bmtype index "bmtype" read getvalue write setvalue ;
property bmwidth index "bmwidth" read getvalue write setvalue;
property bmheight index "bmheight" read getvalue write setvalue;
property bmwidthbytes index "bmwidthbytes" read getvalue write setvalue;
property bmplanes index "bmplanes" read getvalue write setvalue;
property bmbitspixel index "bmbitspixel" read getvalue write setvalue;
{**
@param(id)() ×ÊÔ´id %%
@param(Handle)() ¾ä±ú %%
@param(AutoDestroy)() Îö¹¹Ê±Ïú»Ù¾ä±ú %%
**}
end
type TcustomIcon = class(TPicturebase)
private
{**
@explan(˵Ã÷) ͼ±ê¶ÔÏóÀà %%
**}
FHandle;
FId;
FMask;
FDestroy;
FMaskBMP;
FColorBMP;
FHICON;
FHandleChanged;
static FSystemIcons;
function getvalue(n);
begin
if not FHICON then return 0;
if FHandleChanged then ReadhInfo();
case n of
"ficon": return FHICON.ficon;
"xhotspot": return FHICON.xhotspot;
"yhotspot": return FHICON.yhotspot;
"hbmmask": return FHICON.yhotspot;
"hbmcolor": return FHICON.hbmcolor;
end
end
function setvalue(n,v);
begin
if not FHICON then return 0;
if FHandleChanged then ReadhInfo();
case n of
"ficon": return FHICON.ficon := v;
"xhotspot": return FHICON.xhotspot := v;
"yhotspot": return FHICON.yhotspot := v;
"hbmmask": return FHICON.yhotspot := v;
"hbmcolor": return FHICON.hbmcolor := v;
end
end
function SetHandle(h);
begin
{**
@explan(˵Ã÷) ÉèÖþä±ú %%
**}
if HandleAllocated()then DestroyHandle();
FHandle := h;
FHandleChanged := true;
end
function GetMaskBitMap();
begin
if FHandleChanged then ReadhInfo();
return FMaskBMP;
end
function GetColorBitMap();
begin
if FHandleChanged then ReadhInfo();
return FColorBMP;
end
Function ReadhInfo();
begin
{**
@explan(˵Ã÷) »ñÈ¡ÐÅÏ¢ %%
**}
if FHandleChanged and HandleAllocated()and FHICON then
begin
_wapi.GetIconInfo(FHandle,FHICON._getptr_());
FHandleChanged := false;
if hbmcolor then
begin
FColorBMP := new TcustomBitmap();
FColorBMP.AutoDestroy := true;
FColorBMP.Handle := hbmcolor;
end
if hbmmask then
begin
FMaskBMP := new TcustomBitmap();
FMaskBMP.AutoDestroy := true;
FMaskBMP.handle := hbmmask;
end
end
FHandleChanged := false;
end
function setid(r);
begin
{**
@explan(˵Ã÷) ÉèÖÃid %%;
**}
if r <> FId then
begin
Fid := r;
DestroyHandle();
if ifnumber(r)then h := loadsysico(r);
if h then
begin
FDestroy := false;
end else
begin
//h := getresourcebyid(r,array("type":"ico"));
if not h then
begin
if Image then
begin
Image.LoadFromstr(r);
h := Image.tohicon();
end
end
FDestroy := true;
end
if H then SetHandle(H);
end
end
protected
class function loadsysico(aid);virtual;
begin
if not ifarray(FSystemIcons)then FSystemIcons := array();
r := FSystemIcons[aid];
if r then return r;
r := _wapi.LoadIconA2(nil,aid);
FSystemIcons[aid]:= r;
return r;
end
function DestroyHandle();virtual;
begin
{**
@explan(˵Ã÷) Îö¹¹¾ä±ú %%
@return(bool)
**}
if HandleAllocated()and FDestroy then _wapi.DestroyIcon(FHandle);
FBitmap := nil;
FMaskBMP := nil;
FColorBMP := nil;
FHandle := 0;
end
public
function HandleAllocated();
begin
{**
@explan(˵Ã÷) ÅжÏÊÇÓоä±ú %%
**}
return ifnumber(FHandle)and(FHandle <> 0);
end
function create();
begin
inherited;
FHICON := new TSHICON(nil);
FDestroy := true;
end
function Recycling();override;
begin
DestroyHandle();
FHICON := nil;
inherited;
end
function destroy();override;
begin
inherited;
end
function Tobitmap();
begin
{**
@explan(˵Ã÷) ½«icoת»»Îªbitmap %%
@return(nil|TcustomBitmap)
**}
if HandleAllocated()and FImage then
begin
FImage.FromHIcon(FHandle);
Hbm := FImage.ToHbitmap();
if hbm then
begin
r := new TcustomBitmap();
TBitmap.Handle := Hbm;
return r;
end
end
return nil;
end
function readvcon(d);override;
begin
if Image and ifarray(d)and d["type"]="img" then
begin
Image.StringToImage(d["data"]);
bthandle := Image.tohicon();
SetHandle(bthandle);
AutoDestroy := true;
end
end
function tovcon();override;
begin
r := nil;
if Image and HandleAllocated()then
begin
r := array("type":"ico");
r["ficon"]:= ficon;
r["type"]:= "img";
Image.FromHIcon(FHandle);
r["data"]:= Image.ImageToString("png");
end
return r;
end
published
property id read FId write SetID;
property Handle read FHandle write SetHandle;
property MaskBMP:tbitmap read GetMaskBitMap;
property ColorBMP:tbitmap read GetColorBitMap;
property AutoDestroy read FDestroy write FDestroy;
property ficon index "ficon" read getvalue write setvalue;
property xhotspot index "xhotspot" read getvalue write setvalue;
property yhotspot index "yhotspot" read getvalue write setvalue;
property hbmmask index "hbmmask" read getvalue write setvalue;
property hbmcolor index "hbmcolor" read getvalue write setvalue;
{**
@param(id)(integer|string) ×ÊÔ´id %%
@param(Handle)(intptr) ¾ä±ú %%
@param(MaskBMP)(TcustomBitmap) maskλͼ %%
@param(ColorBMP)(TcustomBitmap) colorλͼ %%
@param(AutoDestroy)(bool) ÊÇ·ñ×Ô¶¯ÊÇ·ñ×ÊÔ´ %%
**}
end
type tcustomcursor=class(tcustomicon)
{**
@explan(˵Ã÷)¹â±êÀà %%
**}
private
static FSystemCursors;
protected
class function loadsysico(id);override;
begin
{**
@param(id)(member of TSystemCursor) cursor id %%
@return(pointer) ¾ä±ú %%
**}
if not ifarray(FSystemCursors)then FSystemCursors := array();
r := FSystemCursors[id];
if r then return r;
r := _wapi.LoadCursorA2(nil,id);
if r then FSystemCursors[id]:= r;
return r;
end
public
function create();override;
begin
inherited;
end
function show();override;
begin
{**
@explan(˵Ã÷) ÏÔʾ¹â±ê
**}
if HandleAllocated()then
begin
//hd := _wapi.SetCursor(_wapi.LoadCursorA2(0,IDC_WAIT));
hd := _wapi.SetCursor(self.Handle);
return hd;
end
end
function Recycling();override;
begin
inherited;
end
end
type TCustomImageList=class(tcomponent)
{**
@explan(˵Ã÷) imgelist Àà·â×° %%
**}
private
FHeight; //¸ß¶È
FWidth; //¿í¶È
FHandle; //¾ä±ú
FInitialCount;
FAutoDestroy; //ÊÇ·ñÏú»Ù¾ä±ú
FCGrow;
FimageCount; //³¤¶È
FOnChange;
FChanged;
FBKColor;
FImages;
FDrawBimpFirst;
FBmpItems;
FBmpAdding;
function inDesigning();
begin
return csDesigning in ComponentState;
end
function addbmps();
begin
if ifarray(FImages)and FImages["type"]="bmps" then
begin
DestroyHandle();
for i,vi in FImages["items"] do
begin
addbmp(vi);
end
FChanged := true;
change();
end
end
function SetImages(v);
begin
if v=FImages then exit;
FImages := v;
if inDesigning()then
begin
//return ;
end
addbmps();
end
function GetImages();
begin
return FImages;
end
function change();virtual;
begin
{**
@explan(˵Ã÷) ÐÞ¸ÄʱµÄ»Øµ÷ %%;
**}
if FChanged and (iffuncptr(FOnChange)) then call(FOnChange,self(true));
FChanged := false;
end
function GetIconSize();
begin
{**
@explan(˵Ã÷) »ñµÃλͼµÄ¸ß¶ÈºÍ¿í¶È %%
@return(array) array(cx,cy) %%
**}
x := y := 0;
_wapi.ImageList_GetIconSize(FHandle,x,y);
r := array(x,y);
return r;
end
function setbkcolor(c);
begin
if not ifnumber(c)then exit;
if c <> FBKColor then
begin
FBKColor := c;
if HandleAllocated()then
begin
_wapi.ImageList_SetBkColor(FHandle,c);
end
end
end
function readinfo()
begin
{**
@explan(˵Ã÷) ¶ÁÈ¡ÐÅÏ¢ %%
**}
if HandleAllocated()then
begin
FimageCount := 0;
FimageCount := _wapi.ImageList_GetImageCount(FHandle);
xy := GetIconSize();
FBKColor := _wapi.ImageList_GetBkColor(FHandle);
FWidth := xy[0];
FHeight := xy[1];
end
end
function indexvalidate(i);
begin
{**
@explan(˵Ã÷) ÊÇ·ñÓÐЧ %%
**}
return HandleAllocated()and i<FimageCount and i>-0.5;
end
function hcreateimagelist();
begin
if not HandleAllocated()then
begin
hd := _wapi.ImageList_Create(FWidth,FHeight,0x00000001,FInitialCount,FcGrow);
if hd then
begin
_wapi.ImageList_SetBkColor(hd,FBKColor);
SetHandle(hd);
FAutoDestroy := true;
FChanged := true;
change();
end
end
end
protected
function SetHandle(H);
begin
{**
@explan(˵Ã÷) ÉèÖþä±ú %%
**}
if h and ifnumber(h)and h <> FHandle then
begin
DestroyHandle();
FHandle := h;
readinfo();
FAutoDestroy := true;
end
end
function SetWidth(w);
begin
if w>0 and w <> FWidth then
begin
FWidth := w;
FChanged := true;
DestroyHandle();
addbmps();
//if inDesigning()then
change();
end
end
function SetHeight(h);
begin
if h>0 and FHeight <> h then
begin
FHeight := h;
FChanged := true;
DestroyHandle();
addbmps();
//if inDesigning()then
change();
//if not inDesigning() then DestroyHandle();
end
end
function HandleNeeded();
begin
if not HandleAllocated()then hcreateimagelist();
return FHandle;
end
public
function create(Owner);override;
begin
FcGrow := 100;
FWidth := 24;
FHeight := 24;
FInitialCount := 100;
FAutoDestroy := true;
FimageCount := 0;
FBKColor :=0xffffff ;//rgb(255,255,255);
FBmpItems := new tnumindexarray();
//FDrawBimpFirst := true;
inherited;
end
function HandleAllocated();
begin
{**
@explan(˵Ã÷) ¾ä±úÊÇ·ñÓÐЧ %%
**}
return ifnumber(FHandle)and FHandle <> 0;
end
function DestroyHandle();
begin
{**
@explan(˵Ã÷)Ïú»Ù¾ä±ú %%
**}
if HandleAllocated()and FAutoDestroy then _wapi.ImageList_Destroy(FHandle);
FHandle := 0;
FimageCount := 0;
FBmpItems := new tnumindexarray();
end
function add(Image,Mask);
begin
{**
@ignore ºöÂÔ%%
@explan(˵Ã÷) Ìí¼Óλͼ %%
**}
if not FAutoDestroy then exit;
if not(Image is class(tcustombitmap))then exit;
HandleNeeded();
r :=-1;
if mask is class(tcustombitmap)then
begin
r := _wapi.ImageList_Add(FHandle,Image.Handle,Mask.Handle);
end else
if ifnumber(mask)then
begin
r := _wapi.ImageList_AddMasked(FHandle,Image.Handle,Mask);
end else
r := _wapi.ImageList_Add(FHandle,Image.Handle,nil);
if r>-0.5 then
begin
FimageCount := _wapi.ImageList_GetImageCount(FHandle);
end
return r;
end
function addbmp(bmp);
begin
{**
@explan(˵Ã÷) Ìí¼Óbitmap µ½imagelist %%
@param(bmp)(tcustombitmap) %%
**}
if not FAutoDestroy then exit;
if not(bmp is class(tcustombitmap))then exit;
HandleNeeded();
if not(HandleAllocated())then exit;
ct := FimageCount;
FBmpAdding := true;
try
addIcon(bmp.ToIcon());
if FimageCount>ct then
begin
//////////////¿½±´bitamp²»Ïú»Ù///////////////////
nbmp := new tcustombitmap();
bmp.AutoDestroy := false;
nbmp.Handle := bmp.Handle;
nbmp.AutoDestroy := true;
//////////////////////////////
FBmpItems.push(nbmp);
end
finally
FBmpAdding := false;
end;
end
function addIcon(ico);
begin
{**
@explan(˵Ã÷) Ìí¼Óͼ±ê %%;
**}
if not(ico is class(tcustomicon))then exit;
if not(ico.HandleAllocated())then exit;
HandleNeeded();
if not(HandleAllocated())then exit;
h := Handle;
_wapi.ImageList_ReplaceIcon(h,-1,ico.Handle);
ct := FimageCount;
FimageCount := _wapi.ImageList_GetImageCount(h);
if not FBmpAdding then
begin
if FimageCount>ct then
begin
FBmpItems.push(ico.Tobitmap());
end
end
return;
end
function draw(i,dc,x,y,flag);
begin
{**
@explan(˵Ã÷) »æÖÆimge %%
@param(i)(integer) ÐòºÅ %%
@param(dc)(tcustomcanvas) dc ¶ÔÏó %%
@param(x)(integer) x×ø±ê %%
@param(y)(integer) y×ø±ê %%
@param(flag)(member of TImageListDrawStyle) 񈬀 %%
**}
if not(dc is class(tcustomcanvas))then exit;
if not dc.HandleAllocated()then exit;
if indexvalidate(i)then
begin
if not(flag >= 0)then flag := ILD_NORMAL;
if DrawBimpFirst then
begin
bmp := FBmpItems[i];
if bmp then
begin
rc := array(x,y,x+height,y+width);
bmp.StretchDraw(dc,rc,(flag=ILC_COLOR4?SRCAND:nil)); //
end else
begin
_wapi.ImageList_Draw(Fhandle,i,DC.Handle,x,y,flag);
end
end else
begin
_wapi.ImageList_Draw(Fhandle,i,DC.Handle,x,y,flag);
end
end
end
function Removeimge(i);
begin
{**
@explan(˵Ã÷) ɾ³ý %%
**}
if indexvalidate(i)then
begin
if _wapi.ImageList_Remove(FHandle,i)then
begin
FBmpItems.splices(i,1);
FimageCount--;
end
end
end
function Replaceimge(i,btmap,msk);
begin
{**
@explan(˵Ã÷) Ìæ»» image %%
@param(i)(integer) λÖà %%;
@param(btmap)(tcustombitmap) λͼ %%
@param(msk)(tbitmap|hbitmap) mask %%
**}
hmsk := 0;
if indexvalidate(i)then
begin
if(btmap is class(tcustombitmap))and(btmap.HandleAllocated())then
begin
if(msk is class(tcustombitmap))and(msk.HandleAllocated())then hmsk := msk.Handle;
else if ifnumber(mask)then hmsk := mask;
if _wapi.ImageList_Replace(FHandle,i,btmap.Handle,hmsk)then
begin
FBmpItems.splices(i,1,array(btmap));
end
end
end
end
function GetIcon(i,flag);
begin
{**
@explan(˵Ã÷) »ñÈ¡ticon ¶ÔÏó %%
@param(i)(integer) ÐòºÅ %%
@param(flag)(member of TImageListDrawStyle) Ñùʽ %%
**}
if HandleAllocated()and i<FimageCount and i>-0.5 then
begin
hi := _wapi.ImageList_GetIcon(FHandle,i,flag);
if hi then
begin
r := new tcustomicon();
r.handle := hi;
r.AutoDestroy := true;
return r;
end
end
end
function loadfromsysbmp(id,cx,cGrow);
begin
{**
@ignore ºöÂÔ %%
@explan(˵Ã÷) µ¼ÈëϵͳλͼÉú³Éimagelist %%
**}
hd := _wapi.ImageList_LoadImageA2(nil,id,cx,cGrow,CLR_NONE,IMAGE_BITMAP,LR_SHARED);
SetHandle(hd);
end
function GetHotSpot();virtual;
begin
return array(0,0);
end
function Recycling();override;
begin
DestroyHandle();
FOnChange := nil;
inherited;
end
function destroy();override;
begin
inherited;
end
function SetSysImageListHandle(h);
begin
{**
@ignore ºöÂÔ %%
@explan(˵Ã÷) ÉèÖù¹ÔìºÃµÄiamgelist µ½¶ÔÏó,ĬÈϲ»Ïú»Ù %%
**}
if h <> FHandle then
begin
SetHandle(H);
FAutoDestroy := false;
end
end
published
property Handle read HandleNeeded write SetHandle;
property AutoDestroy read FAutoDestroy write FAutoDestroy;
property ImageCount read FimageCount;
property Height read FHeight write Setheight;
property Width read FWidth write SetWidth;
property imgHeight:integer read FHeight write Setheight;
property imgWidth:integer read FWidth write SetWidth;
property OnChange read FOnChange write FOnChange;
property BkColor:COLORREF read FBKColor write setbkcolor;
property Images:imagesdata read GetImages write SetImages;
property DrawBimpFirst read FDrawBimpFirst write FDrawBimpFirst;
{**
@param(Handle)(HIMAGELIS) imagelist¾ä±ú %%
@param(AutoDestroy)(bool) ÊÇ·ñÏú»Ù¾ä±ú %%
@param(ImageCount)(integer) ͼ±êÊýÁ¿ %%
@param(OnChange)(function[TCustomImageList]) ¸Ä±äʱµÄ»Øµ÷ %%
**}
end
type tcustomcontrolimagelist=class(TCustomImageList)
{**
@explan(˵Ã÷) ¿Ø¼þimagleit %%
**}
private
FImageControls;
public
function HandleChanged();virtual;
begin
{**
@explan(˵Ã÷) ¾ä±ú·¢Éú±ä»¯ %%
**}
for i := 0 to FImageControls.Count-1 do
begin
FImageControls[i].ImageChanged();
end
end
function create(AOwner);override;
begin
inherited;
FImageControls := new TFpList();
OnChange := thisfunction(HandleChanged);
end
function addControl(v);
begin
id := FImageControls.indexof(v);
if id=-1 then
begin
FImageControls.append(v);
end
end
function deleteControl(v);
begin
{**
@explan(˵Ã÷) ɾ³ý¿Ø¼þ %%
**}
id := FImageControls.indexof(v);
if id >= 0 then
begin
v.ImageList := nil; //ÉèÖÃΪ¿Õ
FImageControls.deli(id);
end
end
function Recycling();override;
begin
{**
@explan(˵Ã÷) »ØÊÕ¿Õ¼ä%%
**}
while FImageControls.Count>0 do
begin
deleteControl(FImageControls[0]);
end
inherited;
end
end
type TcustomCanvas = class(TSLUIBASE)
{**
@explan(˵Ã÷) »­²¼¶ÔÏó %%
**}
private
FHandle;
FFont;
FBrush;
FPen;
FState;
FTEXTMETRICA;
FSaveGdi;
FRgn;
FCounter;
FTabLength;
FTabLenParam;
_xformobj;
static FHDC;
type TCounter=class
private
FCurrentId;
public
function clean();
begin
FCurrentId := 0;
end
function Create();
begin
FCurrentId := 0;
end
function InCrease();
begin
FCurrentId++;
end
function DeCrease();
begin
if FCurrentId>0 then FCurrentId--;
end
property CurrenId read FCurrentId;
end
function SetTextTabLen(v);
begin
nv := integer(v);
if nv <> FTabLength then
begin
FTabLength := nv;
if not FTabLenParam then FTabLenParam := new Ttagdrawtextparams();
FTabLenParam.itablength := nv;
end
end
function SetPen(p);
begin
FPen.copypen(p);
end
function SetFont(f);
begin
if ifarray(f)then
begin
FFont.SetValues(f);
end else
FFont.copyfont(f);
end
function SetBrush(b);
begin
FBrush.copybrush(b);
end
function SelectObject(hgdi);
begin
if HandleAllocated()then
begin
return _wapi.SelectObject(FHandle,hgdi);
end
end
function SetHandle(h);
begin
if ifnumber(h)then
begin
flashhandle();
if FHandle <> h then
begin
FCounter.clean();
end
FHandle := h;
if h then
begin
_wapi.GetTextMetricsA(FHandle,FTEXTMETRICA._getptr_);
end
end
end
function flashhandle();
begin
FState := 1+2+4+8+16+32+64;
end
function ifrect(rect);
begin
return ifarray(rect)and ifnumber(rect[0])and ifnumber(rect[1])and ifnumber(rect[2])and ifnumber(rect[3]);
end
function pointtovector(pts); //µãת»»ÎªÊý×é
begin
{**
@explan(˵Ã÷) ½«Á½ÁеĶþάÊý×éת»»ÎªÒ»Î¬Êý×é %%
@param(pts)(array) һάµÄÊý×é%%
@return(array) Á½ÁÐÊý×é %%
**}
{**
@example(µãÊý×éת»»ÎªÒ»Î¬Êý×é)
// array((x1,y1),(x2,y2),(x3,y3)...) => array(x1,y1,x2,y2,x3,y3,...)
a := array((1,2),(3,4));
return pointtovector(a);//array(1,2,3,4);
**}
t := array();
lt := 0;
if not ifarray(pts)then return array();
for i,v in pts do
begin
if ifarray(v)and ifnumber(v[0])and ifnumber(v[1])then
begin
t[lt++]:= v[0];
t[lt++]:= v[1];
end
end
return t;
end
public
function GetTextExtent(s,mul);
begin
{**
@explan(˵Ã÷) »ñµÃ ×Ö·û´®»æÖÆ¿í¶ÈºÍ¸ß¶È %%
@param(s)(string) ×Ö·û´® %%
@param(mul)(bool) ¶àÐРĬÈ϶àÐÐtrue%%
**}
r := array(0,0);
if ifstring(s)and HandleAllocated()then
begin
requiregdi();
if ifnil(mul)then mul := true;
if mul then
begin
ss := str2array(s,"\n");
if length(ss)then
begin
for i,v in ss do
begin
ri := array(0,0);
vi := trim(v);
if not vi then vi := "\r";
_wapi.GetTextExtentPoint32A2(FHandle,vi,length(v),ri);
r[0]:= max(r[0],ri[0]);
r[1]+= ri[1];
end
end
end else
_wapi.GetTextExtentPoint32A2(FHandle,s,length(s),r);
end
return r;
end
(*function SelectClipRgn(rgn);
begin
{**
@explan(˵Ã÷) ÉèÖÃÇøÓò %%
@param(rgn)(TRgn) Ñ¡ÔñÇøÓò %%
**}
if rgn and (rgn=FRgn) then exit;
r := FRgn;
FRgn := rgn;
if not HandleAllocated()then exit;
if FRgn is class(TRgn)then
begin
r1 := _wapi.SelectClipRgn(FHandle,FRgn.Handle);
end else
begin
r1 := _wapi.SelectClipRgn(FHandle,nil);
end
if r is class(trgn)then return r;
return r1;
end*)
function create();override;
begin
inherited;
FTabLength := 0;
FCounter := new TCounter();
FHandle := 0;
FState := 0;
FPen := new tcustompen();
FPen.Canvas := self;
FBrush := new tcustombrush();
FBrush.Canvas := self;
FFont := new Tcustomfont();
FFont.Canvas := self;
FTEXTMETRICA := new ttagTEXTMETRICA();
_xformobj := new Ttagxform();
end
function Recycling();override;
begin
{**
@explan(˵Ã÷)×ÊÔ´»ØÊÕ %%
**}
FBrush.Recycling();
FPen.Recycling();
FBrush := nil;
FPen := nil;
FState := nil;
inherited;
end
function destroy();override;
begin
inherited;
end
function HandleAllocated();
begin
{**
@explan(˵Ã÷) ÅжÏcanvas¾ä±úÊÇ·ñ¹¹Ôì %%
@return(bool)
**}
return ifnumber(FHandle)and(FHandle <> 0);
end;
procedure requiregdi(rq);
begin
{**
@explan(˵Ã÷) ³õʼ»¯gdi¶ÔÏó Èç»­Ë¢ »­±Ê µÈ %%
**}
if HandleAllocated()then
begin
if FState .& 1 then
begin
SelectObject(FPen.Handle);
end
if FState .& 2 then
begin
SelectObject(FBrush.Handle);
end
if FState .& 4 then
begin
SelectObject(FFont.Handle);
end
if FState .& 8 then
begin
_wapi.SetTextColor(FHandle,FFont.Color);
end
if FState .& 16 then
begin
_wapi.SetBkColor(FHandle,FFont.bkColor);
end
if FState .& 32 then
begin
_wapi.SetbkMode(FHandle,(FFont.bkmode=OPAQUE)?OPAQUE:TRANSPARENT); //OPAQUE
end
if FRgn is class(trgn)then
begin
_wapi.SelectClipRgn(FHandle,FRgn.Handle);
end
FState := 0;
end
end
function OnFontbkmodeChange();
begin
FState .|= 32;
end
function OnPenChange();
begin
FState .|= 1;
end
function OnBrushChange();
begin
FState .|= 2;
end
function OnFontChange();
begin
FState .|= 4;
end
function OnFontColorChange();
begin
FState .|= 8;
end
function OnFontbkColorChange();
begin
FState .|= 16;
end
function SetViewportOrg(xy);
begin
{**
@explan(˵Ã÷)ÉèÖÃÑ¡Ôñ»ù×¼µã %%
@param(xy)(array) array(x,y)%%
@return(integer) %%
**}
if HandleAllocated()then
begin
if not ifarray(xy)then return 0;
return _wapi.SetViewportOrgEx(FHandle,xy[0],xy[1],nil);
end
end
function SetPixel(xy,colr);
begin
{**
@explan(˵Ã÷) »­Ò»¸öÏñËØ %%
@param(xy)(array) array(x,y)%%
@param(colr)(integer) ÑÕÉ«rgbÖµ %%
@return(integer) %%
**}
if HandleAllocated()then return _wapi.SetPixel(FHandle,xy[0],xy[1],colr);
end
function fillrgn(rgn);
begin
{**
@explan(˵Ã÷)ÇøÓòÌî³ä %%
@param(rgn)(trgn) ÇøÓò %%
**}
if not HandleAllocated()then exit;
if not(rgn is class(TRgn))then exit;
_wapi.FillRgn(FHandle,rgn.Handle,FBrush.Handle);
end
function FillRect(rec); //Ìî³ä
begin
{**
@explan(˵Ã÷)Ìî³ärect %%
@param(rec)(array) ÇøÓò array(×ó,ÉÏ,ÓÒ,ÏÂ)%%
@param(br)(tcustombrush) »­Ë¢ %%
**}
if HandleAllocated()then
begin
return _wapi.FillRect(FHandle,(ifrect(rec)?rec:zeros(4)),FBrush.Handle);
end
end
function InvertRect(rec); //·´ÏòÌî³ä,recÇøÓò,br»­Ë¢
begin
{**
@explan(˵Ã÷)·´ÏòÌî³äÇøÓò %%
@param(rec)(array) ÇøÓò array(×ó,ÉÏ,ÓÒ,ÏÂ)%%
**}
if not HandleAllocated()then exit;
return _wapi.InvertRect(FHandle,rec,FBrush.Handle);
end
function moveto(pos);
begin
{**
@explan(˵Ã÷)ÒÆ¶¯µ±Ç°µã%%
@param(pos)(array) λÖÃarray(x,y) %%
@return(array) Ô­À´Î»Öà %%
**}
ret := array(0,0);
if not ifarray(pos)then return-1;
if HandleAllocated()then
begin
_wapi.MoveToEx(FHandle,pos[0],pos[1],ret);
end
return ret;
end
function lineto(pos); //»­Ïß
begin
{**
@explan(˵Ã÷)»­Ïßµ½µã%%
@param(pos)(array) λÖÃarray(x,y) %%
**}
if not ifarray(pos)then return-1;
if HandleAllocated()then
begin
requiregdi();
return _wapi.LineTo(FHandle,pos[0],pos[1]);
end
end
function textout(str,pos); //Êä³öÎÄ×Ö,strÎÄ×Ö,pos¿ªÊ¼Î»ÖÃ
begin
{**
@explan(˵Ã÷)Êä³öÎı¾%%
@param(str)(string) ×Ö·û´® %%
@param(pos)(array) λÖÃarray(x,y) %%
**}
if not ifstring(str)then return 0;
if not ifarray(pos)then pos := array(0,0);
if HandleAllocated()then
begin
requiregdi();
return _wapi.TextOutA(FHandle,pos[0],pos[1],str,length(str));
end
end
function drawtext(str,rec,uft); //ÔÚÇøÓòÖлæÖÆÎÄ×Ö
begin
{**
@explan(˵Ã÷)ÔÚÖ¸¶¨ÇøÓòÉÏÊä³öÎı¾%%
@param(str)(string) »æÖƵÄÎÄ×Ö %%
@param(rec)(array) array(left,top,right,bottom) %%
@param(uft)(integer) DT_CALCRECT£ºÕâ¸ö²ÎÊý±È½ÏÖØÒª£¬¿ÉÒÔʹDrawTextº¯Êý¼ÆËã³öÊä³öÎı¾µÄ³ß´ç¡£
Èç¹ûÊä³öÎı¾ÓжàÐУ¬DrawTextº¯ÊýʹÓÃlpRect¶¨ÒåµÄ¾ØÐεĿí¶È£¬²¢À©Õ¹¾ØÐεĵײ¿ÒÔÈÝÄÉÊä³öÎı¾µÄ×îºóÒ»ÐС£
Èç¹ûÊä³öÎı¾Ö»ÓÐÒ»ÐУ¬ÔòDrawTextº¯Êý¸Ä±ä¾ØÐεÄÓұ߽磬ÒÔÈÝÄÉÏÂÕýÎÄÐеÄ×îºóÒ»¸ö×Ö·û¡£
³öÏÖÉÏÊöÈκÎÒ»ÖÖÇé¿ö£¬DrawTextº¯Êý½«·µ»Ø¸ñʽ»¯Îı¾µÄ¸ß¶È£¬¶ø²»ÊÇ»æÖÆÎı¾¡£
DT_CENTER£ºÖ¸¶¨Îı¾Ë®Æ½¾ÓÖÐÏÔʾ¡£
DT_VCENTER£ºÖ¸¶¨Îı¾´¹Ö±¾ÓÖÐÏÔʾ¡£¸Ã±ê¼ÇÖ»ÔÚµ¥ÐÐÎı¾Êä³öʱÓÐЧ£¬ËùÒÔËü±ØÐëÓëDT_SINGLELINE½áºÏʹÓá£
DT_SINGLELINE£ºµ¥ÐÐÏÔʾÎı¾£¬»Ø³µºÍ»»Ðзû¶¼²»¶ÏÐС£
%%
**}
if not ifstring(str)then return -1;
if not ifnumber(uft)then uft := DT_NOPREFIX; //ĬÈϺöÂÔ &ռλ·û
if not ifarray(rec)then rec := nil;
if not str then return 0;
if HandleAllocated() then
begin
requiregdi();
if FTabLength then
begin
return _wapi.DrawTextExA(FHandle,str,length(str),rec,uft .| DT_EXPANDTABS .| DT_TABSTOP,FTabLenParam._getptr_());
end else
return _wapi.DrawTextA(FHandle,str,length(str),rec,uft);
//
end
end
function StretchDraw(rec,bmp);
begin
{**
@explan(˵Ã÷) »æÖÆbitmap %%
@param(rec)(array of integer) array(×ó,ÉÏ,ÓÒ,ÏÂ) %%
@param(bmp)(tcustombitmap) λͼ %%
**}
if not(bmp is class(tcustombitmap))then exit;
bmp.StretchDraw(self,rec);
end
function DrawBitmap(bmp,p);
begin
{**
@explan(˵Ã÷)»æÖÆbitmap %%
@param(bmp)(tcustombitmap) ͼ±ê %%
@param(p)( array of integer) λÖà array(x,y)
**}
if not(bmp is class(tcustombitmap))then return-1;
if not ifarray(p)then p := array(0,0);
bmp.draw(self,p[0],p[1]);
end
function DrawIcon(ico,p);
begin
{**
@explan(˵Ã÷)»æÖÆicon %%
@param(ico)(ticon) ͼ±ê %%
@param(p)( array of integer) λÖà array(x,y)
**}
if HandleAllocated()then
begin
if not(ifarray(p)and ifnumber(p[1])and ifnumber(p[0]))then p := array(0,0);
if(ico is class(tcustomicon))and ico.Handle then return _wapi.DrawIcon(FHandle,p[0],p[1],ico.Handle);
end
end
function draw_rect(); //¾ØÐλæÖƶÔÏó
begin
if HandleAllocated() then requiregdi();
return new tshapeRectangle(self(true));
end
function draw_roundrect();//Ô²½Ç¾ØÐλæÖƶÔÏó
begin
if HandleAllocated() then requiregdi();
return new tshaperoundrect(self(true));
end
function draw_frame(); //frame »æÖƶÔÏó
begin
if HandleAllocated() then requiregdi();
return new tshapeframe(self(true));
end
function draw_ellipse(); //ÍÖÔ²»æÖƶÔÏó
begin
if HandleAllocated() then requiregdi();
return new tshapeEllipse(self(true));
end
function draw_arc(); //arc »æÖÆ
begin
if HandleAllocated() then requiregdi();
return new tshapearc(self(true));
end
function draw_pie(); //±ý »æÖÆ
begin
if HandleAllocated() then requiregdi();
return new tshapepie(self(true));
end
function draw_chord(); //ÐþÇлæÖÆ
begin
if HandleAllocated() then requiregdi();
return new tshapechord(self(true));
end
function draw_bezier(); //±´Èû¶ûÇúÏß»æÖÆ
begin
if HandleAllocated() then requiregdi();
return new tshapeBezier(self(true));
end
function draw_polygon(); //Ìî³äÕÛÏß»æÖÆ
begin
if HandleAllocated() then requiregdi();
return new tshapepolygon(self(true));
end
function draw_polyline(); //ÕÛÏß»æÖÆ
begin
if HandleAllocated() then requiregdi();
return new tshapepolyline(self(true));
end
function draw(name_,points,f,m);
begin
{**
@explan(˵Ã÷)gdi»­Í¼º¯Êý%%
@param(name_)(string) ͼÐÎÃû³Æ, rectangle ¾ØÐÎ ;ellipse ÍÖÔ²;roundrect Ô²½Ç¾ØÐÎ;chord »¡Ïß ;pie ±ý ;polybezier ±´Èû¶û ;polygon¶àÌõÖ±Ïß %%
@param(points)(array) µãÊý×é ÀýÈç array((0,0),(1,2)) ±íÊöÁ½¸öµãµÄÊý×é,µãµÄ¶àÉÙ¸ù¾Ýname_²ÎÊýÈ·¶¨ %%
@param(f)(integer) ×÷ͼ¸¨Öú²ÎÊý ÔÚ»­»¡ÏßµÄʱºò»áÓõ½µÄ·½Ïò %%
@param(m)(integer) ÔÚpolypolyline ʹÓñíʾ»æÍ¼Ñùʽ %%
**}
if not HandleAllocated()then return 0;
requiregdi();
if not ifstring(name_)then return 0;
_name_1 := lowercase(name_);
r := length(points);
c := mcols(points);
if not(r>1 and c=2)then return 0;
if "framecontrol"=_name_1 then
begin
if r<2 then return 0;
nrc := array(points[0][0],points[0][1],points[1][0],points[1][1]);
ret := _wapi.DrawFrameControl(FHandle,nrc,(f<inf)?f:DFC_BUTTON,(m<inf)?m:DFCS_CHECKED);
end else
if "rectangle"=_name_1 then
begin
ret := _wapi.Rectangle(FHandle,points[0][0],points[0,1],points[1,0],points[1,1]);
end else
if "ellipse"=_name_1 then
begin
ret := _wapi.Ellipse(FHandle,points[0,0],points[0,1],points[1,0],points[1,1]);
end else
if "roundrect"=_name_1 then
begin
if r<3 then return 0;
ret := _wapi.RoundRect(FHandle,points[0,0],points[0,1],points[1,0],points[1,1],points[2,0],points[2,1]);
end else
if "chord"=_name_1 then
begin
if r<4 then return 0;
ret := _wapi.Chord(FHandle,points[0,0],points[0,1],points[1,0],points[1,1],points[2,0],points[2,1],points[3,0],points[3,1]);
end else
if "pie"=_name_1 then
begin
ret := _wapi.Pie(FHandle,points[0,0],points[0,1],points[1,0],points[1,1],points[2,0],points[2,1],points[3,0],points[3,1]);
end else
if "arc"=_name_1 then
begin
if len <> 4 then return 0;
if not ifnil(f)then _wapi.SetArcDirection(FHandle,f);
ret := _wapi.Arc(FHandle,points[0,0],points[0,1],points[1,0],points[1,1],points[2,0],points[2,1],points[3,0],points[3,1]);
end else
if(("polygon"=_name_1)or("polyline"=_name_1))then
begin
if r<2 then return 0;
//pt := pointtovector(points);
if "polygon"=_name_1 then
begin
if r<3 then return 0;
ret := _wapi.Polygon(FHandle,points,r);
end else
ret := _wapi.polyline(FHandle,points,r);
end else
if "polypolyline"=_name_1 then
begin
if ifarray(f)and(sum(f)=length(points))then
begin
//pt := pointtovector(points);
ret := _wapi.polypolyline(FHandle,points,f,m);
end
end else
if("polybezier"=_name_1)then
begin
if r<3 then return 0;
//pt := pointtovector(points);
ret := _wapi.PolyBezier(FHandle,points,r);
end
return ret;
end
function CopyBitmap(rect);
begin
{**
@explan(˵Ã÷) »ñÈ¡canvasÇøÓòµ½Î»Í¼ %%
@param(array of integer) ÇøÓò array(×ó,ÉÏ,ÓÒ,ÏÂ);
@return(tcustombitmap|nil) ³É¹¦·µ»ØÎ»Í¼ %%
**}
r := nil;
{$ifdef linux}
return r;
{$endif}
if not(ifarray(rect)and rect[2]>rect[0]and rect[3]>rect[1])then return r;
if not HandleAllocated()then return r;
if not FHDC then FHDC := _wapi.CreateCompatibleDC(0);
if not FHDC then return r;
bthandle := _wapi.CreateCompatibleBitmap(_wapi.GetDC(0),w,h);
if not bthandle then return r;
oldb := _wapi.SelectObject(FHDC,bthandle);
_wapi.BitBlt(FHDC,0,0,rect[2]-rect[0],rect[3]-rect[1],FHandle,rect[0],rect[1],SRCCOPY);
if oldb then _wapi.SelectObject(FHDC,oldb);
R := new tcustombitmap();
R.handle := bthandle;
return r;
end
function SetWorldTransform(trans);
begin
{**
@explan(˵Ã÷)Îı¾Ðýת%%
@param(trans)(array) array(cos,-sin,sin,cos,x,y)%%
**}
{$ifdef linux}
return r;
{$endif}
_xformobj.em11 := trans[0];
_xformobj.em12 := trans[1];
_xformobj.em21 := trans[2];
_xformobj.em22 := trans[3];
_xformobj.edx := trans[4];
_xformobj.edy := trans[5];
return _wapi.SetWorldTransform(FHandle,_xformobj._getptr_);
end
function trans(ag,x,y);
begin
{**
@explan(˵Ã÷)Îı¾Ðýת%%
@param(ag)(double) ½Ç¶È%%
**}
{$ifdef linux}
_wapi.cairo_translate(FHandle,x,y);
_wapi.cairo_rotate(FHandle,-ag);
return 1;
{$endif}
_xformobj.em11 := cos(ag);
_xformobj.em12 := -sin(ag);
_xformobj.em21 := sin(ag);
_xformobj.em22 := cos(ag);
_xformobj.edx := ifnumber(x)?x:0;
_xformobj.edy := ifnumber(y)?y:0;
return _wapi.SetWorldTransform(FHandle,_xformobj._getptr_);
end
function SetPolyFillMode(md); //ÉèÖÃÌî³äÑùʽ
begin
{**
@explan(˵Ã÷)ÉèÖÃÌî³äģʽ %%
@param(md)(integer) Ìî³äģʽ ALTERNA WINDING %%
**}
if HandleAllocated()then if ifnumber(md)then return _wapi.SetPolyFillMode(FHandle,md);
return-1;
end
function SetBkMode(m);
begin
{**
@explan(˵Ã÷)Îı¾±³¾°Ñùʽ%%
@param(m)(integer) ±³¾°ÑùʽOPAQUE or TRANSPARENT %%
**}
if HandleAllocated()then return _wapi.SetBkMode(FHandle,m);
end
function GetBkMode();
begin
{**
@explan(˵Ã÷)Îı¾±³¾°Ñùʽ%%
@return(integer) ±³¾°Ñùʽ%%
**}
if HandleAllocated()then return _wapi.GetBkMode(FHandle);
end
function SetTextAlign(fmt);
begin
{**
@explan(˵Ã÷)ÎÄ×Ö¶ÔÆä·½Ê½%%
@param(fmt)(integer) ¶ÔÆä·½Ê½TA_LEFT;
TA_RIGHT;
TA_CENTER;
TA_TOP;
TA_BOTTOM;ĬÈÏ×ó¶ÔÆë %%
**}
if not ifnumber(fmt)then fmt := _wapi.TA_LEFT;
if HandleAllocated()then return _wapi.SetTextAlign(FHandle,fmt);
end
function ReleaseDC();virtual;
begin
//if HandleAllocated() then _wapi.ReleaseDC(FHandle);
end
{function BeginPath();
begin
if HandleAllocated() then return _wapi.BeginPath(FHandle);
end
function EndPath();
begin
if HandleAllocated() then return _wapi.EndPath(FHandle);
end
function StrokePath();
begin
requiregdi();
if HandleAllocated() then return _wapi.StrokePath(FHandle);
end
function FillPath();
begin
requiregdi();
if HandleAllocated() then return _wapi.FillPath(FHandle);
end
function StrokeAndFillPath();
begin
requiregdi();
if HandleAllocated() then return _wapi.StrokeAndFillPath(FHandle);
end}
function DeleteDC();
begin
if HandleAllocated()then _wapi.DeleteDC(FHandle);
FHandle := 0;
end
function SaveDC();
begin
{**
@explan(˵Ã÷) ±£´æµ±Ç°µÄdc %%
**}
if HandleAllocated()then
begin
FCounter.InCrease();
_wapi.SaveDC(FHandle);
end
end
function RestoreDC();
begin
{**
@explan(˵Ã÷) »¹Ô­dc %%
**}
if HandleAllocated()then
begin
if FCounter.CurrenId>0 then
begin
FCounter.DeCrease();
_wapi.RestoreDC(FHandle,-1);
end
end
end
property Handle read FHandle write SetHandle;
property pen read FPen write SetPen;
property font read FFont write SetFont;
property brush read FBrush write SetBrush;
property bkmode write SetBkMode;
property TextMetric read FTEXTMETRICA;
property TextTabLength read FTabLength write SetTextTabLen;
{**
@param(pen)(tcustompen) »­±Ê %%
@param(brush)(TBRUSH) »­Ë¢ %%
@param(font)(Tcustomfont) ×ÖÌå %%
@param(bkmode)(integer) ±³¾°Ñùʽ OPAQUE or TRANSPARENT ĬÈÏ TRANSPARENT %%
@param(TextMetric)(ttagTEXTMETRICA) Îı¾ÑùʽÐÅÏ¢ %%
**}
end
type TControlCanvs=class(TcustomCanvas)
function Create();
begin
inherited;
end
property rcpaint read FClipRect write SetClipRect;
private
Function SetClipRect(v);
begin
if ifarray(v)and v[0]<v[2]and v[1]<v[3]then
begin
FClipRect := v;
end
end
FClipRect;
end
implementation
/////////////////////////////////
type TResourcescache=class
{**
@ignore(ºöÂÔ) %%
@explan(˵Ã÷)gdi×ÊÔ´µÈµÄ»º´æ
**}
private
FCache;
_wapi;
public
function create(api);
begin
FCache := array();
_wapi := api;
end
function reference(name);virtual;
begin
{**
@explan(˵Ã÷)ÒýÓÃ×ÊÔ´ %%
@param(name)(string) ×ÊÔ´Ãû³Æ %%
**}
v := Fcache[name];
if ifarray(v)then
begin
Fcache[name,"count"]+= 1;
return Fcache[name,"value"];
end
return 0;
end
function unreference(name);virtual;
begin
{**
@explan(˵Ã÷)È¡ÏûÒýÓÃ×ÊÔ´ %%
@param(name)(string) ×ÊÔ´Ãû³Æ %%
**}
v := Fcache[name];
if ifarray(v)then
begin
count := v["count"];
if count >= 1 then
begin
Fcache[name]["count"]-= 1;
return 1;
end
{else
begin
destroyresource(name);
end}
end
return 0;
end
function addsource(name,value);virtual;
begin
{**
@explan(˵Ã÷)Ìí¼Ó×ÊÔ´ %%
@param(name)(string) ×ÊÔ´Ãû³Æ %%
@param(value)(obj) ×ÊÔ´Öµ %%
**}
//RETURN ; //²»»º´æ
v := Fcache[name];
if not(v)then
begin
Fcache[name]["value"]:= value;
Fcache[name]["count"]:= 1;
//return 1;
end else
begin
if Fcache[name]["value"]=value then
begin
Fcache[name]["count"]++;
end else
if value then
begin
destroyresource(name);
return addsource(name,value);
end
end
FCacheLength := length(FCache);
maxlen := 256;
if FCacheLength>maxlen then
begin
ct := 0;
rdxs := array();
for i,v in FCache do
begin
if v["count"]=0 then
begin
rdxs[ct++]:= i;
end
if FCacheLength-ct <= maxlen then
begin
break;
end
end
for i,v in rdxs do
begin
destroyresource(v);
end
end
return 0;
end
function destroyresource(name);virtual;
begin
{**
@explan(˵Ã÷)ɾ³ýÖ¸¶¨µÄ×ÊÔ´ %%
@param(name)(string) ×ÊÔ´Ãû³Æ %%
**}
v := Fcache[name];
if v then
begin
hd := v["value"];
reindex(Fcache,array(name:nil));
_wapi.DeleteObject(hd);
end
end
end
type tshape = class()
function create(dc);
begin
fcanvas := dc;
end
function draw();virtual;
begin
return self(true);
end
protected
[weakref]fcanvas;
end
type tsepoint = class()
function startpoint(p);overload;
begin
if ifarray(p) and ifnumber(p[0]) and ifnumber(p[1]) then
begin
fsp := array(p[0],p[1]);
end
return self(true);
end
function endpoint(p);overload;
begin
if ifarray(p) and ifnumber(p[0]) and ifnumber(p[1]) then
begin
fep := array(p[0],p[1]);
end
return self(true);
end
function startpoint(x,y);overload;
begin
return startpoint(array(x,y));
end
function endpoint(x,y);overload;
begin
return endpoint(array(x,y));
end
function direct(dir);
begin
fdir := dir;
return self(true);
end
protected
fsp;
fep;
fdir;
end
type tshaperect = class()
function rect(rec);overload;
begin
if ifarray(rec) and rec[2]>rec[0] and rec[3]>rec[1] then
begin
frect := array(rec[0],rec[1],rec[2],rec[3]);
end
return self(true);
end
function rect(l,t,r,b);overload;
begin
return rect(array(l,t,r,b));
end
protected
frect;
end
type tshapeEllipse = class(tshape,tshaperect)
function create(dc);
begin
inherited;
end
function draw();override;
begin
if fcanvas and fcanvas.HandleAllocated() and frect then
begin
fcanvas._wapi.Ellipse(fcanvas.handle,frect[0],frect[1],frect[2],frect[3]);
end
return inherited;
end
end
type tshapeRectangle = class(tshape,tshaperect)
function create(dc);
begin
inherited;
froundw := 0;
froundh := 0;
end
function draw();override;
begin
if fcanvas and fcanvas.HandleAllocated() and frect then
begin
fcanvas._wapi.Rectangle(fcanvas.handle,frect[0],frect[1],frect[2],frect[3]);
end
return inherited;
end
end
type tshaperoundrect = class(tshape,tshaperect)
function create(dc);
begin
inherited;
end
function draw();override;
begin
if fcanvas and fcanvas.HandleAllocated() and frect then
begin
fcanvas._wapi.RoundRect(fcanvas.handle,frect[0],frect[1],frect[2],frect[3],froundw,froundh);
end
return inherited;
end
function setround(w,h);
begin
froundw := w;
froundh := h;
return self(true);
end
private
froundw;
froundh;
end
type tshapeframe = class(tshape,tshaperect)
function create(dc);
begin
inherited;
end
function draw();override;
begin
if fcanvas and fcanvas.HandleAllocated() and frect then
begin
fcanvas._wapi.DrawFrameControl(fcanvas.handle,frect,ftype,fstyle);
end
return inherited;
end
function ctltype(fc);
begin
ftype := fc;
return self(true);
end
function ctlstate(cs);
begin
fstyle := cs;
return self(true);
end
private
ftype;
fstyle;
end
type tshapearc = class(tshape,tshaperect,tsepoint)
function create(dc);
begin
inherited;
end
function draw();override;
begin
if fcanvas and fcanvas.HandleAllocated() and fsp and fep and frect then
begin
if fdir=1 or fdir = 2 then FCanvas._wapi.SetArcDirection(FCanvas.Handle,fdir);
fcanvas._wapi.arc(fcanvas.handle,frect[0],frect[1],frect[2],frect[3],fsp[0],fsp[1],fep[0],fep[1]);
end
return inherited;
end
end
type tshapepie = class(tshape,tshaperect,tsepoint)
function create(dc);
begin
inherited;
end
function draw();override;
begin
if fcanvas and fcanvas.HandleAllocated() and fsp and fep and frect then
begin
if fdir=1 or fdir = 2 then FCanvas._wapi.SetArcDirection(FCanvas.Handle,fdir);
fcanvas._wapi.pie(fcanvas.handle,frect[0],frect[1],frect[2],frect[3],fsp[0],fsp[1],fep[0],fep[1]);
end
return inherited;
end
end
type tshapechord = class(tshape,tshaperect,tsepoint)
function create(dc);
begin
inherited;
end
function draw();override;
begin
if fcanvas and fcanvas.HandleAllocated() and fsp and fep and frect then
begin
if fdir=1 or fdir = 2 then FCanvas._wapi.SetArcDirection(FCanvas.Handle,fdir);
fcanvas._wapi.chord(fcanvas.handle,frect[0],frect[1],frect[2],frect[3],fsp[0],fsp[1],fep[0],fep[1]);
end
return inherited;
end
end
type tshapepolygon = class(tshape)
function create(dc);
begin
inherited;
fbpoints := array();
end
function draw();override;
begin
if fcanvas and fcanvas.HandleAllocated() and fbpoints then
begin
fcanvas._wapi.Polygon(fcanvas.handle,fbpoints,length(fbpoints));
end
return inherited;
end
function points(ps);virtual;
begin
tps := array();
for i,v in ps do
begin
if ifarray(v) and ifnumber(v[0]) and ifnumber(v[1]) then
begin
tps[idx++] := array(v[0],v[1]);
end
end
if length(tps)>2 then
begin
fbpoints := tps;
end
return self(true);
end
protected
fbpoints;
end
type tshapepolyline = class(tshapepolygon)
function create(dc);
begin
inherited;
end
function draw();override;
begin
if fcanvas and fcanvas.HandleAllocated() and fbpoints then
begin
fcanvas._wapi.polyline(fcanvas.handle,fbpoints,length(fbpoints));
end
return self(true);
end
end
type tshapeBezier = class(tshape)
function create(dc);
begin
inherited;
fbpoints := array();
end
function draw();override;
begin
if fcanvas and fcanvas.HandleAllocated() and fbpoints then
begin
fcanvas._wapi.PolyBezier(fcanvas.handle,fbpoints,length(fbpoints));
end
return inherited;
end
function startpoint(p);overload;
begin
if ifarray(p) and ifnumber(p[0]) and ifnumber(p[1]) then
begin
fbpoints := array((p[0],p[1]));
end
return self(true);
end
function startpoint(x,y);overload;
begin
return startpoint(array(x,y));
end
function addpoints(ps);
begin
if ifarray(ps) then
begin
fbpoints union= ps;
end
return self(true);
end
private
fbpoints;
end
function getresourcebyid(id,options);
begin
{**
@explan(˵Ã÷)»ñµÃresourceÐÅÏ¢%%
@param(id)(obj) id ¶ÔÏó %%
@param(options)(array) ¶îÍâ²ÎÊý %%
**}
global G_O_TSWIN32API_;
w32 := G_O_TSWIN32API_;
if not w32 then return 0;
if not ifarray(options)then return 0;
h := 0;
if options["type"]="bmp" then
begin
if ifnumber(id)then h := w32.LoadBitmapA2(nil,id);
else if ifstring(id)then
begin
//h := w32.LoadImageA(0,id,0,100,100,0x10 .| 0x40);//
h := w32.LoadImageA(0,id,0,0,0,0x10 .| 0x40); //
//h := w32.LoadBitmapA(nil,id);
end
end else
if options["type"]="ico" then
begin
if ifnumber(id)then h := w32.LoadIconA2(nil,id);
else if ifstring(id)then h := w32.LoadImageA(0,id,0x1,0,0,0x10);
end
return h;
end
function sinitgidplus();
begin
FGDI := new TGdiplusflat();
vot := array(
("gdiplusversion","int",1),
("debugeventcallback","int",0),
("suppressbackgroundthread","int",0),
("suppressexternalcodecs","int",0));
og := new ctslctrans(tslarraytocstructcalc(vot));
ftoken :=-1;
ig :=-1;
FGDI.GdiplusStartup(ftoken,og._getptr_,ig);
end
function GetTextWidthAndHeightWidthFont(s,f,mul);
begin
{**
@explan(˵Ã÷) »ñµÃÎı¾ÔÚ¸ø¶¨×ÖÌåfÏµĻæÖÆ¿í¸ß %%
@param(s)(string) Îı¾ %%
@param(f)(tfont) ¸ø¶¨×ÖÌå %%
@param(mul)(bool) ÊÇ·ñ¶àÐÐÎı¾ %%
**}
if ifstring(s)and s then
begin
cv := static GetOneCanvas();
if f is class(Tcustomfont)then cv.font := f;
if ifarray(f)and f then cv.font.SetValues(f);
return cv.GetTextExtent(s,mul);
end
return array(0,0);
end
function GetOneCanvas();
begin
cv := new tcustomcanvas();//(getapplication());
cv.handle := cv._wapi.CreateCompatibleDC(0);
return cv;
end
function getdrawablebitmap(w,h,bmp);
begin
{$ifdef linux}
return 0;
{$endif}
if w>1 and h>1 then
begin
cv := static GetOneCanvas();
api := cv._wapi;
bmp := new TcustomBitmap();
bhd :=api.CreateCompatibleBitmap(api.GetDC(0),w,h);
bmp.handle := bhd;
api.SelectObject(cv.handle,bhd);
return cv;
end
end
function GetGdipStatus(v);
begin
{**
@explan(˵Ã÷) »ñµÃgdiflatµÄÔËÐÐ״̬˵Ã÷ %%
@param(v)(integer) ״ֵ̬ %%
@return(string) ״̬˵Ã÷ %%
**}
vs := static array(
"Ok",
"GenericError",
"InvalidParameter",
"OutOfMemory",
"ObjectBusy",
"InsufficientBuffer",
"NotImplemented",
"Win32Error",
"WrongState",
"Aborted",
"FileNotFound",
"ValueOverflow",
"AccessDenied",
"UnknownImageFormat",
"FontFamilyNotFound",
"FontStyleNotFound",
"NotTrueTypeFont",
"UnsupportedGdiplusVersion",
"GdiplusNotInitialized",
"PropertyNotFound",
"PropertyNotSupported",
"ProfileNotFound");
return vs[v];
end
initialization
sinitgidplus();
class(tcustomimage).sinit();
class(tUIglobalData).uisetdata("G_T_BITMAP_",class(TcustomBitmap));
class(tUIglobalData).uisetdata("G_T_ICON_",class(TcustomIcon));
finalization
end.