├── BuildProcessTemplates ├── DefaultTemplate.11.1.xaml ├── DefaultTemplate.xaml ├── LabDefaultTemplate.11.xaml └── UpgradeTemplate.xaml ├── avfp5.53_source ├── ..svnbridge │ ├── ActiveVFP.pjt │ └── ActiveVFP.pjx ├── ActiveVFP.pjt ├── ActiveVFP.pjx ├── prg │ ├── activevfp.prg │ ├── codeblck.prg │ ├── json.h │ ├── json.prg │ ├── proxystub.prg │ ├── vfp2c.h │ └── webthreads2.prg └── reports │ ├── ..svnbridge │ ├── pdfrun.PJT │ └── pdfrun.pjx │ ├── clsheap.prg │ ├── pdfrun.PJT │ ├── pdfrun.pjx │ └── print2pdf.prg └── avfp6.03_source ├── ..svnbridge ├── ActiveVFP.pjt └── ActiveVFP.pjx ├── ActiveVFP.pjt ├── ActiveVFP.pjx ├── HTTP Handler └── App_Code │ └── AVFPHandler.cs ├── prg ├── activevfp.prg ├── codeblck.prg ├── dch.prg ├── json.h ├── json.prg ├── proxystub.prg ├── resthelper.prg ├── vfp2c.h └── webthreads2.prg └── reports ├── ..svnbridge ├── pdfrun.PJT └── pdfrun.pjx ├── clsheap.prg ├── pdfrun.PJT ├── pdfrun.pjx └── print2pdf.prg /BuildProcessTemplates/LabDefaultTemplate.11.xaml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 11.0 16 | 17 | 18 | 19 | 20 | 21 | 920,3702 22 | Assembly references and imported namespaces serialized as XML namespaces 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | True 44 | 45 | 46 | 47 | 48 | 49 | 50 | [LabWorkflowParameters.BuildDetails.BuildUri] 51 | 52 | 53 | [ChildBuildDetail.Uri] 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | [BuildLocation] 66 | 67 | 68 | [If(LabWorkflowParameters.BuildDetails.Configuration Is Nothing, BuildLocation, If(LabWorkflowParameters.BuildDetails.Configuration.IsEmpty Or (SelectedBuildDetail.Information.GetNodesByType(Microsoft.TeamFoundation.Build.Common.InformationTypes.ConfigurationSummary, True)).Count = 1, BuildLocation, If(LabWorkflowParameters.BuildDetails.Configuration.IsPlatformEmptyOrAnyCpu, BuildLocation + "\" + LabWorkflowParameters.BuildDetails.Configuration.Configuration, BuildLocation + "\" + LabWorkflowParameters.BuildDetails.Configuration.Platform + "\" + LabWorkflowParameters.BuildDetails.Configuration.Configuration)))] 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | [LabEnvironmentUri] 81 | 82 | 83 | [LabWorkflowParameters.EnvironmentDetails.LabEnvironmentUri.ToString()] 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | [PostDeploymentSnapshotName] 143 | 144 | 145 | [If(LabWorkflowParameters.BuildDetails.IsTeamSystemBuild = True,String.Format("{0}_{1}_{2}", LabWorkflowParameters.DeploymentDetails.PostDeploymentSnapshotName, BuildNumber,BuildDetail.BuildNumber),String.Format("{0}_{1}", LabWorkflowParameters.DeploymentDetails.PostDeploymentSnapshotName, BuildDetail.BuildNumber))] 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | [BuildStatus] 184 | 185 | 186 | [Microsoft.TeamFoundation.Build.Client.BuildStatus.PartiallySucceeded] 187 | 188 | 189 | 190 | 191 | 192 | 193 | [BuildStatus] 194 | 195 | 196 | [Microsoft.TeamFoundation.Build.Client.BuildStatus.Failed] 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | -------------------------------------------------------------------------------- /BuildProcessTemplates/UpgradeTemplate.xaml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | [New Microsoft.TeamFoundation.Build.Workflow.Activities.AgentSettings() With {.MaxWaitTime = New System.TimeSpan(4, 0, 0), .MaxExecutionTime = New System.TimeSpan(0, 0, 0), .TagComparison = Microsoft.TeamFoundation.Build.Workflow.Activities.TagComparison.MatchExactly }] 21 | 22 | 23 | 24 | [Microsoft.TeamFoundation.Build.Workflow.Activities.ToolPlatform.Auto] 25 | [False] 26 | [False] 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | [Microsoft.TeamFoundation.VersionControl.Client.RecursionType.OneLevel] 37 | [Microsoft.TeamFoundation.Build.Workflow.BuildVerbosity.Normal] 38 | 39 | 40 | 41 | All 42 | Assembly references and imported namespaces serialized as XML namespaces 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /avfp5.53_source/..svnbridge/ActiveVFP.pjt: -------------------------------------------------------------------------------- 1 | svn:mime-typeapplication/octet-stream -------------------------------------------------------------------------------- /avfp5.53_source/..svnbridge/ActiveVFP.pjx: -------------------------------------------------------------------------------- 1 | svn:mime-typeapplication/octet-stream -------------------------------------------------------------------------------- /avfp5.53_source/ActiveVFP.pjt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/claudefox/ActiveVFP/28ada3cd4b268635e3bcd67ea842ec522c3def82/avfp5.53_source/ActiveVFP.pjt -------------------------------------------------------------------------------- /avfp5.53_source/ActiveVFP.pjx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/claudefox/ActiveVFP/28ada3cd4b268635e3bcd67ea842ec522c3def82/avfp5.53_source/ActiveVFP.pjx -------------------------------------------------------------------------------- /avfp5.53_source/prg/json.h: -------------------------------------------------------------------------------- 1 | #DEFINE TOKENTYPE_UNDEFINED 0 2 | #DEFINE TOKENTYPE_OBJECT 1 3 | #DEFINE TOKENTYPE_ARRAY 2 4 | #DEFINE TOKENTYPE_KEY 3 5 | #DEFINE TOKENTYPE_STRING 4 6 | #DEFINE TOKENTYPE_LOGICAL 5 7 | #DEFINE TOKENTYPE_NUMBER 6 8 | #DEFINE TOKENTYPE_DATETIME 8 9 | #DEFINE TOKENTYPE_DATE 9 10 | #DEFINE TOKENTYPE_NULL 10 11 | #DEFINE TOKENTYPE_CURSOR 11 -------------------------------------------------------------------------------- /avfp5.53_source/prg/json.prg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/claudefox/ActiveVFP/28ada3cd4b268635e3bcd67ea842ec522c3def82/avfp5.53_source/prg/json.prg -------------------------------------------------------------------------------- /avfp5.53_source/prg/proxystub.prg: -------------------------------------------------------------------------------- 1 | #DEFINE crlf CHR(13)+CHR(10) 2 | SET STEP ON 3 | oProp=NEWOBJECT('AVFPproperties','activevfp.prg') && create properties shared among classes 4 | oHTML=NEWOBJECT('AVFPhtml','activevfp.prg') 5 | oCookie=NEWOBJECT('AVFPcookie','activevfp.prg') 6 | oProp.ScriptPath=oRequest.servervariables("SCRIPT_NAME") 7 | oProp.SessID=NVL(oRequest.querystring("sid"),"") 8 | oProp.AppStartPath=JUSTPATH(oRequest.ServerVariables("PATH_TRANSLATED"))+[\] &&JUSTPATH(APPLICATION.SERVERNAME)+"\" 9 | oProp.AppName=STREXTRACT(oRequest.ServerVariables("PATH_INFO"),[/],[/]) &&blank if installed to root &&JUSTSTEM(APPLICATION.SERVERNAME) 10 | oProp.RunningPrg=[main.prg] 11 | lcScript=FILETOSTR(oProp.AppStartPath+'\prg\main.prg') 12 | lcHTMLout= EXECSCRIPT(lcScript) &&main() && run the application 13 | RETURN lcHTMLout 14 | ************************************************************* 15 | DEFINE CLASS server AS ActiveVFP OLEPUBLIC 16 | ************************************************************* 17 | * server :: process 18 | * Last Modified: 12/30/11 19 | * ActiveVFP Version 5.61 20 | ************************************************************* 21 | FUNCTION Process 22 | LOCAL lcHTMLout,lcHTMLfile 23 | 24 | * Base ActiveVFP Objects 25 | oRequest = THIS.oRequest 26 | oSession = THIS.oSession 27 | oResponse = THIS.oResponse 28 | oServer= this.oServer 29 | oApplication=this.oApplication 30 | 31 | oProp=NEWOBJECT('AVFPproperties') && create properties shared among classes 32 | oHTML=NEWOBJECT('AVFPhtml') 33 | oCookie=NEWOBJECT('AVFPcookie') 34 | 35 | * init properties 36 | oProp.ScriptPath=oRequest.servervariables("SCRIPT_NAME") 37 | oProp.SessID=NVL(oRequest.querystring("sid"),"") 38 | 39 | 40 | oProp.AppStartPath=JUSTPATH(oRequest.ServerVariables("PATH_TRANSLATED"))+[\] &&JUSTPATH(APPLICATION.SERVERNAME)+"\" 41 | oProp.AppName=STREXTRACT(oRequest.ServerVariables("PATH_INFO"),[/],[/]) &&blank if installed to root &&JUSTSTEM(APPLICATION.SERVERNAME) 42 | oProp.RunningPrg=[main.prg] 43 | 44 | lcScript=FILETOSTR(oProp.AppStartPath+'\prg\main.prg') 45 | 46 | lcHTMLout= EXECSCRIPT(lcScript) &&main() && run the application 47 | 48 | 49 | RETURN lcHTMLout 50 | 51 | ENDFUNC 52 | 53 | ************************************************************* 54 | * server :: debugger 55 | * Last Modified: 12/30/11 56 | * ActiveVFP Version 5.61 57 | ************************************************************* 58 | FUNCTION Debugger() 59 | LOCAL loFox, lcReturn 60 | lcReturn = "" 61 | 62 | loFox = GETOBJECT(,"visualfoxpro.application.9") 63 | 64 | loFox.SetVar("oRequest",THIS.oRequest) 65 | loFox.SetVar("oSession",THIS.oSession) 66 | loFox.SetVar("oResponse",THIS.oResponse) 67 | loFox.SetVar("oServer",THIS.oServer) 68 | loFox.SetVar("oApplication",THIS.oApplication) 69 | 70 | lcReturn = loFox.eval("proxystub()") 71 | 72 | 73 | RELEASE loFox 74 | RETURN lcReturn 75 | ENDFUNC 76 | 77 | 78 | 79 | ENDDEFINE 80 | 81 | 82 | -------------------------------------------------------------------------------- /avfp5.53_source/prg/vfp2c.h: -------------------------------------------------------------------------------- 1 | #IFNDEF _VFP2C_H__ 2 | #DEFINE _VFP2C_H__ 3 | 4 | #DEFINE CRLF CHR(13) + CHR(10) 5 | #DEFINE FLL_MAX_ARRAY_SIZE 65000 && vfp system limit 6 | 7 | && Initialization flags for InitVFP2C32() 8 | #DEFINE VFP2C_INIT_MARSHAL 0x00000001 9 | #DEFINE VFP2C_INIT_ENUM 0x00000002 10 | #DEFINE VFP2C_INIT_ASYNC 0x00000004 11 | #DEFINE VFP2C_INIT_FILE 0x00000008 12 | #DEFINE VFP2C_INIT_WINSOCK 0x00000010 13 | #DEFINE VFP2C_INIT_ODBC 0x00000020 14 | #DEFINE VFP2C_INIT_PRINT 0x00000040 15 | #DEFINE VFP2C_INIT_NETAPI 0x00000080 16 | #DEFINE VFP2C_INIT_CALLBACK 0x00000100 17 | #DEFINE VFP2C_INIT_SERVICES 0x00000200 18 | #DEFINE VFP2C_INIT_WINDOWS 0x00000400 19 | #DEFINE VFP2C_INIT_RAS 0x00000800 20 | #DEFINE VFP2C_INIT_IPHELPER 0x00001000 21 | #DEFINE VFP2C_INIT_URLMON 0x00002000 22 | #DEFINE VFP2C_INIT_ALL 0xFFFFFFFF 23 | 24 | #DEFINE E_INSUFMEMORY 43 25 | #DEFINE E_INVALIDPARAMS 11 26 | #DEFINE E_USERERROR 1098 27 | 28 | #DEFINE SIZEOF_BYTE 1 29 | #DEFINE SIZEOF_CHAR 1 30 | #DEFINE SIZEOF_WCHAR 2 31 | #DEFINE SIZEOF_SHORT 2 32 | #DEFINE SIZEOF_INT 4 33 | #DEFINE SIZEOF_LONG 4 34 | #DEFINE SIZEOF_FLOAT 4 35 | #DEFINE SIZEOF_POINTER 4 36 | #DEFINE SIZEOF_DOUBLE 8 37 | #DEFINE SIZEOF_INT64 8 38 | 39 | #DEFINE CTYPE_SHORT 0 40 | #DEFINE CTYPE_USHORT 1 41 | #DEFINE CTYPE_INT 2 42 | #DEFINE CTYPE_UINT 3 43 | #DEFINE CTYPE_FLOAT 4 44 | #DEFINE CTYPE_DOUBLE 5 45 | #DEFINE CTYPE_BOOL 6 46 | #DEFINE CTYPE_CSTRING 7 47 | #DEFINE CTYPE_WSTRING 8 48 | #DEFINE CTYPE_CHARARRAY 9 49 | #DEFINE CTYPE_WCHARARRAY 10 50 | 51 | #DEFINE MIN_CHAR -128 52 | #DEFINE MAX_CHAR 127 53 | #DEFINE MIN_UCHAR 0 54 | #DEFINE MAX_UCHAR 255 55 | #DEFINE MIN_SHORT -32768 56 | #DEFINE MAX_SHORT 32767 57 | #DEFINE MIN_USHORT 0 58 | #DEFINE MAX_USHORT 65535 59 | #DEFINE MIN_INT -2147483648 60 | #DEFINE MAX_INT 2147483647 61 | #DEFINE MIN_UINT 0 62 | #DEFINE MAX_UINT 4294967295 63 | 64 | && flags for AllocHGlobal & ReAllocHGlobal 65 | #DEFINE GMEM_FIXED 0x0000 66 | #DEFINE GMEM_MOVEABLE 0x0002 67 | #DEFINE GMEM_ZEROINIT 0x0040 68 | #DEFINE GMEM_MODIFY 0x0080 69 | 70 | && CodePages for Unicode string functions (ReadWString, ReadWCharArray, MarshalArrayWString ..) 71 | #DEFINE CP_ACP 0 && default to ANSI code page 72 | #DEFINE CP_OEMCP 1 && default to OEM code page 73 | #DEFINE CP_THREAD_ACP 3 && current thread's ANSI code page 74 | #DEFINE CP_SYMBOL 42 && SYMBOL translations 75 | #DEFINE CP_UTF7 65000 && UTF-7 translation 76 | #DEFINE CP_UTF8 65001 && UTF-8 translation 77 | 78 | && defines for SHBrowseFolder 79 | #DEFINE BIF_RETURNONLYFSDIRS 0x0001 && For finding a folder to start document searching 80 | #DEFINE BIF_DONTGOBELOWDOMAIN 0x0002 && For starting the Find Computer 81 | #DEFINE BIF_STATUSTEXT 0x0004 82 | && Top of the dialog has 2 lines of text for BROWSEINFO.lpszTitle and one line if 83 | && this flag is set. Passing the message BFFM_SETSTATUSTEXTA to the hwnd can set the 84 | && rest of the text. This is not used with BIF_USENEWUI and BROWSEINFO.lpszTitle gets 85 | && all three lines of text. 86 | 87 | #DEFINE BIF_RETURNFSANCESTORS 0x0008 88 | #DEFINE BIF_EDITBOX 0x0010 && Add an editbox to the dialog 89 | #DEFINE BIF_VALIDATE 0x0020 && insist on valid result (or CANCEL) 90 | #DEFINE BIF_NEWDIALOGSTYLE 0x0040 && Use the new dialog layout with the ability to resize 91 | && Caller needs to call OleInitialize() before using this API 92 | #DEFINE BIF_USENEWUI 0x0050 && (BIF_NEWDIALOGSTYLE | BIF_EDITBOX) 93 | #DEFINE BIF_BROWSEINCLUDEURLS 0x0080 && Allow URLs to be displayed or entered. (Requires BIF_USENEWUI) 94 | #DEFINE BIF_UAHINT 0x0100 95 | && Add a UA hint to the dialog, in place of the edit box. May not be combined with BIF_EDITBOX 96 | #DEFINE BIF_NONEWFOLDERBUTTON 0x0200 97 | && Do not add the "New Folder" button to the dialog. Only applicable with BIF_NEWDIALOGSTYLE. 98 | #DEFINE BIF_NOTRANSLATETARGETS 0x0400 && don't traverse target as shortcut 99 | #DEFINE BIF_BROWSEFORCOMPUTER 0x1000 && Browsing for Computers. 100 | #DEFINE BIF_BROWSEFORPRINTER 0x2000 && Browsing for Printers 101 | #DEFINE BIF_BROWSEINCLUDEFILES 0x4000 && Browsing for Everything 102 | #DEFINE BIF_SHAREABLE 0x8000 && sharable resources displayed (remote shares, requires BIF_USENEWUI) 103 | 104 | && message from browser 105 | #DEFINE BFFM_INITIALIZED 1 106 | #DEFINE BFFM_SELCHANGED 2 107 | #DEFINE BFFM_VALIDATEFAILEDA 3 && lParam:szPath ret:1(cont),0(EndDialog) 108 | #DEFINE BFFM_VALIDATEFAILEDW 4 && lParam:wzPath ret:1(cont),0(EndDialog) 109 | #DEFINE BFFM_IUNKNOWN 5 && provides IUnknown to client. lParam: IUnknown* 110 | 111 | && messages to browser 112 | #DEFINE BFFM_SETSTATUSTEXTA (WM_USER + 100) 113 | #DEFINE BFFM_ENABLEOK (WM_USER + 101) 114 | #DEFINE BFFM_SETSELECTIONA (WM_USER + 102) 115 | #DEFINE BFFM_SETSELECTIONW (WM_USER + 103) 116 | #DEFINE BFFM_SETSTATUSTEXTW (WM_USER + 104) 117 | #DEFINE BFFM_SETOKTEXT (WM_USER + 105) && Unicode only 118 | #DEFINE BFFM_SETEXPANDED (WM_USER + 106) && Unicode only 119 | 120 | && defines for GetOpenFileName/GetSaveFileName 121 | #DEFINE OFN_READONLY 0x00000001 122 | #DEFINE OFN_OVERWRITEPROMPT 0x00000002 123 | #DEFINE OFN_HIDEREADONLY 0x00000004 124 | #DEFINE OFN_NOCHANGEDIR 0x00000008 125 | #DEFINE OFN_SHOWHELP 0x00000010 126 | #DEFINE OFN_ENABLEHOOK 0x00000020 127 | #DEFINE OFN_ENABLETEMPLATE 0x00000040 128 | #DEFINE OFN_ENABLETEMPLATEHANDLE 0x00000080 129 | #DEFINE OFN_NOVALIDATE 0x00000100 130 | #DEFINE OFN_ALLOWMULTISELECT 0x00000200 131 | #DEFINE OFN_EXTENSIONDIFFERENT 0x00000400 132 | #DEFINE OFN_PATHMUSTEXIST 0x00000800 133 | #DEFINE OFN_FILEMUSTEXIST 0x00001000 134 | #DEFINE OFN_CREATEPROMPT 0x00002000 135 | #DEFINE OFN_SHAREAWARE 0x00004000 136 | #DEFINE OFN_NOREADONLYRETURN 0x00008000 137 | #DEFINE OFN_NOTESTFILECREATE 0x00010000 138 | #DEFINE OFN_NONETWORKBUTTON 0x00020000 139 | #DEFINE OFN_NOLONGNAMES 0x00040000 && force no long names for 4.x modules 140 | #DEFINE OFN_EXPLORER 0x00080000 && new look commdlg 141 | #DEFINE OFN_NODEREFERENCELINKS 0x00100000 142 | #DEFINE OFN_LONGNAMES 0x00200000 && force long names for 3.x modules 143 | #DEFINE OFN_ENABLEINCLUDENOTIFY 0x00400000 && send include message to callback 144 | #DEFINE OFN_ENABLESIZING 0x00800000 145 | #DEFINE OFN_DONTADDTORECENT 0x02000000 146 | #DEFINE OFN_FORCESHOWHIDDEN 0x10000000 && Show All files including System and hidden files 147 | #DEFINE OFN_EX_NOPLACESBAR 0x00000001 148 | 149 | && defines for Registry functions 150 | #DEFINE HKEY_CLASSES_ROOT 0x80000000 151 | #DEFINE HKEY_CURRENT_USER 0x80000001 152 | #DEFINE HKEY_LOCAL_MACHINE 0x80000002 153 | #DEFINE HKEY_USERS 0x80000003 154 | #DEFINE HKEY_PERFORMANCE_DATA 0x80000004 155 | #DEFINE HKEY_PERFORMANCE_TEXT 0x80000050 156 | #DEFINE HKEY_PERFORMANCE_NLSTEXT 0x80000060 157 | #DEFINE HKEY_CURRENT_CONFIG 0x80000005 158 | #DEFINE HKEY_DYN_DATA 0x80000006 159 | 160 | #DEFINE REG_ENUMCLASSNAME 1 161 | #DEFINE REG_ENUMWRITETIME 2 162 | #DEFINE REG_ENUMTYPE 1 163 | #DEFINE REG_ENUMVALUE 2 164 | 165 | #DEFINE REG_DELETE_NORMAL 1 166 | #DEFINE REG_DELETE_SHELL 2 167 | 168 | && access rights 169 | *!* #DEFINE SYNCHRONIZE 0x00100000 170 | *!* #DEFINE STANDARD_RIGHTS_READ 0x00020000 171 | *!* #DEFINE STANDARD_RIGHTS_WRITE 0x00020000 172 | *!* #DEFINE STANDARD_RIGHTS_EXECUTE 0x00020000 173 | *!* #DEFINE STANDARD_RIGHTS_ALL 0x001F0000 174 | 175 | #DEFINE KEY_QUERY_VALUE 0x0001 176 | #DEFINE KEY_SET_VALUE 0x0002 177 | #DEFINE KEY_CREATE_SUB_KEY 0x0004 178 | #DEFINE KEY_ENUMERATE_SUB_KEYS 0x0008 179 | #DEFINE KEY_NOTIFY 0x0010 180 | #DEFINE KEY_CREATE_LINK 0x0020 181 | #DEFINE KEY_WOW64_64KEY 0x0100 182 | #DEFINE KEY_WOW64_32KEY 0x0200 183 | #DEFINE KEY_WOW64_RES 0x0300 184 | 185 | #DEFINE KEY_READ 0x00020019 186 | *!* #DEFINE KEY_READ (BITAND(BITOR(STANDARD_RIGHTS_READ,KEY_QUERY_VALUE, 187 | *!* KEY_ENUMERATE_SUB_KEYS,KEY_NOTIFY),BITNOT(SYNCHRONIZE)))) 188 | 189 | #DEFINE KEY_WRITE 0x00020006 190 | *!* #DEFINE KEY_WRITE (BITAND(BITOR(STANDARD_RIGHTS_WRITE,KEY_SET_VALUE,KEY_CREATE_SUB_KEY), 191 | *!* BITNOT(SYNCHRONIZE)))) 192 | 193 | #DEFINE KEY_EXECUTE 0x00020019 194 | *!* #DEFINE KEY_EXECUTE (BITAND(KEY_READ,BITNOT(SYNCHRONIZE))) 195 | 196 | #DEFINE KEY_ALL_ACCESS 0x000F003F 197 | *!* #DEFINE KEY_ALL_ACCESS (BITAND(BITOR(STANDARD_RIGHTS_ALL,KEY_QUERY_VALUE, 198 | *!* KEY_SET_VALUE,KEY_CREATE_SUB_KEY,KEY_ENUMERATE_SUB_KEYS,KEY_NOTIFY,KEY_CREATE_LINK), 199 | *!* BITNOT(SYNCHRONIZE)))) 200 | 201 | && types of registry values 202 | #DEFINE REG_SZ 1 203 | #DEFINE REG_EXPAND_SZ 2 204 | #DEFINE REG_BINARY 3 205 | #DEFINE REG_DWORD 4 206 | #DEFINE REG_DWORD_LITTLE_ENDIAN 4 207 | #DEFINE REG_DWORD_BIG_ENDIAN 5 208 | #DEFINE REG_LINK 6 209 | #DEFINE REG_MULTI_SZ 7 210 | #DEFINE REG_QWORD 11 211 | #DEFINE REG_INTEGER 12 212 | #DEFINE REG_DOUBLE 13 213 | #DEFINE REG_DATE 14 214 | #DEFINE REG_DATETIME 15 215 | #DEFINE REG_LOGICAL 16 216 | #DEFINE REG_MONEY 17 217 | 218 | #DEFINE REG_NOTIFY_CHANGE_NAME 0x01 219 | #DEFINE REG_NOTIFY_CHANGE_ATTRIBUTES 0x02 220 | #DEFINE REG_NOTIFY_CHANGE_LAST_SET 0x04 221 | #DEFINE REG_NOTIFY_CHANGE_SECURITY 0x08 222 | 223 | && defines for AServices 224 | #DEFINE SERVICE_ACTIVE 0x01 225 | #DEFINE SERVICE_INACTIVE 0x02 226 | #DEFINE SERVICE_STATE_ALL 0x03 227 | 228 | #DEFINE SERVICE_KERNEL_DRIVER 0x01 229 | #DEFINE SERVICE_FILE_SYSTEM_DRIVER 0x02 230 | #DEFINE SERVICE_ADAPTER 0x04 231 | #DEFINE SERVICE_RECOGNIZER_DRIVER 0x08 232 | #DEFINE SERVICE_DRIVER 0x0B 233 | #DEFINE SERVICE_WIN32_OWN_PROCESS 0x10 234 | #DEFINE SERVICE_WIN32_SHARE_PROCESS 0x20 235 | #DEFINE SERVICE_WIN32 0x30 236 | #DEFINE SERVICE_INTERACTIVE_PROCESS 0x0100 237 | #DEFINE SERVICE_TYPE_ALL 0x013F 238 | 239 | && defines for AServiceStatus (current service state) 240 | #DEFINE SERVICE_STOPPED 0x01 241 | #DEFINE SERVICE_START_PENDING 0x02 242 | #DEFINE SERVICE_STOP_PENDING 0x03 243 | #DEFINE SERVICE_RUNNING 0x04 244 | #DEFINE SERVICE_CONTINUE_PENDING 0x05 245 | #DEFINE SERVICE_PAUSE_PENDING 0x06 246 | #DEFINE SERVICE_PAUSED 0x07 247 | 248 | && defines for Servie Handler function 249 | #DEFINE SERVICE_CONTROL_STOP 0x00000001 250 | #DEFINE SERVICE_CONTROL_PAUSE 0x00000002 251 | #DEFINE SERVICE_CONTROL_CONTINUE 0x00000003 252 | #DEFINE SERVICE_CONTROL_INTERROGATE 0x00000004 253 | #DEFINE SERVICE_CONTROL_SHUTDOWN 0x00000005 254 | #DEFINE SERVICE_CONTROL_PARAMCHANGE 0x00000006 255 | #DEFINE SERVICE_CONTROL_NETBINDADD 0x00000007 256 | #DEFINE SERVICE_CONTROL_NETBINDREMOVE 0x00000008 257 | #DEFINE SERVICE_CONTROL_NETBINDENABLE 0x00000009 258 | #DEFINE SERVICE_CONTROL_NETBINDDISABLE 0x0000000A 259 | #DEFINE SERVICE_CONTROL_DEVICEEVENT 0x0000000B 260 | #DEFINE SERVICE_CONTROL_HARDWAREPROFILECHANGE 0x0000000C 261 | #DEFINE SERVICE_CONTROL_POWEREVENT 0x0000000D 262 | #DEFINE SERVICE_CONTROL_SESSIONCHANGE 0x0000000E 263 | 264 | #DEFINE SERVICE_ACCEPT_STOP 0x00000001 265 | #DEFINE SERVICE_ACCEPT_PAUSE_CONTINUE 0x00000002 266 | #DEFINE SERVICE_ACCEPT_SHUTDOWN 0x00000004 267 | #DEFINE SERVICE_ACCEPT_PARAMCHANGE 0x00000008 268 | #DEFINE SERVICE_ACCEPT_NETBINDCHANGE 0x00000010 269 | #DEFINE SERVICE_ACCEPT_HARDWAREPROFILECHANGE 0x00000020 270 | #DEFINE SERVICE_ACCEPT_POWEREVENT 0x00000040 271 | #DEFINE SERVICE_ACCEPT_SESSIONCHANGE 0x00000080 272 | 273 | #DEFINE ERROR_CALL_NOT_IMPLEMENTED 120 274 | 275 | && defines for OpenService (access rights) 276 | #DEFINE SERVICE_QUERY_CONFIG 0x0001 277 | #DEFINE SERVICE_CHANGE_CONFIG 0x0002 278 | #DEFINE SERVICE_QUERY_STATUS 0x0004 279 | #DEFINE SERVICE_ENUMERATE_DEPENDENTS 0x0008 280 | #DEFINE SERVICE_START 0x0010 281 | #DEFINE SERVICE_STOP 0x0020 282 | #DEFINE SERVICE_PAUSE_CONTINUE 0x0040 283 | #DEFINE SERVICE_INTERROGATE 0x0080 284 | #DEFINE SERVICE_USER_DEFINED_CONTROL 0x0100 285 | #DEFINE SERVICE_ALL_ACCESS 0x000F01FF 286 | *!* #DEFINE SERVICE_ALL_ACCESS (BITOR(STANDARD_RIGHTS_REQUIRED,SERVICE_QUERY_CONFIG,SERVICE_CHANGE_CONFIG, 287 | *!* SERVICE_QUERY_STATUS,SERVICE_ENUMERATE_DEPENDENTS,SERVICE_START,SERVICE_STOP, 288 | *!* SERVICE_PAUSE_CONTINUE,SERVICE_INTERROGATE,SERVICE_USER_DEFINED_CONTROL)) 289 | 290 | && flags for ADIREX 291 | #DEFINE ADIREX_DEST_ARRAY 0x01 292 | #DEFINE ADIREX_DEST_CURSOR 0x02 293 | #DEFINE ADIREX_DEST_CALLBACK 0x04 294 | #DEFINE ADIREX_FILTER_ALL 0x08 295 | #DEFINE ADIREX_FILTER_NONE 0x10 296 | #DEFINE ADIREX_FILTER_EXACT 0x20 297 | #DEFINE ADIREX_UTC_TIMES 0x40 298 | 299 | && file attributes for ADIREX, GETFILEATTRIBUTES, SETFILEATTRIBUTES, AFILEATTRIBUTES & 300 | && AFILEATTRIBUTESEX 301 | #DEFINE FILE_ATTRIBUTE_READONLY 0x00000001 302 | #DEFINE FILE_ATTRIBUTE_HIDDEN 0x00000002 303 | #DEFINE FILE_ATTRIBUTE_SYSTEM 0x00000004 304 | #DEFINE FILE_ATTRIBUTE_DIRECTORY 0x00000010 305 | #DEFINE FILE_ATTRIBUTE_ARCHIVE 0x00000020 306 | #DEFINE FILE_ATTRIBUTE_DEVICE 0x00000040 307 | #DEFINE FILE_ATTRIBUTE_NORMAL 0x00000080 308 | #DEFINE FILE_ATTRIBUTE_TEMPORARY 0x00000100 309 | #DEFINE FILE_ATTRIBUTE_SPARSE_FILE 0x00000200 310 | #DEFINE FILE_ATTRIBUTE_REPARSE_POINT 0x00000400 311 | #DEFINE FILE_ATTRIBUTE_COMPRESSED 0x00000800 312 | #DEFINE FILE_ATTRIBUTE_OFFLINE 0x00001000 313 | #DEFINE FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000 314 | #DEFINE FILE_ATTRIBUTE_ENCRYPTED 0x00004000 315 | #DEFINE FILE_ATTRIBUTE_FAKEDIRECTORY 0x80000000 316 | 317 | && additional flags for FCreateEx, FOpenEx - see MSDN -> CreateFile function for an 318 | && explanation of these constants 319 | #DEFINE FILE_FLAG_OPEN_NO_RECALL 0x00100000 320 | #DEFINE FILE_FLAG_OPEN_REPARSE_POINT 0x00200000 321 | #DEFINE FILE_FLAG_POSIX_SEMANTICS 0x01000000 322 | #DEFINE FILE_FLAG_BACKUP_SEMANTICS 0x02000000 323 | #DEFINE FILE_FLAG_DELETE_ON_CLOSE 0x04000000 324 | #DEFINE FILE_FLAG_SEQUENTIAL_SCAN 0x08000000 325 | #DEFINE FILE_FLAG_RANDOM_ACCESS 0x10000000 326 | #DEFINE FILE_FLAG_NO_BUFFERING 0x20000000 327 | #DEFINE FILE_FLAG_WRITE_THROUGH 0x80000000 328 | 329 | && access mode flags for FCreateEx/FOpenEx 330 | #DEFINE FILE_SHARE_READ 0x01 331 | #DEFINE FILE_SHARE_WRITE 0x02 332 | #DEFINE FILE_SHARE_DELETE 0x04 333 | 334 | && seek mode for FSeekEx 335 | #DEFINE FILE_BEGIN 0 336 | #DEFINE FILE_CURRENT 1 337 | #DEFINE FILE_END 2 338 | 339 | && flags for SHCopy/Rename/Delete/Move Files functions 340 | #DEFINE FOF_MULTIDESTFILES 0x0001 341 | #DEFINE FOF_CONFIRMMOUSE 0x0002 342 | #DEFINE FOF_SILENT 0x0004 343 | #DEFINE FOF_RENAMEONCOLLISION 0x0008 344 | #DEFINE FOF_NOCONFIRMATION 0x0010 345 | #DEFINE FOF_ALLOWUNDO 0x0040 346 | #DEFINE FOF_FILESONLY 0x0080 347 | #DEFINE FOF_SIMPLEPROGRESS 0x0100 348 | #DEFINE FOF_NOCONFIRMMKDIR 0x0200 349 | #DEFINE FOF_NOERRORUI 0x0400 350 | #DEFINE FOF_NOCOPYSECURITYATTRIBS 0x0800 351 | #DEFINE FOF_NORECURSION 0x1000 352 | #DEFINE FOF_NO_CONNECTED_ELEMENTS 0x2000 353 | #DEFINE FOF_WANTNUKEWARNING 0x4000 354 | #DEFINE FOF_NORECURSEREPARSE 0x8000 355 | 356 | && flags for APRINTERSEX 357 | #DEFINE PRINTER_ENUM_DEFAULT 0x00000001 358 | #DEFINE PRINTER_ENUM_LOCAL 0x00000002 359 | #DEFINE PRINTER_ENUM_CONNECTIONS 0x00000004 360 | #DEFINE PRINTER_ENUM_FAVORITE 0x00000004 361 | #DEFINE PRINTER_ENUM_NAME 0x00000008 362 | #DEFINE PRINTER_ENUM_REMOTE 0x00000010 363 | #DEFINE PRINTER_ENUM_SHARED 0x00000020 364 | #DEFINE PRINTER_ENUM_NETWORK 0x00000040 365 | 366 | && flags for APAPERSIZES 367 | #DEFINE PAPERSIZE_UNIT_MM 1 368 | #DEFINE PAPERSIZE_UNIT_INCH 2 369 | #DEFINE PAPERSIZE_UNIT_POINT 3 370 | 371 | && callback flags for CreateCallbackFunc 372 | #DEFINE CALLBACK_SYNCRONOUS 1 373 | #DEFINE CALLBACK_ASYNCRONOUS_POST 2 374 | #DEFINE CALLBACK_ASYNCRONOUS_SEND 4 375 | #DEFINE CALLBACK_CDECL 8 376 | 377 | && callback status codes for UrlDownloadToFileEx 378 | #DEFINE BINDSTATUS_FINDINGRESOURCE 1 379 | #DEFINE BINDSTATUS_CONNECTING 2 380 | #DEFINE BINDSTATUS_REDIRECTING 3 381 | #DEFINE BINDSTATUS_BEGINDOWNLOADDATA 4 382 | #DEFINE BINDSTATUS_DOWNLOADINGDATA 5 383 | #DEFINE BINDSTATUS_ENDDOWNLOADDATA 6 384 | #DEFINE BINDSTATUS_BEGINDOWNLOADCOMPONENTS 7 385 | #DEFINE BINDSTATUS_INSTALLINGCOMPONENTS 8 386 | #DEFINE BINDSTATUS_ENDDOWNLOADCOMPONENTS 9 387 | #DEFINE BINDSTATUS_USINGCACHEDCOPY 10 388 | #DEFINE BINDSTATUS_SENDINGREQUEST 11 389 | #DEFINE BINDSTATUS_CLASSIDAVAILABLE 12 390 | #DEFINE BINDSTATUS_MIMETYPEAVAILABLE 13 391 | #DEFINE BINDSTATUS_CACHEFILENAMEAVAILABLE 14 392 | #DEFINE BINDSTATUS_BEGINSYNCOPERATION 15 393 | #DEFINE BINDSTATUS_ENDSYNCOPERATION 16 394 | #DEFINE BINDSTATUS_BEGINUPLOADDATA 17 395 | #DEFINE BINDSTATUS_UPLOADINGDATA 18 396 | #DEFINE BINDSTATUS_ENDUPLOADINGDATA 19 397 | #DEFINE BINDSTATUS_PROTOCOLCLASSID 20 398 | #DEFINE BINDSTATUS_ENCODING 21 399 | #DEFINE BINDSTATUS_VERFIEDMIMETYPEAVAILABLE 22 400 | #DEFINE BINDSTATUS_CLASSINSTALLLOCATION 23 401 | #DEFINE BINDSTATUS_DECODING 24 402 | #DEFINE BINDSTATUS_LOADINGMIMEHANDLER 25 403 | #DEFINE BINDSTATUS_CONTENTDISPOSITIONATTACH 26 404 | #DEFINE BINDSTATUS_FILTERREPORTMIMETYPE 27 405 | #DEFINE BINDSTATUS_CLSIDCANINSTANTIATE 28 406 | #DEFINE BINDSTATUS_IUNKNOWNAVAILABLE 29 407 | #DEFINE BINDSTATUS_DIRECTBIND 30 408 | #DEFINE BINDSTATUS_RAWMIMETYPE 31 409 | #DEFINE BINDSTATUS_PROXYDETECTING 32 410 | #DEFINE BINDSTATUS_ACCEPTRANGES 33 411 | #DEFINE BINDSTATUS_COOKIE_SENT 34 412 | #DEFINE BINDSTATUS_COMPACT_POLICY_RECEIVED 35 413 | #DEFINE BINDSTATUS_COOKIE_SUPPRESSED 36 414 | #DEFINE BINDSTATUS_COOKIE_STATE_UNKNOWN 37 415 | #DEFINE BINDSTATUS_COOKIE_STATE_ACCEPT 38 416 | #DEFINE BINDSTATUS_COOKIE_STATE_REJECT 39 417 | #DEFINE BINDSTATUS_COOKIE_STATE_PROMPT 40 418 | #DEFINE BINDSTATUS_COOKIE_STATE_LEASH 41 419 | #DEFINE BINDSTATUS_COOKIE_STATE_DOWNGRADE 42 420 | #DEFINE BINDSTATUS_POLICY_HREF 43 421 | #DEFINE BINDSTATUS_P3P_HEADER 44 422 | #DEFINE BINDSTATUS_SESSION_COOKIE_RECEIVED 45 423 | #DEFINE BINDSTATUS_PERSISTENT_COOKIE_RECEIVED 46 424 | #DEFINE BINDSTATUS_SESSION_COOKIES_ALLOWED 47 425 | #DEFINE BINDSTATUS_CACHECONTROL 48 426 | #DEFINE BINDSTATUS_CONTENTDISPOSITIONFILENAME 49 427 | #DEFINE BINDSTATUS_MIMETEXTPLAINMISMATCH 50 428 | #DEFINE BINDSTATUS_PUBLISHERAVAILABLE 51 429 | #DEFINE BINDSTATUS_DISPLAYNAMEAVAILABLE 52 430 | #DEFINE BINDSTATUS_INTRANETREQUESTDENIED 53 431 | #DEFINE BINDSTATUS_SSLUX_NAVBLOCKED 54 432 | #DEFINE BINDSTATUS_DOWNLOAD_FINISHED 99 433 | #DEFINE BINDSTATUS_DOWNLOAD_ABORTED 100 434 | 435 | 436 | && AWindows, AWindowsEx flags 437 | #DEFINE AWINDOWS_TOPLEVEL 0x01 438 | #DEFINE AWINDOWS_CHILD 0x02 439 | #DEFINE AWINDOWS_THREAD 0x04 440 | #DEFINE AWINDOWS_DESKTOP 0x08 441 | #DEFINE AWINDOWS_CALLBACK 0x10 442 | 443 | && SQLExecEx flags 444 | #DEFINE SQLEXECEX_DEST_CURSOR 0x0001 445 | #DEFINE SQLEXECEX_DEST_VARIABLE 0x0002 446 | #DEFINE SQLEXECEX_REUSE_CURSOR 0x0004 447 | #DEFINE SQLEXECEX_NATIVE_SQL 0x0008 448 | #DEFINE SQLEXECEX_CALLBACK_PROGRESS 0x0010 449 | #DEFINE SQLEXECEX_CALLBACK_INFO 0x0020 450 | #DEFINE SQLEXECEX_STORE_INFO 0x0040 451 | 452 | && ODBC SQL types 453 | #DEFINE SQL_UNKNOWN_TYPE 0 454 | #DEFINE SQL_CHAR 1 455 | #DEFINE SQL_NUMERIC 2 456 | #DEFINE SQL_DECIMAL 3 457 | #DEFINE SQL_INTEGER 4 458 | #DEFINE SQL_SMALLINT 5 459 | #DEFINE SQL_FLOAT 6 460 | #DEFINE SQL_REAL 7 461 | #DEFINE SQL_DOUBLE 8 462 | #DEFINE SQL_DATE 9 463 | #DEFINE SQL_DATETIME 9 464 | #DEFINE SQL_TIMESTAMP 11 465 | #DEFINE SQL_VARCHAR 12 466 | #DEFINE SQL_LONGVARCHAR -1 467 | #DEFINE SQL_BINARY -2 468 | #DEFINE SQL_VARBINARY -3 469 | #DEFINE SQL_LONGVARBINARY -4 470 | #DEFINE SQL_BIGINT -5 471 | #DEFINE SQL_TINYINT -6 472 | #DEFINE SQL_BIT -7 473 | #DEFINE SQL_WCHAR -8 474 | #DEFINE SQL_WVARCHAR -9 475 | #DEFINE SQL_WLONGVARCHAR -10 476 | 477 | && BindEventsEx flags 478 | #DEFINE BINDEVENTSEX_CALL_BEFORE 0x0001 479 | #DEFINE BINDEVENTSEX_CALL_AFTER 0x0002 480 | #DEFINE BINDEVENTSEX_RETURN_VALUE 0x0004 481 | #DEFINE BINDEVENTSEX_NO_RECURSION 0x0008 482 | #DEFINE BINDEVENTSEX_CLASSPROC 0x0010 483 | 484 | && some usefull windowmessages 485 | #DEFINE WM_CREATE 0x0001 486 | #DEFINE WM_DESTROY 0x0002 487 | #DEFINE WM_MOVE 0x0003 488 | #DEFINE WM_SIZE 0x0005 489 | #DEFINE WM_ACTIVATE 0x0006 490 | #DEFINE WM_QUERYENDSESSION 0x0011 491 | #DEFINE WM_ENDSESSION 0x0016 492 | #DEFINE WM_SYSCOLORCHANGE 0x0015 493 | #DEFINE WM_WININICHANGE 0x001A 494 | #DEFINE WM_ACTIVATEAPP 0x001C 495 | #DEFINE WM_FONTCHANGE 0x001D 496 | #DEFINE WM_TIMECHANGE 0x001E 497 | #DEFINE WM_POWER 0x0048 498 | #DEFINE WM_USERCHANGED 0x0054 499 | #DEFINE WM_KEYDOWN 0x0100 500 | #DEFINE WM_KEYUP 0x0101 501 | #DEFINE WM_CHAR 0x0102 502 | #DEFINE WM_DEADCHAR 0x0103 503 | #DEFINE WM_SYSKEYDOWN 0x0104 504 | #DEFINE WM_SYSKEYUP 0x0105 505 | #DEFINE WM_SYSCHAR 0x0106 506 | #DEFINE WM_SYSDEADCHAR 0x0107 507 | #DEFINE WM_MOUSEMOVE 0x0200 508 | #DEFINE WM_LBUTTONDOWN 0x0201 509 | #DEFINE WM_LBUTTONUP 0x0202 510 | #DEFINE WM_LBUTTONDBLCLK 0x0203 511 | #DEFINE WM_RBUTTONDOWN 0x0204 512 | #DEFINE WM_RBUTTONUP 0x0205 513 | #DEFINE WM_RBUTTONDBLCLK 0x0206 514 | #DEFINE WM_MBUTTONDOWN 0x0207 515 | #DEFINE WM_MBUTTONUP 0x0208 516 | #DEFINE WM_MBUTTONDBLCLK 0x0209 517 | #DEFINE WM_MOUSEWHEEL 0x020A 518 | #DEFINE WM_ENTERMENULOOP 0x0211 519 | #DEFINE WM_EXITMENULOOP 0x0212 520 | #DEFINE WM_MOVING 0x0216 521 | #DEFINE WM_POWERBROADCAST 0x0218 522 | #DEFINE WM_DEVICECHANGE 0x0219 523 | #DEFINE WM_APPCOMMAND 0x0319 524 | #DEFINE WM_THEMECHANGED 0x031A 525 | 526 | && FindFileChange notification events 527 | #DEFINE FILE_NOTIFY_CHANGE_FILE_NAME 0x00000001 528 | #DEFINE FILE_NOTIFY_CHANGE_DIR_NAME 0x00000002 529 | #DEFINE FILE_NOTIFY_CHANGE_ATTRIBUTES 0x00000004 530 | #DEFINE FILE_NOTIFY_CHANGE_SIZE 0x00000008 531 | #DEFINE FILE_NOTIFY_CHANGE_LAST_WRITE 0x00000010 532 | #DEFINE FILE_NOTIFY_CHANGE_SECURITY 0x00000100 533 | 534 | && OsEx - windows version 535 | #DEFINE OSEX_WINDOWS 0 536 | #DEFINE OSEX_WINDOWS32S 1 537 | #DEFINE OSEX_WINDOWS95 2 538 | #DEFINE OSEX_WINDOWS95OSR2 3 539 | #DEFINE OSEX_WINDOWS98 4 540 | #DEFINE OSEX_WINDOWS98SE 5 541 | #DEFINE OSEX_WINDOWSMILLENNIUM 6 542 | #DEFINE OSEX_WINDOWSNT351 7 543 | #DEFINE OSEX_WINDOWSNT40 8 544 | #DEFINE OSEX_WINDOWSNT40SERVER 9 545 | #DEFINE OSEX_WINDOWS2000 10 546 | #DEFINE OSEX_WINDOWSXP 11 547 | #DEFINE OSEX_WINDOWSXPPROFESSIONALX64 12 548 | #DEFINE OSEX_WINDOWSHOMESERVER 13 549 | #DEFINE OSEX_WINDOWSVISTA 14 550 | #DEFINE OSEX_WINDOWSSERVER2003 15 551 | #DEFINE OSEX_WINDOWSSERVER2003R2 16 552 | #DEFINE OSEX_WINDOWS7 17 553 | #DEFINE OSEX_WINDOWSSERVER2008 18 554 | #DEFINE OSEX_WINDOWSSERVER2008R2 19 555 | #DEFINE OSEX_WINDOWSX 20 556 | 557 | && CreateThreadObject - execution context 558 | #DEFINE CLSCTX_INPROC_SERVER 0x1 559 | #DEFINE CLSCTX_LOCAL_SERVER 0x4 560 | 561 | #ENDIF && _VFP2C_H__ -------------------------------------------------------------------------------- /avfp5.53_source/prg/webthreads2.prg: -------------------------------------------------------------------------------- 1 | ************************************************** 2 | * WEBTHREADS Version 2 for AVFP 3 | * Modified 1/26/13 CKF 4 | * * Runs any vfp code on a background thread 5 | * Uses CreateThreadObject in vfp2c32.fll 6 | * by Christian Ehlscheid 7 | ************************************************** 8 | 9 | DEFINE CLASS ThreadManager AS Session OLEPUBLIC 10 | 11 | CallInfo = .NULL. && "magic" property 12 | oEvent = NULL 13 | lSilent = .f. && just run the thread with no update page, defaults to having an update page 14 | nRecExpire = 5400 && how long to keep Event records 15 | 16 | PROCEDURE CreateThread(ThreadProc as String, ThreadProcParam as String) 17 | LOCAL lcID,ThreadProcParam 18 | PUBLIC loObj, loCallback, xj, lnCallId 19 | #INCLUDE vfp2c.h 20 | SET LIBRARY TO oProp.AppStartPath+[\vfp2c32.fll] ADDITIVE 21 | *!* IF !InitVFP2C32(VFP2C_INIT_ALL) && you can vary the initialization parameter depending on what functions of the FLL you intend to use 22 | *!* LOCAL laError[1], lnCount, xj, lcError 23 | *!* lnCount = AERROREX('laError') 24 | *!* lcError = 'VFP2C32 Library initialization failed:' + CHR(13) 25 | *!* FOR xj = 1 TO lnCount 26 | *!* lcError = lcError + ; 27 | *!* 'Error No : ' + TRANSFORM(laError[1]) + CHR(13) + ; 28 | *!* 'Function : ' + laError[2] + CHR(13) + ; 29 | *!* 'Message : "' + laError[3] + '"' 30 | *!* ENDFOR 31 | *!* RETURN lcError && show/log error and abort program initialization .. 32 | *!* ENDIF 33 | ThreadProcParam = IIF(EMPTY(ThreadProcParam),SUBSTR(SYS(2015),3,10),SUBSTR(SYS(2015),3,10)+[,]+ThreadProcParam) 34 | ALINES(laArr,ThreadProcParam,.F.,",") 35 | lcID = laArr[1] 36 | lcEventFile=oProp.AppStartPath+'temp\events.DBF' 37 | IF !FILE(lcEventFile) 38 | CREATE TABLE (lcEventFile) ; 39 | (id c(10), begin l, finish l , returnval c(50), count n(5,0), cancel l, action m, timestamp t, err l, err_txt m) 40 | INDEX ON id TAG id 41 | INDEX ON timestamp TAG timestamp 42 | 43 | ENDIF 44 | IF ! USED('events') 45 | USE (lcEventFile) IN 0 SHARED 46 | ENDIF 47 | SELECT events 48 | * recycling old events records 49 | *SCAN FOR (DATETIME()-events.timestamp)>5400 &&86400 1 day &&5400 90 minutes 50 | SCAN FOR (DATETIME()-events.timestamp)>; 51 | IIF(EMPTY(THIS.nRecExpire),5400,THIS.nRecExpire) &&86400 1 day &&5400 && 90 minutes 52 | DO WHILE .NOT. RLOCK() 53 | ENDDO 54 | REPL ID WITH '' 55 | UNLOCK 56 | ENDSCAN 57 | DO WHILE .NOT. FLOCK() 58 | ENDDO 59 | LOCATE FOR EMPTY(id) 60 | IF EOF() 61 | APPEND BLANK 62 | REPLACE id WITH lcID 63 | REPLACE finish WITH .f. 64 | REPLACE count WITH 0 65 | REPLACE begin WITH .t. 66 | REPLACE cancel WITH .f. 67 | REPLACE action WITH '' 68 | REPLACE timestamp WITH DATETIME() 69 | REPLACE err WITH .f. 70 | REPLACE err_txt WITH '' 71 | ELSE 72 | REPLACE id WITH lcID 73 | REPLACE finish WITH .f. 74 | REPLACE count WITH 0 75 | REPLACE begin WITH .t. 76 | REPLACE cancel WITH .f. 77 | REPLACE action WITH '' 78 | REPLACE timestamp WITH DATETIME() 79 | REPLACE err WITH .f. 80 | REPLACE err_txt WITH '' 81 | ENDIF 82 | UNLOCK 83 | USE IN events 84 | 85 | IF VARTYPE(ThreadProc)='C' 86 | 87 | *must be compiled object and compile is source date newer 88 | IF !FILE(oProp.AppStartPath+"prg\"+ThreadProc+".fxp") OR ; 89 | FDATE(oProp.AppStartPath+"prg\"+ThreadProc+".prg",1) > FDATE(oProp.AppStartPath+"prg\"+ThreadProc+".fxp",1) 90 | COMPILE oProp.AppStartPath+"prg\"+ThreadProc+".prg" 91 | ENDIF 92 | 93 | m.loCallback = null &&CREATEOBJECT('ExampleCallback') 94 | 95 | TRY 96 | m.loObj = CreateThreadObject("activevfp.c1", m.loCallback) 97 | 98 | CATCH 99 | AERROREX('laError') 100 | && the array "laError" now contains exact information 101 | &&laError 102 | ENDTRY 103 | 104 | m.loObj.MyDoCmd("do '"+oProp.AppStartPath+"prg\"+ThreadProc+"' WITH '"+ThreadProcParam+"'") 105 | 106 | IF !this.lSilent 107 | this.Start(ThreadProcParam) && show update page 108 | ENDIF 109 | 110 | RETURN lcID 111 | ENDIF 112 | 113 | PROCEDURE Check 114 | LPARAMETERS lcID 115 | lcEventFile=oProp.AppStartPath+'temp\events.DBF' 116 | IF !USED('events') 117 | USE (lcEventFile) IN 0 SHARED 118 | ENDIF 119 | SELECT events 120 | 121 | SET ORDER TO 1 122 | SEEK lcID 123 | IF FOUND() 124 | 125 | replace count WITH count+1 126 | SCATTER NAME THIS.oEvent BLANK MEMO 127 | this.oEvent.count=events.count 128 | this.oEvent.action=events.action 129 | this.oEvent.id=events.id 130 | this.oEvent.begin=events.begin 131 | this.oEvent.finish=events.finish 132 | this.oEvent.cancel=events.cancel 133 | this.oEvent.timestamp=events.timestamp 134 | this.oEvent.err=events.err 135 | this.oEvent.err_txt=events.err_txt 136 | IF events.finish .or. events.err 137 | RETURN .T. 138 | ELSE 139 | RETURN .F. 140 | ENDIF 141 | ENDIF 142 | USE IN events 143 | 144 | 145 | PROCEDURE Cancel 146 | 147 | LPARAMETERS lcID 148 | this.SetPath() && set to data directory wherever activevfp.dll is 149 | UPDATE events SET cancel=.T.,finish = .f. WHERE id==lcID 150 | RELEASE ALL 151 | 152 | PROCEDURE GetError 153 | LPARAMETERS lcID 154 | this.SetPath() 155 | *lcEventFile=oProp.AppStartPath+'temp\events.DBF' 156 | IF !USED('events') 157 | USE events IN 0 SHARED 158 | ENDIF 159 | SELECT events 160 | 161 | SET ORDER TO 1 162 | SEEK lcID 163 | IF FOUND() 164 | 165 | 166 | IF events.err 167 | RETURN .T. 168 | ELSE 169 | RETURN .F. 170 | ENDIF 171 | ENDIF 172 | USE IN events 173 | 174 | PROCEDURE Canceled 175 | LPARAMETERS lcID 176 | this.SetPath() 177 | *lcEventFile=oProp.AppStartPath+'temp\events.DBF' 178 | IF !USED('events') 179 | USE events IN 0 SHARED 180 | ENDIF 181 | SELECT events 182 | 183 | SET ORDER TO 1 184 | SEEK lcID 185 | IF FOUND() 186 | 187 | 188 | IF events.cancel 189 | RETURN .T. 190 | ELSE 191 | RETURN .F. 192 | ENDIF 193 | ENDIF 194 | USE IN events 195 | 196 | 197 | FUNCTION Start(params) 198 | LOCAL cEventID 199 | ALINES(arr,params,.F.,",") 200 | cEventID = arr[1] 201 | oResponse.clear 202 | oResponse.Expires=0 203 | oResponse.Redirect(oProp.ScriptPath+[?action=]+oProp.Action+[&step=AsyncCheck&asyncID=]+cEventID) 204 | RETURN 205 | ENDFUNC 206 | 207 | PROCEDURE RecordError(cEventID,cErrorTxt) 208 | this.SetPath() 209 | UPDATE events SET err=.t.,finish = .f.,err_txt=ALLTRIM(cErrorTxt),begin =.f.,action=[Error] WHERE id=cEventID &&,count = 0 210 | 211 | PROCEDURE StartWebEvent(cEventID,cStartActionTxt) 212 | this.SetPath() 213 | UPDATE events SET finish = .f.,begin =.t.,action=ALLTRIM(cStartActionTxt) WHERE id=cEventID &&,count = 0 214 | 215 | PROCEDURE CompleteWebEvent(cEventID,cFinishActionTxt,cfilename) 216 | IF EMPTY(cfilename) 217 | cfilename=[ ] 218 | ENDIF 219 | IF EMPTY(cFinishActionTxt) 220 | cFinishActionTxt=[ ] 221 | ENDIF 222 | &&,returnval=ALLTRIM(cfilename),action=ALLTRIM(LEFT(events.action,254))+CHR(13)+CHR(10)+ALLTRIM(cFinishActionTxt) 223 | this.SetPath() 224 | UPDATE events SET finish = .t.,begin =.f.,returnval=ALLTRIM(cfilename),action=ALLTRIM(LEFT(events.action,254))+CHR(13)+CHR(10)+ALLTRIM(cFinishActionTxt) WHERE id=cEventID &&fix &&,action=ALLTRIM(events.action)+CHR(13)+CHR(10)+ALLTRIM(cFinishActionTxt) 225 | RELEASE ALL 226 | CLEAR ALL 227 | RETURN 228 | 229 | 230 | 231 | PROCEDURE StatusWebEvent(cEventID,cTxt,lAdditive) 232 | this.SetPath() 233 | IF lAdditive 234 | UPDATE events SET begin =.f.,action=ALLTRIM(LEFT(events.action,254))+CHR(13)+CHR(10)+ALLTRIM(cTxt) WHERE id=cEventID && 235 | ELSE 236 | UPDATE events SET begin =.f.,action=ALLTRIM(cTxt) WHERE id=cEventID &&,count = 0 237 | ENDIF 238 | 239 | PROCEDURE SetPath() 240 | 241 | ASTACKINFO(myarray) 242 | lcAppStartPath=JUSTPATH(myarray(1,4)) &&+"\" 243 | lcTempPath= STRTRAN(lcAppStartPath,'prg','temp')+'\' &&temp needs to be writable 244 | SET PATH TO &lcTempPath 245 | RELEASE myarray 246 | RETURN 247 | 248 | FUNCTION ERROR(nError, cMethod, nLine) 249 | 250 | lcErrMsg = cMethod+' err#='+STR(nError,5)+' line='+STR(nline,6)+; 251 | ' '+MESSAGE()+_VFP.SERVERNAME 252 | STRTOFILE(lcErrMsg,oProp.AppStartPath+[temp\threaderror.txt]) 253 | COMreturnerror(lcErrMsg,_VFP.SERVERNAME) 254 | 255 | ENDFUNC 256 | 257 | FUNCTION INIT 258 | SYS(3050, 1, VAL(SYS(3050, 1, 0)) / 3) 259 | ENDFUNC 260 | 261 | 262 | 263 | 264 | ENDDEFINE 265 | 266 | 267 | 268 | *!* 269 | 270 | 271 | 272 | DEFINE CLASS ExampleCallback AS Custom 273 | 274 | FUNCTION OnCallComplete(callid AS Long, result AS Variant, callcontext AS Variant) AS VOID 275 | ? callid, result, callcontext 276 | ENDFUNC 277 | 278 | FUNCTION OnError(callid AS Long, callcontext AS Variant, errornumber AS Long, errorsource AS String, errordescription AS String) AS VOID 279 | ? callid, callcontext, errornumber, errorsource, errordescription 280 | ENDFUNC 281 | 282 | ENDDEFINE 283 | -------------------------------------------------------------------------------- /avfp5.53_source/reports/..svnbridge/pdfrun.PJT: -------------------------------------------------------------------------------- 1 | svn:mime-typeapplication/octet-stream -------------------------------------------------------------------------------- /avfp5.53_source/reports/..svnbridge/pdfrun.pjx: -------------------------------------------------------------------------------- 1 | svn:mime-typeapplication/octet-stream -------------------------------------------------------------------------------- /avfp5.53_source/reports/clsheap.prg: -------------------------------------------------------------------------------- 1 | ************************************************** 2 | *-- Class: heap 3 | *-- ParentClass: custom 4 | *-- BaseClass: custom 5 | * 6 | * Another in the family of relatively undocumented sample classes I've inflicted on others 7 | * Warning - there's no error handling in here, so be careful to check for null returns and 8 | * invalid pointers. Unless you get frisky, or you're resource-tight, it should work well. 9 | * 10 | * Please read the code and comments carefully. I've tried not to assume much knowledge about 11 | * just how pointers work, or how memory allocation works, and have tried to explain some of the 12 | * basic concepts behing memory allocation in the Win32 environment, without having gone into 13 | * any real details on x86 memory management or the Win32 memory model. If you want to explore 14 | * these things (and you should), start by reading Jeff Richter's _Advanced Windows_, especially 15 | * Chapters 4-6, which deal with the Win32 memory model and virtual memory -really- well. 16 | * 17 | * Another good source iss Walter Oney's _Systems Programming for Windows 95_. Be warned that 18 | * both of these books are targeted at the C programmer; to someone who has only worked with 19 | * languages like VFP or VB, it's tough going the first couple of dozen reads. 20 | * 21 | * Online resources - http://www.x86.org is the Intel Secrets Homepage. Lots of deep, dark 22 | * stuff about the x86 architecture. Not for the faint of heart. Lots of pointers to articles 23 | * from DDJ (Doctor Dobbs Journal, one of the oldest and best magazines on microcomputing.) 24 | * 25 | * You also might want to take a look at the transcripts from my "Pointers on Pointers" chat 26 | * sessions, which are available in the WednesdayNightLectureSeries topic on the Fox Wiki, 27 | * http://fox.wikis.com - the Wiki is a great Web site; it provides a vast store of information 28 | * on VFP and related topics, and is probably the best tool available now to develop topics in 29 | * a collaborative environment. Well worth checking out - it's a very different mechanism for 30 | * ongoing discussion of a subject. It's an on-line message base or chat; I find 31 | * myself hitting it when I have a question to see if an answer already exists. It's 32 | * much like using a FAQ, except that most things on the Wiki are editable... 33 | * 34 | * Post-DevCon 2000 revisions: 35 | * 36 | * After some bizarre errors at DevCon, I reworked some of the methods to 37 | * consistently return a NULL whenever a bad pointer/inactive pointer in the 38 | * iaAllocs member array was encountered. I also implemented NumToLong 39 | * using RtlMoveMemory(), relying on a BITOR() to recast what would otherwise 40 | * be a value with the high-order bit set. The result is it's faster, and 41 | * an anomaly reported with values between 0xFFFFFFF1-0xFFFFFFFF goes away, 42 | * at the expense of representing these as negative numbers. Pointer math 43 | * still works. 44 | * 45 | ***** 46 | * How HEAP works: 47 | * 48 | * Overwhelming guilt hit early this morning; maybe I should explain the 49 | * concept of the Heap class and give an example of how to use it, in 50 | * conjunction with the add-on functions that follow in this proc library. 51 | * 52 | * Windows allocates memory from several places; it also provides a 53 | * way to define your own small corner of the universe where you can 54 | * allocate and deallocate blocks of memory for your own purposes. These 55 | * public or private memory areas are referred to commonly as heaps. 56 | * 57 | * VFP is great in most cases; it provides flexible allocation and 58 | * alteration of variables on the fly in a program. You don't need to 59 | * know much about how things are represented internally. This makes 60 | * most programming tasks easy. However, in exchange for VFP's flexibility 61 | * in memory variable allocation, we give up several things, the most 62 | * annoying of which are not knowing the exact location of a VFP 63 | * variable in memory, and not knowing exactly how things are constructed 64 | * inside a variable, both of which make it hard to define new kinds of 65 | * memory structures within VFP to manipulate as a C-style structure. 66 | * 67 | * Enter Heap. Heap creates a growable, private heap, from which you 68 | * can allocate blocks of memory that have a known location and size 69 | * in your memory address space. It also provides a way of transferring 70 | * data to and from these allocated blocks. You build structures in VFP 71 | * strings, and parse the content of what is returned in those blocks by 72 | * extracting substrings from VFP strings. 73 | * 74 | * Heap does its work using a number of Win32 API functions; HeapCreate(), 75 | * which sets up a private heap and assigns it a handle, is invoked in 76 | * the Init method. This sets up the 'heap', where block allocations 77 | * for the object will be constructed. I set up the heap to use a base 78 | * allocation size of twice the size of a swap file 'page' in the x86 79 | * world (8K), and made the heap able to grow; it adds 8K chunks of memory 80 | * to itself as it grows. There's no fixed limit (other than available 81 | * -virtual- memory) on the size of the heap constructed; just realize 82 | * that huge allocations are likely to bump heads with VFP's own desire 83 | * for mondo RAM. 84 | * 85 | * Once the Heap is established, we can allocate blocks of any size we 86 | * want in Heap, outside of VFP's memory, but within the virtual 87 | * address space owned by VFP. Blocks are allocated by HeapAlloc(), and a 88 | * pointer to the block is returned as an integer. 89 | * 90 | * KEEP THE POINTER RETURNED BY ANY Alloc method, it's the key to 91 | * doing things with the block in the future. In addition to being a 92 | * valid pinter, it's the key to finding allocations tracked in iaAllocs[] 93 | * 94 | * Periodically, we need to load things into the block we've created. 95 | * Thanks to work done by Christof Lange, George Tasker and others, 96 | * we found a Win32API call that will do transfers between memory 97 | * locations, called RtlMoveMemory(). RtlMoveMemory() acts like the 98 | * Win32API MoveMemory() call; it takes two pointers (destination 99 | * and source) and a length. In order to make life easy, at times 100 | * we DECLARE the pointers as INTEGER (we pass a number, which is 101 | * treated as a DWORD (32 bit unsigned integer) whose content is the 102 | * address to use), and at other times as STRING @, which passes the 103 | * physical address of a VFP string variable's contents, allowing 104 | * RtlMoveMemory() to read and write VFP strings without knowing how 105 | * to manipulate VFP's internal variable structures. RtlMoveMemory() 106 | * is used by both the CopyFrom and CopyTo methods, and the enhanced 107 | * Alloc methods. 108 | * 109 | * At some point, we're finished with a block of memory. We can free up 110 | * that memory via HeapFree(), which releases a previously-allocated 111 | * block on the heap. It does not compact or rearrange the heap allocations 112 | * but simply makes the memory allocated no longer valid, and the 113 | * address could be reused by another Alloc operation. We track the 114 | * active state of allocations in a member array iaAllocs[] which has 115 | * 3 members per row; the pointer, which is used as a key, the actual 116 | * size of the allocation (sometimes HeapAlloc() gives you a larger block 117 | * than requested; we can see it here. This is the property returned 118 | * by the SizeOfBlock method) and whether or not it's active and available. 119 | * 120 | * When we're done with a Heap, we need to release the allocations and 121 | * the heap itself. HeapDestroy() releases the entire heap back to the 122 | * Windows memory pool. This is invoked in the Destroy method of the 123 | * class to ensure that it gets explcitly released, since it remains alive 124 | * until it is explicitly released or the owning process is released. I 125 | * put this in the Destroy method to ensure that the heap went away when 126 | * the Heap object went out of scope. 127 | * 128 | * The original class methods are: 129 | * 130 | * Init Creates the heap for use 131 | * Alloc(nSize) Allocates a block of nSize bytes, returns an nPtr 132 | * to it. nPtr is NULL if fail 133 | * DeAlloc(nPtr) Releases the block whose base address is nPtr. 134 | * Returns .T./.F. 135 | * CopyTo(nPtr,cSrc) Copies the Content of cSrc to the buffer at nPtr, 136 | * up to the smaller of LEN(cSrc) or the length of 137 | * the block (we look in the iaAllocs[] array). 138 | * Returns .T./.F. 139 | * CopyFrom(nPtr) Copies the content of the block at nPtr (size is 140 | * from iaAllocs[]) and returns it as a VFP string. 141 | * Returns a string, or NULL if fail 142 | * SizeOfBlock(nPtr) Returns the actual allocated size of the block 143 | * pointed to by nPtr. Returns NULL if fail 144 | * Destroy() DeAllocs anything still active, and then frees 145 | * the heap. 146 | ***** 147 | * New methods added 2/12/99 EMR - Attack of the Creeping Feature Creature, 148 | * part I 149 | * 150 | * There are too many times when you know what you want to put in 151 | * a buffer when you allocate it, so why not pass what you want in 152 | * the buffer when you allocate it? And we may as well add an option to 153 | * init the memory to a known value easily, too: 154 | * 155 | * AllocBLOB(cSrc) Allocate a block of SizeOf(cSrc) bytes and 156 | * copy cSrc content to it 157 | * AllocString(cSrc) Allocate a block of SizeOf(cSrc) + 1 bytes and 158 | * copy cSrc content to it, adding a null (CHR(0)) 159 | * to the end to make it a standard C-style string 160 | * AllocInitAs(nSize,nVal) 161 | * Allocate a block of nSize bytes, preinitialized 162 | * with CHR(nVal). If no nVal is passed, or nVal 163 | * is illegal (not a number 0-255), init with nulls 164 | * 165 | ***** 166 | * Property changes 9/29/2000 167 | * 168 | * iaAllocs[] is now protected 169 | * 170 | ***** 171 | * Method modifications 9/29/2000: 172 | * 173 | * All lookups in iaAllocs[] are now done using the new FindAllocID() 174 | * method, which returns a NULL for the ID if not found active in the 175 | * iaAllocs[] entries. Result is less code and more consistent error 176 | * handling, based on checking ISNULL() for pointers. 177 | * 178 | ***** 179 | * The ancillary goodies in the procedure library are there to make life 180 | * easier for people working with structures; they are not optimal 181 | * and infinitely complete, but they do the things that are commonly 182 | * needed when dealing with stuff in structures. The functions are of 183 | * two types; converters, which convert standard C structures to an 184 | * equivalent VFP numeric, or make a string whose value is equivalent 185 | * to a C data type from a number, so that you can embed integers, 186 | * pointers, etc. in the strings used to assemble a structure which you 187 | * load up with CopyTo, or pull out pointers and integers that come back 188 | * embedded in a structure you've grabbed with CopyFrom. 189 | * 190 | * The second type of functions provided are memory copiers. The 191 | * CopyFrom and CopyTo methods are set up to work with our heap, 192 | * and nPtrs must take on the values of block addresses grabbed 193 | * from our heap. There will be lots of times where you need to 194 | * get the content of memory not necessarily on our heap, so 195 | * SetMem, GetMem and GetMemString go to work for us here. SetMem 196 | * copies the content of a string into the absolute memory block 197 | * at nPtr, for the length of the string, using RtlMoveMemory(). 198 | * BE AWARE THAT MISUSE CAN (and most likely will) RESULT IN 199 | * 0xC0000005 ERRORS, memory access violations, or similar OPERATING 200 | * SYSTEM level errors that will smash VFP like an empty beer can in 201 | * a trash compactor. 202 | * 203 | * There are two functions to copy things from a known address back 204 | * to the VFP world. If you know the size of the block to grab, 205 | * GetMem(nPtr,nSize) will copy nSize bytes from the address nPtr 206 | * and return it as a VFP string. See the caveat above. 207 | * GetMemString(nPtr) uses a different API call, lstrcpyn(), to 208 | * copy a null terminated string from the address specified by nPtr. 209 | * You can hurt yourself with this one, too. 210 | * 211 | * Functions in the procedure library not a part of the class: 212 | * 213 | * GetMem(nPtr,nSize) Copy nSize bytes at address nPtr into a VFP string 214 | * SetMem(nPtr,cSource) Copy the string in cSource to the block beginning 215 | * at nPtr 216 | * GetMemString(nPtr) Get the null-terminated string (up to 512 bytes) 217 | * from the address at nPtr 218 | * 219 | * DWORDToNum(cString) Convert the first 4 bytes of cString as a DWORD 220 | * to a VFP numeric (0 to 2^32) 221 | * SHORTToNum(cString) Convert the first 2 bytes of cString as a SHORT 222 | * to a VFP numeric (-32768 to 32767) 223 | * WORDToNum(cString) Convert the first 2 bytes of cString as a WORD 224 | * to a VFP numeric (0 to 65535) 225 | * NumToDWORD(nInteger) Converts nInteger into a string equivalent to a 226 | * C DWORD (4 byte unsigned) 227 | * NumToWORD(nInteger) Converts nInteger into a string equivalent to a 228 | * C WORD (2 byte unsigned) 229 | * NumToSHORT(nInteger) Converts nInteger into a string equivalent to a 230 | * C SHORT ( 2 byte signed) 231 | * 232 | ****** 233 | * New external functions added 2/13/99 234 | * 235 | * I see a need to handle NetAPIBuffers, which are used to transfer 236 | * structures for some of the Net family of API calls; their memory 237 | * isn't on a user-controlled heap, but is mapped into the current 238 | * application address space in a special way. I've added two 239 | * functions to manage them, but you're responsible for releasing 240 | * them yourself. I could implement a class, but in many cases, a 241 | * call to the API actually performs the allocation for you. The 242 | * two new calls are: 243 | * 244 | * AllocNetAPIBuffer(nSize) Allocates a NetAPIBuffer of at least 245 | * nBytes, and returns a pointer 246 | * to it as an integer. A NULL is returned 247 | * if allocation fails. 248 | * DeAllocNetAPIBuffer(nPtr) Frees the NetAPIBuffer allocated at the 249 | * address specified by nPtr. It returns 250 | * .T./.F. for success and failure 251 | * 252 | * These functions are only available under NT, and will return 253 | * NULL or .F. under Win9x 254 | * 255 | ***** 256 | * Function changes 9/29/2000 257 | * 258 | * NumToDWORD(tnNum) Redirected to NumToLONG() 259 | * NumToLONG(tnNum) Generates a 32 bit LONG from the VFP number, recast 260 | * using BITOR() as needed 261 | * LONGToNum(tcLong) Extracts a signed VFP INTEGER from a 4 byte string 262 | * 263 | ***** 264 | * That's it for the docs to date; more stuff to come. The code below 265 | * is copyright Ed Rauh, 1999; you may use it without royalties in 266 | * your own code as you see fit, as long as the code is attributed to me. 267 | * 268 | * This is provided as-is, with no implied warranty. Be aware that you 269 | * can hurt yourself with this code, most * easily when using the 270 | * SetMem(), GetMem() and GetMemString() functions. I will continue to 271 | * add features and functions to this periodically. If you find a bug, 272 | * please notify me. It does no good to tell me that "It doesn't work 273 | * the way I think it should..WAAAAH!" I need to know exactly how things 274 | * fail to work with the code I supplied. A small code snippet that can 275 | * be used to test the failure would be most helpful in trying 276 | * to track down miscues. I'm not going to run through hundreds or 277 | * thousands of lines of code to try to track down where exactly 278 | * something broke. 279 | * 280 | * Please post questions regarding this code on Universal Thread; I go out 281 | * there regularly and will generally respond to questions posed in the 282 | * message base promptly (not the Chat). http://www.universalthread.com 283 | * In addition to me, there are other API experts who frequent UT, and 284 | * they may well be able to help, in many cases better than I could. 285 | * Posting questions on UT helps not only with getting support 286 | * from the VFP community at large, it also makes the information about 287 | * the problem and its solution available to others who might have the 288 | * same or similar problems. 289 | * 290 | * Other than by UT, especially if you have to send files to help 291 | * diagnose the problem, send them to me at edrauh@earthlink.net or 292 | * erauh@snet.net, preferably the earthlink.net account. 293 | * 294 | * If you have questions about this code, you can ask. If you have 295 | * questions about using it with API calls and the like, you can ask. 296 | * If you have enhancements that you'd like to see added to the code, 297 | * you can ask, but you have the source, and ought to add them yourself. 298 | * Flames will be ignored. I'll try to answer promptly, but realize 299 | * that support and enhancements for this are done in my own spare time. 300 | * If you need specific support that goes beyond what I feel is 301 | * reasonable, I'll tell you. 302 | * 303 | * Do not call me at home or work for support. Period. 304 | * 305 | * 306 | * Feel free to modify this code to fit your specific needs. Since 307 | * I'm not providing any warranty with this in any case, if you change 308 | * it and it breaks, you own both pieces. 309 | * 310 | DEFINE CLASS heap AS custom 311 | 312 | 313 | PROTECTED inHandle, inNumAllocsActive,iaAllocs[1,3] 314 | inHandle = NULL 315 | inNumAllocsActive = 0 316 | iaAllocs = NULL 317 | Name = "heap" 318 | 319 | PROCEDURE Alloc 320 | * Allocate a block, returning a pointer to it 321 | LPARAMETER nSize 322 | DECLARE INTEGER HeapAlloc IN WIN32API AS HAlloc; 323 | INTEGER hHeap, ; 324 | INTEGER dwFlags, ; 325 | INTEGER dwBytes 326 | DECLARE INTEGER HeapSize IN WIN32API AS HSize ; 327 | INTEGER hHeap, ; 328 | INTEGER dwFlags, ; 329 | INTEGER lpcMem 330 | LOCAL nPtr 331 | WITH this 332 | nPtr = HAlloc(.inHandle, 0, @nSize) 333 | IF nPtr # 0 334 | * Bump the allocation array 335 | .inNumAllocsActive = .inNumAllocsActive + 1 336 | DIMENSION .iaAllocs[.inNumAllocsActive,3] 337 | * Pointer 338 | .iaAllocs[.inNumAllocsActive,1] = nPtr 339 | * Size actually allocated - get with HeapSize() 340 | .iaAllocs[.inNumAllocsActive,2] = HSize(.inHandle, 0, nPtr) 341 | * It's alive...alive I tell you! 342 | .iaAllocs[.inNumAllocsActive,3] = .T. 343 | ELSE 344 | * HeapAlloc() failed - return a NULL for the pointer 345 | nPtr = NULL 346 | ENDIF 347 | ENDWITH 348 | RETURN nPtr 349 | ENDPROC 350 | 351 | * new methods added 2/11-2/12; pretty simple, actually, but they make 352 | * coding using the heap object much cleaner. In case it isn't clear, 353 | * what I refer to as a BString is just the normal view of a VFP string 354 | * variable; it's any array of char with an explicit length, as opposed 355 | * to the normal CString view of the world, which has an explicit 356 | * terminator (the null char at the end.) 357 | 358 | FUNCTION AllocBLOB 359 | * Allocate a block of memory the size of the BString passed. The 360 | * allocation will be at least LEN(cBStringToCopy) off the heap. 361 | LPARAMETER cBStringToCopy 362 | LOCAL nAllocPtr 363 | WITH this 364 | nAllocPtr = .Alloc(LEN(cBStringToCopy)) 365 | IF ! ISNULL(nAllocPtr) 366 | .CopyTo(nAllocPtr,cBStringToCopy) 367 | ENDIF 368 | ENDWITH 369 | RETURN nAllocPtr 370 | ENDFUNC 371 | 372 | FUNCTION AllocString 373 | * Allocate a block of memory to fill with a null-terminated string 374 | * make a null-terminated string by appending CHR(0) to the end 375 | * Note - I don't check if a null character precedes the end of the 376 | * inbound string, so if there's an embedded null and whatever is 377 | * using the block works with CStrings, it might bite you. 378 | LPARAMETER cString 379 | RETURN this.AllocBLOB(cString + CHR(0)) 380 | ENDFUNC 381 | 382 | FUNCTION AllocInitAs 383 | * Allocate a block of memory preinitialized to CHR(nByteValue) 384 | LPARAMETER nSizeOfBuffer, nByteValue 385 | IF TYPE('nByteValue') # 'N' OR ! BETWEEN(nByteValue,0,255) 386 | * Default to initialize with nulls 387 | nByteValue = 0 388 | ENDIF 389 | RETURN this.AllocBLOB(REPLICATE(CHR(nByteValue),nSizeOfBuffer)) 390 | ENDFUNC 391 | 392 | * This is the end of the new methods added 2/12/99 393 | 394 | PROCEDURE DeAlloc 395 | * Discard a previous Allocated block 396 | LPARAMETER nPtr 397 | DECLARE INTEGER HeapFree IN WIN32API AS HFree ; 398 | INTEGER hHeap, ; 399 | INTEGER dwFlags, ; 400 | INTEGER lpMem 401 | LOCAL nCtr 402 | * Change to use .FindAllocID() and return !ISNULL() 9/29/2000 EMR 403 | nCtr = NULL 404 | WITH this 405 | nCtr = .FindAllocID(nPtr) 406 | IF ! ISNULL(nCtr) 407 | =HFree(.inHandle, 0, nPtr) 408 | .iaAllocs[nCtr,3] = .F. 409 | ENDIF 410 | ENDWITH 411 | RETURN ! ISNULL(nCtr) 412 | ENDPROC 413 | 414 | 415 | PROCEDURE CopyTo 416 | * Copy a VFP string into a block 417 | LPARAMETER nPtr, cSource 418 | * ReDECLARE RtlMoveMemory to make copy parameters easy 419 | DECLARE RtlMoveMemory IN WIN32API AS RtlCopy ; 420 | INTEGER nDestBuffer, ; 421 | STRING @pVoidSource, ; 422 | INTEGER nLength 423 | LOCAL nCtr 424 | nCtr = NULL 425 | * Change to use .FindAllocID() and return ! ISNULL() 9/29/2000 EMR 426 | IF TYPE('nPtr') = 'N' AND TYPE('cSource') $ 'CM' ; 427 | AND ! (ISNULL(nPtr) OR ISNULL(cSource)) 428 | WITH this 429 | * Find the Allocation pointed to by nPtr 430 | nCtr = .FindAllocID(nPtr) 431 | IF ! ISNULL(nCtr) 432 | * Copy the smaller of the buffer size or the source string 433 | =RtlCopy((.iaAllocs[nCtr,1]), ; 434 | cSource, ; 435 | MIN(LEN(cSource),.iaAllocs[nCtr,2])) 436 | ENDIF 437 | ENDWITH 438 | ENDIF 439 | RETURN ! ISNULL(nCtr) 440 | ENDPROC 441 | 442 | 443 | PROCEDURE CopyFrom 444 | * Copy the content of a buffer back to the VFP world 445 | LPARAMETER nPtr 446 | * Note that we reDECLARE RtlMoveMemory to make passing things easier 447 | DECLARE RtlMoveMemory IN WIN32API AS RtlCopy ; 448 | STRING @DestBuffer, ; 449 | INTEGER pVoidSource, ; 450 | INTEGER nLength 451 | LOCAL nCtr, uBuffer 452 | uBuffer = NULL 453 | nCtr = NULL 454 | * Change to use .FindAllocID() and return NULL 9/29/2000 EMR 455 | IF TYPE('nPtr') = 'N' AND ! ISNULL(nPtr) 456 | WITH this 457 | * Find the allocation whose address is nPtr 458 | nCtr = .FindAllocID(nPtr) 459 | IF ! ISNULL(nCtr) 460 | * Allocate a buffer in VFP big enough to receive the block 461 | uBuffer = REPL(CHR(0),.iaAllocs[nCtr,2]) 462 | =RtlCopy(@uBuffer, ; 463 | (.iaAllocs[nCtr,1]), ; 464 | (.iaAllocs[nCtr,2])) 465 | ENDIF 466 | ENDWITH 467 | ENDIF 468 | RETURN uBuffer 469 | ENDPROC 470 | 471 | PROTECTED FUNCTION FindAllocID 472 | * Search for iaAllocs entry matching the pointer 473 | * passed to the function. If found, it returns the 474 | * element ID; returns NULL if not found 475 | LPARAMETER nPtr 476 | LOCAL nCtr 477 | WITH this 478 | FOR nCtr = 1 TO .inNumAllocsActive 479 | IF .iaAllocs[nCtr,1] = nPtr AND .iaAllocs[nCtr,3] 480 | EXIT 481 | ENDIF 482 | ENDFOR 483 | RETURN IIF(nCtr <= .inNumAllocsActive,nCtr,NULL) 484 | ENDWITH 485 | ENDPROC 486 | 487 | PROCEDURE SizeOfBlock 488 | * Retrieve the actual memory size of an allocated block 489 | LPARAMETERS nPtr 490 | LOCAL nCtr, nSizeOfBlock 491 | nSizeOfBlock = NULL 492 | * Change to use .FindAllocID() and return NULL 9/29/2000 EMR 493 | WITH this 494 | * Find the allocation whose address is nPtr 495 | nCtr = .FindAllocID(nPtr) 496 | RETURN IIF(ISNULL(nCtr),NULL,.iaAllocs[nCtr,2]) 497 | ENDWITH 498 | ENDPROC 499 | 500 | PROCEDURE Destroy 501 | DECLARE HeapDestroy IN WIN32API AS HDestroy ; 502 | INTEGER hHeap 503 | 504 | LOCAL nCtr 505 | WITH this 506 | FOR nCtr = 1 TO .inNumAllocsActive 507 | IF .iaAllocs[nCtr,3] 508 | .Dealloc(.iaAllocs[nCtr,1]) 509 | ENDIF 510 | ENDFOR 511 | HDestroy[.inHandle] 512 | ENDWITH 513 | DODEFAULT() 514 | ENDPROC 515 | 516 | 517 | PROCEDURE Init 518 | DECLARE INTEGER HeapCreate IN WIN32API AS HCreate ; 519 | INTEGER dwOptions, ; 520 | INTEGER dwInitialSize, ; 521 | INTEGER dwMaxSize 522 | #DEFINE SwapFilePageSize 4096 523 | #DEFINE BlockAllocSize 2 * SwapFilePageSize 524 | WITH this 525 | .inHandle = HCreate(0, BlockAllocSize, 0) 526 | DIMENSION .iaAllocs[1,3] 527 | .iaAllocs[1,1] = 0 528 | .iaAllocs[1,2] = 0 529 | .iaAllocs[1,3] = .F. 530 | .inNumAllocsActive = 0 531 | ENDWITH 532 | RETURN (this.inHandle # 0) 533 | ENDPROC 534 | 535 | 536 | ENDDEFINE 537 | * 538 | *-- EndDefine: heap 539 | ************************************************** 540 | * 541 | * Additional functions for working with structures and pointers and stuff 542 | * 543 | FUNCTION SetMem 544 | LPARAMETERS nPtr, cSource 545 | * Copy cSource to the memory location specified by nPtr 546 | * ReDECLARE RtlMoveMemory to make copy parameters easy 547 | * nPtr is not validated against legal allocations on the heap 548 | DECLARE RtlMoveMemory IN WIN32API AS RtlCopy ; 549 | INTEGER nDestBuffer, ; 550 | STRING @pVoidSource, ; 551 | INTEGER nLength 552 | 553 | RtlCopy(nPtr, ; 554 | cSource, ; 555 | LEN(cSource)) 556 | RETURN .T. 557 | 558 | FUNCTION GetMem 559 | LPARAMETERS nPtr, nLen 560 | * Copy the content of a memory block at nPtr for nLen bytes back to a VFP string 561 | * Note that we ReDECLARE RtlMoveMemory to make passing things easier 562 | * nPtr is not validated against legal allocations on the heap 563 | DECLARE RtlMoveMemory IN WIN32API AS RtlCopy ; 564 | STRING @DestBuffer, ; 565 | INTEGER pVoidSource, ; 566 | INTEGER nLength 567 | LOCAL uBuffer 568 | * Allocate a buffer in VFP big enough to receive the block 569 | uBuffer = REPL(CHR(0),nLen) 570 | =RtlCopy(@uBuffer, ; 571 | nPtr, ; 572 | nLen) 573 | RETURN uBuffer 574 | 575 | FUNCTION GetMemString 576 | LPARAMETERS nPtr, nSize 577 | * Copy the string at location nPtr into a VFP string 578 | * We're going to use lstrcpyn rather than RtlMoveMemory to copy up to a terminating null 579 | * nPtr is not validated against legal allocations on the heap 580 | * 581 | * Change 9/29/2000 - second optional parameter nSize added to allow an override 582 | * of the string length; no major expense, but probably an open invitation 583 | * to cliff-diving, since variant CStrings longer than 511 bytes, or less 584 | * often, 254 bytes, will generally fall down go Boom! 585 | * 586 | DECLARE INTEGER lstrcpyn IN WIN32API AS StrCpyN ; 587 | STRING @ lpDestString, ; 588 | INTEGER lpSource, ; 589 | INTEGER nMaxLength 590 | LOCAL uBuffer 591 | IF TYPE('nSize') # 'N' OR ISNULL(nSize) 592 | nSize = 512 593 | ENDIF 594 | * Allocate a buffer big enough to receive the data 595 | uBuffer = REPL(CHR(0), nSize) 596 | IF StrCpyN(@uBuffer, nPtr, nSize-1) # 0 597 | uBuffer = LEFT(uBuffer, MAX(0,AT(CHR(0),uBuffer) - 1)) 598 | ELSE 599 | uBuffer = NULL 600 | ENDIF 601 | RETURN uBuffer 602 | 603 | FUNCTION SHORTToNum 604 | * Converts a 16 bit signed integer in a structure to a VFP Numeric 605 | LPARAMETER tcInt 606 | LOCAL b0,b1,nRetVal 607 | b0=asc(tcInt) 608 | b1=asc(subs(tcInt,2,1)) 609 | if b1<128 610 | * 611 | * positive - do a straight conversion 612 | * 613 | nRetVal=b1 * 256 + b0 614 | else 615 | * 616 | * negative value - take twos complement and negate 617 | * 618 | b1=255-b1 619 | b0=256-b0 620 | nRetVal= -( (b1 * 256) + b0) 621 | endif 622 | return nRetVal 623 | 624 | FUNCTION NumToSHORT 625 | * 626 | * Creates a C SHORT as a string from a number 627 | * 628 | * Parameters: 629 | * 630 | * tnNum (R) Number to convert 631 | * 632 | LPARAMETER tnNum 633 | * 634 | * b0, b1, x hold small ints 635 | * 636 | LOCAL b0,b1,x 637 | IF tnNum>=0 638 | x=INT(tnNum) 639 | b1=INT(x/256) 640 | b0=MOD(x,256) 641 | ELSE 642 | x=INT(-tnNum) 643 | b1=255-INT(x/256) 644 | b0=256-MOD(x,256) 645 | IF b0=256 646 | b0=0 647 | b1=b1+1 648 | ENDIF 649 | ENDIF 650 | RETURN CHR(b0)+CHR(b1) 651 | 652 | FUNCTION DWORDToNum 653 | * Take a binary DWORD and convert it to a VFP Numeric 654 | * use this to extract an embedded pointer in a structure in a string to an nPtr 655 | LPARAMETER tcDWORD 656 | LOCAL b0,b1,b2,b3 657 | b0=asc(tcDWORD) 658 | b1=asc(subs(tcDWORD,2,1)) 659 | b2=asc(subs(tcDWORD,3,1)) 660 | b3=asc(subs(tcDWORD,4,1)) 661 | RETURN ( ( (b3 * 256 + b2) * 256 + b1) * 256 + b0) 662 | 663 | *!* FUNCTION NumToDWORD 664 | *!* * 665 | *!* * Creates a 4 byte binary string equivalent to a C DWORD from a number 666 | *!* * use to embed a pointer or other DWORD in a structure 667 | *!* * Parameters: 668 | *!* * 669 | *!* * tnNum (R) Number to convert 670 | *!* * 671 | *!* LPARAMETER tnNum 672 | *!* * 673 | *!* * x,n,i,b[] will hold small ints 674 | *!* * 675 | *!* LOCAL x,n,i,b[4] 676 | *!* x=INT(tnNum) 677 | *!* FOR i=3 TO 0 STEP -1 678 | *!* b[i+1]=INT(x/(256^i)) 679 | *!* x=MOD(x,(256^i)) 680 | *!* ENDFOR 681 | *!* RETURN CHR(b[1])+CHR(b[2])+CHR(b[3])+CHR(b[4]) 682 | * Redirected to NumToLong() using recasting; comment out 683 | * the redirection and uncomment NumToDWORD() if original is needed 684 | FUNCTION NumToDWORD 685 | LPARAMETER tnNum 686 | RETURN NumToLong(tnNum) 687 | * End redirection 688 | 689 | FUNCTION WORDToNum 690 | * Take a binary WORD (16 bit USHORT) and convert it to a VFP Numeric 691 | LPARAMETER tcWORD 692 | RETURN (256 * ASC(SUBST(tcWORD,2,1)) ) + ASC(tcWORD) 693 | 694 | FUNCTION NumToWORD 695 | * 696 | * Creates a C USHORT (WORD) from a number 697 | * 698 | * Parameters: 699 | * 700 | * tnNum (R) Number to convert 701 | * 702 | LPARAMETER tnNum 703 | * 704 | * x holds an int 705 | * 706 | LOCAL x 707 | x=INT(tnNum) 708 | RETURN CHR(MOD(x,256))+CHR(INT(x/256)) 709 | 710 | FUNCTION NumToLong 711 | * 712 | * Creates a C LONG (signed 32-bit) 4 byte string from a number 713 | * NB: this works faster than the original NumToDWORD(), which could have 714 | * problems with trunaction of values > 2^31 under some versions of VFP with 715 | * #DEFINEd or converted constant values in excess of 2^31-1 (0x7FFFFFFF). 716 | * I've redirected NumToDWORD() and commented it out; NumToLong() 717 | * expects to work with signed values and uses BITOR() to recast values 718 | * in the range of -(2^31) to (2^31-1), 0xFFFFFFFF is not the same 719 | * as -1 when represented in an N-type field. If you don't need to 720 | * use constants with the high-order bit set, or are willing to let 721 | * the UDF cast the value consistently, especially using pointer math 722 | * on the system's part of the address space, this and its counterpart 723 | * LONGToNum() are the better choice for speed, or to save to an I-field. 724 | * 725 | * To properly cast a constant/value with the high-order bit set, you 726 | * can BITOR(nVal,0); 0xFFFFFFFF # -1 but BITOR(0xFFFFFFFF,0) = BITOR(-1,0) 727 | * is true, and converts the N-type in the range 2^31 - (2^32-1) to a 728 | * twos-complement negative integer value. You can disable BITOR() casting 729 | * in this function by commenting the proper line in this UDF(); this 730 | * results in a slight speed increase. 731 | * 732 | * Parameters: 733 | * 734 | * tnNum (R) Number to convert 735 | * 736 | LPARAMETER tnNum 737 | DECLARE RtlMoveMemory IN WIN32API AS RtlCopyLong ; 738 | STRING @pDestString, ; 739 | INTEGER @pVoidSource, ; 740 | INTEGER nLength 741 | LOCAL cString 742 | cString = SPACE(4) 743 | * Function call not using BITOR() 744 | * =RtlCopyLong(@cString, tnNum, 4) 745 | * Function call using BITOR() to cast numerics 746 | =RtlCopyLong(@cString, BITOR(tnNum,0), 4) 747 | RETURN cString 748 | 749 | FUNCTION LongToNum 750 | * 751 | * Converts a 32 bit LONG to a VFP numeric; it treats the result as a 752 | * signed value, with a range -2^31 - (2^31-1). This is faster than 753 | * DWORDToNum(). There is no one-function call that causes negative 754 | * values to recast as positive values from 2^31 - (2^32-1) that I've 755 | * found that doesn't take a speed hit. 756 | * 757 | * Parameters: 758 | * 759 | * tcLong (R) 4 byte string containing the LONG 760 | * 761 | LPARAMETER tcLong 762 | DECLARE RtlMoveMemory IN WIN32API AS RtlCopyLong ; 763 | INTEGER @ DestNum, ; 764 | STRING @ pVoidSource, ; 765 | INTEGER nLength 766 | LOCAL nNum 767 | nNum = 0 768 | =RtlCopyLong(@nNum, tcLong, 4) 769 | RETURN nNum 770 | 771 | FUNCTION AllocNetAPIBuffer 772 | * 773 | * Allocates a NetAPIBuffer at least nBtes in Size, and returns a pointer 774 | * to it as an integer. A NULL is returned if allocation fails. 775 | * The API call is not supported under Win9x 776 | * 777 | * Parameters: 778 | * 779 | * nSize (R) Number of bytes to allocate 780 | * 781 | LPARAMETER nSize 782 | IF TYPE('nSize') # 'N' OR nSize <= 0 783 | * Invalid argument passed, so return a null 784 | RETURN NULL 785 | ENDIF 786 | IF ! 'NT' $ OS() 787 | * API call only supported under NT, so return failure 788 | RETURN NULL 789 | ENDIF 790 | DECLARE INTEGER NetApiBufferAllocate IN NETAPI32.DLL ; 791 | INTEGER dwByteCount, ; 792 | INTEGER lpBuffer 793 | LOCAL nBufferPointer 794 | nBufferPointer = 0 795 | IF NetApiBufferAllocate(INT(nSize), @nBufferPointer) # 0 796 | * The call failed, so return a NULL value 797 | nBufferPointer = NULL 798 | ENDIF 799 | RETURN nBufferPointer 800 | 801 | FUNCTION DeAllocNetAPIBuffer 802 | * 803 | * Frees the NetAPIBuffer allocated at the address specified by nPtr. 804 | * The API call is not supported under Win9x 805 | * 806 | * Parameters: 807 | * 808 | * nPtr (R) Address of buffer to free 809 | * 810 | * Returns: .T./.F. 811 | * 812 | LPARAMETER nPtr 813 | IF TYPE('nPtr') # 'N' 814 | * Invalid argument passed, so return failure 815 | RETURN .F. 816 | ENDIF 817 | IF ! 'NT' $ OS() 818 | * API call only supported under NT, so return failure 819 | RETURN .F. 820 | ENDIF 821 | DECLARE INTEGER NetApiBufferFree IN NETAPI32.DLL ; 822 | INTEGER lpBuffer 823 | RETURN (NetApiBufferFree(INT(nPtr)) = 0) 824 | 825 | Function CopyDoubleToString 826 | LPARAMETER nDoubleToCopy 827 | * ReDECLARE RtlMoveMemory to make copy parameters easy 828 | DECLARE RtlMoveMemory IN WIN32API AS RtlCopyDbl ; 829 | STRING @DestString, ; 830 | DOUBLE @pVoidSource, ; 831 | INTEGER nLength 832 | LOCAL cString 833 | cString = SPACE(8) 834 | =RtlCopyDbl(@cString, nDoubleToCopy, 8) 835 | RETURN cString 836 | 837 | FUNCTION DoubleToNum 838 | LPARAMETER cDoubleInString 839 | DECLARE RtlMoveMemory IN WIN32API AS RtlCopyDbl ; 840 | DOUBLE @DestNumeric, ; 841 | STRING @pVoidSource, ; 842 | INTEGER nLength 843 | LOCAL nNum 844 | * Christof Lange pointed out that there's a feature of VFP that results 845 | * in the entry in the NTI retaining its precision after updating the value 846 | * directly; force the resulting precision to a large value before moving 847 | * data into the temp variable 848 | nNum = 0.000000000000000000 849 | =RtlCopyDbl(@nNum, cDoubleInString, 8) 850 | RETURN nNum -------------------------------------------------------------------------------- /avfp5.53_source/reports/pdfrun.PJT: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/claudefox/ActiveVFP/28ada3cd4b268635e3bcd67ea842ec522c3def82/avfp5.53_source/reports/pdfrun.PJT -------------------------------------------------------------------------------- /avfp5.53_source/reports/pdfrun.pjx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/claudefox/ActiveVFP/28ada3cd4b268635e3bcd67ea842ec522c3def82/avfp5.53_source/reports/pdfrun.pjx -------------------------------------------------------------------------------- /avfp6.03_source/..svnbridge/ActiveVFP.pjt: -------------------------------------------------------------------------------- 1 | svn:mime-typeapplication/octet-stream -------------------------------------------------------------------------------- /avfp6.03_source/..svnbridge/ActiveVFP.pjx: -------------------------------------------------------------------------------- 1 | svn:mime-typeapplication/octet-stream -------------------------------------------------------------------------------- /avfp6.03_source/ActiveVFP.pjt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/claudefox/ActiveVFP/28ada3cd4b268635e3bcd67ea842ec522c3def82/avfp6.03_source/ActiveVFP.pjt -------------------------------------------------------------------------------- /avfp6.03_source/ActiveVFP.pjx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/claudefox/ActiveVFP/28ada3cd4b268635e3bcd67ea842ec522c3def82/avfp6.03_source/ActiveVFP.pjx -------------------------------------------------------------------------------- /avfp6.03_source/HTTP Handler/App_Code/AVFPHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Web; 3 | using System.Web.UI; 4 | using System.Web.SessionState; 5 | using activevfp_dotnetproxy; 6 | public class AVFPHandler : Page, IHttpAsyncHandler, IRequiresSessionState 7 | { 8 | 9 | 10 | 11 | public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback callback, object extraData) 12 | { 13 | 14 | return AspCompatBeginProcessRequest(context, callback, extraData); 15 | 16 | } 17 | 18 | 19 | 20 | public void EndProcessRequest(IAsyncResult result) 21 | { 22 | 23 | AspCompatEndProcessRequest(result); 24 | 25 | } 26 | 27 | 28 | 29 | /// 30 | 31 | /// Overrides Page.OnInit which is called as part of Async callbacks 32 | 33 | /// 34 | 35 | /// 36 | 37 | protected override void OnInit(EventArgs e) 38 | 39 | { 40 | 41 | /// Call my base handler 42 | this.ProcessRequest(HttpContext.Current); 43 | 44 | HttpContext.Current.ApplicationInstance.CompleteRequest(); 45 | 46 | } 47 | 48 | //protected override void OnInit(EventArgs e) 49 | 50 | public void ProcessRequest(HttpContext context) 51 | { 52 | HttpRequest Request = context.Request; 53 | HttpResponse Response = context.Response; 54 | 55 | // This handler is called whenever a file ending 56 | // in .avfp is requested. A file with that extension 57 | // does not need to exist. 58 | 59 | server x; 60 | x = new server(); 61 | try 62 | { 63 | Response.Write(x.Process()); 64 | } 65 | catch (Exception ex) 66 | { 67 | Response.Write("Caught .NET exception, source: " + ex.Source + " message: " + ex.Message); 68 | } 69 | 70 | } 71 | public bool IsReusable 72 | { 73 | // To enable pooling, return true here. 74 | // This keeps the handler in memory. 75 | get { return true; } 76 | } 77 | 78 | 79 | } 80 | 81 | 82 | -------------------------------------------------------------------------------- /avfp6.03_source/prg/dch.prg: -------------------------------------------------------------------------------- 1 | * DCH (Class) 2 | * Dynamic Class Handler 3 | * 4 | * Author: Victor Espina 5 | * Date: May 2012 6 | * 7 | * This class allows to create an instance of a given 8 | * class stored in an external PRG file and then release 9 | * that PRG from memory after being used. 10 | * 11 | * This will allow the PRG to be modified without quiting AVFP. 12 | * 13 | DEFINE CLASS dch AS Custom 14 | * 15 | className = "" 16 | classPRG = "" 17 | Instance = NULL 18 | 19 | PROCEDURE initWithClass(pcClass, pcClassPRG) 20 | THIS.className = pcClass 21 | THIS.classPRG = pcClassPRG 22 | ENDPROC 23 | 24 | PROCEDURE createInstance 25 | IF NOT THIS.Recompile() 26 | RETURN NULL 27 | ENDIF 28 | THIS.Instance = NEWOBJECT(THIS.className, THIS.classPrg) 29 | ENDPROC 30 | 31 | PROCEDURE Recompile 32 | LOCAL cPRG, cFXP, lResult 33 | cPRG = THIS.classPRG 34 | cFXP = FORCEEXT(cPRG, "FXP") 35 | lResult = .T. 36 | IF !FILE(cFXP) OR FDATE(cPRG,1) > FDATE(cFXP,1) 37 | TRY 38 | COMPILE (cPRG) 39 | CATCH TO ex 40 | STRTOFILE(ex.Message, FORCEEXT(cPRG, "TXT")) 41 | lResult = .F. 42 | ENDTRY 43 | ENDIF 44 | RETURN lResult 45 | ENDPROC 46 | 47 | PROCEDURE releaseInstance 48 | THIS.Instance = NULL 49 | CLEAR CLASS (THIS.className) 50 | CLEAR PROGRAM (THIS.classPRG) 51 | CLEAR RESOURCES 52 | ENDPROC 53 | * 54 | ENDDEFINE -------------------------------------------------------------------------------- /avfp6.03_source/prg/json.h: -------------------------------------------------------------------------------- 1 | #DEFINE TOKENTYPE_UNDEFINED 0 2 | #DEFINE TOKENTYPE_OBJECT 1 3 | #DEFINE TOKENTYPE_ARRAY 2 4 | #DEFINE TOKENTYPE_KEY 3 5 | #DEFINE TOKENTYPE_STRING 4 6 | #DEFINE TOKENTYPE_LOGICAL 5 7 | #DEFINE TOKENTYPE_NUMBER 6 8 | #DEFINE TOKENTYPE_DATETIME 8 9 | #DEFINE TOKENTYPE_DATE 9 10 | #DEFINE TOKENTYPE_NULL 10 11 | #DEFINE TOKENTYPE_CURSOR 11 -------------------------------------------------------------------------------- /avfp6.03_source/prg/json.prg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/claudefox/ActiveVFP/28ada3cd4b268635e3bcd67ea842ec522c3def82/avfp6.03_source/prg/json.prg -------------------------------------------------------------------------------- /avfp6.03_source/prg/proxystub.prg: -------------------------------------------------------------------------------- 1 | #DEFINE crlf CHR(13)+CHR(10) 2 | SET STEP ON 3 | oProp=NEWOBJECT('AVFPproperties','activevfp.prg') && create properties shared among classes 4 | oHTML=NEWOBJECT('AVFPhtml','activevfp.prg') 5 | oCookie=NEWOBJECT('AVFPcookie','activevfp.prg') 6 | oProp.ScriptPath=oRequest.servervariables("SCRIPT_NAME") 7 | oProp.SessID=NVL(oRequest.querystring("sid"),"") 8 | oProp.AppStartPath=JUSTPATH(oRequest.ServerVariables("PATH_TRANSLATED"))+[\] &&JUSTPATH(APPLICATION.SERVERNAME)+"\" 9 | oProp.AppName=STREXTRACT(oRequest.ServerVariables("PATH_INFO"),[/],[/]) &&blank if installed to root &&JUSTSTEM(APPLICATION.SERVERNAME) 10 | oProp.RunningPrg=[main.prg] 11 | 12 | lcScript=FILETOSTR(oProp.AppStartPath+'\prg\main.prg') 13 | lcHTMLout= EXECSCRIPT(lcScript) &&main() && run the application 14 | 15 | RETURN lcHTMLout 16 | 17 | 18 | ************************************************************* 19 | DEFINE CLASS server AS ActiveVFP OLEPUBLIC 20 | ************************************************************* 21 | * server :: process 22 | * Last Modified: 12/30/11 23 | * ActiveVFP Version 5.61 24 | ************************************************************* 25 | FUNCTION Process 26 | LOCAL lcHTMLout,lcHTMLfile 27 | 28 | * Base ActiveVFP Objects 29 | oRequest = THIS.oRequest 30 | oSession = THIS.oSession 31 | oResponse = THIS.oResponse 32 | oServer= this.oServer 33 | oApplication=this.oApplication 34 | 35 | oProp=NEWOBJECT('AVFPproperties') && create properties shared among classes 36 | oHTML=NEWOBJECT('AVFPhtml') 37 | oCookie=NEWOBJECT('AVFPcookie') 38 | 39 | * init properties 40 | oProp.ScriptPath=oRequest.servervariables("SCRIPT_NAME") 41 | oProp.SessID=NVL(oRequest.querystring("sid"),"") 42 | oProp.AppStartPath=JUSTPATH(oRequest.ServerVariables("PATH_TRANSLATED"))+[\] &&JUSTPATH(APPLICATION.SERVERNAME)+"\" 43 | oProp.AppName=STREXTRACT(oRequest.ServerVariables("PATH_INFO"),[/],[/]) &&blank if installed to root &&JUSTSTEM(APPLICATION.SERVERNAME) 44 | oProp.RunningPrg=[main.prg] 45 | 46 | 47 | ************************************************************** 48 | * REST-like APIs implementation 49 | * 50 | * Author: Victor Espina 51 | * Date: April 2012 52 | * 53 | ************************************************************** 54 | * Create an instancia of RESTHelper class 55 | LOCAL oRESTHelper, cRootPath 56 | cRootPath = oRequest.serverVariables("APPL_PHYSICAL_PATH") 57 | oRESTHelper = NEWOBJECT("restHelper","PRG\RESTHelper.PRG") 58 | oRESTHelper.setFolder("ROOT", cRootPath) 59 | oRESTHelper.setFolder("CONTROLLERS", ADDBS(cRootPath) + "prg/rest/controllers") 60 | oRESTHelper.loadControllers() 61 | 62 | * Use RESTHelper object to check if the request conforms a REST-like API call. If so, pass 63 | * the request object to RESTHelper in order to let the right resource controller handle it. 64 | IF oRESTHelper.isREST(oRequest) 65 | oProp.appStartPath = oRequest.serverVariables("APPL_PHYSICAL_PATH") 66 | RETURN oRESTHelper.handleRequest(oRequest, oProp) 67 | ENDIF 68 | 69 | * If the request was not a REST-like API call, check if MAIN.PRG exists in 70 | * oProp.appStartPath. If it doesn't, we change oProp.appStartPath to point 71 | * to app's root folder. This will avoid an innecessary "file not found" 72 | * error. 73 | IF NOT FILE(oProp.appStartPath + "\PRG\MAIN.PRG") 74 | oProp.appStartPath = oRequest.serverVariables("APPL_PHYSICAL_PATH") 75 | ENDIF 76 | 77 | * If for some reason we can't find a valid processor, return 78 | * an error message 79 | IF NOT FILE(oProp.AppStartPath+'\prg\main.prg') 80 | RETURN "oRESTHelper: cannot find " + oProp.appStartPath+"\prg\main.prg" 81 | ENDIF 82 | ************************************************************** 83 | 84 | lcScript=FILETOSTR(oProp.AppStartPath+'\prg\main.prg') 85 | lcHTMLout= EXECSCRIPT(lcScript) &&main() && run the application 86 | 87 | RETURN lcHTMLout 88 | 89 | ENDFUNC 90 | 91 | ************************************************************* 92 | * server :: debugger 93 | * Last Modified: 12/30/11 94 | * ActiveVFP Version 5.61 95 | ************************************************************* 96 | FUNCTION Debugger() 97 | LOCAL loFox, lcReturn 98 | lcReturn = "" 99 | 100 | loFox = GETOBJECT(,"visualfoxpro.application.9") 101 | 102 | loFox.SetVar("oRequest",THIS.oRequest) 103 | loFox.SetVar("oSession",THIS.oSession) 104 | loFox.SetVar("oResponse",THIS.oResponse) 105 | loFox.SetVar("oServer",THIS.oServer) 106 | loFox.SetVar("oApplication",THIS.oApplication) 107 | 108 | lcReturn = loFox.eval("proxystub()") 109 | 110 | 111 | RELEASE loFox 112 | RETURN lcReturn 113 | ENDFUNC 114 | 115 | 116 | 117 | ENDDEFINE 118 | 119 | 120 | 121 | 122 | * VictorEspina Feb 6, 2012 123 | * 124 | * VELoadPRG 125 | * Dinamically loads a given PRG. This routines try to find the given 126 | * PRG name in the request's PRG folder or the App's main PRG folder. 127 | * 128 | PROCEDURE VELoadPRG(pcName, poProp, poRequest) 129 | * 130 | LOCAL lcScript 131 | lcScript = ADDBS(poProp.AppStartPath) + "prg\" + pcName 132 | IF NOT FILE(lcScript) 133 | lcScript = ADDBS(poRequest.serverVariables("APPL_PHYSICAL_PATH")) + "prg\" + pcName 134 | ENDIF 135 | IF FILE(lcScript) 136 | lcScript = FILETOSTR(lcScript) 137 | ELSE 138 | lcScript = "RETURN 'File " + pcName + ".prg could not be found.'" 139 | ENDIF 140 | 141 | RETURN lcScript 142 | * 143 | ENDPROC -------------------------------------------------------------------------------- /avfp6.03_source/prg/resthelper.prg: -------------------------------------------------------------------------------- 1 | * restHelper.prg 2 | * Helper class that allow an easy implementation of REST-like calls 3 | * within ActiveVFP 4 | * 5 | * Author : Victor Espina 6 | * Version: 1.0 7 | * 8 | * VERSION HISTORY 9 | * 10 | * DATE VERSION DESCRIPTION 11 | * ========= =========== ================================ 12 | * Apr 2012 1.0 Initial version 13 | * Aug 2012 1.1 CKF Custom methods for MVC 14 | 15 | * Test code 16 | LOCAL oRESTHelper 17 | oRESTHelper = CREATEOBJECT("restHElper") 18 | oRESTHelper.setFolder("ROOT","c:\vfp5.61demo\") 19 | oRESTHelper.setFolder("CONTROLLERS","c:\avfp5.61demo\prg\rest\controllers\") 20 | oRESTHelper.loadControllers() 21 | ?oRESTHelper.handleRequest("/avfp5.61demo/users/") 22 | 23 | 24 | RETURN 25 | 26 | 27 | DEFINE CLASS restHelper AS Custom 28 | * 29 | Folders = NULL 30 | Controllers = NULL 31 | 32 | * Constructor 33 | * 34 | PROCEDURE Init 35 | * 36 | THIS.Folders = CREATEOBJECT("Dictionary") 37 | THIS.Folders.Add("ROOT","") 38 | THIS.Folders.Add("CONTROLLERS","") 39 | 40 | THIS.Controllers = CREATEOBJECT("Dictionary") 41 | * 42 | ENDPROC 43 | 44 | 45 | * setFolder 46 | * Sets a folder location 47 | * 48 | PROCEDURE setFolder(pcFolderID, pcFolderPath) 49 | THIS.Folders.Values[pcFolderId] = ADDBS(CHRTRAN(pcFolderPath,"/","\")) 50 | ENDPROC 51 | 52 | 53 | * loadControllers 54 | * Look for controllers in the controller's folder 55 | * 56 | PROCEDURE loadControllers 57 | * 58 | LOCAL ARRAY aControllers[1] 59 | LOCAL cPath,cFile,cController,nCount,i 60 | cPath = THIS.Folders.Values["CONTROLLERS"] 61 | nCount = ADIR(aControllers, cPath + "*.PRG") 62 | THIS.Controllers.Clear() 63 | FOR i = 1 TO nCount 64 | cFile = ADDBS(cPath) + aControllers[i,1] 65 | cController = LOWER(JUSTSTEM(cFile)) 66 | THIS.Controllers.Add(cController, cFile) 67 | ENDFOR 68 | * 69 | ENDPROC 70 | 71 | 72 | * isREST 73 | * Check if the given request is a RESTful request. A request is considered 74 | * a REST-compliant request if: 75 | * 76 | * a) Does not contains a file extension 77 | * b) Does not contains a ? sign 78 | * c) The URL conforms to the form http://server/resource/ 79 | * 80 | PROCEDURE isREST(poRequest) 81 | * 82 | LOCAL cUri 83 | IF VARTYPE(poRequest)<>"C" 84 | cUri = poRequest.serverVariables("SCRIPT_NAME") 85 | ELSE 86 | cUri = poREquest 87 | ENDIF 88 | 89 | * Basic syntax check 90 | IF !EMPTY(JUSTEXT(cUri)) OR AT("?",cUri)<>0 91 | RETURN .F. 92 | ENDIF 93 | 94 | * Check if URI contains a reference to an available resource controller 95 | LOCAL lHasController,i 96 | lHasController = .F. 97 | FOR i = 1 TO THIS.Controllers.Count 98 | IF ATC("/" + THIS.Controllers.Keys[i], cUri) > 0 &&IF ATC("/" + THIS.Controllers.Keys[i] + "/", cUri) > 0 99 | lHasController = .T. 100 | EXIT 101 | ENDIF 102 | ENDFOR 103 | IF NOT lHasController 104 | RETURN .F. 105 | ENDIF 106 | 107 | * If we get through here, then the uri MAY be a REST api call 108 | RETURN .T. 109 | * 110 | ENDPROC 111 | 112 | 113 | * handleRequest 114 | * Handle a given HTTP request 115 | * 116 | PROCEDURE handleRequest(poRequest, poProps) 117 | * 118 | * Analyze the requested URL to obtain: 119 | * a) VERB 120 | * b) Resource controller 121 | * c) Resource's parameters 122 | * 123 | LOCAL cUri,cRESTUri,cVerb,cResource,cParams,i,j,cController,cBaseURL 124 | IF VARTYPE(poRequest)<>"C" 125 | cUri = poRequest.serverVariables("SCRIPT_NAME") 126 | cVerb = poRequest.serverVariables("REQUEST_METHOD") 127 | ELSE 128 | cUri = poRequest 129 | cVerb = "GET" 130 | ENDIF 131 | 132 | j = 0 133 | cResource = "" 134 | cController = "" 135 | FOR i = 1 TO THIS.Controllers.Count 136 | cResource = THIS.Controllers.Keys[i] 137 | cController = THIS.Controllers.Values[i] 138 | IF ATC(cResource, cUri) > 0 139 | j = ATC("/" + cResource, cUri) &&ATC("/" + cResource + "/", cUri) 140 | IF j > 0 141 | EXIT 142 | ENDIF 143 | ENDIF 144 | ENDFOR 145 | IF EMPTY(cResource) && There is no controller for the specified resource 146 | RETURN "restHelper: unhandled resource on REST call (" + cUri + ")" 147 | ENDIF 148 | IF j = 0 && Invalid REST call 149 | RETURN "restHelper: unrecognized REST call (" + cUri + ")" 150 | ENDIF 151 | 152 | cBaseURL = LEFT(cUri, j - 1) 153 | cRESTUri = SUBSTR(cUri,j) && /server/resource/params --> /resource/params 154 | cParams = SUBSTR(cRESTUri,LEN(cResource) + 3) 155 | 156 | * Convert the parameter list to a collection 157 | LOCAL ARRAY aParams[1] 158 | LOCAL nCount, cPAram 159 | LOCAL oParams AS Collection 160 | nCount = ALINES(aParams, STRT(cParams,"/",CHR(13)+CHR(10))) 161 | oParams = CREATEOBJECT("Collection") 162 | FOR EACH cParam IN aParams 163 | IF !EMPTY(cParam) 164 | oParams.Add(cParam) 165 | ENDIF 166 | ENDFOR 167 | 168 | 169 | * Use the verb + parameter count to deduce the actual action 170 | * to be invoked on the controller 171 | * 172 | LOCAL cAction 173 | cAction = "" 174 | DO CASE 175 | CASE cVerb == "GET" AND oParams.Count = 1 AND LOWER(oParams.Item[1]) == "info" 176 | cAction = "infoAction" 177 | 178 | CASE cVerb == "GET" AND oParams.Count = 1 AND LOWER(oParams.Item[1]) == "help" 179 | cAction = "helpAction" 180 | 181 | CASE cVerb == "GET" AND oParams.Count = 0 182 | cAction = "listAction" 183 | 184 | CASE cVerb == "GET" AND oParams.Count > 0 AND !(ISALPHA(oParams.Item[1])) 185 | cAction = "getAction" 186 | 187 | CASE cVerb == "POST" AND oParams.Count = 0 188 | cAction = "addAction" 189 | 190 | CASE cVerb == "POST" AND oParams.Count > 0 191 | cAction = "updAction" 192 | 193 | CASE cVerb == "DELETE" AND oParams.Count = 0 194 | cAction = "zapAction" 195 | 196 | CASE cVerb == "DELETE" AND oPArams.Count > 0 197 | cAction = "dropAction" 198 | 199 | OTHERWISE 200 | cAction = oParams.Item[1] &&"customAction" 201 | ENDCASE 202 | IF EMPTY(cAction) 203 | RETURN "restHelper: unrecognized REST call (" + cRESTUri + ")" 204 | ENDIF 205 | 206 | * Create a instance of the resource's controller 207 | LOCAL oDCH,oController,cHTMLOut 208 | IF NOT FILE(cController) 209 | RETURN "restHelper: controller file " + cController + " could not be found" 210 | ENDIF 211 | 212 | oDCH = NEWOBJECT("dch","prg\dch.prg") 213 | oDCH.initWithClass(cResource + "Controller", cController) 214 | IF NOT oDCH.createInstance() 215 | RETURN "restHelper: controller " + cController + " has some errors:
" + FILETOSTR(FORCEEXT(cController,"TXT")) 216 | ENDIF 217 | 218 | oController = oDCH.Instance 219 | cHTMLOut = "" 220 | TRY 221 | oController.Request = poRequest 222 | oController.Props = poProps 223 | oController.Params = oParams 224 | oController.homeFolder = ADDBS(JUSTPATH(cController)) 225 | oController.baseURL = cBaseURL 226 | 227 | IF PEMSTATUS(oController, cAction, 5) 228 | cHTMLOut = EVALUATE("oController." + cAction + "()") 229 | ELSE 230 | cHTMLOut = "restHelper: the " + PROPER(cResource) + "'s controller does not implement the requested action (" + cAction + ")" 231 | ENDIF 232 | 233 | CATCH TO ex 234 | cHTMLOut = "restHelper: error while processing the request " + cRESTUri + ":
" + ; 235 | ex.Message + "
" + cController 236 | 237 | FINALLY 238 | oController = NULL 239 | oDCH.releaseInstance() 240 | 241 | ENDTRY 242 | 243 | RETURN cHTMLOut 244 | * 245 | ENDPROC 246 | 247 | 248 | * compileController 249 | * Recompile a controller PRG (only if needed) 250 | * 251 | PROCEDURE compileController(pcPRG) 252 | * 253 | LOCAL cFXP, lResult 254 | cFXP = FORCEEXT(pcPRG, "FXP") 255 | lResult = .T. 256 | IF !FILE(cFXP) OR FDATE(pcPRG,1) > FDATE(cFXP,1) 257 | TRY 258 | COMPILE (pcPRG) 259 | 260 | CATCH TO ex 261 | STRTOFILE(ex.Message, FORCEEXT(pcPRG, "TXT")) 262 | lResult = .F. 263 | 264 | ENDTRY 265 | ENDIF 266 | 267 | RETURN lResult 268 | * 269 | ENDPROC 270 | * 271 | ENDDEFINE 272 | 273 | 274 | 275 | * Dictionary (Class) 276 | * Implementacion de un array asociativo 277 | * 278 | * Autor: Victor Espina 279 | * Fecha: Abril 2012 280 | * 281 | * Uso: 282 | * LOCAL oDict 283 | * oDict = CREATE("Dictionary") 284 | * oDict.Add("nombre","VICTOR") 285 | * oDict.Add("apellido","ESPINA") 286 | * ?oDict.Values["nombre"] --> "VICTOR" 287 | * 288 | * IF oDict.containsKey("apellido") 289 | * oDict.Values["apellido"] = "SARCOS" 290 | * ENDIF 291 | * 292 | * FOR i = 1 TO oDict.Count 293 | * ?oDict.Keys[i], oDict.Values[i] 294 | * ENDFOR 295 | * 296 | * oCopy = oDict.Clone() 297 | * ?oCopy.Values["apellido"] --> "SARCOS" 298 | * 299 | DEFINE CLASS Dictionary AS Custom 300 | 301 | DIMEN Values[1] 302 | DIMEN Keys[1] 303 | Count = 0 304 | 305 | PROCEDURE Init(pnCapacity) 306 | IF PCOUNT() = 0 307 | pnCapacity = 0 308 | ENDIF 309 | DIMEN THIS.Values[MAX(1,pnCapacity)] 310 | DIMEN THIS.Keys[MAX(1,pnCapacity)] 311 | THIS.Count = pnCapacity 312 | ENDPROC 313 | 314 | PROCEDURE Values_Access(nIndex1,nIndex2) 315 | IF VARTYPE(nIndex1) = "N" 316 | RETURN THIS.Values[nIndex1] 317 | ENDIF 318 | LOCAL i 319 | FOR i = 1 TO THIS.Count 320 | IF THIS.Keys[i] == nIndex1 321 | RETURN THIS.Values[i] 322 | ENDIF 323 | ENDFOR 324 | ENDPROC 325 | 326 | PROCEDURE Values_Assign(cNewVal,nIndex1,nIndex2) 327 | IF VARTYPE(nIndex1) = "N" 328 | THIS.Values[nIndex1] = m.cNewVal 329 | ELSE 330 | LOCAL i 331 | FOR i = 1 TO THIS.Count 332 | IF THIS.Keys[i] == nIndex1 333 | THIS.Values[i] = m.cNewVal 334 | EXIT 335 | ENDIF 336 | ENDFOR 337 | ENDIF 338 | ENDPROC 339 | 340 | 341 | * Clear 342 | * Elimina el contenido de la clase 343 | * 344 | PROCEDURE Clear 345 | DIMEN THIS.Values[1] 346 | DIMEN THIS.Keys[1] 347 | THIS.Count = 0 348 | ENDPROC 349 | 350 | * Add 351 | * Incluye un nuevo item en el diccionario 352 | * 353 | PROCEDURE Add(pcKey, puValue) 354 | IF THIS.ContainsKey(pcKey) 355 | RETURN .F. 356 | ENDIF 357 | THIS.Count = THIS.Count + 1 358 | DIMEN THIS.Values[THIS.Count] 359 | DIMEN THIS.Keys[THIS.Count] 360 | THIS.Values[THIS.Count] = puValue 361 | THIS.Keys[THIS.Count] = pcKey 362 | ENDPROC 363 | 364 | * containsKey 365 | * Permite determinar si existe un item registrado 366 | * con la clase indicada 367 | * 368 | PROCEDURE ContainsKey(pcKey) 369 | LOCAL i,lResult 370 | lResult = .F. 371 | FOR i = 1 TO THIS.Count 372 | IF THIS.Keys[i] == pcKey 373 | lResult = .T. 374 | EXIT 375 | ENDIF 376 | ENDFOR 377 | RETURN lResult 378 | ENDPROC 379 | 380 | * getKeys 381 | * Copia en un array la lista de claves registradas 382 | * 383 | PROCEDURE getKeys(paTarget) 384 | IF THIS.Count = 0 385 | RETURN .F. 386 | ENDIF 387 | DIMEN paTarget[THIS.Count] 388 | ACOPY(THIS.Keys, paTarget) 389 | RETURN THIS.Count 390 | ENDPROC 391 | 392 | * Clone 393 | * Devuelve una copia del diccionario con todo su contenido 394 | * 395 | PROCEDURE Clone() 396 | LOCAL oClone,i 397 | oClone = CREATE(THIS.Class) 398 | FOR i = 1 TO THIS.Count 399 | oClone.Add(THIS.Keys[i], THIS.Values[i]) 400 | ENDFOR 401 | RETURN oClone 402 | ENDPROC 403 | 404 | ENDDEFINE 405 | 406 | 407 | * restController (Class) 408 | * Abstract class for REST resource's controllers 409 | * 410 | DEFINE CLASS restController AS Custom 411 | Request = NULL 412 | Props = NULL 413 | Params = NULL 414 | homeFolder = "" 415 | baseUrl = "" 416 | 417 | PROCEDURE infoAction 418 | RETURN "infoAction: not implemented" 419 | ENDPROC 420 | PROCEDURE helpAction 421 | RETURN "helpAction: not implemented" 422 | ENDPROC 423 | PROCEDURE getAction 424 | RETURN "getAction: not implemented" 425 | ENDPROC 426 | PROCEDURE listAction 427 | RETURN "listAction: not implemented" 428 | ENDPROC 429 | PROCEDURE addAction 430 | RETURN "addAction: not implemented" 431 | ENDPROC 432 | PROCEDURE updAction 433 | RETURN "updAction: not implemented" 434 | ENDPROC 435 | PROCEDURE dropAction 436 | RETURN "dropAction: not implemented" 437 | ENDPROC 438 | PROCEDURE zapAction 439 | RETURN "zapAction: not implemented" 440 | ENDPROC 441 | PROCEDURE listParameters 442 | LOCAL cHTML,i 443 | cHTML = THIS.Class + " - Received Parameters:
    " 444 | FOR i = 1 TO THIS.PArams.Count 445 | cHTML = cHTML + "
  • " + THIS.Params.Item[i] + "
  • " 446 | ENDFOR 447 | RETURN cHTML 448 | ENDPROC 449 | ENDDEFINE 450 | -------------------------------------------------------------------------------- /avfp6.03_source/prg/vfp2c.h: -------------------------------------------------------------------------------- 1 | #IFNDEF _VFP2C_H__ 2 | #DEFINE _VFP2C_H__ 3 | 4 | #DEFINE CRLF CHR(13) + CHR(10) 5 | #DEFINE FLL_MAX_ARRAY_SIZE 65000 && vfp system limit 6 | 7 | && Initialization flags for InitVFP2C32() 8 | #DEFINE VFP2C_INIT_MARSHAL 0x00000001 9 | #DEFINE VFP2C_INIT_ENUM 0x00000002 10 | #DEFINE VFP2C_INIT_ASYNC 0x00000004 11 | #DEFINE VFP2C_INIT_FILE 0x00000008 12 | #DEFINE VFP2C_INIT_WINSOCK 0x00000010 13 | #DEFINE VFP2C_INIT_ODBC 0x00000020 14 | #DEFINE VFP2C_INIT_PRINT 0x00000040 15 | #DEFINE VFP2C_INIT_NETAPI 0x00000080 16 | #DEFINE VFP2C_INIT_CALLBACK 0x00000100 17 | #DEFINE VFP2C_INIT_SERVICES 0x00000200 18 | #DEFINE VFP2C_INIT_WINDOWS 0x00000400 19 | #DEFINE VFP2C_INIT_RAS 0x00000800 20 | #DEFINE VFP2C_INIT_IPHELPER 0x00001000 21 | #DEFINE VFP2C_INIT_URLMON 0x00002000 22 | #DEFINE VFP2C_INIT_ALL 0xFFFFFFFF 23 | 24 | #DEFINE E_INSUFMEMORY 43 25 | #DEFINE E_INVALIDPARAMS 11 26 | #DEFINE E_USERERROR 1098 27 | 28 | #DEFINE SIZEOF_BYTE 1 29 | #DEFINE SIZEOF_CHAR 1 30 | #DEFINE SIZEOF_WCHAR 2 31 | #DEFINE SIZEOF_SHORT 2 32 | #DEFINE SIZEOF_INT 4 33 | #DEFINE SIZEOF_LONG 4 34 | #DEFINE SIZEOF_FLOAT 4 35 | #DEFINE SIZEOF_POINTER 4 36 | #DEFINE SIZEOF_DOUBLE 8 37 | #DEFINE SIZEOF_INT64 8 38 | 39 | #DEFINE CTYPE_SHORT 0 40 | #DEFINE CTYPE_USHORT 1 41 | #DEFINE CTYPE_INT 2 42 | #DEFINE CTYPE_UINT 3 43 | #DEFINE CTYPE_FLOAT 4 44 | #DEFINE CTYPE_DOUBLE 5 45 | #DEFINE CTYPE_BOOL 6 46 | #DEFINE CTYPE_CSTRING 7 47 | #DEFINE CTYPE_WSTRING 8 48 | #DEFINE CTYPE_CHARARRAY 9 49 | #DEFINE CTYPE_WCHARARRAY 10 50 | 51 | #DEFINE MIN_CHAR -128 52 | #DEFINE MAX_CHAR 127 53 | #DEFINE MIN_UCHAR 0 54 | #DEFINE MAX_UCHAR 255 55 | #DEFINE MIN_SHORT -32768 56 | #DEFINE MAX_SHORT 32767 57 | #DEFINE MIN_USHORT 0 58 | #DEFINE MAX_USHORT 65535 59 | #DEFINE MIN_INT -2147483648 60 | #DEFINE MAX_INT 2147483647 61 | #DEFINE MIN_UINT 0 62 | #DEFINE MAX_UINT 4294967295 63 | 64 | && flags for AllocHGlobal & ReAllocHGlobal 65 | #DEFINE GMEM_FIXED 0x0000 66 | #DEFINE GMEM_MOVEABLE 0x0002 67 | #DEFINE GMEM_ZEROINIT 0x0040 68 | #DEFINE GMEM_MODIFY 0x0080 69 | 70 | && CodePages for Unicode string functions (ReadWString, ReadWCharArray, MarshalArrayWString ..) 71 | #DEFINE CP_ACP 0 && default to ANSI code page 72 | #DEFINE CP_OEMCP 1 && default to OEM code page 73 | #DEFINE CP_THREAD_ACP 3 && current thread's ANSI code page 74 | #DEFINE CP_SYMBOL 42 && SYMBOL translations 75 | #DEFINE CP_UTF7 65000 && UTF-7 translation 76 | #DEFINE CP_UTF8 65001 && UTF-8 translation 77 | 78 | && defines for SHBrowseFolder 79 | #DEFINE BIF_RETURNONLYFSDIRS 0x0001 && For finding a folder to start document searching 80 | #DEFINE BIF_DONTGOBELOWDOMAIN 0x0002 && For starting the Find Computer 81 | #DEFINE BIF_STATUSTEXT 0x0004 82 | && Top of the dialog has 2 lines of text for BROWSEINFO.lpszTitle and one line if 83 | && this flag is set. Passing the message BFFM_SETSTATUSTEXTA to the hwnd can set the 84 | && rest of the text. This is not used with BIF_USENEWUI and BROWSEINFO.lpszTitle gets 85 | && all three lines of text. 86 | 87 | #DEFINE BIF_RETURNFSANCESTORS 0x0008 88 | #DEFINE BIF_EDITBOX 0x0010 && Add an editbox to the dialog 89 | #DEFINE BIF_VALIDATE 0x0020 && insist on valid result (or CANCEL) 90 | #DEFINE BIF_NEWDIALOGSTYLE 0x0040 && Use the new dialog layout with the ability to resize 91 | && Caller needs to call OleInitialize() before using this API 92 | #DEFINE BIF_USENEWUI 0x0050 && (BIF_NEWDIALOGSTYLE | BIF_EDITBOX) 93 | #DEFINE BIF_BROWSEINCLUDEURLS 0x0080 && Allow URLs to be displayed or entered. (Requires BIF_USENEWUI) 94 | #DEFINE BIF_UAHINT 0x0100 95 | && Add a UA hint to the dialog, in place of the edit box. May not be combined with BIF_EDITBOX 96 | #DEFINE BIF_NONEWFOLDERBUTTON 0x0200 97 | && Do not add the "New Folder" button to the dialog. Only applicable with BIF_NEWDIALOGSTYLE. 98 | #DEFINE BIF_NOTRANSLATETARGETS 0x0400 && don't traverse target as shortcut 99 | #DEFINE BIF_BROWSEFORCOMPUTER 0x1000 && Browsing for Computers. 100 | #DEFINE BIF_BROWSEFORPRINTER 0x2000 && Browsing for Printers 101 | #DEFINE BIF_BROWSEINCLUDEFILES 0x4000 && Browsing for Everything 102 | #DEFINE BIF_SHAREABLE 0x8000 && sharable resources displayed (remote shares, requires BIF_USENEWUI) 103 | 104 | && message from browser 105 | #DEFINE BFFM_INITIALIZED 1 106 | #DEFINE BFFM_SELCHANGED 2 107 | #DEFINE BFFM_VALIDATEFAILEDA 3 && lParam:szPath ret:1(cont),0(EndDialog) 108 | #DEFINE BFFM_VALIDATEFAILEDW 4 && lParam:wzPath ret:1(cont),0(EndDialog) 109 | #DEFINE BFFM_IUNKNOWN 5 && provides IUnknown to client. lParam: IUnknown* 110 | 111 | && messages to browser 112 | #DEFINE BFFM_SETSTATUSTEXTA (WM_USER + 100) 113 | #DEFINE BFFM_ENABLEOK (WM_USER + 101) 114 | #DEFINE BFFM_SETSELECTIONA (WM_USER + 102) 115 | #DEFINE BFFM_SETSELECTIONW (WM_USER + 103) 116 | #DEFINE BFFM_SETSTATUSTEXTW (WM_USER + 104) 117 | #DEFINE BFFM_SETOKTEXT (WM_USER + 105) && Unicode only 118 | #DEFINE BFFM_SETEXPANDED (WM_USER + 106) && Unicode only 119 | 120 | && defines for GetOpenFileName/GetSaveFileName 121 | #DEFINE OFN_READONLY 0x00000001 122 | #DEFINE OFN_OVERWRITEPROMPT 0x00000002 123 | #DEFINE OFN_HIDEREADONLY 0x00000004 124 | #DEFINE OFN_NOCHANGEDIR 0x00000008 125 | #DEFINE OFN_SHOWHELP 0x00000010 126 | #DEFINE OFN_ENABLEHOOK 0x00000020 127 | #DEFINE OFN_ENABLETEMPLATE 0x00000040 128 | #DEFINE OFN_ENABLETEMPLATEHANDLE 0x00000080 129 | #DEFINE OFN_NOVALIDATE 0x00000100 130 | #DEFINE OFN_ALLOWMULTISELECT 0x00000200 131 | #DEFINE OFN_EXTENSIONDIFFERENT 0x00000400 132 | #DEFINE OFN_PATHMUSTEXIST 0x00000800 133 | #DEFINE OFN_FILEMUSTEXIST 0x00001000 134 | #DEFINE OFN_CREATEPROMPT 0x00002000 135 | #DEFINE OFN_SHAREAWARE 0x00004000 136 | #DEFINE OFN_NOREADONLYRETURN 0x00008000 137 | #DEFINE OFN_NOTESTFILECREATE 0x00010000 138 | #DEFINE OFN_NONETWORKBUTTON 0x00020000 139 | #DEFINE OFN_NOLONGNAMES 0x00040000 && force no long names for 4.x modules 140 | #DEFINE OFN_EXPLORER 0x00080000 && new look commdlg 141 | #DEFINE OFN_NODEREFERENCELINKS 0x00100000 142 | #DEFINE OFN_LONGNAMES 0x00200000 && force long names for 3.x modules 143 | #DEFINE OFN_ENABLEINCLUDENOTIFY 0x00400000 && send include message to callback 144 | #DEFINE OFN_ENABLESIZING 0x00800000 145 | #DEFINE OFN_DONTADDTORECENT 0x02000000 146 | #DEFINE OFN_FORCESHOWHIDDEN 0x10000000 && Show All files including System and hidden files 147 | #DEFINE OFN_EX_NOPLACESBAR 0x00000001 148 | 149 | && defines for Registry functions 150 | #DEFINE HKEY_CLASSES_ROOT 0x80000000 151 | #DEFINE HKEY_CURRENT_USER 0x80000001 152 | #DEFINE HKEY_LOCAL_MACHINE 0x80000002 153 | #DEFINE HKEY_USERS 0x80000003 154 | #DEFINE HKEY_PERFORMANCE_DATA 0x80000004 155 | #DEFINE HKEY_PERFORMANCE_TEXT 0x80000050 156 | #DEFINE HKEY_PERFORMANCE_NLSTEXT 0x80000060 157 | #DEFINE HKEY_CURRENT_CONFIG 0x80000005 158 | #DEFINE HKEY_DYN_DATA 0x80000006 159 | 160 | #DEFINE REG_ENUMCLASSNAME 1 161 | #DEFINE REG_ENUMWRITETIME 2 162 | #DEFINE REG_ENUMTYPE 1 163 | #DEFINE REG_ENUMVALUE 2 164 | 165 | #DEFINE REG_DELETE_NORMAL 1 166 | #DEFINE REG_DELETE_SHELL 2 167 | 168 | && access rights 169 | *!* #DEFINE SYNCHRONIZE 0x00100000 170 | *!* #DEFINE STANDARD_RIGHTS_READ 0x00020000 171 | *!* #DEFINE STANDARD_RIGHTS_WRITE 0x00020000 172 | *!* #DEFINE STANDARD_RIGHTS_EXECUTE 0x00020000 173 | *!* #DEFINE STANDARD_RIGHTS_ALL 0x001F0000 174 | 175 | #DEFINE KEY_QUERY_VALUE 0x0001 176 | #DEFINE KEY_SET_VALUE 0x0002 177 | #DEFINE KEY_CREATE_SUB_KEY 0x0004 178 | #DEFINE KEY_ENUMERATE_SUB_KEYS 0x0008 179 | #DEFINE KEY_NOTIFY 0x0010 180 | #DEFINE KEY_CREATE_LINK 0x0020 181 | #DEFINE KEY_WOW64_64KEY 0x0100 182 | #DEFINE KEY_WOW64_32KEY 0x0200 183 | #DEFINE KEY_WOW64_RES 0x0300 184 | 185 | #DEFINE KEY_READ 0x00020019 186 | *!* #DEFINE KEY_READ (BITAND(BITOR(STANDARD_RIGHTS_READ,KEY_QUERY_VALUE, 187 | *!* KEY_ENUMERATE_SUB_KEYS,KEY_NOTIFY),BITNOT(SYNCHRONIZE)))) 188 | 189 | #DEFINE KEY_WRITE 0x00020006 190 | *!* #DEFINE KEY_WRITE (BITAND(BITOR(STANDARD_RIGHTS_WRITE,KEY_SET_VALUE,KEY_CREATE_SUB_KEY), 191 | *!* BITNOT(SYNCHRONIZE)))) 192 | 193 | #DEFINE KEY_EXECUTE 0x00020019 194 | *!* #DEFINE KEY_EXECUTE (BITAND(KEY_READ,BITNOT(SYNCHRONIZE))) 195 | 196 | #DEFINE KEY_ALL_ACCESS 0x000F003F 197 | *!* #DEFINE KEY_ALL_ACCESS (BITAND(BITOR(STANDARD_RIGHTS_ALL,KEY_QUERY_VALUE, 198 | *!* KEY_SET_VALUE,KEY_CREATE_SUB_KEY,KEY_ENUMERATE_SUB_KEYS,KEY_NOTIFY,KEY_CREATE_LINK), 199 | *!* BITNOT(SYNCHRONIZE)))) 200 | 201 | && types of registry values 202 | #DEFINE REG_SZ 1 203 | #DEFINE REG_EXPAND_SZ 2 204 | #DEFINE REG_BINARY 3 205 | #DEFINE REG_DWORD 4 206 | #DEFINE REG_DWORD_LITTLE_ENDIAN 4 207 | #DEFINE REG_DWORD_BIG_ENDIAN 5 208 | #DEFINE REG_LINK 6 209 | #DEFINE REG_MULTI_SZ 7 210 | #DEFINE REG_QWORD 11 211 | #DEFINE REG_INTEGER 12 212 | #DEFINE REG_DOUBLE 13 213 | #DEFINE REG_DATE 14 214 | #DEFINE REG_DATETIME 15 215 | #DEFINE REG_LOGICAL 16 216 | #DEFINE REG_MONEY 17 217 | 218 | #DEFINE REG_NOTIFY_CHANGE_NAME 0x01 219 | #DEFINE REG_NOTIFY_CHANGE_ATTRIBUTES 0x02 220 | #DEFINE REG_NOTIFY_CHANGE_LAST_SET 0x04 221 | #DEFINE REG_NOTIFY_CHANGE_SECURITY 0x08 222 | 223 | && defines for AServices 224 | #DEFINE SERVICE_ACTIVE 0x01 225 | #DEFINE SERVICE_INACTIVE 0x02 226 | #DEFINE SERVICE_STATE_ALL 0x03 227 | 228 | #DEFINE SERVICE_KERNEL_DRIVER 0x01 229 | #DEFINE SERVICE_FILE_SYSTEM_DRIVER 0x02 230 | #DEFINE SERVICE_ADAPTER 0x04 231 | #DEFINE SERVICE_RECOGNIZER_DRIVER 0x08 232 | #DEFINE SERVICE_DRIVER 0x0B 233 | #DEFINE SERVICE_WIN32_OWN_PROCESS 0x10 234 | #DEFINE SERVICE_WIN32_SHARE_PROCESS 0x20 235 | #DEFINE SERVICE_WIN32 0x30 236 | #DEFINE SERVICE_INTERACTIVE_PROCESS 0x0100 237 | #DEFINE SERVICE_TYPE_ALL 0x013F 238 | 239 | && defines for AServiceStatus (current service state) 240 | #DEFINE SERVICE_STOPPED 0x01 241 | #DEFINE SERVICE_START_PENDING 0x02 242 | #DEFINE SERVICE_STOP_PENDING 0x03 243 | #DEFINE SERVICE_RUNNING 0x04 244 | #DEFINE SERVICE_CONTINUE_PENDING 0x05 245 | #DEFINE SERVICE_PAUSE_PENDING 0x06 246 | #DEFINE SERVICE_PAUSED 0x07 247 | 248 | && defines for Servie Handler function 249 | #DEFINE SERVICE_CONTROL_STOP 0x00000001 250 | #DEFINE SERVICE_CONTROL_PAUSE 0x00000002 251 | #DEFINE SERVICE_CONTROL_CONTINUE 0x00000003 252 | #DEFINE SERVICE_CONTROL_INTERROGATE 0x00000004 253 | #DEFINE SERVICE_CONTROL_SHUTDOWN 0x00000005 254 | #DEFINE SERVICE_CONTROL_PARAMCHANGE 0x00000006 255 | #DEFINE SERVICE_CONTROL_NETBINDADD 0x00000007 256 | #DEFINE SERVICE_CONTROL_NETBINDREMOVE 0x00000008 257 | #DEFINE SERVICE_CONTROL_NETBINDENABLE 0x00000009 258 | #DEFINE SERVICE_CONTROL_NETBINDDISABLE 0x0000000A 259 | #DEFINE SERVICE_CONTROL_DEVICEEVENT 0x0000000B 260 | #DEFINE SERVICE_CONTROL_HARDWAREPROFILECHANGE 0x0000000C 261 | #DEFINE SERVICE_CONTROL_POWEREVENT 0x0000000D 262 | #DEFINE SERVICE_CONTROL_SESSIONCHANGE 0x0000000E 263 | 264 | #DEFINE SERVICE_ACCEPT_STOP 0x00000001 265 | #DEFINE SERVICE_ACCEPT_PAUSE_CONTINUE 0x00000002 266 | #DEFINE SERVICE_ACCEPT_SHUTDOWN 0x00000004 267 | #DEFINE SERVICE_ACCEPT_PARAMCHANGE 0x00000008 268 | #DEFINE SERVICE_ACCEPT_NETBINDCHANGE 0x00000010 269 | #DEFINE SERVICE_ACCEPT_HARDWAREPROFILECHANGE 0x00000020 270 | #DEFINE SERVICE_ACCEPT_POWEREVENT 0x00000040 271 | #DEFINE SERVICE_ACCEPT_SESSIONCHANGE 0x00000080 272 | 273 | #DEFINE ERROR_CALL_NOT_IMPLEMENTED 120 274 | 275 | && defines for OpenService (access rights) 276 | #DEFINE SERVICE_QUERY_CONFIG 0x0001 277 | #DEFINE SERVICE_CHANGE_CONFIG 0x0002 278 | #DEFINE SERVICE_QUERY_STATUS 0x0004 279 | #DEFINE SERVICE_ENUMERATE_DEPENDENTS 0x0008 280 | #DEFINE SERVICE_START 0x0010 281 | #DEFINE SERVICE_STOP 0x0020 282 | #DEFINE SERVICE_PAUSE_CONTINUE 0x0040 283 | #DEFINE SERVICE_INTERROGATE 0x0080 284 | #DEFINE SERVICE_USER_DEFINED_CONTROL 0x0100 285 | #DEFINE SERVICE_ALL_ACCESS 0x000F01FF 286 | *!* #DEFINE SERVICE_ALL_ACCESS (BITOR(STANDARD_RIGHTS_REQUIRED,SERVICE_QUERY_CONFIG,SERVICE_CHANGE_CONFIG, 287 | *!* SERVICE_QUERY_STATUS,SERVICE_ENUMERATE_DEPENDENTS,SERVICE_START,SERVICE_STOP, 288 | *!* SERVICE_PAUSE_CONTINUE,SERVICE_INTERROGATE,SERVICE_USER_DEFINED_CONTROL)) 289 | 290 | && flags for ADIREX 291 | #DEFINE ADIREX_DEST_ARRAY 0x01 292 | #DEFINE ADIREX_DEST_CURSOR 0x02 293 | #DEFINE ADIREX_DEST_CALLBACK 0x04 294 | #DEFINE ADIREX_FILTER_ALL 0x08 295 | #DEFINE ADIREX_FILTER_NONE 0x10 296 | #DEFINE ADIREX_FILTER_EXACT 0x20 297 | #DEFINE ADIREX_UTC_TIMES 0x40 298 | 299 | && file attributes for ADIREX, GETFILEATTRIBUTES, SETFILEATTRIBUTES, AFILEATTRIBUTES & 300 | && AFILEATTRIBUTESEX 301 | #DEFINE FILE_ATTRIBUTE_READONLY 0x00000001 302 | #DEFINE FILE_ATTRIBUTE_HIDDEN 0x00000002 303 | #DEFINE FILE_ATTRIBUTE_SYSTEM 0x00000004 304 | #DEFINE FILE_ATTRIBUTE_DIRECTORY 0x00000010 305 | #DEFINE FILE_ATTRIBUTE_ARCHIVE 0x00000020 306 | #DEFINE FILE_ATTRIBUTE_DEVICE 0x00000040 307 | #DEFINE FILE_ATTRIBUTE_NORMAL 0x00000080 308 | #DEFINE FILE_ATTRIBUTE_TEMPORARY 0x00000100 309 | #DEFINE FILE_ATTRIBUTE_SPARSE_FILE 0x00000200 310 | #DEFINE FILE_ATTRIBUTE_REPARSE_POINT 0x00000400 311 | #DEFINE FILE_ATTRIBUTE_COMPRESSED 0x00000800 312 | #DEFINE FILE_ATTRIBUTE_OFFLINE 0x00001000 313 | #DEFINE FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000 314 | #DEFINE FILE_ATTRIBUTE_ENCRYPTED 0x00004000 315 | #DEFINE FILE_ATTRIBUTE_FAKEDIRECTORY 0x80000000 316 | 317 | && additional flags for FCreateEx, FOpenEx - see MSDN -> CreateFile function for an 318 | && explanation of these constants 319 | #DEFINE FILE_FLAG_OPEN_NO_RECALL 0x00100000 320 | #DEFINE FILE_FLAG_OPEN_REPARSE_POINT 0x00200000 321 | #DEFINE FILE_FLAG_POSIX_SEMANTICS 0x01000000 322 | #DEFINE FILE_FLAG_BACKUP_SEMANTICS 0x02000000 323 | #DEFINE FILE_FLAG_DELETE_ON_CLOSE 0x04000000 324 | #DEFINE FILE_FLAG_SEQUENTIAL_SCAN 0x08000000 325 | #DEFINE FILE_FLAG_RANDOM_ACCESS 0x10000000 326 | #DEFINE FILE_FLAG_NO_BUFFERING 0x20000000 327 | #DEFINE FILE_FLAG_WRITE_THROUGH 0x80000000 328 | 329 | && access mode flags for FCreateEx/FOpenEx 330 | #DEFINE FILE_SHARE_READ 0x01 331 | #DEFINE FILE_SHARE_WRITE 0x02 332 | #DEFINE FILE_SHARE_DELETE 0x04 333 | 334 | && seek mode for FSeekEx 335 | #DEFINE FILE_BEGIN 0 336 | #DEFINE FILE_CURRENT 1 337 | #DEFINE FILE_END 2 338 | 339 | && flags for SHCopy/Rename/Delete/Move Files functions 340 | #DEFINE FOF_MULTIDESTFILES 0x0001 341 | #DEFINE FOF_CONFIRMMOUSE 0x0002 342 | #DEFINE FOF_SILENT 0x0004 343 | #DEFINE FOF_RENAMEONCOLLISION 0x0008 344 | #DEFINE FOF_NOCONFIRMATION 0x0010 345 | #DEFINE FOF_ALLOWUNDO 0x0040 346 | #DEFINE FOF_FILESONLY 0x0080 347 | #DEFINE FOF_SIMPLEPROGRESS 0x0100 348 | #DEFINE FOF_NOCONFIRMMKDIR 0x0200 349 | #DEFINE FOF_NOERRORUI 0x0400 350 | #DEFINE FOF_NOCOPYSECURITYATTRIBS 0x0800 351 | #DEFINE FOF_NORECURSION 0x1000 352 | #DEFINE FOF_NO_CONNECTED_ELEMENTS 0x2000 353 | #DEFINE FOF_WANTNUKEWARNING 0x4000 354 | #DEFINE FOF_NORECURSEREPARSE 0x8000 355 | 356 | && flags for APRINTERSEX 357 | #DEFINE PRINTER_ENUM_DEFAULT 0x00000001 358 | #DEFINE PRINTER_ENUM_LOCAL 0x00000002 359 | #DEFINE PRINTER_ENUM_CONNECTIONS 0x00000004 360 | #DEFINE PRINTER_ENUM_FAVORITE 0x00000004 361 | #DEFINE PRINTER_ENUM_NAME 0x00000008 362 | #DEFINE PRINTER_ENUM_REMOTE 0x00000010 363 | #DEFINE PRINTER_ENUM_SHARED 0x00000020 364 | #DEFINE PRINTER_ENUM_NETWORK 0x00000040 365 | 366 | && flags for APAPERSIZES 367 | #DEFINE PAPERSIZE_UNIT_MM 1 368 | #DEFINE PAPERSIZE_UNIT_INCH 2 369 | #DEFINE PAPERSIZE_UNIT_POINT 3 370 | 371 | && callback flags for CreateCallbackFunc 372 | #DEFINE CALLBACK_SYNCRONOUS 1 373 | #DEFINE CALLBACK_ASYNCRONOUS_POST 2 374 | #DEFINE CALLBACK_ASYNCRONOUS_SEND 4 375 | #DEFINE CALLBACK_CDECL 8 376 | 377 | && callback status codes for UrlDownloadToFileEx 378 | #DEFINE BINDSTATUS_FINDINGRESOURCE 1 379 | #DEFINE BINDSTATUS_CONNECTING 2 380 | #DEFINE BINDSTATUS_REDIRECTING 3 381 | #DEFINE BINDSTATUS_BEGINDOWNLOADDATA 4 382 | #DEFINE BINDSTATUS_DOWNLOADINGDATA 5 383 | #DEFINE BINDSTATUS_ENDDOWNLOADDATA 6 384 | #DEFINE BINDSTATUS_BEGINDOWNLOADCOMPONENTS 7 385 | #DEFINE BINDSTATUS_INSTALLINGCOMPONENTS 8 386 | #DEFINE BINDSTATUS_ENDDOWNLOADCOMPONENTS 9 387 | #DEFINE BINDSTATUS_USINGCACHEDCOPY 10 388 | #DEFINE BINDSTATUS_SENDINGREQUEST 11 389 | #DEFINE BINDSTATUS_CLASSIDAVAILABLE 12 390 | #DEFINE BINDSTATUS_MIMETYPEAVAILABLE 13 391 | #DEFINE BINDSTATUS_CACHEFILENAMEAVAILABLE 14 392 | #DEFINE BINDSTATUS_BEGINSYNCOPERATION 15 393 | #DEFINE BINDSTATUS_ENDSYNCOPERATION 16 394 | #DEFINE BINDSTATUS_BEGINUPLOADDATA 17 395 | #DEFINE BINDSTATUS_UPLOADINGDATA 18 396 | #DEFINE BINDSTATUS_ENDUPLOADINGDATA 19 397 | #DEFINE BINDSTATUS_PROTOCOLCLASSID 20 398 | #DEFINE BINDSTATUS_ENCODING 21 399 | #DEFINE BINDSTATUS_VERFIEDMIMETYPEAVAILABLE 22 400 | #DEFINE BINDSTATUS_CLASSINSTALLLOCATION 23 401 | #DEFINE BINDSTATUS_DECODING 24 402 | #DEFINE BINDSTATUS_LOADINGMIMEHANDLER 25 403 | #DEFINE BINDSTATUS_CONTENTDISPOSITIONATTACH 26 404 | #DEFINE BINDSTATUS_FILTERREPORTMIMETYPE 27 405 | #DEFINE BINDSTATUS_CLSIDCANINSTANTIATE 28 406 | #DEFINE BINDSTATUS_IUNKNOWNAVAILABLE 29 407 | #DEFINE BINDSTATUS_DIRECTBIND 30 408 | #DEFINE BINDSTATUS_RAWMIMETYPE 31 409 | #DEFINE BINDSTATUS_PROXYDETECTING 32 410 | #DEFINE BINDSTATUS_ACCEPTRANGES 33 411 | #DEFINE BINDSTATUS_COOKIE_SENT 34 412 | #DEFINE BINDSTATUS_COMPACT_POLICY_RECEIVED 35 413 | #DEFINE BINDSTATUS_COOKIE_SUPPRESSED 36 414 | #DEFINE BINDSTATUS_COOKIE_STATE_UNKNOWN 37 415 | #DEFINE BINDSTATUS_COOKIE_STATE_ACCEPT 38 416 | #DEFINE BINDSTATUS_COOKIE_STATE_REJECT 39 417 | #DEFINE BINDSTATUS_COOKIE_STATE_PROMPT 40 418 | #DEFINE BINDSTATUS_COOKIE_STATE_LEASH 41 419 | #DEFINE BINDSTATUS_COOKIE_STATE_DOWNGRADE 42 420 | #DEFINE BINDSTATUS_POLICY_HREF 43 421 | #DEFINE BINDSTATUS_P3P_HEADER 44 422 | #DEFINE BINDSTATUS_SESSION_COOKIE_RECEIVED 45 423 | #DEFINE BINDSTATUS_PERSISTENT_COOKIE_RECEIVED 46 424 | #DEFINE BINDSTATUS_SESSION_COOKIES_ALLOWED 47 425 | #DEFINE BINDSTATUS_CACHECONTROL 48 426 | #DEFINE BINDSTATUS_CONTENTDISPOSITIONFILENAME 49 427 | #DEFINE BINDSTATUS_MIMETEXTPLAINMISMATCH 50 428 | #DEFINE BINDSTATUS_PUBLISHERAVAILABLE 51 429 | #DEFINE BINDSTATUS_DISPLAYNAMEAVAILABLE 52 430 | #DEFINE BINDSTATUS_INTRANETREQUESTDENIED 53 431 | #DEFINE BINDSTATUS_SSLUX_NAVBLOCKED 54 432 | #DEFINE BINDSTATUS_DOWNLOAD_FINISHED 99 433 | #DEFINE BINDSTATUS_DOWNLOAD_ABORTED 100 434 | 435 | 436 | && AWindows, AWindowsEx flags 437 | #DEFINE AWINDOWS_TOPLEVEL 0x01 438 | #DEFINE AWINDOWS_CHILD 0x02 439 | #DEFINE AWINDOWS_THREAD 0x04 440 | #DEFINE AWINDOWS_DESKTOP 0x08 441 | #DEFINE AWINDOWS_CALLBACK 0x10 442 | 443 | && SQLExecEx flags 444 | #DEFINE SQLEXECEX_DEST_CURSOR 0x0001 445 | #DEFINE SQLEXECEX_DEST_VARIABLE 0x0002 446 | #DEFINE SQLEXECEX_REUSE_CURSOR 0x0004 447 | #DEFINE SQLEXECEX_NATIVE_SQL 0x0008 448 | #DEFINE SQLEXECEX_CALLBACK_PROGRESS 0x0010 449 | #DEFINE SQLEXECEX_CALLBACK_INFO 0x0020 450 | #DEFINE SQLEXECEX_STORE_INFO 0x0040 451 | 452 | && ODBC SQL types 453 | #DEFINE SQL_UNKNOWN_TYPE 0 454 | #DEFINE SQL_CHAR 1 455 | #DEFINE SQL_NUMERIC 2 456 | #DEFINE SQL_DECIMAL 3 457 | #DEFINE SQL_INTEGER 4 458 | #DEFINE SQL_SMALLINT 5 459 | #DEFINE SQL_FLOAT 6 460 | #DEFINE SQL_REAL 7 461 | #DEFINE SQL_DOUBLE 8 462 | #DEFINE SQL_DATE 9 463 | #DEFINE SQL_DATETIME 9 464 | #DEFINE SQL_TIMESTAMP 11 465 | #DEFINE SQL_VARCHAR 12 466 | #DEFINE SQL_LONGVARCHAR -1 467 | #DEFINE SQL_BINARY -2 468 | #DEFINE SQL_VARBINARY -3 469 | #DEFINE SQL_LONGVARBINARY -4 470 | #DEFINE SQL_BIGINT -5 471 | #DEFINE SQL_TINYINT -6 472 | #DEFINE SQL_BIT -7 473 | #DEFINE SQL_WCHAR -8 474 | #DEFINE SQL_WVARCHAR -9 475 | #DEFINE SQL_WLONGVARCHAR -10 476 | 477 | && BindEventsEx flags 478 | #DEFINE BINDEVENTSEX_CALL_BEFORE 0x0001 479 | #DEFINE BINDEVENTSEX_CALL_AFTER 0x0002 480 | #DEFINE BINDEVENTSEX_RETURN_VALUE 0x0004 481 | #DEFINE BINDEVENTSEX_NO_RECURSION 0x0008 482 | #DEFINE BINDEVENTSEX_CLASSPROC 0x0010 483 | 484 | && some usefull windowmessages 485 | #DEFINE WM_CREATE 0x0001 486 | #DEFINE WM_DESTROY 0x0002 487 | #DEFINE WM_MOVE 0x0003 488 | #DEFINE WM_SIZE 0x0005 489 | #DEFINE WM_ACTIVATE 0x0006 490 | #DEFINE WM_QUERYENDSESSION 0x0011 491 | #DEFINE WM_ENDSESSION 0x0016 492 | #DEFINE WM_SYSCOLORCHANGE 0x0015 493 | #DEFINE WM_WININICHANGE 0x001A 494 | #DEFINE WM_ACTIVATEAPP 0x001C 495 | #DEFINE WM_FONTCHANGE 0x001D 496 | #DEFINE WM_TIMECHANGE 0x001E 497 | #DEFINE WM_POWER 0x0048 498 | #DEFINE WM_USERCHANGED 0x0054 499 | #DEFINE WM_KEYDOWN 0x0100 500 | #DEFINE WM_KEYUP 0x0101 501 | #DEFINE WM_CHAR 0x0102 502 | #DEFINE WM_DEADCHAR 0x0103 503 | #DEFINE WM_SYSKEYDOWN 0x0104 504 | #DEFINE WM_SYSKEYUP 0x0105 505 | #DEFINE WM_SYSCHAR 0x0106 506 | #DEFINE WM_SYSDEADCHAR 0x0107 507 | #DEFINE WM_MOUSEMOVE 0x0200 508 | #DEFINE WM_LBUTTONDOWN 0x0201 509 | #DEFINE WM_LBUTTONUP 0x0202 510 | #DEFINE WM_LBUTTONDBLCLK 0x0203 511 | #DEFINE WM_RBUTTONDOWN 0x0204 512 | #DEFINE WM_RBUTTONUP 0x0205 513 | #DEFINE WM_RBUTTONDBLCLK 0x0206 514 | #DEFINE WM_MBUTTONDOWN 0x0207 515 | #DEFINE WM_MBUTTONUP 0x0208 516 | #DEFINE WM_MBUTTONDBLCLK 0x0209 517 | #DEFINE WM_MOUSEWHEEL 0x020A 518 | #DEFINE WM_ENTERMENULOOP 0x0211 519 | #DEFINE WM_EXITMENULOOP 0x0212 520 | #DEFINE WM_MOVING 0x0216 521 | #DEFINE WM_POWERBROADCAST 0x0218 522 | #DEFINE WM_DEVICECHANGE 0x0219 523 | #DEFINE WM_APPCOMMAND 0x0319 524 | #DEFINE WM_THEMECHANGED 0x031A 525 | 526 | && FindFileChange notification events 527 | #DEFINE FILE_NOTIFY_CHANGE_FILE_NAME 0x00000001 528 | #DEFINE FILE_NOTIFY_CHANGE_DIR_NAME 0x00000002 529 | #DEFINE FILE_NOTIFY_CHANGE_ATTRIBUTES 0x00000004 530 | #DEFINE FILE_NOTIFY_CHANGE_SIZE 0x00000008 531 | #DEFINE FILE_NOTIFY_CHANGE_LAST_WRITE 0x00000010 532 | #DEFINE FILE_NOTIFY_CHANGE_SECURITY 0x00000100 533 | 534 | && OsEx - windows version 535 | #DEFINE OSEX_WINDOWS 0 536 | #DEFINE OSEX_WINDOWS32S 1 537 | #DEFINE OSEX_WINDOWS95 2 538 | #DEFINE OSEX_WINDOWS95OSR2 3 539 | #DEFINE OSEX_WINDOWS98 4 540 | #DEFINE OSEX_WINDOWS98SE 5 541 | #DEFINE OSEX_WINDOWSMILLENNIUM 6 542 | #DEFINE OSEX_WINDOWSNT351 7 543 | #DEFINE OSEX_WINDOWSNT40 8 544 | #DEFINE OSEX_WINDOWSNT40SERVER 9 545 | #DEFINE OSEX_WINDOWS2000 10 546 | #DEFINE OSEX_WINDOWSXP 11 547 | #DEFINE OSEX_WINDOWSXPPROFESSIONALX64 12 548 | #DEFINE OSEX_WINDOWSHOMESERVER 13 549 | #DEFINE OSEX_WINDOWSVISTA 14 550 | #DEFINE OSEX_WINDOWSSERVER2003 15 551 | #DEFINE OSEX_WINDOWSSERVER2003R2 16 552 | #DEFINE OSEX_WINDOWS7 17 553 | #DEFINE OSEX_WINDOWSSERVER2008 18 554 | #DEFINE OSEX_WINDOWSSERVER2008R2 19 555 | #DEFINE OSEX_WINDOWSX 20 556 | 557 | && CreateThreadObject - execution context 558 | #DEFINE CLSCTX_INPROC_SERVER 0x1 559 | #DEFINE CLSCTX_LOCAL_SERVER 0x4 560 | 561 | #ENDIF && _VFP2C_H__ -------------------------------------------------------------------------------- /avfp6.03_source/prg/webthreads2.prg: -------------------------------------------------------------------------------- 1 | ************************************************** 2 | * WEBTHREADS Version 2 for AVFP 3 | * Modified 1/26/13 CKF 4 | * * Runs any vfp code on a background thread 5 | * Uses CreateThreadObject in vfp2c32.fll 6 | * by Christian Ehlscheid 7 | ************************************************** 8 | 9 | DEFINE CLASS ThreadManager AS Session OLEPUBLIC 10 | 11 | CallInfo = .NULL. && "magic" property 12 | oEvent = NULL 13 | lSilent = .f. && just run the thread with no update page, defaults to having an update page 14 | nRecExpire = 5400 && how long to keep Event records 15 | 16 | PROCEDURE CreateThread(ThreadProc as String, ThreadProcParam as String) 17 | LOCAL lcID,ThreadProcParam 18 | PUBLIC loObj, loCallback, xj, lnCallId 19 | #INCLUDE vfp2c.h 20 | SET LIBRARY TO oProp.AppStartPath+[\vfp2c32.fll] ADDITIVE 21 | *!* IF !InitVFP2C32(VFP2C_INIT_ALL) && you can vary the initialization parameter depending on what functions of the FLL you intend to use 22 | *!* LOCAL laError[1], lnCount, xj, lcError 23 | *!* lnCount = AERROREX('laError') 24 | *!* lcError = 'VFP2C32 Library initialization failed:' + CHR(13) 25 | *!* FOR xj = 1 TO lnCount 26 | *!* lcError = lcError + ; 27 | *!* 'Error No : ' + TRANSFORM(laError[1]) + CHR(13) + ; 28 | *!* 'Function : ' + laError[2] + CHR(13) + ; 29 | *!* 'Message : "' + laError[3] + '"' 30 | *!* ENDFOR 31 | *!* RETURN lcError && show/log error and abort program initialization .. 32 | *!* ENDIF 33 | ThreadProcParam = IIF(EMPTY(ThreadProcParam),SUBSTR(SYS(2015),3,10),SUBSTR(SYS(2015),3,10)+[,]+ThreadProcParam) 34 | ALINES(laArr,ThreadProcParam,.F.,",") 35 | lcID = laArr[1] 36 | lcEventFile=oProp.AppStartPath+'temp\events.DBF' 37 | IF !FILE(lcEventFile) 38 | CREATE TABLE (lcEventFile) ; 39 | (id c(10), begin l, finish l , returnval c(50), count n(5,0), cancel l, action m, timestamp t, err l, err_txt m) 40 | INDEX ON id TAG id 41 | INDEX ON timestamp TAG timestamp 42 | 43 | ENDIF 44 | IF ! USED('events') 45 | USE (lcEventFile) IN 0 SHARED 46 | ENDIF 47 | SELECT events 48 | * recycling old events records 49 | *SCAN FOR (DATETIME()-events.timestamp)>5400 &&86400 1 day &&5400 90 minutes 50 | SCAN FOR (DATETIME()-events.timestamp)>; 51 | IIF(EMPTY(THIS.nRecExpire),5400,THIS.nRecExpire) &&86400 1 day &&5400 && 90 minutes 52 | DO WHILE .NOT. RLOCK() 53 | ENDDO 54 | REPL ID WITH '' 55 | UNLOCK 56 | ENDSCAN 57 | DO WHILE .NOT. FLOCK() 58 | ENDDO 59 | LOCATE FOR EMPTY(id) 60 | IF EOF() 61 | APPEND BLANK 62 | REPLACE id WITH lcID 63 | REPLACE finish WITH .f. 64 | REPLACE count WITH 0 65 | REPLACE begin WITH .t. 66 | REPLACE cancel WITH .f. 67 | REPLACE action WITH '' 68 | REPLACE timestamp WITH DATETIME() 69 | REPLACE err WITH .f. 70 | REPLACE err_txt WITH '' 71 | ELSE 72 | REPLACE id WITH lcID 73 | REPLACE finish WITH .f. 74 | REPLACE count WITH 0 75 | REPLACE begin WITH .t. 76 | REPLACE cancel WITH .f. 77 | REPLACE action WITH '' 78 | REPLACE timestamp WITH DATETIME() 79 | REPLACE err WITH .f. 80 | REPLACE err_txt WITH '' 81 | ENDIF 82 | UNLOCK 83 | USE IN events 84 | 85 | IF VARTYPE(ThreadProc)='C' 86 | 87 | *must be compiled object and compile is source date newer 88 | IF !FILE(oProp.AppStartPath+"prg\"+ThreadProc+".fxp") OR ; 89 | FDATE(oProp.AppStartPath+"prg\"+ThreadProc+".prg",1) > FDATE(oProp.AppStartPath+"prg\"+ThreadProc+".fxp",1) 90 | COMPILE oProp.AppStartPath+"prg\"+ThreadProc+".prg" 91 | ENDIF 92 | 93 | m.loCallback = null &&CREATEOBJECT('ExampleCallback') 94 | 95 | TRY 96 | m.loObj = CreateThreadObject("activevfp.c1", m.loCallback) 97 | 98 | CATCH 99 | AERROREX('laError') 100 | && the array "laError" now contains exact information 101 | &&laError 102 | ENDTRY 103 | 104 | m.loObj.MyDoCmd("do '"+oProp.AppStartPath+"prg\"+ThreadProc+"' WITH '"+ThreadProcParam+"'") 105 | 106 | IF !this.lSilent 107 | this.Start(ThreadProcParam) && show update page 108 | ENDIF 109 | 110 | RETURN lcID 111 | ENDIF 112 | 113 | PROCEDURE Check 114 | LPARAMETERS lcID 115 | lcEventFile=oProp.AppStartPath+'temp\events.DBF' 116 | IF !USED('events') 117 | USE (lcEventFile) IN 0 SHARED 118 | ENDIF 119 | SELECT events 120 | 121 | SET ORDER TO 1 122 | SEEK lcID 123 | IF FOUND() 124 | 125 | replace count WITH count+1 126 | SCATTER NAME THIS.oEvent BLANK MEMO 127 | this.oEvent.count=events.count 128 | this.oEvent.action=events.action 129 | this.oEvent.id=events.id 130 | this.oEvent.begin=events.begin 131 | this.oEvent.finish=events.finish 132 | this.oEvent.cancel=events.cancel 133 | this.oEvent.timestamp=events.timestamp 134 | this.oEvent.err=events.err 135 | this.oEvent.err_txt=events.err_txt 136 | IF events.finish .or. events.err 137 | RETURN .T. 138 | ELSE 139 | RETURN .F. 140 | ENDIF 141 | ENDIF 142 | USE IN events 143 | 144 | 145 | PROCEDURE Cancel 146 | 147 | LPARAMETERS lcID 148 | this.SetPath() && set to data directory wherever activevfp.dll is 149 | UPDATE events SET cancel=.T.,finish = .f. WHERE id==lcID 150 | RELEASE ALL 151 | 152 | PROCEDURE GetError 153 | LPARAMETERS lcID 154 | this.SetPath() 155 | *lcEventFile=oProp.AppStartPath+'temp\events.DBF' 156 | IF !USED('events') 157 | USE events IN 0 SHARED 158 | ENDIF 159 | SELECT events 160 | 161 | SET ORDER TO 1 162 | SEEK lcID 163 | IF FOUND() 164 | 165 | 166 | IF events.err 167 | RETURN .T. 168 | ELSE 169 | RETURN .F. 170 | ENDIF 171 | ENDIF 172 | USE IN events 173 | 174 | PROCEDURE Canceled 175 | LPARAMETERS lcID 176 | this.SetPath() 177 | *lcEventFile=oProp.AppStartPath+'temp\events.DBF' 178 | IF !USED('events') 179 | USE events IN 0 SHARED 180 | ENDIF 181 | SELECT events 182 | 183 | SET ORDER TO 1 184 | SEEK lcID 185 | IF FOUND() 186 | 187 | 188 | IF events.cancel 189 | RETURN .T. 190 | ELSE 191 | RETURN .F. 192 | ENDIF 193 | ENDIF 194 | USE IN events 195 | 196 | 197 | FUNCTION Start(params) 198 | LOCAL cEventID 199 | ALINES(arr,params,.F.,",") 200 | cEventID = arr[1] 201 | oResponse.clear 202 | oResponse.Expires=0 203 | oResponse.Redirect(oProp.ScriptPath+[?action=]+oProp.Action+[&step=AsyncCheck&asyncID=]+cEventID) 204 | RETURN 205 | ENDFUNC 206 | 207 | PROCEDURE RecordError(cEventID,cErrorTxt) 208 | this.SetPath() 209 | UPDATE events SET err=.t.,finish = .f.,err_txt=ALLTRIM(cErrorTxt),begin =.f.,action=[Error] WHERE id=cEventID &&,count = 0 210 | 211 | PROCEDURE StartWebEvent(cEventID,cStartActionTxt) 212 | this.SetPath() 213 | UPDATE events SET finish = .f.,begin =.t.,action=ALLTRIM(cStartActionTxt) WHERE id=cEventID &&,count = 0 214 | 215 | PROCEDURE CompleteWebEvent(cEventID,cFinishActionTxt,cfilename) 216 | IF EMPTY(cfilename) 217 | cfilename=[ ] 218 | ENDIF 219 | IF EMPTY(cFinishActionTxt) 220 | cFinishActionTxt=[ ] 221 | ENDIF 222 | &&,returnval=ALLTRIM(cfilename),action=ALLTRIM(LEFT(events.action,254))+CHR(13)+CHR(10)+ALLTRIM(cFinishActionTxt) 223 | this.SetPath() 224 | UPDATE events SET finish = .t.,begin =.f.,returnval=ALLTRIM(cfilename),action=ALLTRIM(LEFT(events.action,254))+CHR(13)+CHR(10)+ALLTRIM(cFinishActionTxt) WHERE id=cEventID &&fix &&,action=ALLTRIM(events.action)+CHR(13)+CHR(10)+ALLTRIM(cFinishActionTxt) 225 | RELEASE ALL 226 | CLEAR ALL 227 | RETURN 228 | 229 | 230 | 231 | PROCEDURE StatusWebEvent(cEventID,cTxt,lAdditive) 232 | this.SetPath() 233 | IF lAdditive 234 | UPDATE events SET begin =.f.,action=ALLTRIM(LEFT(events.action,254))+CHR(13)+CHR(10)+ALLTRIM(cTxt) WHERE id=cEventID && 235 | ELSE 236 | UPDATE events SET begin =.f.,action=ALLTRIM(cTxt) WHERE id=cEventID &&,count = 0 237 | ENDIF 238 | 239 | PROCEDURE SetPath() 240 | 241 | ASTACKINFO(myarray) 242 | lcAppStartPath=JUSTPATH(myarray(1,4)) &&+"\" 243 | lcTempPath= STRTRAN(lcAppStartPath,'prg','temp')+'\' &&temp needs to be writable 244 | SET PATH TO &lcTempPath 245 | RELEASE myarray 246 | RETURN 247 | 248 | FUNCTION ERROR(nError, cMethod, nLine) 249 | 250 | lcErrMsg = cMethod+' err#='+STR(nError,5)+' line='+STR(nline,6)+; 251 | ' '+MESSAGE()+_VFP.SERVERNAME 252 | STRTOFILE(lcErrMsg,oProp.AppStartPath+[temp\threaderror.txt]) 253 | COMreturnerror(lcErrMsg,_VFP.SERVERNAME) 254 | 255 | ENDFUNC 256 | 257 | FUNCTION INIT 258 | SYS(3050, 1, VAL(SYS(3050, 1, 0)) / 3) 259 | ENDFUNC 260 | 261 | 262 | 263 | 264 | ENDDEFINE 265 | 266 | 267 | 268 | *!* 269 | 270 | 271 | 272 | DEFINE CLASS ExampleCallback AS Custom 273 | 274 | FUNCTION OnCallComplete(callid AS Long, result AS Variant, callcontext AS Variant) AS VOID 275 | ? callid, result, callcontext 276 | ENDFUNC 277 | 278 | FUNCTION OnError(callid AS Long, callcontext AS Variant, errornumber AS Long, errorsource AS String, errordescription AS String) AS VOID 279 | ? callid, callcontext, errornumber, errorsource, errordescription 280 | ENDFUNC 281 | 282 | ENDDEFINE 283 | -------------------------------------------------------------------------------- /avfp6.03_source/reports/..svnbridge/pdfrun.PJT: -------------------------------------------------------------------------------- 1 | svn:mime-typeapplication/octet-stream -------------------------------------------------------------------------------- /avfp6.03_source/reports/..svnbridge/pdfrun.pjx: -------------------------------------------------------------------------------- 1 | svn:mime-typeapplication/octet-stream -------------------------------------------------------------------------------- /avfp6.03_source/reports/clsheap.prg: -------------------------------------------------------------------------------- 1 | ************************************************** 2 | *-- Class: heap 3 | *-- ParentClass: custom 4 | *-- BaseClass: custom 5 | * 6 | * Another in the family of relatively undocumented sample classes I've inflicted on others 7 | * Warning - there's no error handling in here, so be careful to check for null returns and 8 | * invalid pointers. Unless you get frisky, or you're resource-tight, it should work well. 9 | * 10 | * Please read the code and comments carefully. I've tried not to assume much knowledge about 11 | * just how pointers work, or how memory allocation works, and have tried to explain some of the 12 | * basic concepts behing memory allocation in the Win32 environment, without having gone into 13 | * any real details on x86 memory management or the Win32 memory model. If you want to explore 14 | * these things (and you should), start by reading Jeff Richter's _Advanced Windows_, especially 15 | * Chapters 4-6, which deal with the Win32 memory model and virtual memory -really- well. 16 | * 17 | * Another good source iss Walter Oney's _Systems Programming for Windows 95_. Be warned that 18 | * both of these books are targeted at the C programmer; to someone who has only worked with 19 | * languages like VFP or VB, it's tough going the first couple of dozen reads. 20 | * 21 | * Online resources - http://www.x86.org is the Intel Secrets Homepage. Lots of deep, dark 22 | * stuff about the x86 architecture. Not for the faint of heart. Lots of pointers to articles 23 | * from DDJ (Doctor Dobbs Journal, one of the oldest and best magazines on microcomputing.) 24 | * 25 | * You also might want to take a look at the transcripts from my "Pointers on Pointers" chat 26 | * sessions, which are available in the WednesdayNightLectureSeries topic on the Fox Wiki, 27 | * http://fox.wikis.com - the Wiki is a great Web site; it provides a vast store of information 28 | * on VFP and related topics, and is probably the best tool available now to develop topics in 29 | * a collaborative environment. Well worth checking out - it's a very different mechanism for 30 | * ongoing discussion of a subject. It's an on-line message base or chat; I find 31 | * myself hitting it when I have a question to see if an answer already exists. It's 32 | * much like using a FAQ, except that most things on the Wiki are editable... 33 | * 34 | * Post-DevCon 2000 revisions: 35 | * 36 | * After some bizarre errors at DevCon, I reworked some of the methods to 37 | * consistently return a NULL whenever a bad pointer/inactive pointer in the 38 | * iaAllocs member array was encountered. I also implemented NumToLong 39 | * using RtlMoveMemory(), relying on a BITOR() to recast what would otherwise 40 | * be a value with the high-order bit set. The result is it's faster, and 41 | * an anomaly reported with values between 0xFFFFFFF1-0xFFFFFFFF goes away, 42 | * at the expense of representing these as negative numbers. Pointer math 43 | * still works. 44 | * 45 | ***** 46 | * How HEAP works: 47 | * 48 | * Overwhelming guilt hit early this morning; maybe I should explain the 49 | * concept of the Heap class and give an example of how to use it, in 50 | * conjunction with the add-on functions that follow in this proc library. 51 | * 52 | * Windows allocates memory from several places; it also provides a 53 | * way to define your own small corner of the universe where you can 54 | * allocate and deallocate blocks of memory for your own purposes. These 55 | * public or private memory areas are referred to commonly as heaps. 56 | * 57 | * VFP is great in most cases; it provides flexible allocation and 58 | * alteration of variables on the fly in a program. You don't need to 59 | * know much about how things are represented internally. This makes 60 | * most programming tasks easy. However, in exchange for VFP's flexibility 61 | * in memory variable allocation, we give up several things, the most 62 | * annoying of which are not knowing the exact location of a VFP 63 | * variable in memory, and not knowing exactly how things are constructed 64 | * inside a variable, both of which make it hard to define new kinds of 65 | * memory structures within VFP to manipulate as a C-style structure. 66 | * 67 | * Enter Heap. Heap creates a growable, private heap, from which you 68 | * can allocate blocks of memory that have a known location and size 69 | * in your memory address space. It also provides a way of transferring 70 | * data to and from these allocated blocks. You build structures in VFP 71 | * strings, and parse the content of what is returned in those blocks by 72 | * extracting substrings from VFP strings. 73 | * 74 | * Heap does its work using a number of Win32 API functions; HeapCreate(), 75 | * which sets up a private heap and assigns it a handle, is invoked in 76 | * the Init method. This sets up the 'heap', where block allocations 77 | * for the object will be constructed. I set up the heap to use a base 78 | * allocation size of twice the size of a swap file 'page' in the x86 79 | * world (8K), and made the heap able to grow; it adds 8K chunks of memory 80 | * to itself as it grows. There's no fixed limit (other than available 81 | * -virtual- memory) on the size of the heap constructed; just realize 82 | * that huge allocations are likely to bump heads with VFP's own desire 83 | * for mondo RAM. 84 | * 85 | * Once the Heap is established, we can allocate blocks of any size we 86 | * want in Heap, outside of VFP's memory, but within the virtual 87 | * address space owned by VFP. Blocks are allocated by HeapAlloc(), and a 88 | * pointer to the block is returned as an integer. 89 | * 90 | * KEEP THE POINTER RETURNED BY ANY Alloc method, it's the key to 91 | * doing things with the block in the future. In addition to being a 92 | * valid pinter, it's the key to finding allocations tracked in iaAllocs[] 93 | * 94 | * Periodically, we need to load things into the block we've created. 95 | * Thanks to work done by Christof Lange, George Tasker and others, 96 | * we found a Win32API call that will do transfers between memory 97 | * locations, called RtlMoveMemory(). RtlMoveMemory() acts like the 98 | * Win32API MoveMemory() call; it takes two pointers (destination 99 | * and source) and a length. In order to make life easy, at times 100 | * we DECLARE the pointers as INTEGER (we pass a number, which is 101 | * treated as a DWORD (32 bit unsigned integer) whose content is the 102 | * address to use), and at other times as STRING @, which passes the 103 | * physical address of a VFP string variable's contents, allowing 104 | * RtlMoveMemory() to read and write VFP strings without knowing how 105 | * to manipulate VFP's internal variable structures. RtlMoveMemory() 106 | * is used by both the CopyFrom and CopyTo methods, and the enhanced 107 | * Alloc methods. 108 | * 109 | * At some point, we're finished with a block of memory. We can free up 110 | * that memory via HeapFree(), which releases a previously-allocated 111 | * block on the heap. It does not compact or rearrange the heap allocations 112 | * but simply makes the memory allocated no longer valid, and the 113 | * address could be reused by another Alloc operation. We track the 114 | * active state of allocations in a member array iaAllocs[] which has 115 | * 3 members per row; the pointer, which is used as a key, the actual 116 | * size of the allocation (sometimes HeapAlloc() gives you a larger block 117 | * than requested; we can see it here. This is the property returned 118 | * by the SizeOfBlock method) and whether or not it's active and available. 119 | * 120 | * When we're done with a Heap, we need to release the allocations and 121 | * the heap itself. HeapDestroy() releases the entire heap back to the 122 | * Windows memory pool. This is invoked in the Destroy method of the 123 | * class to ensure that it gets explcitly released, since it remains alive 124 | * until it is explicitly released or the owning process is released. I 125 | * put this in the Destroy method to ensure that the heap went away when 126 | * the Heap object went out of scope. 127 | * 128 | * The original class methods are: 129 | * 130 | * Init Creates the heap for use 131 | * Alloc(nSize) Allocates a block of nSize bytes, returns an nPtr 132 | * to it. nPtr is NULL if fail 133 | * DeAlloc(nPtr) Releases the block whose base address is nPtr. 134 | * Returns .T./.F. 135 | * CopyTo(nPtr,cSrc) Copies the Content of cSrc to the buffer at nPtr, 136 | * up to the smaller of LEN(cSrc) or the length of 137 | * the block (we look in the iaAllocs[] array). 138 | * Returns .T./.F. 139 | * CopyFrom(nPtr) Copies the content of the block at nPtr (size is 140 | * from iaAllocs[]) and returns it as a VFP string. 141 | * Returns a string, or NULL if fail 142 | * SizeOfBlock(nPtr) Returns the actual allocated size of the block 143 | * pointed to by nPtr. Returns NULL if fail 144 | * Destroy() DeAllocs anything still active, and then frees 145 | * the heap. 146 | ***** 147 | * New methods added 2/12/99 EMR - Attack of the Creeping Feature Creature, 148 | * part I 149 | * 150 | * There are too many times when you know what you want to put in 151 | * a buffer when you allocate it, so why not pass what you want in 152 | * the buffer when you allocate it? And we may as well add an option to 153 | * init the memory to a known value easily, too: 154 | * 155 | * AllocBLOB(cSrc) Allocate a block of SizeOf(cSrc) bytes and 156 | * copy cSrc content to it 157 | * AllocString(cSrc) Allocate a block of SizeOf(cSrc) + 1 bytes and 158 | * copy cSrc content to it, adding a null (CHR(0)) 159 | * to the end to make it a standard C-style string 160 | * AllocInitAs(nSize,nVal) 161 | * Allocate a block of nSize bytes, preinitialized 162 | * with CHR(nVal). If no nVal is passed, or nVal 163 | * is illegal (not a number 0-255), init with nulls 164 | * 165 | ***** 166 | * Property changes 9/29/2000 167 | * 168 | * iaAllocs[] is now protected 169 | * 170 | ***** 171 | * Method modifications 9/29/2000: 172 | * 173 | * All lookups in iaAllocs[] are now done using the new FindAllocID() 174 | * method, which returns a NULL for the ID if not found active in the 175 | * iaAllocs[] entries. Result is less code and more consistent error 176 | * handling, based on checking ISNULL() for pointers. 177 | * 178 | ***** 179 | * The ancillary goodies in the procedure library are there to make life 180 | * easier for people working with structures; they are not optimal 181 | * and infinitely complete, but they do the things that are commonly 182 | * needed when dealing with stuff in structures. The functions are of 183 | * two types; converters, which convert standard C structures to an 184 | * equivalent VFP numeric, or make a string whose value is equivalent 185 | * to a C data type from a number, so that you can embed integers, 186 | * pointers, etc. in the strings used to assemble a structure which you 187 | * load up with CopyTo, or pull out pointers and integers that come back 188 | * embedded in a structure you've grabbed with CopyFrom. 189 | * 190 | * The second type of functions provided are memory copiers. The 191 | * CopyFrom and CopyTo methods are set up to work with our heap, 192 | * and nPtrs must take on the values of block addresses grabbed 193 | * from our heap. There will be lots of times where you need to 194 | * get the content of memory not necessarily on our heap, so 195 | * SetMem, GetMem and GetMemString go to work for us here. SetMem 196 | * copies the content of a string into the absolute memory block 197 | * at nPtr, for the length of the string, using RtlMoveMemory(). 198 | * BE AWARE THAT MISUSE CAN (and most likely will) RESULT IN 199 | * 0xC0000005 ERRORS, memory access violations, or similar OPERATING 200 | * SYSTEM level errors that will smash VFP like an empty beer can in 201 | * a trash compactor. 202 | * 203 | * There are two functions to copy things from a known address back 204 | * to the VFP world. If you know the size of the block to grab, 205 | * GetMem(nPtr,nSize) will copy nSize bytes from the address nPtr 206 | * and return it as a VFP string. See the caveat above. 207 | * GetMemString(nPtr) uses a different API call, lstrcpyn(), to 208 | * copy a null terminated string from the address specified by nPtr. 209 | * You can hurt yourself with this one, too. 210 | * 211 | * Functions in the procedure library not a part of the class: 212 | * 213 | * GetMem(nPtr,nSize) Copy nSize bytes at address nPtr into a VFP string 214 | * SetMem(nPtr,cSource) Copy the string in cSource to the block beginning 215 | * at nPtr 216 | * GetMemString(nPtr) Get the null-terminated string (up to 512 bytes) 217 | * from the address at nPtr 218 | * 219 | * DWORDToNum(cString) Convert the first 4 bytes of cString as a DWORD 220 | * to a VFP numeric (0 to 2^32) 221 | * SHORTToNum(cString) Convert the first 2 bytes of cString as a SHORT 222 | * to a VFP numeric (-32768 to 32767) 223 | * WORDToNum(cString) Convert the first 2 bytes of cString as a WORD 224 | * to a VFP numeric (0 to 65535) 225 | * NumToDWORD(nInteger) Converts nInteger into a string equivalent to a 226 | * C DWORD (4 byte unsigned) 227 | * NumToWORD(nInteger) Converts nInteger into a string equivalent to a 228 | * C WORD (2 byte unsigned) 229 | * NumToSHORT(nInteger) Converts nInteger into a string equivalent to a 230 | * C SHORT ( 2 byte signed) 231 | * 232 | ****** 233 | * New external functions added 2/13/99 234 | * 235 | * I see a need to handle NetAPIBuffers, which are used to transfer 236 | * structures for some of the Net family of API calls; their memory 237 | * isn't on a user-controlled heap, but is mapped into the current 238 | * application address space in a special way. I've added two 239 | * functions to manage them, but you're responsible for releasing 240 | * them yourself. I could implement a class, but in many cases, a 241 | * call to the API actually performs the allocation for you. The 242 | * two new calls are: 243 | * 244 | * AllocNetAPIBuffer(nSize) Allocates a NetAPIBuffer of at least 245 | * nBytes, and returns a pointer 246 | * to it as an integer. A NULL is returned 247 | * if allocation fails. 248 | * DeAllocNetAPIBuffer(nPtr) Frees the NetAPIBuffer allocated at the 249 | * address specified by nPtr. It returns 250 | * .T./.F. for success and failure 251 | * 252 | * These functions are only available under NT, and will return 253 | * NULL or .F. under Win9x 254 | * 255 | ***** 256 | * Function changes 9/29/2000 257 | * 258 | * NumToDWORD(tnNum) Redirected to NumToLONG() 259 | * NumToLONG(tnNum) Generates a 32 bit LONG from the VFP number, recast 260 | * using BITOR() as needed 261 | * LONGToNum(tcLong) Extracts a signed VFP INTEGER from a 4 byte string 262 | * 263 | ***** 264 | * That's it for the docs to date; more stuff to come. The code below 265 | * is copyright Ed Rauh, 1999; you may use it without royalties in 266 | * your own code as you see fit, as long as the code is attributed to me. 267 | * 268 | * This is provided as-is, with no implied warranty. Be aware that you 269 | * can hurt yourself with this code, most * easily when using the 270 | * SetMem(), GetMem() and GetMemString() functions. I will continue to 271 | * add features and functions to this periodically. If you find a bug, 272 | * please notify me. It does no good to tell me that "It doesn't work 273 | * the way I think it should..WAAAAH!" I need to know exactly how things 274 | * fail to work with the code I supplied. A small code snippet that can 275 | * be used to test the failure would be most helpful in trying 276 | * to track down miscues. I'm not going to run through hundreds or 277 | * thousands of lines of code to try to track down where exactly 278 | * something broke. 279 | * 280 | * Please post questions regarding this code on Universal Thread; I go out 281 | * there regularly and will generally respond to questions posed in the 282 | * message base promptly (not the Chat). http://www.universalthread.com 283 | * In addition to me, there are other API experts who frequent UT, and 284 | * they may well be able to help, in many cases better than I could. 285 | * Posting questions on UT helps not only with getting support 286 | * from the VFP community at large, it also makes the information about 287 | * the problem and its solution available to others who might have the 288 | * same or similar problems. 289 | * 290 | * Other than by UT, especially if you have to send files to help 291 | * diagnose the problem, send them to me at edrauh@earthlink.net or 292 | * erauh@snet.net, preferably the earthlink.net account. 293 | * 294 | * If you have questions about this code, you can ask. If you have 295 | * questions about using it with API calls and the like, you can ask. 296 | * If you have enhancements that you'd like to see added to the code, 297 | * you can ask, but you have the source, and ought to add them yourself. 298 | * Flames will be ignored. I'll try to answer promptly, but realize 299 | * that support and enhancements for this are done in my own spare time. 300 | * If you need specific support that goes beyond what I feel is 301 | * reasonable, I'll tell you. 302 | * 303 | * Do not call me at home or work for support. Period. 304 | * 305 | * 306 | * Feel free to modify this code to fit your specific needs. Since 307 | * I'm not providing any warranty with this in any case, if you change 308 | * it and it breaks, you own both pieces. 309 | * 310 | DEFINE CLASS heap AS custom 311 | 312 | 313 | PROTECTED inHandle, inNumAllocsActive,iaAllocs[1,3] 314 | inHandle = NULL 315 | inNumAllocsActive = 0 316 | iaAllocs = NULL 317 | Name = "heap" 318 | 319 | PROCEDURE Alloc 320 | * Allocate a block, returning a pointer to it 321 | LPARAMETER nSize 322 | DECLARE INTEGER HeapAlloc IN WIN32API AS HAlloc; 323 | INTEGER hHeap, ; 324 | INTEGER dwFlags, ; 325 | INTEGER dwBytes 326 | DECLARE INTEGER HeapSize IN WIN32API AS HSize ; 327 | INTEGER hHeap, ; 328 | INTEGER dwFlags, ; 329 | INTEGER lpcMem 330 | LOCAL nPtr 331 | WITH this 332 | nPtr = HAlloc(.inHandle, 0, @nSize) 333 | IF nPtr # 0 334 | * Bump the allocation array 335 | .inNumAllocsActive = .inNumAllocsActive + 1 336 | DIMENSION .iaAllocs[.inNumAllocsActive,3] 337 | * Pointer 338 | .iaAllocs[.inNumAllocsActive,1] = nPtr 339 | * Size actually allocated - get with HeapSize() 340 | .iaAllocs[.inNumAllocsActive,2] = HSize(.inHandle, 0, nPtr) 341 | * It's alive...alive I tell you! 342 | .iaAllocs[.inNumAllocsActive,3] = .T. 343 | ELSE 344 | * HeapAlloc() failed - return a NULL for the pointer 345 | nPtr = NULL 346 | ENDIF 347 | ENDWITH 348 | RETURN nPtr 349 | ENDPROC 350 | 351 | * new methods added 2/11-2/12; pretty simple, actually, but they make 352 | * coding using the heap object much cleaner. In case it isn't clear, 353 | * what I refer to as a BString is just the normal view of a VFP string 354 | * variable; it's any array of char with an explicit length, as opposed 355 | * to the normal CString view of the world, which has an explicit 356 | * terminator (the null char at the end.) 357 | 358 | FUNCTION AllocBLOB 359 | * Allocate a block of memory the size of the BString passed. The 360 | * allocation will be at least LEN(cBStringToCopy) off the heap. 361 | LPARAMETER cBStringToCopy 362 | LOCAL nAllocPtr 363 | WITH this 364 | nAllocPtr = .Alloc(LEN(cBStringToCopy)) 365 | IF ! ISNULL(nAllocPtr) 366 | .CopyTo(nAllocPtr,cBStringToCopy) 367 | ENDIF 368 | ENDWITH 369 | RETURN nAllocPtr 370 | ENDFUNC 371 | 372 | FUNCTION AllocString 373 | * Allocate a block of memory to fill with a null-terminated string 374 | * make a null-terminated string by appending CHR(0) to the end 375 | * Note - I don't check if a null character precedes the end of the 376 | * inbound string, so if there's an embedded null and whatever is 377 | * using the block works with CStrings, it might bite you. 378 | LPARAMETER cString 379 | RETURN this.AllocBLOB(cString + CHR(0)) 380 | ENDFUNC 381 | 382 | FUNCTION AllocInitAs 383 | * Allocate a block of memory preinitialized to CHR(nByteValue) 384 | LPARAMETER nSizeOfBuffer, nByteValue 385 | IF TYPE('nByteValue') # 'N' OR ! BETWEEN(nByteValue,0,255) 386 | * Default to initialize with nulls 387 | nByteValue = 0 388 | ENDIF 389 | RETURN this.AllocBLOB(REPLICATE(CHR(nByteValue),nSizeOfBuffer)) 390 | ENDFUNC 391 | 392 | * This is the end of the new methods added 2/12/99 393 | 394 | PROCEDURE DeAlloc 395 | * Discard a previous Allocated block 396 | LPARAMETER nPtr 397 | DECLARE INTEGER HeapFree IN WIN32API AS HFree ; 398 | INTEGER hHeap, ; 399 | INTEGER dwFlags, ; 400 | INTEGER lpMem 401 | LOCAL nCtr 402 | * Change to use .FindAllocID() and return !ISNULL() 9/29/2000 EMR 403 | nCtr = NULL 404 | WITH this 405 | nCtr = .FindAllocID(nPtr) 406 | IF ! ISNULL(nCtr) 407 | =HFree(.inHandle, 0, nPtr) 408 | .iaAllocs[nCtr,3] = .F. 409 | ENDIF 410 | ENDWITH 411 | RETURN ! ISNULL(nCtr) 412 | ENDPROC 413 | 414 | 415 | PROCEDURE CopyTo 416 | * Copy a VFP string into a block 417 | LPARAMETER nPtr, cSource 418 | * ReDECLARE RtlMoveMemory to make copy parameters easy 419 | DECLARE RtlMoveMemory IN WIN32API AS RtlCopy ; 420 | INTEGER nDestBuffer, ; 421 | STRING @pVoidSource, ; 422 | INTEGER nLength 423 | LOCAL nCtr 424 | nCtr = NULL 425 | * Change to use .FindAllocID() and return ! ISNULL() 9/29/2000 EMR 426 | IF TYPE('nPtr') = 'N' AND TYPE('cSource') $ 'CM' ; 427 | AND ! (ISNULL(nPtr) OR ISNULL(cSource)) 428 | WITH this 429 | * Find the Allocation pointed to by nPtr 430 | nCtr = .FindAllocID(nPtr) 431 | IF ! ISNULL(nCtr) 432 | * Copy the smaller of the buffer size or the source string 433 | =RtlCopy((.iaAllocs[nCtr,1]), ; 434 | cSource, ; 435 | MIN(LEN(cSource),.iaAllocs[nCtr,2])) 436 | ENDIF 437 | ENDWITH 438 | ENDIF 439 | RETURN ! ISNULL(nCtr) 440 | ENDPROC 441 | 442 | 443 | PROCEDURE CopyFrom 444 | * Copy the content of a buffer back to the VFP world 445 | LPARAMETER nPtr 446 | * Note that we reDECLARE RtlMoveMemory to make passing things easier 447 | DECLARE RtlMoveMemory IN WIN32API AS RtlCopy ; 448 | STRING @DestBuffer, ; 449 | INTEGER pVoidSource, ; 450 | INTEGER nLength 451 | LOCAL nCtr, uBuffer 452 | uBuffer = NULL 453 | nCtr = NULL 454 | * Change to use .FindAllocID() and return NULL 9/29/2000 EMR 455 | IF TYPE('nPtr') = 'N' AND ! ISNULL(nPtr) 456 | WITH this 457 | * Find the allocation whose address is nPtr 458 | nCtr = .FindAllocID(nPtr) 459 | IF ! ISNULL(nCtr) 460 | * Allocate a buffer in VFP big enough to receive the block 461 | uBuffer = REPL(CHR(0),.iaAllocs[nCtr,2]) 462 | =RtlCopy(@uBuffer, ; 463 | (.iaAllocs[nCtr,1]), ; 464 | (.iaAllocs[nCtr,2])) 465 | ENDIF 466 | ENDWITH 467 | ENDIF 468 | RETURN uBuffer 469 | ENDPROC 470 | 471 | PROTECTED FUNCTION FindAllocID 472 | * Search for iaAllocs entry matching the pointer 473 | * passed to the function. If found, it returns the 474 | * element ID; returns NULL if not found 475 | LPARAMETER nPtr 476 | LOCAL nCtr 477 | WITH this 478 | FOR nCtr = 1 TO .inNumAllocsActive 479 | IF .iaAllocs[nCtr,1] = nPtr AND .iaAllocs[nCtr,3] 480 | EXIT 481 | ENDIF 482 | ENDFOR 483 | RETURN IIF(nCtr <= .inNumAllocsActive,nCtr,NULL) 484 | ENDWITH 485 | ENDPROC 486 | 487 | PROCEDURE SizeOfBlock 488 | * Retrieve the actual memory size of an allocated block 489 | LPARAMETERS nPtr 490 | LOCAL nCtr, nSizeOfBlock 491 | nSizeOfBlock = NULL 492 | * Change to use .FindAllocID() and return NULL 9/29/2000 EMR 493 | WITH this 494 | * Find the allocation whose address is nPtr 495 | nCtr = .FindAllocID(nPtr) 496 | RETURN IIF(ISNULL(nCtr),NULL,.iaAllocs[nCtr,2]) 497 | ENDWITH 498 | ENDPROC 499 | 500 | PROCEDURE Destroy 501 | DECLARE HeapDestroy IN WIN32API AS HDestroy ; 502 | INTEGER hHeap 503 | 504 | LOCAL nCtr 505 | WITH this 506 | FOR nCtr = 1 TO .inNumAllocsActive 507 | IF .iaAllocs[nCtr,3] 508 | .Dealloc(.iaAllocs[nCtr,1]) 509 | ENDIF 510 | ENDFOR 511 | HDestroy[.inHandle] 512 | ENDWITH 513 | DODEFAULT() 514 | ENDPROC 515 | 516 | 517 | PROCEDURE Init 518 | DECLARE INTEGER HeapCreate IN WIN32API AS HCreate ; 519 | INTEGER dwOptions, ; 520 | INTEGER dwInitialSize, ; 521 | INTEGER dwMaxSize 522 | #DEFINE SwapFilePageSize 4096 523 | #DEFINE BlockAllocSize 2 * SwapFilePageSize 524 | WITH this 525 | .inHandle = HCreate(0, BlockAllocSize, 0) 526 | DIMENSION .iaAllocs[1,3] 527 | .iaAllocs[1,1] = 0 528 | .iaAllocs[1,2] = 0 529 | .iaAllocs[1,3] = .F. 530 | .inNumAllocsActive = 0 531 | ENDWITH 532 | RETURN (this.inHandle # 0) 533 | ENDPROC 534 | 535 | 536 | ENDDEFINE 537 | * 538 | *-- EndDefine: heap 539 | ************************************************** 540 | * 541 | * Additional functions for working with structures and pointers and stuff 542 | * 543 | FUNCTION SetMem 544 | LPARAMETERS nPtr, cSource 545 | * Copy cSource to the memory location specified by nPtr 546 | * ReDECLARE RtlMoveMemory to make copy parameters easy 547 | * nPtr is not validated against legal allocations on the heap 548 | DECLARE RtlMoveMemory IN WIN32API AS RtlCopy ; 549 | INTEGER nDestBuffer, ; 550 | STRING @pVoidSource, ; 551 | INTEGER nLength 552 | 553 | RtlCopy(nPtr, ; 554 | cSource, ; 555 | LEN(cSource)) 556 | RETURN .T. 557 | 558 | FUNCTION GetMem 559 | LPARAMETERS nPtr, nLen 560 | * Copy the content of a memory block at nPtr for nLen bytes back to a VFP string 561 | * Note that we ReDECLARE RtlMoveMemory to make passing things easier 562 | * nPtr is not validated against legal allocations on the heap 563 | DECLARE RtlMoveMemory IN WIN32API AS RtlCopy ; 564 | STRING @DestBuffer, ; 565 | INTEGER pVoidSource, ; 566 | INTEGER nLength 567 | LOCAL uBuffer 568 | * Allocate a buffer in VFP big enough to receive the block 569 | uBuffer = REPL(CHR(0),nLen) 570 | =RtlCopy(@uBuffer, ; 571 | nPtr, ; 572 | nLen) 573 | RETURN uBuffer 574 | 575 | FUNCTION GetMemString 576 | LPARAMETERS nPtr, nSize 577 | * Copy the string at location nPtr into a VFP string 578 | * We're going to use lstrcpyn rather than RtlMoveMemory to copy up to a terminating null 579 | * nPtr is not validated against legal allocations on the heap 580 | * 581 | * Change 9/29/2000 - second optional parameter nSize added to allow an override 582 | * of the string length; no major expense, but probably an open invitation 583 | * to cliff-diving, since variant CStrings longer than 511 bytes, or less 584 | * often, 254 bytes, will generally fall down go Boom! 585 | * 586 | DECLARE INTEGER lstrcpyn IN WIN32API AS StrCpyN ; 587 | STRING @ lpDestString, ; 588 | INTEGER lpSource, ; 589 | INTEGER nMaxLength 590 | LOCAL uBuffer 591 | IF TYPE('nSize') # 'N' OR ISNULL(nSize) 592 | nSize = 512 593 | ENDIF 594 | * Allocate a buffer big enough to receive the data 595 | uBuffer = REPL(CHR(0), nSize) 596 | IF StrCpyN(@uBuffer, nPtr, nSize-1) # 0 597 | uBuffer = LEFT(uBuffer, MAX(0,AT(CHR(0),uBuffer) - 1)) 598 | ELSE 599 | uBuffer = NULL 600 | ENDIF 601 | RETURN uBuffer 602 | 603 | FUNCTION SHORTToNum 604 | * Converts a 16 bit signed integer in a structure to a VFP Numeric 605 | LPARAMETER tcInt 606 | LOCAL b0,b1,nRetVal 607 | b0=asc(tcInt) 608 | b1=asc(subs(tcInt,2,1)) 609 | if b1<128 610 | * 611 | * positive - do a straight conversion 612 | * 613 | nRetVal=b1 * 256 + b0 614 | else 615 | * 616 | * negative value - take twos complement and negate 617 | * 618 | b1=255-b1 619 | b0=256-b0 620 | nRetVal= -( (b1 * 256) + b0) 621 | endif 622 | return nRetVal 623 | 624 | FUNCTION NumToSHORT 625 | * 626 | * Creates a C SHORT as a string from a number 627 | * 628 | * Parameters: 629 | * 630 | * tnNum (R) Number to convert 631 | * 632 | LPARAMETER tnNum 633 | * 634 | * b0, b1, x hold small ints 635 | * 636 | LOCAL b0,b1,x 637 | IF tnNum>=0 638 | x=INT(tnNum) 639 | b1=INT(x/256) 640 | b0=MOD(x,256) 641 | ELSE 642 | x=INT(-tnNum) 643 | b1=255-INT(x/256) 644 | b0=256-MOD(x,256) 645 | IF b0=256 646 | b0=0 647 | b1=b1+1 648 | ENDIF 649 | ENDIF 650 | RETURN CHR(b0)+CHR(b1) 651 | 652 | FUNCTION DWORDToNum 653 | * Take a binary DWORD and convert it to a VFP Numeric 654 | * use this to extract an embedded pointer in a structure in a string to an nPtr 655 | LPARAMETER tcDWORD 656 | LOCAL b0,b1,b2,b3 657 | b0=asc(tcDWORD) 658 | b1=asc(subs(tcDWORD,2,1)) 659 | b2=asc(subs(tcDWORD,3,1)) 660 | b3=asc(subs(tcDWORD,4,1)) 661 | RETURN ( ( (b3 * 256 + b2) * 256 + b1) * 256 + b0) 662 | 663 | *!* FUNCTION NumToDWORD 664 | *!* * 665 | *!* * Creates a 4 byte binary string equivalent to a C DWORD from a number 666 | *!* * use to embed a pointer or other DWORD in a structure 667 | *!* * Parameters: 668 | *!* * 669 | *!* * tnNum (R) Number to convert 670 | *!* * 671 | *!* LPARAMETER tnNum 672 | *!* * 673 | *!* * x,n,i,b[] will hold small ints 674 | *!* * 675 | *!* LOCAL x,n,i,b[4] 676 | *!* x=INT(tnNum) 677 | *!* FOR i=3 TO 0 STEP -1 678 | *!* b[i+1]=INT(x/(256^i)) 679 | *!* x=MOD(x,(256^i)) 680 | *!* ENDFOR 681 | *!* RETURN CHR(b[1])+CHR(b[2])+CHR(b[3])+CHR(b[4]) 682 | * Redirected to NumToLong() using recasting; comment out 683 | * the redirection and uncomment NumToDWORD() if original is needed 684 | FUNCTION NumToDWORD 685 | LPARAMETER tnNum 686 | RETURN NumToLong(tnNum) 687 | * End redirection 688 | 689 | FUNCTION WORDToNum 690 | * Take a binary WORD (16 bit USHORT) and convert it to a VFP Numeric 691 | LPARAMETER tcWORD 692 | RETURN (256 * ASC(SUBST(tcWORD,2,1)) ) + ASC(tcWORD) 693 | 694 | FUNCTION NumToWORD 695 | * 696 | * Creates a C USHORT (WORD) from a number 697 | * 698 | * Parameters: 699 | * 700 | * tnNum (R) Number to convert 701 | * 702 | LPARAMETER tnNum 703 | * 704 | * x holds an int 705 | * 706 | LOCAL x 707 | x=INT(tnNum) 708 | RETURN CHR(MOD(x,256))+CHR(INT(x/256)) 709 | 710 | FUNCTION NumToLong 711 | * 712 | * Creates a C LONG (signed 32-bit) 4 byte string from a number 713 | * NB: this works faster than the original NumToDWORD(), which could have 714 | * problems with trunaction of values > 2^31 under some versions of VFP with 715 | * #DEFINEd or converted constant values in excess of 2^31-1 (0x7FFFFFFF). 716 | * I've redirected NumToDWORD() and commented it out; NumToLong() 717 | * expects to work with signed values and uses BITOR() to recast values 718 | * in the range of -(2^31) to (2^31-1), 0xFFFFFFFF is not the same 719 | * as -1 when represented in an N-type field. If you don't need to 720 | * use constants with the high-order bit set, or are willing to let 721 | * the UDF cast the value consistently, especially using pointer math 722 | * on the system's part of the address space, this and its counterpart 723 | * LONGToNum() are the better choice for speed, or to save to an I-field. 724 | * 725 | * To properly cast a constant/value with the high-order bit set, you 726 | * can BITOR(nVal,0); 0xFFFFFFFF # -1 but BITOR(0xFFFFFFFF,0) = BITOR(-1,0) 727 | * is true, and converts the N-type in the range 2^31 - (2^32-1) to a 728 | * twos-complement negative integer value. You can disable BITOR() casting 729 | * in this function by commenting the proper line in this UDF(); this 730 | * results in a slight speed increase. 731 | * 732 | * Parameters: 733 | * 734 | * tnNum (R) Number to convert 735 | * 736 | LPARAMETER tnNum 737 | DECLARE RtlMoveMemory IN WIN32API AS RtlCopyLong ; 738 | STRING @pDestString, ; 739 | INTEGER @pVoidSource, ; 740 | INTEGER nLength 741 | LOCAL cString 742 | cString = SPACE(4) 743 | * Function call not using BITOR() 744 | * =RtlCopyLong(@cString, tnNum, 4) 745 | * Function call using BITOR() to cast numerics 746 | =RtlCopyLong(@cString, BITOR(tnNum,0), 4) 747 | RETURN cString 748 | 749 | FUNCTION LongToNum 750 | * 751 | * Converts a 32 bit LONG to a VFP numeric; it treats the result as a 752 | * signed value, with a range -2^31 - (2^31-1). This is faster than 753 | * DWORDToNum(). There is no one-function call that causes negative 754 | * values to recast as positive values from 2^31 - (2^32-1) that I've 755 | * found that doesn't take a speed hit. 756 | * 757 | * Parameters: 758 | * 759 | * tcLong (R) 4 byte string containing the LONG 760 | * 761 | LPARAMETER tcLong 762 | DECLARE RtlMoveMemory IN WIN32API AS RtlCopyLong ; 763 | INTEGER @ DestNum, ; 764 | STRING @ pVoidSource, ; 765 | INTEGER nLength 766 | LOCAL nNum 767 | nNum = 0 768 | =RtlCopyLong(@nNum, tcLong, 4) 769 | RETURN nNum 770 | 771 | FUNCTION AllocNetAPIBuffer 772 | * 773 | * Allocates a NetAPIBuffer at least nBtes in Size, and returns a pointer 774 | * to it as an integer. A NULL is returned if allocation fails. 775 | * The API call is not supported under Win9x 776 | * 777 | * Parameters: 778 | * 779 | * nSize (R) Number of bytes to allocate 780 | * 781 | LPARAMETER nSize 782 | IF TYPE('nSize') # 'N' OR nSize <= 0 783 | * Invalid argument passed, so return a null 784 | RETURN NULL 785 | ENDIF 786 | IF ! 'NT' $ OS() 787 | * API call only supported under NT, so return failure 788 | RETURN NULL 789 | ENDIF 790 | DECLARE INTEGER NetApiBufferAllocate IN NETAPI32.DLL ; 791 | INTEGER dwByteCount, ; 792 | INTEGER lpBuffer 793 | LOCAL nBufferPointer 794 | nBufferPointer = 0 795 | IF NetApiBufferAllocate(INT(nSize), @nBufferPointer) # 0 796 | * The call failed, so return a NULL value 797 | nBufferPointer = NULL 798 | ENDIF 799 | RETURN nBufferPointer 800 | 801 | FUNCTION DeAllocNetAPIBuffer 802 | * 803 | * Frees the NetAPIBuffer allocated at the address specified by nPtr. 804 | * The API call is not supported under Win9x 805 | * 806 | * Parameters: 807 | * 808 | * nPtr (R) Address of buffer to free 809 | * 810 | * Returns: .T./.F. 811 | * 812 | LPARAMETER nPtr 813 | IF TYPE('nPtr') # 'N' 814 | * Invalid argument passed, so return failure 815 | RETURN .F. 816 | ENDIF 817 | IF ! 'NT' $ OS() 818 | * API call only supported under NT, so return failure 819 | RETURN .F. 820 | ENDIF 821 | DECLARE INTEGER NetApiBufferFree IN NETAPI32.DLL ; 822 | INTEGER lpBuffer 823 | RETURN (NetApiBufferFree(INT(nPtr)) = 0) 824 | 825 | Function CopyDoubleToString 826 | LPARAMETER nDoubleToCopy 827 | * ReDECLARE RtlMoveMemory to make copy parameters easy 828 | DECLARE RtlMoveMemory IN WIN32API AS RtlCopyDbl ; 829 | STRING @DestString, ; 830 | DOUBLE @pVoidSource, ; 831 | INTEGER nLength 832 | LOCAL cString 833 | cString = SPACE(8) 834 | =RtlCopyDbl(@cString, nDoubleToCopy, 8) 835 | RETURN cString 836 | 837 | FUNCTION DoubleToNum 838 | LPARAMETER cDoubleInString 839 | DECLARE RtlMoveMemory IN WIN32API AS RtlCopyDbl ; 840 | DOUBLE @DestNumeric, ; 841 | STRING @pVoidSource, ; 842 | INTEGER nLength 843 | LOCAL nNum 844 | * Christof Lange pointed out that there's a feature of VFP that results 845 | * in the entry in the NTI retaining its precision after updating the value 846 | * directly; force the resulting precision to a large value before moving 847 | * data into the temp variable 848 | nNum = 0.000000000000000000 849 | =RtlCopyDbl(@nNum, cDoubleInString, 8) 850 | RETURN nNum -------------------------------------------------------------------------------- /avfp6.03_source/reports/pdfrun.PJT: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/claudefox/ActiveVFP/28ada3cd4b268635e3bcd67ea842ec522c3def82/avfp6.03_source/reports/pdfrun.PJT -------------------------------------------------------------------------------- /avfp6.03_source/reports/pdfrun.pjx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/claudefox/ActiveVFP/28ada3cd4b268635e3bcd67ea842ec522c3def82/avfp6.03_source/reports/pdfrun.pjx --------------------------------------------------------------------------------