以下是引用cssnet在2022-3-15 11:18:48的发言:
倘若是相对复杂的struct,比如指针成员,即使是用类封装,也十分困难,几近徒劳。
就“指针成员”问题也写个示例,觉得没什么特别。
程序代码:
**
** StructCalss.h
**
#define WM_USER 0x0400
#define MAX_PATH 260
#define EM_SETPARAFORMAT (WM_USER + 71)
程序代码:
**
** StructCalss.prg
**
DEFINE CLASS OPENFILENAME AS STRUCT_CALSS
PROCEDURE init
DIMENSION this.aSTRUCT[20,4]
this.stInit(1, "lStructSize", "N",4)
this.stInit(2, "hwndOwner", "N",4)
this.stInit(3, "hInstance", "N",4)
this.stInit(4, "lpstrFilter", "N",4)
this.stInit(5, "lpstrCustomFilter", "N",4)
this.stInit(6, "nMaxCustFilter", "N",4)
this.stInit(7, "nFilterIndex", "N",4)
this.stInit(8, "lpstrFile", "N",4)
this.stInit(9, "nMaxFile", "N",4)
this.stInit(10, "lpstrFileTitle", "N",4)
this.stInit(11, "nMaxFileTitle", "N",4)
this.stInit(12, "lpstrInitialDir", "N",4)
this.stInit(13, "lpstrTitle", "N",4)
this.stInit(14, "Flags", "N",4)
this.stInit(15, "nFileOffset", "N",2)
this.stInit(16, "nFileExtension", "N",2)
this.stInit(17, "lpstrDefExt", "N",4)
this.stInit(18, "lCustData", "N",4)
this.stInit(19, "lpfnHook", "N",4)
this.stInit(20, "lpTemplateName", "N",4)
STRUCT_CALSS::init
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
FUNCTION LoadApi()
DECLARE long malloc IN msvcrt as apiMalloc long
DECLARE long calloc IN msvcrt as apiCalloc long,long
DECLARE long free IN msvcrt as apiFree long
DECLARE long _strdup IN msvcrt as apiStrdup string@
DECLARE long strlen IN msvcrt as apiStrlen long
DECLARE long SendMessage IN user32 as apiSendMessage long,long,long,long
DECLARE long GetOpenFileName IN comdlg32 long
DECLARE long GetSaveFileName IN comdlg32 long
ENDFUNC
程序代码:
**
** StructCalss_demo.prg
**
#INCLUDE StructCalss.h
SET PROCEDURE TO StructCalss.prg ADDITIVE
LoadApi()
? myGetFileName(0, "C:\TEMP\__temp.txt", "Text Files (*.txt)|*.txt|All Files (*.*)|*.*", "打开文件", 0)
*? myGetFileName(0, "C:\TEMP\__temp.txt", "Text Files (*.txt)|*.txt|All Files (*.*)|*.*", "另存文件", 1, 0x80806)
SET PROCEDURE TO
CLEAR ALL
RETURN
*
* 打开对话框
* myGetFileName(hWnd, cDefFile, cType, cTitle, nDialogType, nFlags)
*
* 参数:hWnd .....。.... 指向所有者对话框窗口的句柄, 没有时为0。
* cDefFile ....... 默认指定文件名
* cType .......... 文件类型格式过滤字符串。
* 如文件格式选择列表:
*
* [color=#0000FF]Text Files (*.txt) [/color]
* [color=#808080]All Files (*.*)[/color]
*
* cType:"[color=#0000FF]Text Files (*.txt)|*.txt|All Files (*.*)|*.*"[/color]
*
* cTitle ........ 对话框标题
*
* nDialogType ... 对话框类型,[color=#800000]0 选择打开文件, 1 选择另存文件[/color]
*
* nFlags ........ 对话框的选项,参考 OPENFILENAME 结构成员 Flags 的描述。
* 如不选择则按默认设置。
*
* 返回:返回选择的文件名,“取消”或选择无效的文件名时返回空串。
*
FUNCTION myGetFileName(hWnd, cDefFile, cType, cTitle, nDialogType, nFlags)
LOCAL nBuffSize, of, pFile, pType, pTitle, ret, nLen, cPaht, cFiles
nBuffSize = 80 * MAX_PATH && 要有足够空间存放多个文件名。
pFile = apiMalloc(nBuffSize)
SYS(2600, pFile, LEN(cDefFile)+1, cDefFile+0h00)
pType = apiMalloc(LEN(cType)+1)
cType = STRTRAN(cType, "|", 0h00) && 转为以0h00分隔
SYS(2600, pType, LEN(cType)+1, cType+0h00)
pTitle = apiStrdup(cTitle)
IF EMPTY(nFlags) && 设置默认值
* 打开,0x80000|0x1000|0x4|0x200 = OFN_EXPLORER|OFN_FILEMUSTEXIST|OFN_HIDEREADONLY|OFN_ALLOWMULTISELECT
* 另存,0x80000|0x800 |0x4|0x2 = OFN_EXPLORER|OFN_PATHMUSTEXIST|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT
nFlags = IIF(nDialogType==0, 0x81204, 0x80806)
ENDIF
of = CREATEOBJECT("OPENFILENAME")
of.setValue("lStructSize", of.nSize)
of.setValue("hwndOwner", hWnd)
of.setValue("lpstrFilter", pType)
of.setValue("lpstrFile", pFile)
of.setValue("nMaxFile", nBuffSize)
of.setValue("lpstrTitle", pTitle)
of.setValue("Flags", nFlags)
IF nDialogType==0
ret = GetOpenFileName(of.pBuffer)
ELSE
ret = GetSaveFileName(of.pBuffer)
ENDIF
cFiles = ""
IF ret > 0
LOCAL ptr
ptr = pFile
nLen = apiStrlen(ptr) && pFile 以0h00分隔,以0h0000结束
cFiles = SYS(2600, ptr, nLen)
ptr = ptr + nLen + 1
nLen = apiStrlen(ptr)
IF nDialogType==0 AND nLen > 0
cPaht = ADDBS(cFiles)
cFiles = ""
DO WHILE nLen > 0 && 多选
cFiles = cFiles + cPaht + SYS(2600, ptr, nLen) + 0h0D0A
ptr = ptr + nLen + 1
nLen = apiStrlen(ptr)
ENDDO
cFiles = RTRIM(cFiles,0h0D0A)
ENDIF
ENDIF
apiFree(pFile)
apiFree(pType)
apiFree(pTitle)
RETURN cFiles
ENDFUNC
[此贴子已经被作者于2022-3-17 15:13编辑过]