home *** CD-ROM | disk | FTP | other *** search
- *********************************************************************
- *
- * DDEData - Simple FoxPro DDE server
- *
- *********************************************************************
-
- #DEFINE SVR_NAME "DDEData"
-
- PUBLIC ARRAY aiCh(100)
-
- = DDESetService(SVR_NAME, "define")
- = DDESetService(SVR_NAME, "request", .T.)
- = DDESetService(SVR_NAME, "poke", .T.)
- = DDESetService(SVR_NAME, "execute", .T.)
- = DDESetService(SVR_NAME, "advise", .F.)
-
- = DDESetTopic(SVR_NAME, "", "cbDataTopic")
-
- RETURN
-
-
- *************************************************************
- * cbDataTopic - call back for Table, Query or SQL topics
- *
- * Valid Topics:
- * <database>;TABLE <table name>
- *
- * Any other topic will cause the INITIATE to fail
- *
- * Valid Items:
- * All - all data, including field names
- * Data - all data, without field names
- * FieldNames - a list of field names
- * NextRow - the next row of data
- * PrevRow - the previous row
- * FirstRow - the first row of data
- * Last row - the last row of data
- * FieldCount - the number of fields in the table
- * nn - row number to return
- * mm-nn range of rows to return
- *
- * A Poke request expects the field name as the Item, and
- * the new data for that field. No other Pokes are executed.
- *
- *************************************************************
-
- PROCEDURE cbDataTopic
-
- PARAMETERS iChannel, sAction, sItem, sData, sFormat, iStatus
- PRIVATE bResult, sDatabase, sRowType, sRowSrc, iTemp, sUpItem, sUpData
- PRIVATE sResult, iTemp2, bEnabState
- PRIVATE sTagTable, sTagSQL, sCRLF, sTAB
-
- = DDEEnabled(.F.) && we don't want interruptions
-
- sTagTable = ";TABLE" && must be uppercase
-
- bResult = .T.
-
- DO CASE
-
- CASE sAction = "INITIATE"
- sUpData = UPPER(sData)
- IF ! sTagTable $ sUpData
- bResult = .F.
- ELSE
- iTemp = AT(sTagTable, sUpData)
- sDatabase = LTRIM(SUBSTR(sUpData, 1, iTemp-1))
- SET DEFAULT TO (sDatabase)
-
- sRowSrc = ALLTRIM(SUBSTR(sData, iTemp + LEN(sTagTable)))
- IF NOT (FILE(sRowSrc) OR FILE(sRowSrc+".dbf"))
- bResult = .F.
- ELSE
- * Keep track of work areas used by separate DDE channels.
- iTemp = ASCAN(aiCh, .F.)
- IF iTemp = 0
- bResult = .F.
- ELSE
- aiCh[iTemp] = iChannel
- USE (sRowSrc) IN (iTemp) AGAIN
- ENDIF
- ENDIF
- ENDIF
-
- CASE sAction = "REQUEST"
- * Select work area for this DDE channel.
- iTemp = ASCAN(aiCh, iChannel)
- IF iTemp <> 0
- SELECT (iTemp)
- ENDIF
-
- sUpItem = UPPER(sItem)
- DO CASE
- CASE sUpItem = "FIELDNAMES"
- sResult = sFldNames()
-
- CASE sUpItem = "FIELDCOUNT"
- sResult = sFldCount()
-
- CASE sUpItem = "FIRSTROW"
- GOTO TOP
- sResult = sRowData()
-
- CASE sUpItem = "LASTROW"
- GOTO BOTTOM
- sResult = sRowData()
-
- CASE sUpItem = "NEXTROW"
- IF EOF()
- bResult = .F.
- ELSE
- SKIP
- sResult = sRowData()
- ENDIF
-
- CASE sUpItem = "PREVROW"
- IF BOF()
- bResult = .F.
- ELSE
- SKIP -1
- sResult = sRowData()
- ENDIF
-
- CASE sUpItem = "ALL"
- sResult = sFldNames() + sAllData()
-
- CASE sUpItem = "DATA"
- sResult = sAllData()
-
- CASE VAL(sUpItem) <> 0
- iFirst = MAX(1, MIN(INT(VAL(sUpItem)), RECCOUNT()))
- IF "-" $ sUpItem
- iLast = VAL(SUBSTR(sUpItem, AT("-", sUpItem)+1))
- iLast = MAX(1, MIN(iLast, RECCOUNT()))
- iLast = MAX(iFirst, iLast)
- sResult = ""
- GOTO iFirst
- FOR iTemp = iFirst TO iLast
- sResult = sResult + sRowData()
- SKIP
- ENDFOR
- ELSE
- GOTO iFirst
- sResult = sRowData()
- ENDIF
-
- OTHERWISE
- bResult = .F.
- ENDCASE
-
- * Send the requested data to the other application.
-
- IF bResult
- = DDEPoke(iChannel, sItem, sResult)
- ENDIF
-
- CASE sAction = "POKE"
- FOR iTemp = 1 TO FCOUNT()
- IF FIELD(iTemp) = UPPER(sItem)
- iTemp = 0
- REPLACE &sItem WITH vCvtField(TYPE('&sItem'), sData)
- EXIT
- ENDIF
- ENDFOR
- IF iTemp <> 0
- bResult = .F.
- ENDIF
-
- CASE sAction = "TERMINATE"
- iTemp = ASCAN(aiCh, iChannel)
- IF iTemp <> 0
- SELECT (iTemp)
- USE
- aiCh[iTemp] = .F.
- ENDIF
-
- OTHERWISE
- bResult = .F.
- ENDCASE
-
- = DDEEnabled(.T.)
-
- RETURN bResult
-
-
- ***********************************************************************
- *
- * Utility functions
- *
- ***********************************************************************
-
- #DEFINE sCRLF CHR(13) + CHR(10)
- #DEFINE sTAB CHR(9)
-
-
- FUNCTION sFldNames
- PRIVATE sResult, iTemp
-
- sResult = ""
- FOR iTemp = 1 TO FCOUNT()
- sResult = sResult + FIELD(iTemp) + sTAB
- ENDFOR
- sResult = SUBSTR(sResult, 1, LEN(sResult)-1) + sCRLF
-
- RETURN sResult
-
-
- FUNCTION sFldCount
- PRIVATE sResult
-
- sResult = STR(FCOUNT())+sCRLF
-
- RETURN sResult
-
-
- FUNCTION sRowData
- PRIVATE sResult, iTemp, avData
-
- SCATTER MEMO TO avData
-
- sResult = ""
- FOR iTemp = 1 TO FCOUNT()
- sResult = sResult + sCvtField(TYPE('avData[iTemp]'), avData[iTemp]) + sTAB
- ENDFOR
- sResult = SUBSTR(sResult, 1, LEN(sResult)-1) + sCRLF
-
- RETURN sResult
-
-
- FUNCTION sAllData
- PRIVATE sResult
-
- sResult = ""
- SCAN
- sResult = sResult + sRowData()
- ENDSCAN
-
- RETURN sResult
-
-
- FUNCTION sCvtField
- PARAMETERS sType, vValue
- PRIVATE sTemp
-
- DO CASE
- CASE INLIST(sType, 'C', 'M')
- sTemp = vValue
- CASE INLIST(sType, 'N', 'F')
- sTemp = ALLTRIM(STR(vValue,15))
- CASE sType = 'D'
- sTemp = DTOC(vValue)
- CASE sType = 'L'
- sTemp = IIF(vValue, 'YES', 'NO')
- ENDCASE
-
- RETURN sTemp
-
-
- FUNCTION vCvtField
- PARAMETERS sType, sValue
- PRIVATE vTemp
-
- DO CASE
- CASE INLIST(sType, 'C', 'M')
- vTemp = sValue
- CASE INLIST(sType, 'N', 'F')
- vTemp = VAL(sValue)
- CASE sType = 'D'
- vTemp = CTOD(sValue)
- CASE sType = 'L'
- vTemp = IIF(UPPER(ALLTRIM(sValue)) $ 'YES', .T., .F.)
- ENDCASE
-
- RETURN vTemp
-