tslediter/funcext/tvclib/utslvclauxiliary.tsf

3656 lines
90 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

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 utslvclauxiliary;
{**
@explan(说明) tslvcl 辅助库 %%
**}
//20221118 抽象计数锁定对象
//20220914 移入tire树
interface
function iffuncptr(fn);
function includestate(u,s);
function excludestate(u,s);
function makelong(low,high,ptrl);
function makeposition(x,y);
function getbitsfrominteger(n,b,e);
function unsignedtosigned(v,n);
function signedtounsigned(v,n);
function lowuperdword(value_,lvalue,uvalue,ptrl);
function FormatTslData(d,sj,tn);
function gettemppath();
function TSL_ReservedKeys2(); //保留关键字
function parsershortcutstr(s_); //快捷键解析
function lineintersect(xx1,xx2,xx);
function formatshortcut(d);
function getmonthdates(y,m);
function CallMessgeFunction(f,o,e);
////////////////////点区域操作//////////////////
function pointinrect(p,rec);
function intersectrect(rec1,rec2,irec);
function bitcombination(s,v,f);
function IsTextUTF8(str);
function exportjsonformat(d,tbw,ct);
//****************************
///////////////////
function ParserCommandLine(s); //解析命令行参数
//function FormatTslData(d,sj,tn);
//function HexStrToTsl(hex);
//function TslToHexStr(d);
function TslToHexFormatStr(tsl);
function HexFormatStrToTsl(D);
function DeleteAllFiles(path);
function CreateDirWithFileName(fname);
function TS_GetUserProfileHome();
function gettslexefullpath();
type tuiglobaldata=class() //全局对象存储
static UIData;
class Function uisetdata(n,d);
begin
InitUiData();
UIData[n]:= d;
end
class function uigetdata(n);
begin
InitUiData();
return UIData[n];
end
private
class function InitUiData();
begin
if not ifarray(UIData)then UIData := array();
end
end
type TCharDiscrimi=class() //字符判断
private
static CD_SMA;
static CD_BGA;
static CD_SMZ;
static CD_BGZ;
static CD_UDL;
static CD_NIN;
static CD_ZER;
static CD_ISOK;
class function sinit();virtual;
begin
if not CD_ISOK then
begin
CD_ISOK := 1;
CD_SMA := ord("a");
CD_BGA := ord("A");
CD_SMZ := ord("z");
CD_BGZ := ord("Z");
CD_UDL := ord("_");
CD_NIN := ord("9");
CD_ZER := ord("0");
end
end
public
function IsLetter(cc);
begin
return IsUppercaseLetter(CC)OR IsLowercaseLetter(cc);
end
function IsLowercaseLetter(cc);
begin
return(cc >= CD_SMA)and(cc <= CD_SMZ);
end
function IsUppercaseLetter(cc);
begin
return(cc >= CD_BGA)and(cc <= CD_BGZ);
end
function IsNumber(cc);
begin
return(cc >= CD_ZER)and(cc <= CD_NIN);
end
function IsVariableName(s);
begin
if ifstring(s)and length(s)>= 1 then
begin
cc := ord(s[1]);
if IsLetter(cc)or cc=CD_UDL then
begin
for i := 2 To length(s) do
begin
cc := ord(s[i]);
if not(IsLetter(cc)or IsNumber(cc)or(cc=CD_UDL))then
begin
return false;
end
end
return true;
end
end
return 0;
end
function IsLowercaseVariableName(s);
begin
if ifstring(s)and length(s)>= 1 then
begin
cc := ord(s[1]);
if IsLowercaseLetter(cc)or cc=CD_UDL then
begin
for i := 2 To length(s) do
begin
cc := ord(s[i]);
if not(IsLowercaseLetter(cc)or IsNumber(cc)or(cc=CD_UDL))then
begin
return false;
end
end
return true;
end
end
return 0;
end
function create();
begin
sinit();
end
end
type tidcreater=class() //id生成
{**
@ignore(忽略)
**}
private
__sid;
cid;
Reuseids;
usedids;
//protected
{**
@explan(说明) 不重复整数id 生成类 %%
@param(cid)(integer) 当前id值 %%
@param(Reuseids) (array) 已经回收的id %%
**}
public
function clean();
begin
Reuseids := array();
cid := __sid;
end
function create(sid);
begin
{**
@explan(说明) 构造函数 %%
@param(sid)(integer) 初始化的id值
**}
if ifnumber(sid)then cid := sid;
else cid := 0;
__sid := cid;
usedids := Reuseids := array();
end
function createid();
begin
{**
@explan(说明) 构造id %%
@return(integer) id值 %%
**}
ret := nil;
for i in Reuseids do
begin
if ifnumber(i)then
begin
ret := i;
break;
end
end
if ifnumber(ret)then
begin
reindex(Reuseids,array(ret:nil));
usedids[ret]:= ret;
return ret;
end
cid += 1;
usedids[cid]:= cid;
return cid;
end
function deleteid(id);
begin
{**
@explan(说明) 不重复整数id 生成类 %%
@param(id)(integer) 需要回收的id值 %%
@return(bool) 是否成功
**}
if ifnumber(id)then
begin
Reuseids[integer(id)]:= id;
reindex(usedids,array(integer(id):nil));
return 1;
end
return 0;
end
function addid(id);
begin
if ifnumber(id)and id>0 then
begin
cid := max(cid,id);
usedids[id]:= id;
end
end
end
type TByteDataOP=class() //位操作类
{**
@explan(说明) 位操作封装
**}
{**
@example(范例:byte数组转整数)
oa := new TByteDataOP();
echo tostn(oa.bytesasint(array(1,1,1,1)));
**}
{**
@example(范例:整数转byte数组)
oa := new TByteDataOP();
echo tostn(oa.intasbytes(235);
**}
class function BytesAsInt(a);
begin
{**
@explan(说明) 四个byte转换为integer %%
@param(a)(array) 正式表示的四字节 %%
@return(integer) 组装好的整数 %%
**}
uu := a[0];
ul := a[1];
lu := a[2];
ll := a[3];
l := makelong(ll,lu,8);
u := makelong(ul,uu,8);
return makelong(l,u);
end
class function IntAsBytes(v);
begin
{**
@explan(说明) 整数转换为byte 数组(整数数组模拟) %%
@param(v)(integer) %%
@return(array) 模拟的byte数组 %%
**}
lowuperdword(v,l,u);
lowuperdword(l,ll,lu);
lowuperdword(u,ul,uu);
return array(uu,ul,lu,ll);
end
class function ShortsToInt(a);
begin
{**
@explan(说明) 两个short转换为一个int %%
@param(a)(array) 两个元素的数组 %%
@return(integer) 整数 %%
**}
l := a[1];
u := a[0];
return makelong(l,u);
end
class function IntToShorts(v);
begin
{**
@explan(说明) 整数转换为两个short 数组(整数数组模拟) %%
@param(v)(integer) %%
@return(array) 模拟的short数组 %%
**}
lowuperdword(v,l,u);
return array(l,u);
end
class function StrAsBytes(s);
begin
{**
@explan(说明) 字符串转换为byte数组 %%
@param(s)(string) 字符串 %%
@return(array) 模拟的byte数组 %%
**}
r := array();
for i := 0 to length(s) do r[i]:= ord(s[i]);
return r;
end
class function BytesAsStr(b);
begin
{**
@explan(说明) byte数组转字符串 %%
@param(b)(array) byte数组 %%
@return(string) 字符串
**}
r := "";
for i := 0 to length(b)-1 do r += chr(b[i]);
return r;
end
end
//**************************数组链表类******************************************
type tarray1dlk=class //从0开始
private
_len;
[weakref]FCompareValue;
protected _data; //数据
public
{**
@explan(说明) 一维链表类 %%
@param(_len)(integer) 长度 %%
@param(_data)(array) 数据 %%
@param(CompareValue)(fpointer) 回调函数 function(v1,v2)begin return v1 = v2 ; end %%
**}
function setdata(data);
begin
{**
@explan(说明) 一次性设置数据 %%
@param(data)(array) 数据 %%
**}
_data := data;
_len := length(data);
end
function clean();
begin
{**
@explan(说明) 清空 %%
**}
_data := array();
_len := 0;
end
function create(); //构造
begin
{**
@explan(说明) 构造 %%
**}
_data := array();
_len := 0;
onchangelock := true;
end
function CallCompare(v1,v2,f);
begin
if iffuncptr(f) then return call(f,v1,v2);
if iffuncptr(FCompareValue)then return call(FCompareValue,v1,v2);
return v1=v2;
end
function append(v) //追加
begin
{**
@explan(说明) 追加 %%
@param(v)() tsl数据 %%
**}
_data[_len++]:= v;
dochanged("append");
end;
function geti(i); //获取
begin
{**
@explan(说明) 获得 %%
@param(i)(integer) id %%
**}
return _data[i];
end
function seti(i,v); //设置值
begin
{**
@explan(说明) 设置值 %%
@param(i)(integer) id %%
@param(v)() tsl数据 %%
**}
if i >= 0 and i<_len then
begin
_data[i]:= v;
dochanged("set");
end
end
function deli(i); //删除
begin
{**
@explan(说明) 删除 %%
@param(i)(integer) id %%
**}
if i<0 or i >= _len then return 0;
_len -= 1;
r := deleteindex(_data,i,1);
dochanged("del");
return r;
end
function delis(i);
begin
{**
@explan(说明) 批量删除 %%
@param(i)(array) 删除的id %%
**}
dels := getdels(i);
bkonchangelock := onchangelock;
onchangelock := true;
for ii,v in dels do deli(v);
onchangelock := bkonchangelock;
dochanged("dels");
end
function getdels(i); //删除多行
begin
{**
@ignore (忽略) %%
@explan(说明) 批量删除 %%
@param(i)(array) 删除的id %%
**}
ii := sselect thisrow from(i union2 array())where(thisrow >= 0 and thisrow<_len)order by thisrow end;
dels := array();
ix := 0;
for iv in ii do
begin
dels[iv]:= ii[iv]-ix;
ix++;
end
return dels;
end
function insertbefor(v,i); //之前插入
begin
{**
@explan(说明) 在i之前插入 %%
@param(v)() 插入数据 %%
@param(i)(integer) id %%
**}
if not ifnumber(i)then return;
if i >= _len then return append(v);
else if i <= 0 then
begin
_data := array(v)union _data;
end else
begin
_data := _data[0:(i-1)]union array(v)union _data[i:];
end
_len++;
end
function insertafter(v,i); //之后插入
begin
{**
@explan(说明) 在i之后插入 %%
@param(v)() 插入数据 %%
@param(i)(integer) id %%
**}
if not ifnumber(i)then return;
if i >= _len then return append(v);
else if i<0 then
begin
_data := array(v)union _data;
end else
begin
_data := _data[0:i]union array(v)union _data[i+1:];
end
_len++;
dochanged("insert");
end
function findvid(v1,func,lx); //查找序号,func通过送入的比较函数
begin
{**
@explan(说明) 查找序号和v1 匹配的id %%
@param(v1)(any) tsl数据 %%
@param(lx)(bool) 逆序查找 %%
@param(func)(fpointer) 比较函数 第一个参数为 数组中对象,第二个参数为输入判断条件 %%
**}
ret :=-1;
if lx then
begin
for i := length(_data) downto 0 do
begin
if CallCompare(_data[i],v1,func)then return i;
end
return ret;
end
for i,v in _data do
begin
if CallCompare(v,v1,func)then
begin
return i;
end
end
return ret;
end
function getprev(v1); //获得上一个
begin
{**
@explan(说明) 获得上一个 匹配的id %%
@param(v1)() tsl数据 %%
**}
if _len<2 then return nil;
id :=-1;
for i,v in _data do
begin
if CallCompare(v,v1)then
begin
id := i;
break;
end
end
return _data[id-1];
end
function getnext(v1); //获得下一个
begin
{**
@explan(说明) 获得下一个 匹配的id %%
@param(v1)() tsl数据 %%
**}
if _len<2 then return nil;
id := _len;
for i,v in _data do
begin
if CallCompare(v,v1)then
begin
id := i;
break;
end
end
return _data[id+1];
end
function ergodic(f); //循环处理
begin
{**
@explan(说明) 循环所有数据 %%
@param(f)(fpointer) 处理函数 function(id,v) begin end %%
**}
if not iffuncptr(f)then return nil;
for i,v in _data do
begin
ret := call(f,i,v); //## f(i,v);
if ret=-1 then break;
end
return 1;
end
function data(); //数组数据
begin
{**
@explan(说明) 返回所有数据 %%
**}
return _data;
end
function replace(i,v) //替换
begin
{**
@explan(说明) 替换 %%
@param(i)(integer) 序号 %%
@param(v)() tsl数据 %%
**}
if i >= 0 and i<_len then
begin
ret := _data[i];
_data[i]:= v;
dochanged("replace");
return ret;
end else
return nil;
end
function len(); //大小
begin
{**
@explan(说明) 长度 %%
**}
//return length(_data);
return _len;
end
function setorder(i,j);
begin
{**
@explan(说明) 设置元素位置 %%
@param(i)(integer)原始位置 %%
@param(j)(integer) 移动后的位置
**}
if j>_len-1 then j := _len-1;
if j<0 then j := 0;
if i=j or(i<0 or i>_len)then exit; //修改
sl := createserial(i,j);
for ii := 0 to length(sl)-2 do
begin
SwapNoCheck(sl[ii],sl[ii+1]);
end
dochanged("order");
end
function swap(i,j); //交换
begin
{**
@explan(说明) 交换 %%
@param(i)(integer) 序号 %%
@param(j)(integer) 序号 %%
**}
if ifnumber(i)and ifnumber(j)and i <> j and i >= 0 and j >= 0 and i<_len and j<_len then
begin
SwapNoCheck(i,j);
//vi := _data[i];
//_data[i]:=_data[j];
//_data[j] := vi;
end
dochanged("order");
end
property CompareValue read FCompareValue write FCompareValue;
property onchanged read fonchanged write fonchanged;
onchangelock;
private
function dochanged(info);
begin
if onchangelock then return ;
if fonchanged then CallMessgeFunction(fonchanged,self(true),info);
end
function SwapNoCheck(i,j);
begin
vi := _data[i];
_data[i]:= _data[j];
_data[j]:= vi;
end
function createserial(i,j);
begin
if j>i then return i -> j;
r := array();
kk := 0;
for ii := i downto j do r[kk++]:= ii;
return r;
end
function moveto(i,j); //将i移动到j前面
begin
{**
@ignore 忽略%%
@explan(说明) 将i移动到j前面 %%
@param(i)(integer) 序号 %%
@param(j)(integer) 序号 %%
**}
if not(ifnumber(i)and i >= 0 and i<_len)then return-1;
if ifnil(j)then j := 0;
if i=j then return-1;
vi := geti(i);
insertbefor(vi,j);
if i>j then
begin
deli(i+1);
end else
begin
deli(i);
end
end
fonchanged;
end
type TFpList=class(tarray1dlk)
{**
@explan(说明) list类 %%
**}
function create();
begin
inherited;
end
function indexof(v,f,lx);
begin
{**
@explan(说明) 查找值v在序列中的位置 %%
@param(v)(any) 任何类型 %%
@return(integer) 位置 ,等于-1 表示没查找到 %%
**}
return findvid(v,f,lx);
end
function operator[](index);
begin
{**
@explan(说明)获取序号为index的值 %%
@return(any) 数据 %%
**}
return geti(index);
end
function add(v);
begin
{**
@explan(说明)追加数据到链表 %%
@param(v)(any) 数据 %%
**}
return append(v);
end
function Remove(v);
begin
{**
@explan(说明)删除数据V %%
@param(v)(any) 数据 %%
**}
return deli(indexof(v));
end
function last();
begin
{**
@explan(说明)获取最后一个数据 %%
@return(any) 数据 %%
**}
return geti(self.Count()-1);
end
function Count();
begin
{**
@explan(说明)获取数据个数 %%
@return(integer) %%
**}
return len();
end
end
type tstrindexarray = class() //字符串大小写无关下标数组
{**
@explan(数组类型) 忽略字符串下标的大小写%%
**}
function create();
begin
FData := array();
FRows := array();
end
function DeleteIndex(idx);
begin
{**
@explan(说明) 删除指定下标 %%
**}
if ifnil(idx) or ifobj(idx)then return 0;
if ifstring(idx)then
begin
lidx := lowercase(idx);
::deleteindex(FData,lidx,0);
return ::deleteindex(FRows,lidx,0);
end
::deleteindex(FData,idx,0);
return ::deleteindex(FRows,idx,0);
end
function Operator[1](index,value);
begin
if ifstring(index)then
begin
li := lowercase(index);
end else
li := index;
if ifnone(value)then
begin
r := FData[li];
if r then return r;
r := new tstrindexarray();
FData[li]:= r;
FRows[li]:= index;
return r;
end
FRows[li]:= index;
if ifarray(value)and value then
begin
r := new tstrindexarray();
FData[li]:= r;
for i,v in value do
begin
r[i]:= v;
end
return;
end
FData[li]:= value;
end
function Operator[](index);
begin
if ifstring(index)then r := FData[lowercase(index)];
else r := FData[index];
//if ifnil(r) then return NeW tstrindexarray();
return r;
end
function Size();
begin
{**
@explan(说明) 获得长度 %%
**}
return Length(FData);
end
function toarray(n);
begin
{**
@explan(说明) 获得tsl array %%
@param(n)(bool) false 返回小写下标true 返回原始下标 %%
**}
r := array();
for i,v in FData do
begin
if v is class(tstrindexarray)then
begin
r[n?i:FRows[i]]:= v.toarray(n);
end else
r[n?i:FRows[i]]:= v;
end
return r;
end
function IndexNames();
begin
{**
@explan(说明) 获得 所有下标 %%
**}
return FRows;
end
function HaveIndex();
begin
{**
@explan(说明) 判断是否有某个下标 %%
**}
o := self(true);
for i := 1 to Paramcount do
begin
if not(o is class(tstrindexarray))then return false;
id := params[i];
if ifnil(o.TrueIndex(id))then return false;
o := o[id];
end
return true;
end
function TrueIndex(n);
begin
{**
@explan(说明) 获得对应下标 %%
**}
if ifstring(n)then idx := lowercase(n);
else idx := n;
return FRows[idx];
end
property Data write SetData;
function destroy();
begin
FData := nil;
FRows := nil;
end
private
function SetData(d);
begin
if not ifarray(d)then return false;
FRows := array();
FData := array();
si := self(true);
for i,v in d do
begin
si[i]:= v;
end
return true;
end
FData;
FRows;
end
type tnumindexarray = Class() //栈模拟
{**
@explan(说明) 数字下标数组对象 %%
**}
private
FData;
fdlength;
public
function Create();virtual;
begin
{**
@explan(说明) 构造函数 %%
**}
FData := array();
fdlength := 0;
end
function Operator[1](idx,v);
begin
{**
@explan(说明)通过下标设置元素 %%
**}
return SetValueByIndex(idx,v);
end
function Operator[](idx);
begin
{**
@explan(说明) 通过下标获取元素 %%
**}
return GetValueByIndex(idx);
end
function length();
begin
{**
@explan(说明) 获得数据长度 %%
@return(integer) 长度 %%
**}
return fdlength;
end
function Push({value1,value2,....});
begin
{**
@explan(说明) 在末尾追加元素,参数个数不定 %%
**}
r := fdlength;
r1 := r;
for i := 0 to ParamCount-1 do
begin
FData[r]:= Params[i+1];
r++;
end
fdlength := r;
if r1 <> r then LengthChanged(r1-r);
return r;
end
function Pop();
begin
{**
@explan(说明) 弹出末尾的元素 %%
**}
if FData then
begin
id := fdlength-1;
r := FData[id];
deleteindex(FData,id);
fdlength--;
LengthChanged(-1);
return r;
end
return nil;
end
function IndexOf(v);
begin
for i,vi in FData do
begin
if vi=v then return i;
end
return -1;
end
function LastIndexOf(v);
begin
len := fdlength;
for i := len-1 downto 0 do
begin
if v=FData[i]then return i;
end
return -1;
end
function GetValueByIndex(idx);virtual;
begin
return FData[idx];
end
function SetValueByIndex(idx,v);virtual;
begin
len := fdlength;
if not(idx>=0) then return nil;
if idx <= len then
begin
FData[idx]:= v;
end else
begin
for i := len to idx do FData[i]:= nil;
FData[idx]:= v;
end
fdlength := ::length(FData);
return v;
end
function splice({startid,sellength,value1,valfue2,....});
begin
{**
@explan(说明) 替换元素,第一个参数为开始位置,第二个为替换的个数,以后的参数为用来替换的值,返回被替换的值%%
**}
p := params;
st := p[0];
if not(st>=0) then st := 0;
sl := p[1];
sl := ifnil(sl)?inf:sl;
sl := (sl>=0)?sl:0;
len := fdlength;
st := st<0?0:st;
st := st >= len?(len):st;
et := st+sl;
et := et >= len?(len):et;
r := array();
{idx := 0;
for i := st to et-1 do
begin
r[idx++]:= FData[i];
end }
r := FData[st:(et-1)];
r1 := FData[0:st-1];
r2 := FData[et:len-1];
FData := r1 union p[2:] union r2;
fdlength := ::length(FData);
if len <> fdlength then LengthChanged(fdlength-len);
return r;
end
function shift();
begin
{**
@explan(说明) 弹出头部元素 %%
**}
r := nil;
len := fdlength;
if len>0 then
begin
deleteindex(FData,0);
fdlength--;
LengthChanged(-1);
end
return len<1?(len):(len-1);
end
function unshift({value1,value2,....});
begin
{**
@explan(说明) 在数据头部加入元素,个数待定 %%
**}
p := Params;
if p then
begin
FData := p union FData;
fdlength := ::length(FData);
LengthChanged(1);
end
return fdlength;
end
function swap(i,j);
begin
{**
@explan(说明) 交换下标中的值 %%
**}
if i=j then return false;
len := fdlength;
if i >= 0 and i<len and j >= 0 and j<len then
begin
t := FData[i];
FData[i]:= FData[j];
FData[j]:= t;
return true;
end
return false;
end
function pushs(vs);
begin
return callinarray(thisfunction(push),vs);
end
function unshifts(vs);
begin
return callinarray(thisfunction(unshift),vs);
end
function splices(startid,sellength,vs);
begin
if ifarray(vs)then return callinarray(thisfunction(splice),array(startid,sellength) union vs);
return array();
end
function LengthChanged(n);virtual;
begin
end
property Data read FData;
{**
@param(Data)(array) 数据 %%
**}
end
type tnumindexarrayex = class(tnumindexarray)
{**
@explan(说明) 扩展模拟数组 %%
**}
function create();
begin
inherited;
end
function Deli(idx);
begin
r := splice(idx,1);
return r?true:false;
end
function geti(i);
begin
return GetValueByIndex(i);
end
function InsertBefor(it,idx);
begin
splice(idx,0,it);
end
function clean();
begin
splice(nil,nil);
end
function setorder(i,j);
begin
{**
@explan(说明) 设置元素位置 %%
@param(i)(integer)原始位置 %%
@param(j)(integer) 移动后的位置
**}
len := count-1;
if j>len then j := len;
if j<0 then j := 0;
if i=j or(i<0 or i>len)then exit;
d := splice(i,1);
splice(j,0,d[0]);
end
function append(v);
begin
Push(v);
end
function add(v) ;
begin
Push(v);
end
function Remove(v);
begin
return deli(indexof(v));
end
property count read length;
end
//ifdef newgetop
type trefarray = class() //数组成员引用模拟
function create(d,bidxs); //构造函数
begin
if ifarray(d) or (d is class(trefarray)) then
begin
FData := d;
end else
begin
FData := array();
end
if ifarray(bidxs) then
begin
FBindexs := bidxs;
end else
begin
FBindexs := array();
end
end
function mgset(idxs,v); //根据下标设置值
begin
if not ifarray(idxs) then return nil;
if ifarray(FData) then
begin
return magicsetarray(FData,FBindexs union idxs,v);
end
return FData.mgset(FBindexs union idxs,v);
end
function mgget(idxs); //根据获得值
begin
if not ifarray(idxs) then return nil;
if ifarray(FData) then
begin
return magicgetarray(FData,idxs);
end
return FData.mgget(FBindexs union idxs,v);
end
function operator[0](idx,v); //获取值
begin
if v<0 then //一级直接返回
begin
return mgget(array(idx));
end
return new trefgetter(self,idx);//多级的时候构建一个中间对象
end
function operator[1](idx,v); //设置值
begin
if ifnone(v) then //多级构建一个中间对象
begin
return new trefsetter(self,idx);
end
return mgset(array(idx),v); //一级直接返回
end
private //成员变量
FData;
FBindexs;
private //中间对象
type trefsgter = class()
function create(a,idx);
begin
FA := a;
FIndexs := array(idx);
FIndexsidx := 1;
end
protected
FA;
FIndexs;
FIndexsidx;
end
type trefgetter = class(trefsgter) //getter 对象
function operator[0](idx,v);
begin
FIndexs[FIndexsidx++] := idx;
if v<0 then
begin
return fa.mgget(FIndexs);
end
return self;
end
function create(a,idx);
begin
inherited;
end
end
type trefsetter = class(trefsgter) //setter 对象
function operator[1](idx,v);
begin
FIndexs[FIndexsidx++] := idx;
if ifnone(v) then return self;
return fa.mgset(FIndexs,v);
end
function create(a,idx);
begin
inherited;
end
end
end;
type TGlobalValues=class() //全局对象,窗口构造中使用
private
static FValues;
FId;
class function sinit();
begin
if not ifarray(FValues)then FValues := array();
end
public
class function getvalue(id);
begin
sinit();
r := FValues[inttostr(id)];
//if r then reindex(FValues,id);
return r;
end
function Create(id,value);
begin
sinit();
tid := inttostr(id);
FOld := FValues[tid];
if not ifnil(FOld)then raise "全局变量冲突!";
FId := tid;
FValues[tid]:= value;
end
function destroy();
begin
reindex(FValues,array(FId:nil));
end
end
type TArrayTreeClass = class() //数组到树的转换
{**
@explan(说明) 树形类 %%
@param(FIdName)(integer | string) id名称 %%
@param(FPIdName)(integer | string) 父节点名称 %%
**}
{**
@example(转换范例) %%
d := array(("id":1,"pid":5,"caption":"jd1"),
("id":4,"pid":2,"caption":"jd2"),
("id":2,"pid":1,"caption":"jd3"),
("id":3,"pid":2,"caption":"jd4"),
("id":5,"pid":7,"caption":"jd5"),
);
dt := class(TArrayTreeClass).ToTreeArray(d,array("id":"id","pid":"pid","sub":"sub"));
return dt;
**}
private
class function ClumnNameOk(id);
begin
return ifnumber(id) or ifstring(id) ;
end
static FCounter;
static FIdName;
Static FPIdName;
static FSubName;
static FSInToArray;
FRecyce;
FInToArray;
FComponents; //节点
FId; //id
FValue; //数据
class function initconter();
begin
FCounter := 1;
end
class function GetCounter();
begin
return FCounter++;
end
public
class function SetIdName(id,pid,sub);
begin
if(id <> pid)and(ifstring(id)or ifnumber(id))and(ifstring(pid)or ifnumber(pid))and(ifstring(sub)or ifnumber(sub))then
begin
FIdName := id;
FPIdName := pid;
FSubName := sub;
end
end
function create(v);
begin
{**
@explan(说明) 构造节点 %%
**}
FId := v[FIdName];
FValue := v;
FComponents := array();
end
function addcomponent(o);
begin
{**
@explan(说明) 添加节点 %%
**}
len := length(FComponents);
for i := 0 to len-1 do if o=FComponents[i]then exit;
FComponents[len]:= o;
end
function Recycle();
begin
{**
@explan(说明) 出现死循环的时候的处理 %%
**}
if FRecyce then return;
FRecyce := true;
for i,v in FComponents do
begin
v.Recycle();
end
FComponents := array();
end
function toarray();
begin
{**
@explan(说明) 转换为array %%
**}
if FInToArray=FSInToArray then
begin
Recycle();
raise "节点关系出现循环";
end
FInToArray := FSInToArray;
ret := array();
sub := array();
for i := 0 to length(FComponents)-1 do
begin
ret[FSubName,i]:= FComponents[i].toarray();
end
for i,v in FValue do
begin
if i=FSubName then continue;
ret[i]:= v;
end
return ret;
end
class function SetColumnName(info);
begin
if not ifarray(info)then info := array("id":"id","pid":"pid","sub":"sub");
if not ClumnNameOk(info["id"])then info["id"]:= "id";
if not ClumnNameOk(info["pid"])then info["pid"]:= "pid";
if not ClumnNameOk(info["sub"])then info["sub"]:= "sub";
SetIdName(info["id"],info["pid"],info["sub"]);
end
class function ToTree(d,info);
begin
{**
@explan(说明) 二维表转换为树结构 %%
@param(d)(array) 数据包含 信息 %%
@param(info)(array) 字段信息 "id" 当前节点的字段,"pid" 当前节点的父节点字段,"sub" ,返回子节点的字段
默认值 array("id":"id","pid":"pid","sub":"sub"); %%
@return(TArrayTreeClass)
**}
SetColumnName(info);
root := new TArrayTreeClass(array(FIdName:nil,FPIdName:nil));
oarray := array();
oarray[-inf]:= root;
for i,v in d do //构建id
begin
id := v[FIdName];
ido := oarray[id];
if ifnil(ido)then
begin
ido := new TArrayTreeClass(v);
oarray[id]:= ido;
end
end
ifcycle := true;
for i,v in d do
begin
id := v[FIdName];
ido := oarray[id];
pid := v[FPIdName];
pdo := oarray[pid];
if not pdo then
begin
pdo := oarray[-inf];
ifcycle := false;
end
pdo.addcomponent(ido);
end
if ifcycle and oarray then
begin
for i,v in oarray do
begin
v.Recycle();
raise "节点关系出现循环";
break;
end
end
return root;
end
class function CreateRow(d,id,r);
begin
for i,v in d do
begin
ri := array();
if not v then continue;
ri[FIdName]:= GetCounter();
ri[FPIdName]:= id;
for j,vi in v do
begin
if j=FSubName then
begin
call(thisfunction,vi,ri[FIdName],r);
end
{else if j=FIdName or j = FPIdName then
begin
end}else
begin
ri[j]:= vi;
end
end
if ri then
begin
r[length(r)]:= ri;
end
end
end
class function TreeArrayToArray(d,info);
begin
{**
@explan(说明) 树结构转换为二维表 %%
@param(d)(array) 数据包含 信息 %%
@param(info)(array) 字段信息 "id" 当前节点的字段,"pid" 当前节点的父节点字段,"sub" ,返回子节点的字段
默认值 array("id":"id","pid":"pid","sub":"sub"); %%
@return(array)
**}
if not ifarray(d)then exit;
SetColumnName(info);
r := array();
initconter();
CreateRow(d,GetCounter(),r);
return r;
end
class function ToTreeArray(d,info);
begin
{**
@explan(说明) 二维表转换为树结构 %%
@param(d)(array) 数据包含 信息 %%
@param(info)(array) 字段信息 "id" 当前节点的字段,"pid" 当前节点的父节点字段,"sub" ,返回子节点的字段
默认值 array("id":"id","pid":"pid","sub":"sub"); %%
@return(array) 树形结构的array
**}
root := ToTree(d,info);
if not root then return;
FSInToArray := tostn(now());
r :=(root.toarray());
return r;
end
end
type TNode = class() //树节点
{**
@explan(说明) 树结点 %%
**}
private
FItems; //子项
[weakref]FParent; //父节点
public
function Create();virtual;
begin
inherited;
FExpanded := true;
FItems := new TFpList(); //子项
end
function CreateNode();virtual;
begin
return CreateObject(self(true).Classinfo(1));
end
function CreateNodeAndAppend();virtual; //构造并追加
begin
nd := CreateNode();
AppendNode(nd);
return nd;
end
function GetNodeByIndex(idx);
begin
{**
@explan(说明) 通过序号获得子节点%%
@param(idx)(TNode) %%
**}
if idx >= 0 then return FItems[idx];
return nil;
end
function indexof(v); //获得序号
begin
return FItems.indexof(v);
end
function GetIndex();virtual;
begin
{**
@explan(说明) 获得在父节点中的序号 %%
@return(integer) 序号 %%
**}
if Parent then Parent.indexof(self);
end
function AppendNode(it);virtual;
begin
{**
@explan(说明) 插入一个节点 %%
@param(it)(TNode) 节点 %%
@return(bool) 是否成功 %%
**}
return InsertNode(it,FItems.Count);
end
function HasNode(nd);virtual;
begin
{**
@explan(说明) 是否为某个节点的祖先节点 %%
@param(nd)(TNode) 子节点 %%
@return(TNode|0) 如果为祖先节点,就返回查询节点的父节点 %%
**}
if not(nd is class(TNode))then return 0;
p1 := nd.Parent;
p := p1;
while p do
begin
if p=self then return p1;
if p is class(TNode)then p := p.Parent;
end
return 0;
end
function DeleteNode(nd);virtual;
begin
{**
@explan(说明) 删除节点 %%
@param(nd)(TNode) 待删除节点 %%
**}
if nd=self then return 0;
pn := HasNode(nd);
if not pn then return;
return pn.DeleteChildNode(nd);
end
function DeleteChildNode(nd);
begin
{**
@explan(说明) 删除子节点%%
@param(nd)(TNode) 节点 %%
**}
idx :=-1;
idx := indexof(nd);
if idx=-1 then return 0;
return DeleteNodeByIndex(idx);
end
function DeleteNodeByIndex(idx);
begin
{**
@explan(说明) 根据位置删除节点%%
@param(idx)(integer) 序号 %%
**}
nd := FItems[idx];
if not nd then return;
//是否显示处理
FItems.Deli(idx);
CurrentDeleteNode := nd;
nd.parent := self(true);
CurrentDeleteNode := nil;
return true;
end
function DeleteChildren();virtual; //
begin
{**
@explan(说明) 删除所有的子节点%%
**}
while NodeCount>0 do
begin
idx := 0;
it := FItems[idx];
CurrentDeleteNode := it;
it.parent := self(true);
CurrentDeleteNode := nil;
FItems.Deli(idx);
end
end
function InsertNodes(its,idx);virtual;
begin
{**
@explan(说明) 插入一个节点 %%
@param(it)( array of TNode) 字符串 %%
@param(idx)(integer) 序号 默认为0 %%
**}
idx0 := idx;
if idx<0 then idx0 := 0;
if idx>FItems.Count then idx0 := FItems.Count;
bidx := idx0;
for i,it in its do
begin
if(it is class(TNode))and(not it.Parent)then
begin
FItems.InsertBefor(it,idx0);
CurrentAddNode := it;
it.Parent := self(true);
CurrentAddNode := nil;
idx0++;
end
end
end
function InsertNode(it,idx);virtual;
begin
{**
@explan(说明) 插入一个节点 %%
@param(it)(TNode) 字符串 %%
@param(idx)(integer) 序号 默认为0 %%
**}
if(it is class(TNode))and(not it.Parent)then
begin
if idx<0 then idx := 0;
if idx>FItems.Count then idx := FItems.Count;
if not(idx >= 0)then idx := 0;
FItems.InsertBefor(it,idx);
CurrentAddNode := it;
it.Parent := self(true);
CurrentAddNode := nil;
return true;
end
end
function Expand();virtual; //展开
begin
FExpanded := true;
end
function UnExpand();virtual; //折叠
begin
FExpanded := false;
end
function RecyclingChildren();virtual;
begin
while NodeCount>0 do
begin
it := FItems[0];
it.Recycling();
end
end
function Recycling();virtual;
begin
p := FParent;
if p then
begin
p.DeleteNode(self);
end
while NodeCount>0 do
begin
it := FItems[0];
it.Recycling();
end
//inherited;
end
property NodeCount read GetNodeCount; //节点数
property Expanded read FExpanded write SetExpand; //展开
property Parent read FParent write SetParent; //父节点
property LastChild read GetLstChild;
{**
@param(NodeCount)(integer) 子节点数量 %%
@param(Expanded)(bool) 是否展开 %%
@param(Parent)(TNode) 父节点 %%
**}
protected
property CurrentDeleteNode read FCurrentDeleteNode write FCurrentDeleteNode;
property CurrentAddNode read FCurrentAddNode write FCurrentAddNode;
{**
@ignoremembers(CurrentDeleteNode,CurrentAddNode)
**}
function SetParent(V);virtual;
begin
tp := Parent;
if v=tp then return;
if(v is class(TNode))then
begin
if v.CurrentAddNode=self then
begin
FParent := v; //新节点
end else
if v.CurrentDeleteNode=self then //从节点移除
begin
FParent := nil;
end else
begin
if tp=v then return;
if tp then
begin
tp.DeleteNode(self(true));
end
v.InsertNode(self(true),v.NodeCount);
end
end else
begin
if tp then tp.DeleteNode(self(true));
end
end
private
function GetLstChild();
begin
return FItems[FItems.Count-1];
end
FCurrentDeleteNode;
FCurrentAddNode;
FExpanded;
function SetExpand(v);virtual; //已经展开
begin
if v then Expanded();
else UnExpand();
end
function GetNodeCount(); //子节点数
begin
return FItems.Count;
end
end
type TTire = class
{**
@explan(说明) tire树
**}
type TTireNode = class
FChar;
FSub;
FEnd;
Ficase;
function Create(v);
begin
FChar := v;
FSub := array();
FEnd := false;
Ficase := false;
end
function Add(s);
begin
v0 := s[1];
if Ficase then v0 := lowercase(v0);
vsub := FSub[v0];
if not vsub then
begin
vsub := new TTireNode(v0);
vsub.Ficase := Ficase;
FSub[v0] := vsub;
end
ls := length(s);
if ls>1 then
vsub.Add(s[2:]);
else
begin
vsub.FEnd := true;
end
end
function Find(s,slen,idx);
begin
if idx>slen then return FEnd;
v0 := s[idx];
if Ficase then v0 := lowercase(v0);
vsub := FSub[v0];
if vsub then
begin
idx++;
return vsub.Find(s,slen,idx);
end
return FEnd ;
end
function seticase(i);
begin
ni := i?true:false;
if ni<>Ficase then
begin
Ficase := ni;
for i,v in mrows(FSub,1) do
begin
vi := FSub[v];
if ni then //忽略大小写
begin
reindex(FSub,array(v:nil));
FSub[lowercase(vi.FChar)] := vi;
end else //区分大小写
begin
reindex(FSub,array(v:nil));
FSub[vi.FChar] := vi;
end
vi.seticase(i);
end
end
end
end
function Add(s);
begin
FRoot.Add(s);
end
function Create();
begin
fignorecase := false;
FRoot := new TTireNode();
FRoot.Ficase := false;
end
function Find(s,slen,idx,outidx,ostr);
begin
tid := idx;
r := FRoot.Find(s,slen,idx);
if r then
begin
ostr := s[tid:idx-1];
outidx := idx;
end
idx := tid;
return r;
end
FRoot;
property ignorecase read fignorecase write setignorecase;
private
function setignorecase(i);
begin
ni := i?true :false;
if ni<>fignorecase then
begin
FRoot.seticase(ni);
end
end
fignorecase;
end
type tpairstate =class //括号状态
function Create(t);
begin
FType := ifstring(t)?t:"";
FCJ := 0;
FState := 0;
FIndexs := array(0);
FIndex := 0;
FCstate := false;
FSubcount := array(0);
end
function subitemadd();
begin
FSubcount[FIndex]++;
end
function subitemcount();
begin
return FSubcount[FIndex];
end
function GetLeft();
begin
FCstate := true;
if FState then // 上一个是左括号
begin
FCJ++;
FIndex++;
FIndexs[FIndex]:=0;
end else //上一个非左括号
begin
FIndexs[FIndex]++;
FSubcount[FIndex]:=0;
end
FState := true;
end
function GetRight();
begin
FCstate := true;
//if FCJ=0 then return ;
if FState then // 上一个是左括号
begin
//FIndexs[FIndex]++;
end else //上一个非左括号
begin
if FCJ>0 then
begin
FCJ--;
DeleteIndex(FIndexs,FIndex);
FIndex--;
end else
begin
FCstate := false;
end
end
FState := false;
end
function GetSate();
begin
if FCstate then
begin
//return inttostr(FIndexs[FCJ])+FType;
return tostn(FIndexs)+FType;// inttostr(FCJ)+"+"+inttostr(FIndexs[FIndex])+FType; length(FIndexs)+FType ;//
end
end
function Show();
begin
echo "层级:",FCJ," 序号:",FIndexs[FIndex],"状态:", FCstate;
end
property state read FState;
function Clone();
begin
r := new tpairstate(FType);
r.FCstate := FCstate;
r.FState := FState;
r.FCJ := FCJ;
r.FIndexs := FIndexs;
r.FIndex := FIndex;
r.FSubcount := FSubcount;
return r;
end
protected
FCstate;
FState;
FCJ;
FIndexs;
FSubcount;
FIndex;
FType;
end
type TIniFileExter=class()
{**
@explan(说明) ini文件读写封装 %%
**}
private
FTStringa;
FVtype;
FLowerKey;
FLowerValue;
function CheckSK(s,k);
begin
return ifstring(s) and s and ifstring(k) and k;
end
function ChangeV(V);
begin
vv := v;
case Vtype of
1:vv := vv="0"?false:true;
2:vv := StrToIntDef(vv,0);
else
begin
if FLowerValue then vv := lowercase(vv);
end
end
return vv;
end
function STNVA();
begin
{**
@explan(说明) 转换为name,value 列的二维数组 %%
**}
r := array();
for i := 0 to FTStringa.Count-1 do
begin
n := FTStringa.Names(i);
if n then
begin
if FLowerKey then n := lowercase(n);
vv := FTStringa.Values(n);
r[length(r)]:= array("name":n,"value":ChangeV(vv));
end
end
FTStringa.Clear();
return r;
end
function STNV();
begin
{**
@explan(说明) 转换为name:value 一维数组 %%
**}
nr := STNVA();
r := array();
for i,v in nr do
begin
r[v["name"]]:= v["value"];
end
return r;
end
function STA();
begin
{**
@explan(说明) 转换为一维数组 %%
**}
r := array();
for i := 0 to FTStringa.Count-1 do
begin
vi := FTStringa.Strings(i);
r[i]:= FLowerKey?lowercase(vi):vi;
end
FTStringa.Clear();
return r;
end
public
function create();
begin
{**
@explan(说明) 构造函数 %%
@param(al)(string) 别名 %%
@param(name)(string) 文件名 %%
**}
FTStringa := new TStringlist();
FAlias := "";
ffilename := "";
end
function readSection(sn);virtual;
begin
{**
@explan(说明) 读取section 下面key %%
**}
if ifstring(sn)and sn then Fini.readSection(sn,FTStringa);
return STA();
end
function ReadSections();virtual;
begin
{**
@explan(说明) 读取所有section名字 %%
**}
FIni.ReadSections(FTStringa);
return STA();
end
function ReadSectionValues(sn);virtual;
begin
{**
@explan(说明) 读取section下面的所有key:value %%
**}
if ifstring(sn)and sn then FIni.ReadSectionValues(sn,FTStringa);
return STNV();
end
function RenameSection(sn1,sn2);virtual;
begin
{**
@explan(说明) 重命名section %%
@param(sn1)(string) 旧名字 %%
@param(sn2)(string) 新名字 %%
**}
if not(sn1 and sn2 and ifstring(sn1))and ifstring(sn2)then exit;
vs1 := ReadSectionValues(sn1);
EraseSection(sn1);
for i,v in vs1 do
begin
WriteKey(sn2,i,v);
end
end
function RenameKey(sec,k1,k2);virtual;
begin
{**
@explan(说明) 重命名key %%
@param(sec)(string) section名称 %%
@param(k1)(string) 旧名字 %%
@param(k2)(string) 新名字 %%
**}
if(sec and k2 and k1 and ifstring(sec)and ifstring(k1)and ifstring(k2))then exit;
v := ReadKey(sec,k1);
DeleteKey(sec,k1);
WriteKey(sec,k2,v);
end
function ReadSectionValues2(sn);
begin
{**
@explan(说明) 获得section 数据,二维表,name,value 列
**}
if ifstring(sn)and sn then FIni.ReadSectionValues(sn,FTStringa);
return STNVA();
end
function ReadSectionValues3(sn);
begin
{**
@explan(说明) 获得section 数据,二维表,0列为key,1列为value
**}
d := ReadSectionValues2(sn);
r := array();
for i,v in d do
begin
r[length(r)]:= array(v["name"],v["value"]);
end
return r;
end
function ReadKey(sn,key,def);virtual;
begin
{**
@explan(说明) 读取key %%
**}
if CheckSK(sn,key)then return FIni.ReadString(sn,key,ifstring(def)?def:"");
return nil;
end
function WriteKey(sn,key,v);virtual;
begin
{**
@explan(说明) 写入key %%
**}
if ifnil(v)then v := "";
if CheckSK(sn,key)then return FIni.WriteString(sn,key,ifstring(v)?v:tostn(v));
return 0;
end
function DeleteKey(sn,key);virtual;
begin
if CheckSK(sn,key)then return FIni.DeleteKey(sn,key);
end
function EraseSection(sn);virtual;
begin
{**
@explan(说明)删除section %%
**}
if ifstring(sn)and sn then return FIni.EraseSection(sn);
end
function Destroy();virtual;
begin
finiobj := nil;
FTStringa := nil;
end
property VType read FVtype write FVtype;
property LowerKey read FLowerKey write FLowerKey;
property LowerValue read FLowerValue write FLowerValue;
property Alias read FAlias write setalias; //目录别名
property filename read ffilename write setfilename; //文件名
_tag;
private
property Fini read getiniobj write finiobj;
private
function getiniobj();
begin
if not(finiobj) then
begin
if ifstring(FAlias) and ifstring(ffilename) then
begin
finiobj := new TIniFile(FAlias,ffilename);
end else
begin
raise "ini读写文件错误";
end
end
return finiobj;
end
function setfilename(v);
begin
if ifstring(v) and v<>ffilename then
begin
ffilename := v;
finiobj := nil;
end
end
function setalias(v);
begin
if ifstring(v) and v<>FAlias then
begin
FAlias := v;
finiobj := nil;
end
end
FAlias;
ffilename;
finiobj;
end
type TCanvsRgnClipAutoSave=class
{**
@expan(说明) 裁剪canvas区域,销毁时还原 %%
**}
function Create(cvs,rec);
begin
{**
@explan(说明)构造裁剪对象 %%
@param(cvs)(tcustomcanvas) canvas 对象 %%
@param(rec)(array(左上右下))区域 %%
**}
if(ifobj(cvs))and cvs.HandleAllocated()and ifarray(rec)then
begin
FW32api := cvs._wapi;
FCvsHandle := cvs.Handle;
FCrg := FW32api.CreateRectRgn(rec[0],rec[1],rec[2],rec[3]);
FBKrg := FW32api.SelectClipRgn(FCvsHandle,FCrg); //裁剪区域
end
end
function Destroy();
begin
if FW32api and FCvsHandle and FBKrg and FCrg then
begin
FW32api.SelectClipRgn(FCvsHandle,FBKrg); //恢复区域
FW32api.DeleteObject(FCrg); //销毁区域
end
FW32api := nil;
end
private
FBKrg;
FCrg;
FCvsHandle;
FW32api;
end
type tcountkernel = class() //锁计数对象
function create();
begin
Flocked := 0;
end
function add();
begin
Flocked++;
end
function del();
begin
Flocked--;
end
property locked read Flocked;
private
Flocked;
end
type tcountlocker = class() //锁对象
function create(v);
begin
if v is class(tcountkernel) then
begin
fkernel := v;
fkernel.add();
end
end
function destroy();
begin
if fkernel then fkernel.del();
end
private
fkernel;
end
type tinstancemanager = class()
{**
@explan(说明)函数c语言指针管理器 %%
**}
function create();
begin
fhandles := array();
end
function destroy();
begin
for i,v in fhandles do
begin
deleteinstance(v);
end
fhandles := array();
end
function get(f); //获得
begin
{**
@explan(说明)通过函数句柄获取c回调指针 %%
@param(f)(handler) tsl函数对象 %%
@return(pointer) c函数回调 %%
**}
id := integer(f);
r := fhandles[id];
if r then return r;
r := makeinstance(f);
if r then
begin
fhandles[id] := r;
return r;
end
end
function del(f);
begin
{**
@explan(说明)通过函数句柄删除c回调指针 %%
@param(f)(handler) tsl函数对象 %%
@return(bool) 是否成功 %%
**}
id := integer(f);
h := fhandles[id];
if h then
begin
r := deleteinstance(h);
reindex(fhandles,array(id:nil));
return r;
end
end
private
fhandles;
end
implementation
function iffuncptr(fn);
begin
//return datatype(fn)=7;
return ifobj(fn);
end
function includestate(u,s);
begin
{**
@explan(说明) 状态扩展 %%
**}
if not ifarray(u)then u := array();
if ifarray(s)then u union2= s;
else u union2= array(s);
return u;
end
function excludestate(u,s);
begin
{**
@explan(说明) 状态缩减%%
**}
if not ifarray(u)then u := array();
if ifarray(s)then u minus= s;
else u minus= array(s);
return u;
end
//*************makelong*****************************
function makelong(low,high,ptrl);
begin
{**
@explan(说明) 合并高低为 %%
@return(integer) 整数 %%
@param(low)(integer) 低位 %%
@param(high)(integer) 高位 %%
@param(ptrl)(integer) 长度 默认为 8 %%
**}
if not ifnumber(ptrl)then ptrl := 16;
mask := 2^(ptrl)-1;
low1 := low .& mask;
high1 := high .& mask;
return _shl(high1,ptrl).| low1;
end
function makeposition(x,y);
begin
{**
@explan(说明)将x,y构造为一个int类型 %%
@return(integer)
**}
if ifnumber(x)and ifnumber(y)then return makelong(signedtounsigned(x),signedtounsigned(y));
return 0;
end
function lowuperdword(value_,lvalue,uvalue,ptrl);
begin
{**
@explan(说明) 高低位获取 %%
@param(value_)(integer) 整数 %%
@param(lvalue)(integer) 低位 %%
@param(uvalue)(integer) 高位 %%
@param(ptrl)(integer) 长度 默认为 8 %%
**}
lvalue := uvalue := 0;
if not ifnumber(value_)then return array(0,0);
if not ifnumber(ptrl)then ptrl := 16;
value :=(value_);
mask := 2^(ptrl)-1;
uvalue := _shr(value,ptrl).& mask;
//t := _shl(value,ptrl);
//lvalue := _shr(t,ptrl) .& mask;
lvalue := value .& mask;
return array(lvalue,uvalue);
end
function signedtounsigned(v,n);
begin
{**
@explan(说明) 符号数转换为无符号数 %%
@param(v)(integer) 数字 %%
@param(n)(integer) 有效位数 %%
@return(integer)
**}
if not ifnumber(n)then n := 16;
if n>64 then n := 64;
mkv2 := 1;
ret := mkv2 .& v;
for i := 1 to n-1 do
begin
mkv2 := _shl(mkv2,1);
ret +=(mkv2 .& v);
end
mkv2 := _shl(mkv2,1);
if v<0 then
begin
ret .|= mkv2;
end else
begin
ret .&=(.! mkv2);
end
return ret;
end
function getbitsfrominteger(n,b,e);
begin
{**
@explan(说明) 获取数字的位数并转换为整数 %%
@param(b)(integer) 开始位 %%
@param(e)(integer) 截止位 %%
@param(n)(integer) 数字 %%
@return(integer)
**}
r := 0;
if b<0 then return 0;
mk := 2^(b);
for i := b to e do
begin
if(mk .& n)>0 then r += _shr(mk,b);
mk := _shl(mk,1);
end
return r;
end
function unsignedtosigned(v,n);
begin
{**
@explan(说明) 无符号数转换为符号数 %%
@param(v)(integer) 数字 %%
@param(n)(integer) 有效位数 %%
@return(integer)
**}
if not ifnumber(n)then n := 16;
if n>64 then n := 64;
mkv := 0;
mkv := _shl(1,n-1);
mkv2 := 1;
for i := 1 to n-1 do
begin
mkv2 := _shl(mkv2,1);
mkv2 += 1;
end
vv := v .& mkv2;
if(v .& mkv)then
begin
return 0-((_not(vv) .& mkv2)+1);
end
return vv;
end
function bitcombination(s,v,f);
begin
{**
@explan(说明)bit位组合 %%
@param(s)(integer) 原有值 %%
@param(v)(integer) 追加或者删除 %%
@param(f)(integer) 0 为 or ,1 为 and ;2 表示 删除 v的值 %%
**}
if not(ifnumber(s)and ifnumber(v))then return 0;
case f of
0:return s .| v;
1:return s .& v;
2:return(.!v).& s;
else return s;
end
hv :=((s .& v)=v);
if(hv)and f=2 then
begin
return(.!v).& s;
end else
if(f=0)and not(hv)then
begin
return s .| v;
end else
if(f=1)and not(hv)then
begin
return s .& v;
end else
return s;
end
function formatshortcut(d);
begin
r := "";
if d then
begin
if d["c"] then r +=(r)?"+Ctrl":"Ctrl";
if d["s"] then r +=(r)?"+Shift":"Shift";
if d["a"] then r +=(r)?"+Alt":"Alt";
if d["f"] then r +=(r)?("+"+d["f"]):d["f"];
if d["w"] then r +=(r)?("+"+d["w"]):d["w"];
end
return r;
end
function parsershortcutstr(s_); //快捷键解析
begin
s := uppercase(s_);
ls := length(s);
zmb := array();
fb := array();
for i := 65 to 90 do zmb[chr(i)] := true;
for i:= 1 to 12 do fb["F"+inttostr(i)] := true;
cword :="";
i := 1;
r := array();
while(i<=ls) do
begin
vi := s[i];
vio := ord(vi);
case vio of
65 to 90 ,48 to 57:
begin
cword +=vi;
end
else
begin
if cword then
begin
case cword of
"SHIFT":
begin
r["s"] := true;
end
"CTRL":
begin
r["c"] := true;
end
"ALT":
begin
r["a"] := true;
end
else
begin
if fb[cword] and not(r["w"]) then
begin
r["f"] := cword;
end else
if r and not(r["f"]) then
begin
if zmb[cword] then r["w"] := cword;
end
end
end ;
end
cword := "";
end
end;
i++;
end
if cword then
begin
case cword of
"SHIFT":
begin
r["s"] := true;
end
"CTRL":
begin
r["c"] := true;
end
"ALT":
begin
r["a"] := true;
end
else
begin
if fb[cword] and not(r["w"]) then
begin
r["f"] := cword;
end else
if r and not(r["f"]) then
begin
if zmb[cword] then r["w"] := cword;
end
end
end ;
end
if not(r["w"] or r["f"]) then r := array();
return r;
end
function FormatTslData(d,sj,tn);
begin
{**
@explan(说明) 格式化tsl数据 %%
@param(d)(any) tsl数据 %%
@param(sj)(string) 空格距离 %%
@param(tn)(nil) 空参数 %%
@return(string) 格式化后的字符串 %%
**}
r := "";
if not(sj and ifstring(sj))then sj := " ";
if ifarray(d)then
begin
r := "(\r\n";
if ifnil(tn)then
begin
tn := 0;
r := "array(\r\n";
end
di := 0;
len := length(d);
for i,v in d do
begin
bt := sj;
if di <> i then
begin
bt += tostn(i)+":";
end
di++;
vr := FormatTslData(v,sj,1);
if len>di then vr += ",";
r += bt;
if ifarray(v)then
begin
vrs := str2array(vr,"\r\n");
dii := 0;
for j,vj in vrs do
begin
if dii<1 then r += vj;
else r += sj+vj;
r += "\r\n";
dii++;
end
end else
r += vr+"\r\n";
end
r += ")";
return r;
end else
return tostn(d);
end
function DeleteItemsByIndexs(r,dxs);
begin
{**
@explan(说明) 删除数组下标, %%
@param(r)(array) 待删除下标的数组,采用字符串下标的数组,变参返回%%;
**}
if not ifarray(r)then exit;
rdx := array();
for i,v in dxs do rdx[v]:= nil;
return reindex(r,rdx);
end
function HexHash();
begin
c := array("A","B","C","D","E","F");
idxs := inttostr(0 -> 9)union c union lowercase(c);
r := array();
for i,v in idxs do
begin
if i<16 then r[v]:= i;
else r[v]:= i-6;
end
return r;
end
function TslToHexStr(t);
begin
{**
@explan(说明) 将tsl数据转换为16进制字符串 %%
@param(t)(any) 任意的tsl数据 %%;
@return(string) 16进制字符串 %%
**}
r := "";
str := tostm(t);
ky := static(inttostr(0 -> 9)union array("A","B","C","D","E","F"));
idx := 1;
setlength(r,length(str)* 2);
for i := 0 to length(str)-1 do
begin
vi := ord(str[i]);
//r += ky[_shr(vi,4) .& 0xf];
//r += ky[vi .& 0xf] ;
r[idx]:= ky[_shr(vi,4).& 0xf];
r[idx+1]:= ky[vi .& 0xf];
idx += 2;
end
return r;
end
function HexFormatStrToTsl(hex);
begin
{**
@explan(说明)将带有换行符的16进制字符串转换为tsl数据 %%
@param(hex)(string) 16进制字符串 %%
@return(any) tsl数据类型 %%
**}
r := "";
hs := static HexHash();
//rs := inttostr(0 -> 9)union array("A","B","C","D","E","F","a","b","c","d","e","f");
for i := 1 to length(hex) do
begin
ri := hex[i];
if hs[ri]>=0 then
begin
r += ri;
end
end
return HexStrToTsl(r);
end
function TslToHexFormatStr(tsl);
begin
{**
@explan(说明) 将tsl类型转换为16进制字符串,每行长度为64,用\r\n分割 %%
@param(tsl)(any) tsl基础类型%%
@return(string) 字符串形式的16进制 %%
**}
s := TslToHexStr(tsl);
r := "";
n := length(s);
i := 1;
bc := 64;
while true do
begin
if i>n then break;
ij := i+bc;
if ij>n and i <= n then
begin
r += s[i:n];
break;
end else
r += s[i:ij];
if ij>n then break;
r += "\r\n";
i := ij+1;
end
return r;
end
function HexStrToTsl(hex);
begin
{**
@explan(说明)16进制字符串转换为tsl数据 %%
@param(hex)(string) 16进制字符串 %%
@return(any) tsl数据类型 %%
**}
if not(hex and ifstring(hex)) then return nil;
r := tostm(nil);
setlength(r,Integer(length(hex)/2));
hs := static HexHash();
idx := 0;
for i := 1 to length(hex)-1 step 2 do
begin
vi := hs[hex[i]];
vi1 := hs[hex[i+1]];
r[idx]:= _shl(vi,4).| vi1;
idx++;
end
return stm(r);
end
function gettemppath();
begin
{**
@explan(说明)获取windows临时目录 %%
@return(string) 目录;
**}
{$ifdef linux}
return "/var/tmp/";
{$endif}
s := "";
n := 1024;
setlength(s,n);
s1 := s;
GetTempPathA(n,s);
GetLongPathNameA(s,s1,n);
r := "";
for i := 1 to n do
begin
vi := s1[i];
if vi="\0" then
begin
return s1[1:(i-1)];
end
end
return "";
end
function TSL_ReservedKeys(var buf:string;buflen:integer):integer;cdecl;external{$ifdef linux}"libTSSVRAPI.so"{$else}"TSSVRAPI.dll"{$endif} name "TSL_ReservedKeys";
function TSL_ReservedKeys2();
begin
ks := "";
setlength(ks,1024 * 10);
TSL_ReservedKeys(ks,length(ks)-1);
r := array();
rl := 0;
ki := "";
for i := 1 to length(ks)-1 do
begin
vi := ks[i];
if vi="\0" then break;
if vi="\n" then
begin
if ki then
begin
r[rl++]:= ki;
ki := "";
end
end else
ki += vi;
end
return r union2 array("read","write"); //添加read write 关键字
end
function GetLongPathNameA(var s1:string;var s:string;L:integer):integer;stdcall;external "Kernel32.dll" name "GetLongPathNameA";
function GetTempPathA(L:integer;var s:string):integer;stdcall;external "Kernel32.dll" name "GetTempPathA";
function ParserCommandLine(s); //解析命令行参数
begin
r := array();
if not ifstring(s) then return r;
len := length(s);
p := "";
while idx<len do
begin
idx ++;
vi := s[idx];
if vi = '"' then
begin
if p then r[length(r)] := p;
p := "";
while idx<len do
begin
idx++;
vi := s[idx];
if vi = '"' then
begin
r[length(r)] := p;
p := "";
break;
end
p+=vi;
end
end else
if vi=" " or vi="\t" then
begin
if p then r[length(r)] := p;
p := "";
end else
p+=vi;
end
if p then r[length(r)] := p;
return r;
end
function intersectrect(rec1,rec2,irec);
begin
{**
@explan(说明) 计算矩形的交集 %%
@param(rec1)(array of integer) 矩形区域 %%
@param(rec2)(array of integer) 矩形区域 %%
@param(irec)(var array of integer) 重叠的区域 %%
@return(bool)
**}
if lineintersect(array(rec1[0],rec1[2]),array(rec2[0],rec2[2]),d1)and lineintersect(array(rec1[1],rec1[3]),array(rec2[1],rec2[3]),d2)then
begin
irec := array(d1[0],d2[0],d1[1],d2[1]);
return true;
end
return 0;
end
function pointinrect(p,rec);
begin
{**
@explan(说明) 判断点是否在矩形中 %%
@param(rec)(array of integer) 矩形区域 %%
@param(p)(array of integer) 点 array(x,y) %%
@return(bool)
**}
x := p[0];
y := p[1];
return x>rec[0]and y>rec[1]and x<rec[2]and y<rec[3];
end
function lineintersect(xx1,xx2,xx);
begin
if(xx1[0]>xx2[0]and xx1[0]>xx2[1])or(xx2[0]>xx1[1]and xx2[1]>xx1[0])then return 0;
xx := array(max(xx1[0],xx2[0]),min(xx1[1],xx2[1]));
return 1;
end
function leapyear(y); //闰年判断
begin
if not(y mod 4) then
begin
if not(y mod 100) then
begin
return not(y mod 400);
end
return 1;
end
return 0;
end
function getmonthdates(y,m); //获得所在月的天数
begin
if m = 2 then return leapyear(y)+ 28;
if m in array(1,3,5,7,8,10,12) then return 31;
return 30;
end
function CallMessgeFunction(f,o,e);
begin
{**
@ignore(忽略)
**}
if iffuncptr(f) then return call(f,o,e);
end
function CheckArrayIsNumbers(Value,n);
begin
if not(ifnumber(n)and n >= 1)then n := 4;
if ifarray(Value)then
begin
for i := 0 to n-1 do
begin
if not(ifnumber(Value[i]))then return 1;
end
return 0;
end
return 1;
end
function CheckArrayIsControlRect(Value);
begin
{**
@explan(说明) 检查数组是否可以作为control的rect %%;
**}
if not(CheckArrayIsNumbers(Value,4))then
begin
return Value[3]>0 and Value[2]>0;
end
end
function CheckArrayIsControlBounds(Value);
begin
{**
@explan(说明) 检查数组是否可以作为control 的 bounds
**}
if not(CheckArrayIsNumbers(Value,4))then
begin
return(Value[3]>Value[1])and(Value[2]>Value[0]);
end
end
function intasposition(i);
begin
if ifnumber(i)then
begin
return lowuperdword(i);
end
return array(0,0);
end
function DeleteAllFiles(path);
begin
{**
@explan(说明) 删除指定路径的文件或者文件夹 %%
**}
if not ifstring(path)then return 0;
if not path then return 0;
iofp := ioFileseparator();
if path[length(path)]=iofp then return call(thisfunction,path[1:(length(path)-1)]);
info := FileList("",path); //"A"
if info then
begin
if pos("D",info[0]["Attr"])then
begin
fs := FileList("",path+iofp+"*");
for i,v in fs do
begin
n := v["FileName"];
if n in array(".","..")then continue;
call(thisfunction,path+iofp+n);
end
return RemoveDir("",path);
end else
begin
return FileDelete("",path);
end
return 0;
end
end
function CreateDirWithFileName(fname);
begin
{**
@explan(说明) 根据文件全名构造目录 %%
**}
if not(ifstring(fname)and(length(fname)>4))then exit;
info := FileList("",fname);
if info then exit;
len := length(fname);
iofp := ioFileseparator();
for i := len downto 1 do
begin
vi := fname[i];
if vi=iofp then
begin
ffname := fname[1:i];
break;
end
end
if not ffname then exit;
nct := 4;
{$ifdef linux}
nct := 1;
{$endif}
if length(ffname)<1 then exit;
ph := ffname[1:nct];
for i := nct+1 to length(ffname) do
begin
vi := ffname[i];
if vi=iofp then
begin
if not FileList("",ph)then
begin
CreateDir("",ph);
end
end
ph += vi;
end
end
function TS_GetUserProfileHome():string;cdecl;external {$ifdef linux}"libTSSVRAPI.so"{$else}"TSSVRAPI.dll"{$endif} name "TS_GetUserProfileHome";
function IsTextUTF8(str)
begin
{utf8规则
单字节: 0xxxxxxx
二字节 110xxxxx 10xxxxxx
三字节 1110xxxx 10xxxxxx 10xxxxxx
四字节 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
五字节 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
刘字节 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
}
// 0 为ansi 编码,1 为utf8编码 -1 不能确定什么编码
nBytes := 0; //UFT8可用1-6个字节编码,ASCII用一个字节
DY := 0;
chr := "";
bAllAscii := TRUE; //如果全部都是ASCII, 说明不是UTF-8
for i := 1 to length(str) do
begin
chr := ord(str[i]);
if((chr .& 0x80)<> 0)then
begin // 判断是否ASCII编码,如果不是,说明有可能是UTF-8,ASCII用7位编码,但用一个字节存,最高位标记为0,o0xxxxxxx
bAllAscii := FALSE;
end
if(nBytes=0)then //如果不是ASCII码,应该是多字节符,计算字节数
begin
if(chr >= 0x80)then
begin
if(chr >= 0xFC and chr <= 0xFD)then nBytes := 6;
else if(chr >= 0xF8)then nBytes := 5;
else if(chr >= 0xF0)then nBytes := 4;
else if(chr >= 0xE0)then nBytes := 3;
else if(chr >= 0xC0)then nBytes := 2;
else return 0;
DY := MAX(nBytes,DY);
nBytes--;
end
end else //多字节符的非首字节,应为 10xxxxxx
begin
if((chr .& 0xC0)<> 0x80)then return -1;
nBytes--;
end
end;
//违返规则
if(nBytes>0)then
return -1;
//如果全部都是ASCII, 说明不是UTF-8
if(bAllAscii)then
return 0;
//return 1;
return DY>2;
end
function exportjsonformat(d,tbw,ct);
begin
//d:天软数据
//tbw : 字符串,tab 宽度
//ct 递归深度,忽略
case datatype(d) of
0,20:return inttostr(d);
1:return floattostr(d);
2:return tostn(d);
8,10,11,12:return "null";
end;
if not(ct>0)then ct := 0;
if not ifstring(tbw)then tbw := " ";
tbstr := "";
tbstra := "";
for i := 0 to ct do
begin
tbstr += tbw;
if i>0 then tbstra += tbw
end
if ifarray(d)then
begin
if not d then return "[]";
idx := 0;
for i,v in d do
begin
if idx <> i then
begin
fobj := true;
break;
end
idx++;
end
if fobj then
begin
r := "{";
for i,v in d do
begin
if ifstring(i)then ii := tostn(i);
else ii := tostn(tostn(i));
r += "\r\n"+tbstr+ii+":";
if ifarray(v)and v then
begin
r += "\r\n"+tbstr;
end
r += exportjsonformat(v,tbw,ct+1)+",";
end
lr := length(r);
r[lr:]:= "\r\n"+tbstra+"}";
end else
begin
r := "[";
for i,v in d do
begin
r += "\r\n"+(tbstr)+exportjsonformat(v,tbw,ct+1)+",";
end
lr := length(r);
r[lr:]:= "\r\n"+tbstra+"]";
end
return r;
end else
if ifobj(d)then
begin
try
//return "{}";
//此处可以遍历对象信息
tslobjtoarray(d,dinfo);
for i,v in mrows(dinfo,1) do
begin
nv := invoke(d,v);
if ifobj(nv)then nv := nil; //避免死循环
dinfo[v]:= nv;
end
return exportjsonformat(dinfo,tbw,ct);
except
return "{}";
end
end else
return "null";
end
function tslobjtoarray(o,r);
begin
d := o.classinfo();
if not ifarray(r)then r := array();
for i,v in d["inherited"] do
begin
tslobjtoarray(findclass(v,o),r);
end
for i,v in d["members"] do
begin
n := v["name"];
if v["access"]in array(0,1)then
begin
r[n]:= 0;
end else
begin
reindex(r,array(n:nil));
end
end
for i,v in d["properties"] do
begin
n := v["name"];
if v["read"]and(v["access"]in array(0,1))then
begin
r[n]:= 0;
end else
begin
reindex(r,array(n:nil));
end
end
end
function gettslexefullpath();
begin
plg := pluginpath();
sp := ioFileseparator();
for i:= length(plg)-1 downto 1 do
begin
if plg[i]=sp then
begin
if sp="/" then
begin
return plg[1:i]+"TSL";
end else
begin
return plg[1:i]+"tsl.exe";
end
end
end
return "";
end
initialization
end.
//////////////////////暂时没用到的类型///////////////////////////////////////
(*
type TFileLocker=class()
{**
@ignore(忽略) %%
@explan(说明) 文件锁定 %%
**}
private
FHandle;
FLocked;
FApi;
function GetFileOpen();
begin
return FHandle <> 0;
end
function GetFileLocked();
begin
return FLocked <> 0;
end
public
function Create(F);
begin
{**
@explan(说明)对文件加锁,防止其他进程读写 %%
@param(f)(string) 文件名 %%
**}
FHandle := 0;
FLocked := 0;
if not FileExists("",f)then exit;
FApi := gettswin32api();
FHandle := FApi.CreateFileA(F,0x40000000L,0,0,3,0x00000080,0);
if not FHandle then exit;
FLocked := FApi.LockFile(FHandle,0,0,0,0);
end
function Destroy();
begin
if FLocked then
begin
FApi.UnlockFile(FHandle,0,0,0,0);
end
if FHandle then
begin
FApi.CloseHandle(FHandle);
end
end
property FileOpend read GetFileOpen;
property FileLocked read GetFileLocked;
{**
@param(FileOpend)(bool) 是否有效%%
@param(FileLocked)(bool) 是否已经锁定%%
**}
end
type Ttagaccel=class(tslcstructureobj)
private
static SSTRUCT;
class function getstruct()
begin
if not SSTRUCT then SSTRUCT := MemoryAlignmentCalculate(array(
("fvirt","byte",0),
("key","short",0),
("cmd","short",0)));
return SSTRUCT;
end
public
function create(ptr)
begin
inherited create(getstruct(),ptr);
end
property fvirt index "fvirt" read _getvalue_ write _setvalue_;
property key index "key" read _getvalue_ write _setvalue_;
property cmd index "cmd" read _getvalue_ write _setvalue_;
end
type TBITMAPINFOHEADER=class(tslcstructureobj)
private
static SSTRUCT;
class function getstruct()
begin
if not SSTRUCT then SSTRUCT := MemoryAlignmentCalculate(array(
("bisize","int",40),
("biwidth","int",0),
("biheight","int",0),
("biplanes","short",0),
("bibitcount","short",0),
("bicompression","int",0),
("bisizeimage","int",0),
("bixpelspermeter","int",0),
("biypelspermeter","int",0),
("biclrused","int",0),
("biclrimportant","int",0)
));
return SSTRUCT;
end
public
function create(ptr)
begin
inherited create(getstruct(),ptr);
bisize := _size_();
end
property bisize index "bisize" read _getvalue_ write _setvalue_;
property biwidth index "biwidth" read _getvalue_ write _setvalue_;
property biheight index "biheight" read _getvalue_ write _setvalue_;
property biplanes index "biplanes" read _getvalue_ write _setvalue_;
property bibitcount index "bibitcount" read _getvalue_ write _setvalue_;
property bicompression index "bicompression" read _getvalue_ write _setvalue_;
property bisizeimage index "bisizeimage" read _getvalue_ write _setvalue_;
property bixpelspermeter index "bixpelspermeter" read _getvalue_ write _setvalue_;
property biypelspermeter index "biypelspermeter" read _getvalue_ write _setvalue_;
property biclrused index "biclrused" read _getvalue_ write _setvalue_;
property biclrimportant index "biclrimportant" read _getvalue_ write _setvalue_;
end
type TTBBUTTONINFOA=class(tcstructwithcharptr)
{**
@explan(说明) 工具条项内存对象 %%
**}
private
static SSTRUCT;
function getstruct()
begin
if not SSTRUCT then SSTRUCT := array(
("cbsize","int",0),
("dwmask","int",0),
("idcommand","int",0),
("iimage","int",0),
("fsstate","byte",0),
("fsstyle","byte",0),
("cx","short",0),
("lparam","intptr",0),
("psztext","char*",0),
("cchtext","int",100));
return SSTRUCT;
end
public
function create();override;
begin
inherited create(getstruct(),array("psztext":"cchtext"),nil);
cbsize := _size_();
end
property cbsize index "cbsize" read _getvalue_ write _setvalue_;
property dwmask index "dwmask" read _getvalue_ write _setvalue_;
property idcommand index "idcommand" read _getvalue_ write _setvalue_;
property iimage index "iimage" read _getvalue_ write _setvalue_;
property fsstate index "fsstate" read _getvalue_ write _setvalue_;
property fsstyle index "fsstyle" read _getvalue_ write _setvalue_;
property cx index "cx" read _getvalue_ write _setvalue_;
property lparam index "lparam" read _getvalue_ write _setvalue_;
property psztext index "psztext" read _getvalue_ write _setvalue_;
property cchtext index "cchtext" read _getvalue_ write _setvalue_;
end
type TTBBUTTON=class(tslcstructureobj)
{**
@explan(说明) 工具栏按钮内存对象 %%
**}
private
static SSTRUCT;
function getstruct()
begin
if not SSTRUCT then SSTRUCT := MemoryAlignmentCalculate(array(
("ibitmap","int",0),
("idcommand","int",0),
("fsstate","byte",0),
("fsstyle","byte",0),
("dwdata","intptr",0),
("istring","char*",128)));
return SSTRUCT;
end
public
function create(ptr)
begin
inherited create(getstruct(),ptr);
end
function _setvalue_(id,v);
begin
if id="istring" then
begin
if ifstring(v)and length(v)<127 then
begin
return inherited;
end
return;
end
return inherited;
end
property ibitmap index "ibitmap" read _getvalue_ write _setvalue_;
property idcommand index "idcommand" read _getvalue_ write _setvalue_;
property fsstate index "fsstate" read _getvalue_ write _setvalue_;
property fsstyle index "fsstyle" read _getvalue_ write _setvalue_;
property dwdata index "dwdata" read _getvalue_ write _setvalue_;
property istring index "istring" read _getvalue_ write _setvalue_;
end
type TScrollBarKind=class(tenumeration)
static sbHorizontal;
static sbVertical;
end
type TToolTipsFlags=class
{**
@ignore(忽略) %%
@explan() tooltips flags 常量 %%
**}
static TTF_IDISHWND;
static TTF_CENTERTIP;
static TTF_RTLREADING;
static TTF_SUBCLASS;
static TTF_TRACK;
static TTF_ABSOLUTE;
static TTF_TRANSPARENT;
static TTF_PARSELINKS;
static TTF_DI_SETITEM;
end
type TIMAGEINFO = class(tslcstructureobj)
{**
@ignore 忽略 %%
@explan(说明) imgelist中image的信息 %%
**}
private
static SSTRUCT;
function getstruct()
begin
if not SSTRUCT then SSTRUCT := MemoryAlignmentCalculate(
array(
("hbmimage","intptr",0),
("hbmmask","intptr",0),
("unused1","int",0),
("unused2","int",0),
("rcimage","int[4]",
(0,0,0,0))));
return SSTRUCT;
end
function getbmp(v);
begin
{**
@explan(说明)构造tbitmap对象 %%
**}
hm := _getvalue_(v);
if hm then
begin
r := new tbitmap();
r.handle := hm;
r.AutoDestroy := false;
return r;
end
end
public
function create(ptr)
begin
inherited create(getstruct(),ptr);
end
property bmimage:tbitmap index "hbmimage" read getbmp write getbmp;
property bmmask:tbitmap index "hbmmask" read getbmp write getbmp;
property hbmimage index "hbmimage" read _getvalue_ write _setvalue_;
property hbmmask index "hbmmask" read _getvalue_ write _setvalue_;
property unused1 index "unused1" read _getvalue_ write _setvalue_;
property unused2 index "unused2" read _getvalue_ write _setvalue_;
property rcimage index "rcimage" read _getvalue_ write _setvalue_;
{**
@param(bmimage)(tbitmap) 位图 %%
@param(bmmask)(tbitmap) mask %%
@param(rcimage)(array) 左上右下 %%
**}
end
*)
//////////////twincontrol 中移除的函数
(*
function CreateDrawItemEvent();virtual;
begin
{**
@explan(说明) 主动构造drawitem消息,可以自行填写信息在DoDrawItem中使用,与DestroyDrawItemEvent成对出现 %%
@return(TMDRAWITEM|nil) item绘制对象 %%
**}
e := nil;
if HandleAllocated() then
begin
hd := self.Handle;
itptr := FTtageDrawItem._getptr_;
e := new TMDRAWITEM(WM_DRAWITEM,0,itptr,hd);
e.canvas := canvas;
canvas.handle := _wapi.GetDC(self.Handle);
end
return e;
end
function DestroyDrawItemEvent(e);virtual;
begin
{**
@explan(说明) 与CreateDrawItemEvent配合使用 %%
@param(e)(TMDRAWITEM) CreateDrawItemEvent 构造的消息对象 %%
**}
if HandleAllocated() and ( e is class(TMDRAWITEM)) and (e.lparam = FTtageDrawItem._getptr_()) then
begin
dc := canvas.Handle;
if dc then
begin
canvas.handle := 0;
return _wapi.ReleaseDC(self.Handle,dc);
end
end
end
*)
(*
//tcontrol 移除代码
function GetDeviceContext(var WindowHandle:HWND);virtual; //type_tcontrol
begin
{**
@explan(说明) 获取设备hdc %%
@param(WindowHandle)(pointer) 窗口句柄 %%
@return(pointer) dc 句柄 %%
**}
if Parent is class(TWinControl)then
begin
Result := Parent.GetDeviceContext(WindowHandle);
MoveWindowOrgEx(Result,Left,Top);
IntersectClipRect(Result,0,0,Width,Height);
end else
raise "错误";
return Result;
end;
function IntersectClipRect(hdc, x0, y0, x1, y1);virtual; //type_tcontrol
begin
_wapi.IntersectClipRect(hdc, x0, y0, x1, y1);
end
function MoveWindowOrgEx(hdc;x:integer;y:integer);virtual; //type_tcontrol
begin
{**
@explan(说明) 移动dc原点 %%
@param(hdc)(pointer) dc 句柄 %%
**}
return _wapi.SetViewportOrgEx(hdc,x,y,nil);
end
function WMXButtonDown(o,e): LM_XBUTTONDOWN;virtual;
begin
end
function WMMButtonDBLCLK(o,e): LM_MBUTTONDBLCLK;virtual;
begin
end
function WMXButtonDBLCLK(o,e): LM_XBUTTONDBLCLK;virtual;
begin
end
function WMLButtonTripleCLK(o,e): LM_LBUTTONTRIPLECLK;virtual;
begin
end
function WMRButtonTripleCLK(o,e): LM_RBUTTONTRIPLECLK;virtual;
begin
end
function WMMButtonTripleCLK(o,e): LM_MBUTTONTRIPLECLK;virtual;
begin
end
function WMXButtonTripleCLK(o,e): LM_XBUTTONTRIPLECLK;virtual;
begin
end
function WMXButtonUp(o,e): LM_XBUTTONUP;virtual;
begin
end
function WMLButtonQuadCLK(): LM_LBUTTONQUADCLK;virtual;
function WMRButtonQuadCLK(): LM_RBUTTONQUADCLK;virtual;
function WMMButtonQuadCLK(): LM_MBUTTONQUADCLK;virtual;
function WMXButtonQuadCLK(): LM_XBUTTONQUADCLK;virtual;
*)
(*
function SetMainMenubk(mu);
begin
if csDesigning in ComponentState then
begin
if FMainMenu and mu then //已经存在 %%
begin
return ;
end
if (not FMainMenu) and mu then
begin
mu := new TMainmenu(self); //构造一个假的菜单
tm := new TMenu(mu);
tm.caption := "menu";
tm.parent := mu;
end
end
if FMainMenu<>mu then
begin
OM := FMainMenu;
if OM is class(tmainmenu) then
begin
OM.DestroyHandle(); //删除句柄 %%
OM.Hwnd := 0;
//if HandleAllocated() then _wapi.SetMenu(self.Handle,0); //删除窗口上面的菜单句柄
end
if (mu is class(tmainmenu)) then
begin
if HandleAllocated() then
begin
mu.Hwnd := handle;
//_wapi.SetMenu(self.Handle,mu.handle);
end
end
FMainMenu := mu;
end
end
type TTempFile = class
function Create(dt);
begin
if not ifarray(FFiles) then FFiles := array();
bp :=gettemppath()+"tinysoft"+ioFileseparator()+"tslvcl"+ioFileseparator();
{if not fileexists("",bp) then
begin
for i:=2 to length(bp) do
begin
if bp[i]=ioFileseparator() then
begin
if fileexists("",bp[1:i-1]) then
begin
createdir("",bp[1:i-1])
end
end
end
end }
for i,v in mrows( FFiles,1) do
begin
if not(FFiles[v]) then
begin
FFiles[v] := true;
FPath := v;
break;
end
end
while not FPath do
begin
i := 0;
while true do
begin
subdir := tostn( rand(3)[1]);
p := bp+subdir[3]+ioFileseparator()+subdir[4]+".png";
echo p,"\r\n";
if not(FFiles[p]) then
begin
FFiles[p] := true;
FPath := p;
//writefile(rwraw(),"",FPath,0,1,"0") ;
break;
end
end
end
if ifstring(dt) then
begin
//if FileExists("",FPath) then filedelete("",FPath);
writefile(rwraw(),"",FPath,0,length(dt),dt) ;
end
end
function GetData(buf);//获得数据
begin
if FPath then
begin
sz := filesize("",FPath);
return readfile(rwraw(),"",FPath,0,sz,buf);
end
end
function Destroy();
begin
//FFiles[FPath] := false;
if FileExists("",FPath) then echo "\r\ndeletefile:",filedelete("",FPath);
FPath := "";
end
property path read FPath ;
private
FPath;
static FFiles;
end
*)
//暂时不用的函数
{function chartoint(c);
begin
v := ord(c);
case v of
48 to 57:vk := v-48;
65 to 70:vk := v-65+10;
97 to 102:vk := v-97+10;
else raise "非16进制字符串";
end
return vk;
end}