![]() |
#2
吹水佬2022-03-15 08:12
将 STRUCT_ARRAY 整合到 STRUCT_CALSSS,这样简洁些
![]() ** VFP封装结构类型示例 ** 思路: ** 定义一个二维数组(aSTRUCT)用来描述结构体成员属性 ** 每一行表达一个成员属性:名称(Name),类型(Type), 大小(Size),地址偏移量(Offset) ** 定义 STRUCT_CALSS 类,提供初始化结构成员属性、读写结构成员数据函数 stInit()、getValue()、setValue() DECLARE long malloc IN msvcrt as apiMalloc long DECLARE long free IN msvcrt as apiFree long DECLARE long SendMessage IN user32 as apiSendMessage long,long,long,long of = CREATEOBJECT("form1") of.show(1) CLEAR ALL RETURN DEFINE CLASS form1 as Form ADD OBJECT rich AS Olecontrol WITH top=10,left=10,width=200,height=200,OleClass="RICHTEXT.RichtextCtrl.1",visible=1 PROCEDURE rich.init this.text = "" pf = CREATEOBJECT("PARAFORMAT2") pf.setValue("cbSize", pf.nSize) pf.setValue("dwMask", 256) pf.setValue("dyLineSpacing", 300) pf.setValue("bLineSpacingRule", 4) #define WM_USER 0x0400 #define EM_SETPARAFORMAT (WM_USER + 71) apiSendMessage(this.hWnd, EM_SETPARAFORMAT, 0, pf.pBuffer) RELEASE pf this.text = "123456789"+0h0D0A+"abcdefghijk"+0h0D0A+"ABCDEFGHIJK"++0h0D0A ENDPROC ENDDEFINE DEFINE CLASS PARAFORMAT2 AS STRUCT_CALSS PROCEDURE init DIMENSION this.aSTRUCT[24,4] this.stInit(1, "cbSize", "N",4) && DWORD this.stInit(2, "dwMask", "N",4) this.stInit(3, "wNumbering", "N",2) && WORD this.stInit(4, "wEffects", "N",2) this.stInit(5, "dxStartIndent", "N",4) this.stInit(6, "dxRightIndent", "N",4) this.stInit(7, "dxOffset", "N",4) this.stInit(8, "wAlignment", "N",2) this.stInit(9, "cTabCount", "N",2) this.stInit(10, "rgxTabs", "C",128) && DWORD[MAX_TAB_STOPS], MAX_TAB_STOPS=32 this.stInit(11, "dySpaceBefore", "N",4) this.stInit(12, "dySpaceAfter", "N",4) this.stInit(13, "dyLineSpacing", "N",4) this.stInit(14, "sStyle", "N",2) this.stInit(15, "bLineSpacingRule", "N",1) && BYTE this.stInit(16, "bOutlineLevel", "N",1) this.stInit(17, "wShadingWeight", "N",2) this.stInit(18, "wShadingStyle", "N",2) this.stInit(19, "wNumberingStart", "N",2) this.stInit(20, "wNumberingStyle", "N",2) this.stInit(21, "wNumberingTab", "N",2) this.stInit(22, "wBorderSpace", "N",2) this.stInit(23, "wBorderWidth", "N",2) this.stInit(24, "wBorders", "N",2) STRUCT_CALSS::init ENDPROC ENDDEFINE DEFINE CLASS STRUCT_CALSS AS Session DIMENSION aSTRUCT[1,4] pBuffer = 0 nSize = 0 PROCEDURE init LOCAL nRowCount nRowCount = ALEN(this.aSTRUCT, 1) this.nSize = this.aSTRUCT[nRowCount,3] + this.aSTRUCT[nRowCount,4] this.pBuffer = apiMalloc(this.nSize) SYS(2600, this.pBuffer, this.nSize, REPLICATE(0h00,this.nSize)) ENDPROC PROCEDURE Destroy apiFree(this.pBuffer) ENDPROC PROCEDURE stInit(n, cName, cType, nSize) this.aSTRUCT[n,1] = cName this.aSTRUCT[n,2] = cType this.aSTRUCT[n,3] = nSize this.aSTRUCT[n,4] = IIF(n>1, this.aSTRUCT[n-1,3]+this.aSTRUCT[n-1,4], 0) ENDFUNC HIDDEN FUNCTION getRow(cName) LOCAL nRow nRow = ASCAN(this.aSTRUCT, cName) RETURN IIF(nRow>0, ASUBSCRIPT(this.aSTRUCT,nRow,1), 0) ENDFUNC FUNCTION getValue(cName) LOCAL n, nSize, nOffset n = this.getRow(cName) IF n == 0 RETURN NULL ENDIF nSize = this.aSTRUCT[n,3] nOffset = this.aSTRUCT[n,4] RETURN ICASE(this.aSTRUCT[n,2]=="N", CTOBIN(SYS(2600, this.pBuffer+nOffset, nSize), TRANSFORM(nSize)+"RS"),; this.aSTRUCT[n,2]=="C", SYS(2600, this.pBuffer+nOffset, nSize),; NULL) ENDFUNC FUNCTION setValue(cName, vValue) LOCAL n, nSize, nOffset n = this.getRow(cName) IF n == 0 RETURN "" ENDIF nSize = this.aSTRUCT[n,3] nOffset = this.aSTRUCT[n,4] IF this.aSTRUCT[n,2]=="N" AND VARTYPE(vValue)=="N" RETURN SYS(2600, this.pBuffer+nOffset, nSize, BINTOC(vValue, TRANSFORM(nSize)+"RS")) ELSE IF this.aSTRUCT[n,2]=="C" AND VARTYPE(vValue)=="C" vValue = LEFT(vValue, nSize) nSize = LEN(vValue) RETURN SYS(2600, this.pBuffer+nOffset, nSize, vValue) ENDIF ENDIF RETURN "" ENDFUNC ENDDEFINE |
连接:https://bbs.bccn.net/thread-508544-1-1.html
VFP调用API涉及到结构类型,通常是用字符串来表达结构类型成员数据,这方法看似简单,
但易读性差,很不好理解,尤其对初接触调用API的容易搞错。
封装结构类型的类,可提高VFP语言的表达能力,提高学习编程效率。
示例以 PARAFORMAT2 结构简单描述,对于复杂的结构体有待探讨
只有本站会员才能查看附件,请 登录

** VFP封装结构类型示例
** 思路:
** 定义一个二维数组(aSTRUCT)用来描述结构体成员属性
** 每一行表达一个成员属性:名称(Name),类型(Type), 大小(Size),地址偏移量(Offset)
** 定义 STRUCT_ARRAY 类,提供初始化结构成员属性函数 stInit()
** 定义 STRUCT_CALSS 类,提供读写结构成员数据函数 getValue()、setValue()
DECLARE long malloc IN msvcrt as apiMalloc long
DECLARE long free IN msvcrt as apiFree long
DECLARE long SendMessage IN user32 as apiSendMessage long,long,long,long
of = CREATEOBJECT("form1")
of.show(1)
CLEAR ALL
RETURN
DEFINE CLASS form1 as Form
ADD OBJECT rich AS Olecontrol WITH top=10,left=10,width=200,height=200,OleClass="RICHTEXT.RichtextCtrl.1",visible=1
PROCEDURE rich.init
this.text = ""
pf = CREATEOBJECT("PARAFORMAT2")
st = CREATEOBJECT("STRUCT_CALSS", pf)
st.setValue("cbSize", st.nSize)
st.setValue("dwMask", 256)
st.setValue("dyLineSpacing", 300)
st.setValue("bLineSpacingRule", 4)
#define WM_USER 0x0400
#define EM_SETPARAFORMAT (WM_USER + 71)
apiSendMessage(this.hWnd, EM_SETPARAFORMAT, 0, st.pBuffer)
RELEASE st,pf
this.text = "123456789"+0h0D0A+"abcdefghijk"+0h0D0A+"ABCDEFGHIJK"++0h0D0A
ENDPROC
ENDDEFINE
DEFINE CLASS PARAFORMAT2 AS STRUCT_ARRAY
PROCEDURE init
DIMENSION this.aSTRUCT[24,4]
this.stInit(1, "cbSize", "N",4) && DWORD
this.stInit(2, "dwMask", "N",4)
this.stInit(3, "wNumbering", "N",2) && WORD
this.stInit(4, "wEffects", "N",2)
this.stInit(5, "dxStartIndent", "N",4)
this.stInit(6, "dxRightIndent", "N",4)
this.stInit(7, "dxOffset", "N",4)
this.stInit(8, "wAlignment", "N",2)
this.stInit(9, "cTabCount", "N",2)
this.stInit(10, "rgxTabs", "C",128) && DWORD[MAX_TAB_STOPS], MAX_TAB_STOPS=32
this.stInit(11, "dySpaceBefore", "N",4)
this.stInit(12, "dySpaceAfter", "N",4)
this.stInit(13, "dyLineSpacing", "N",4)
this.stInit(14, "sStyle", "N",2)
this.stInit(15, "bLineSpacingRule", "N",1) && BYTE
this.stInit(16, "bOutlineLevel", "N",1)
this.stInit(17, "wShadingWeight", "N",2)
this.stInit(18, "wShadingStyle", "N",2)
this.stInit(19, "wNumberingStart", "N",2)
this.stInit(20, "wNumberingStyle", "N",2)
this.stInit(21, "wNumberingTab", "N",2)
this.stInit(22, "wBorderSpace", "N",2)
this.stInit(23, "wBorderWidth", "N",2)
this.stInit(24, "wBorders", "N",2)
ENDPROC
ENDDEFINE
DEFINE CLASS STRUCT_ARRAY AS Session
DIMENSION aSTRUCT[1,4]
PROCEDURE stInit(n, cName, cType, nSize)
this.aSTRUCT[n,1] = cName
this.aSTRUCT[n,2] = cType
this.aSTRUCT[n,3] = nSize
this.aSTRUCT[n,4] = IIF(n>1, this.aSTRUCT[n-1,3]+this.aSTRUCT[n-1,4], 0)
ENDFUNC
ENDDEFINE
DEFINE CLASS STRUCT_CALSS AS Session
stObj = NULL
pBuffer = 0
nSize = 0
PROCEDURE init(stObj)
this.stObj = stObj
LOCAL nRowCount
nRowCount = ALEN(this.stObj.aSTRUCT, 1)
this.nSize = this.stObj.aSTRUCT[nRowCount,3] + this.stObj.aSTRUCT[nRowCount,4]
this.pBuffer = apiMalloc(this.nSize)
SYS(2600, this.pBuffer, this.nSize, REPLICATE(0h00,this.nSize))
ENDPROC
PROCEDURE Destroy
apiFree(this.pBuffer)
ENDPROC
HIDDEN FUNCTION getRow(cName)
LOCAL nRow
nRow = ASCAN(this.stObj.aSTRUCT, cName)
RETURN IIF(nRow>0, ASUBSCRIPT(this.stObj.aSTRUCT,nRow,1), 0)
ENDFUNC
FUNCTION getValue(cName)
LOCAL n, nSize, nOffset, ret
n = this.getRow(cName)
IF n == 0
RETURN NULL
ENDIF
nSize = this.stObj.aSTRUCT[n,3]
nOffset = this.stObj.aSTRUCT[n,4]
RETURN ICASE(this.stObj.aSTRUCT[n,2]=="N", CTOBIN(SYS(2600, this.pBuffer+nOffset, nSize), TRANSFORM(nSize)+"RS"),;
this.stObj.aSTRUCT[n,2]=="C", SYS(2600, this.pBuffer+nOffset, nSize),;
NULL)
ENDFUNC
FUNCTION setValue(cName, vValue)
LOCAL n, nSize, nOffset, ret
n = this.getRow(cName)
IF n == 0
RETURN ""
ENDIF
nSize = this.stObj.aSTRUCT[n,3]
nOffset = this.stObj.aSTRUCT[n,4]
IF this.stObj.aSTRUCT[n,2]=="N" AND VARTYPE(vValue)=="N"
RETURN SYS(2600, this.pBuffer+nOffset, nSize, BINTOC(vValue, TRANSFORM(nSize)+"RS"))
ELSE
IF this.stObj.aSTRUCT[n,2]=="C" AND VARTYPE(vValue)=="C"
vValue = LEFT(vValue, nSize)
nSize = LEN(vValue)
RETURN SYS(2600, this.pBuffer+nOffset, nSize, vValue)
ENDIF
ENDIF
RETURN ""
ENDFUNC
ENDDEFINE
** 思路:
** 定义一个二维数组(aSTRUCT)用来描述结构体成员属性
** 每一行表达一个成员属性:名称(Name),类型(Type), 大小(Size),地址偏移量(Offset)
** 定义 STRUCT_ARRAY 类,提供初始化结构成员属性函数 stInit()
** 定义 STRUCT_CALSS 类,提供读写结构成员数据函数 getValue()、setValue()
DECLARE long malloc IN msvcrt as apiMalloc long
DECLARE long free IN msvcrt as apiFree long
DECLARE long SendMessage IN user32 as apiSendMessage long,long,long,long
of = CREATEOBJECT("form1")
of.show(1)
CLEAR ALL
RETURN
DEFINE CLASS form1 as Form
ADD OBJECT rich AS Olecontrol WITH top=10,left=10,width=200,height=200,OleClass="RICHTEXT.RichtextCtrl.1",visible=1
PROCEDURE rich.init
this.text = ""
pf = CREATEOBJECT("PARAFORMAT2")
st = CREATEOBJECT("STRUCT_CALSS", pf)
st.setValue("cbSize", st.nSize)
st.setValue("dwMask", 256)
st.setValue("dyLineSpacing", 300)
st.setValue("bLineSpacingRule", 4)
#define WM_USER 0x0400
#define EM_SETPARAFORMAT (WM_USER + 71)
apiSendMessage(this.hWnd, EM_SETPARAFORMAT, 0, st.pBuffer)
RELEASE st,pf
this.text = "123456789"+0h0D0A+"abcdefghijk"+0h0D0A+"ABCDEFGHIJK"++0h0D0A
ENDPROC
ENDDEFINE
DEFINE CLASS PARAFORMAT2 AS STRUCT_ARRAY
PROCEDURE init
DIMENSION this.aSTRUCT[24,4]
this.stInit(1, "cbSize", "N",4) && DWORD
this.stInit(2, "dwMask", "N",4)
this.stInit(3, "wNumbering", "N",2) && WORD
this.stInit(4, "wEffects", "N",2)
this.stInit(5, "dxStartIndent", "N",4)
this.stInit(6, "dxRightIndent", "N",4)
this.stInit(7, "dxOffset", "N",4)
this.stInit(8, "wAlignment", "N",2)
this.stInit(9, "cTabCount", "N",2)
this.stInit(10, "rgxTabs", "C",128) && DWORD[MAX_TAB_STOPS], MAX_TAB_STOPS=32
this.stInit(11, "dySpaceBefore", "N",4)
this.stInit(12, "dySpaceAfter", "N",4)
this.stInit(13, "dyLineSpacing", "N",4)
this.stInit(14, "sStyle", "N",2)
this.stInit(15, "bLineSpacingRule", "N",1) && BYTE
this.stInit(16, "bOutlineLevel", "N",1)
this.stInit(17, "wShadingWeight", "N",2)
this.stInit(18, "wShadingStyle", "N",2)
this.stInit(19, "wNumberingStart", "N",2)
this.stInit(20, "wNumberingStyle", "N",2)
this.stInit(21, "wNumberingTab", "N",2)
this.stInit(22, "wBorderSpace", "N",2)
this.stInit(23, "wBorderWidth", "N",2)
this.stInit(24, "wBorders", "N",2)
ENDPROC
ENDDEFINE
DEFINE CLASS STRUCT_ARRAY AS Session
DIMENSION aSTRUCT[1,4]
PROCEDURE stInit(n, cName, cType, nSize)
this.aSTRUCT[n,1] = cName
this.aSTRUCT[n,2] = cType
this.aSTRUCT[n,3] = nSize
this.aSTRUCT[n,4] = IIF(n>1, this.aSTRUCT[n-1,3]+this.aSTRUCT[n-1,4], 0)
ENDFUNC
ENDDEFINE
DEFINE CLASS STRUCT_CALSS AS Session
stObj = NULL
pBuffer = 0
nSize = 0
PROCEDURE init(stObj)
this.stObj = stObj
LOCAL nRowCount
nRowCount = ALEN(this.stObj.aSTRUCT, 1)
this.nSize = this.stObj.aSTRUCT[nRowCount,3] + this.stObj.aSTRUCT[nRowCount,4]
this.pBuffer = apiMalloc(this.nSize)
SYS(2600, this.pBuffer, this.nSize, REPLICATE(0h00,this.nSize))
ENDPROC
PROCEDURE Destroy
apiFree(this.pBuffer)
ENDPROC
HIDDEN FUNCTION getRow(cName)
LOCAL nRow
nRow = ASCAN(this.stObj.aSTRUCT, cName)
RETURN IIF(nRow>0, ASUBSCRIPT(this.stObj.aSTRUCT,nRow,1), 0)
ENDFUNC
FUNCTION getValue(cName)
LOCAL n, nSize, nOffset, ret
n = this.getRow(cName)
IF n == 0
RETURN NULL
ENDIF
nSize = this.stObj.aSTRUCT[n,3]
nOffset = this.stObj.aSTRUCT[n,4]
RETURN ICASE(this.stObj.aSTRUCT[n,2]=="N", CTOBIN(SYS(2600, this.pBuffer+nOffset, nSize), TRANSFORM(nSize)+"RS"),;
this.stObj.aSTRUCT[n,2]=="C", SYS(2600, this.pBuffer+nOffset, nSize),;
NULL)
ENDFUNC
FUNCTION setValue(cName, vValue)
LOCAL n, nSize, nOffset, ret
n = this.getRow(cName)
IF n == 0
RETURN ""
ENDIF
nSize = this.stObj.aSTRUCT[n,3]
nOffset = this.stObj.aSTRUCT[n,4]
IF this.stObj.aSTRUCT[n,2]=="N" AND VARTYPE(vValue)=="N"
RETURN SYS(2600, this.pBuffer+nOffset, nSize, BINTOC(vValue, TRANSFORM(nSize)+"RS"))
ELSE
IF this.stObj.aSTRUCT[n,2]=="C" AND VARTYPE(vValue)=="C"
vValue = LEFT(vValue, nSize)
nSize = LEN(vValue)
RETURN SYS(2600, this.pBuffer+nOffset, nSize, vValue)
ENDIF
ENDIF
RETURN ""
ENDFUNC
ENDDEFINE