home *** CD-ROM | disk | FTP | other *** search
- /*
- SpreadSh.c
-
- High Level Functions for AutoCAD and Spreadsheet DDE
-
- ________________________________________________________________________
-
- (C) Copyright 1990-1995 by Autodesk, Inc.
-
- Permission to use, copy, modify, and distribute this software and its
- documentation for any purpose and without fee is hereby granted.
-
- THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
- ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF
- MERCHANTABILITY ARE HEREBY DISCLAIMED.
- ________________________________________________________________________
-
-
-
- See "Dde.txt" for more information.
-
-
- A DDE channel must be opened using an application name and a
- topic, or work file, name. See DdeInitiate.
- Transfers on that channel then use a string called an "item "to
- identify the range of data. A DDE "item", in the case of
- spreadsheets, is a string referencing a range in a two dimensional
- array of cells. For example, the item string "R3C1:R4C2" would refer
- to cells from row 3, col 1 to row 4, col 2. Data in those cells
- might look like:
-
- 10 5
- 20 6
-
- and would be returned by DDE functions such as DdeRequest in
- pdde->pData, in the form:
-
- "10<TAB>5<CR><LF>20<TAB>6<CR><LF>"
-
- This is the clipboard/DDE text format, CF_TEXT.
- */
-
-
-
- #include "options.h"
-
- #include <stdio.h>
- #include <math.h>
-
- #include "adslib.h"
-
- #include <process.h>
- #include <string.h>
- #include <memory.h>
- #include <dos.h>
- #include <ctype.h>
-
- #include "winutil.h"
- #include "ddewin.h"
- #include "ddeconv.h"
- #include "spreadsh.h"
- #include "acaddefs.h"
-
- extern ddeDATA DdeData; /* DDE globals and defaults. */
-
- static char *ssrow = DdeData.rowspec;
- static char *sscol = DdeData.colspec;
- static char *ssdelim = DdeData.rangespec;
-
- /* Specify Excel or Lotus cell specification style */
- void
- AppType(int ss_type)
- {
- DdeData.apptype = ss_type;
-
- #ifdef DOMESTIC_US
- switch (ss_type) {
- case SSEXCEL:
- /* R1C1:R234C4 */
- strcpy(ssrow, "R");
- strcpy(sscol, "C");
- strcpy(ssdelim, ":");
- break;
-
- case SSLOTUS:
- /* A1..D234 */
- strcpy(ssrow, "");
- strcpy(sscol, "");
- strcpy(ssdelim, "..");
- break;
-
- default:
- break;
- }
- #endif /* DOMESTIC_US */
- }
-
-
-
- /*
- Spreadsheet DDE Receive Functions
- */
-
-
-
- /* Get an ads_real (double) request data in pReal, which
- could be a pointer to an array of ads_reals. Request
- spreadsheet data starting at Row, Col. nRow is the
- number of rows, nCol the number of columns.
- */
- int RequestRealArray(PDDE pdde, ads_real *pReal, UINT Row, UINT Col,
- UINT nRow, UINT nCol)
- {
- char CellItem[CELLMAX];
- short Ret = FALSE;
- DWORD DdeResult;
- short cnt;
-
- CellRange(CellItem, Row, Col, nRow, nCol);
- DdeResult = DdeRequest(pdde, CellItem, CF_TEXT, DATAWAIT);
- if (pdde->DataSize != 0) {
-
- /* load array of points with converted
- string data from the spreadsheet */
- cnt = StrToReals(pdde->pData, pReal, nRow, nCol);
- DdeFreeData(pdde); /* free shared data */
- return cnt;
- }
- else
- return 0;
- }
-
-
- /* Get ads_real (double) request data in pReal.
- */
- int ReqCellData(PDDE pdde, ads_real *pReal, UINT Row, UINT Col)
- {
- short Ret = FALSE;
- DWORD DdeResult;
- char CellItem[CELLMAX];
-
- CellItemName(CellItem, Row, Col);
- DdeResult = DdeRequest(pdde, CellItem, CF_TEXT, DATAWAIT);
- if (pdde->DataSize != 0) {
- *pReal = StrToReal(pdde->pData);
- DdeFreeData(pdde); /* free shared data */
- Ret = TRUE;
- }
- return Ret;
- }
-
-
- /*
- Spreadsheet DDE Transmit Functions
- */
-
- /* Send out a range of ads_reals (doubles), in array starting
- at pReal.
- */
- int PokeRealArray(PDDE pdde, ads_real *pReal, UINT Row, UINT Col,
- UINT nRow, UINT nCol)
- {
- char CellItem[CELLMAX];
- DWORD DdeResult;
- ULONG DataLen;
- PHDATA CellDataStr;
-
- CellDataStr = RealsToStr(pReal, nRow, nCol, &DataLen);
- if (!CellDataStr)
- return 0;
- ++DataLen; /* include NULL */
- CellRange(CellItem, Row, Col, nRow, nCol);
- DdeResult = DdePoke(pdde, CellItem, DataLen, CellDataStr, CF_TEXT);
- FreeFar(CellDataStr);
- return DdeResult != 0;
- }
-
-
- /* Send out a list of strings to a range in a spreadsheet.
- TextLink is the first PLINK in a list.
- */
- int PokeList(PDDE pdde, PLINK TextLink, UINT Row, UINT Col,
- UINT nRow, UINT nCol)
- {
- char CellItem[CELLMAX];
- DWORD DdeResult;
- ULONG DataLen = 0L;
- UINT cCol = 0;
- PHDATA CellDataStr;
-
- CellDataStr = DdeFormatList(TextLink, nCol, &DataLen);
- CellRange(CellItem, Row, Col, nRow, nCol);
- DdeResult = DdePoke(pdde, CellItem, DataLen, CellDataStr, CF_TEXT);
- FreeFar(CellDataStr);
- return DdeResult != 0;
- }
-
-
-
-
- /* Send out a ads_real (double).
- */
- int PokeReal(PDDE pdde, ads_real Real, UINT Row, UINT Col)
- {
- char CellItem[CELLMAX];
- char StrData[FPSTR+1];
- DWORD DdeResult;
-
- RealToStr(Real, StrData);
- CellItemName(CellItem, Row, Col);
- DdeResult = DdePokeString(pdde, CellItem, StrData);
- return DdeResult != 0;
- }
-
-
-
- /* For inserting formulas into spreadsheets:
- build a cell reference string to Row, Col
- (1 based). E.g., row 3, col 1: "=A3"
- */
- VOID CellRef(char *CellRefStr, UINT Row, UINT Col)
- {
- char NumStr[20];
- char *pstr = CellRefStr;
-
- *pstr++ = '=';
- if (Col > 26) {
- *pstr++ = (char)((Col / 26) - 1 + 'A');
- *pstr++ = (char)((Col % 26) - 1 + 'A');
- } else {
- *pstr++ = (char)(Col - 1 + 'A');
- }
- _itoa(Row, NumStr, 10);
- strcpy(pstr, NumStr);
- }
-
-
- /* Build DDE Item name, such as "R2C5:R11C10", from start
- row, col, number of rows, cols.
- */
- VOID CellRange(char *CellItem, UINT Row, UINT Col,
- UINT nRow, UINT nCol)
- {
- UINT Row2, Col2;
- char NumStr[20];
-
- Row2 = Row + nRow - 1;
- Col2 = Col + nCol - 1;
-
- if (DdeData.apptype == SSEXCEL) {
- strcpy(CellItem, ssrow);
- _itoa(Row, NumStr, 10);
- strcat(CellItem, NumStr);
-
- strcat(CellItem, sscol);
- _itoa(Col, NumStr, 10);
- strcat(CellItem, NumStr);
- if (nRow == 1 && nCol == 1)
- return;
-
- strcat(CellItem, ssdelim);
- strcat(CellItem, ssrow);
- _itoa(Row2, NumStr, 10);
- strcat(CellItem, NumStr);
-
- strcat(CellItem, sscol);
- _itoa(Col2, NumStr, 10);
- strcat(CellItem, NumStr);
- } else {
- CellItemName(CellItem, Row, Col);
- if (nRow == 1 && nCol == 1)
- return;
- strcat(CellItem, ssdelim);
- CellItemName(NumStr, Row2, Col2);
- strcat(CellItem, NumStr);
- }
- }
-
-
- /* For DDE Item field: build "R2C5" from Row 2, Col 5, into your
- passed string, CellItemName.
- */
- VOID CellItemName(char *CellItem, UINT Row, UINT Col)
- {
- char NumStr[20];
- char ColChar;
-
- if (DdeData.apptype == SSEXCEL) {
- strcpy(CellItem, ssrow);
- _itoa(Row, NumStr, 10);
- strcat(CellItem, NumStr);
-
- strcat(CellItem, sscol);
- _itoa(Col, NumStr, 10);
- strcat(CellItem, NumStr);
- } else {
- ColChar = (char)(Col-1+'A');
- CellItem[0] = ColChar;
- CellItem[1] = EOS;
- _itoa(Row, NumStr, 10);
- strcat(CellItem, NumStr);
- }
- }
-
-
-
- /* Get the row, col, number of rows, number of cols expressed in
- the RxCx:RyCy string, CellItem. Returns TRUE if the ":" was
- found, indicating a range of cells.
- */
- int GetCellRange(char *CellItem, UINT *Row, UINT *Col,
- UINT *nRow, UINT *nCol)
- {
- char *ptr;
- char *Range2;
- short Idx;
- UINT ScanRow[2], ScanCol[2];
- char ItemStr[41];
- short RangeFlag = FALSE;
- int delimlen = strlen(ssdelim);
-
- *Row = *Col = *nRow = *nCol = 1;
- if (!CellItem || !CellItem[0])
- return FALSE;
- if (CellItem[0] != *ssrow && CellItem[0] != tolower(*ssrow))
- return FALSE;
- strzcpy(ItemStr, CellItem, 40);
- ptr = ItemStr;
-
- /* Look for ":" or ".." the range separators. */
- for ( ; *ptr != EOS; ++ptr) {
- if (!strncmp(ptr, ssdelim, delimlen)) {
- RangeFlag = TRUE;
- Range2 = ptr+delimlen; /* Second half of range */
- *ptr = 0;
- break;
- }
- }
-
- for (Idx = 0; Idx <= 1; ++Idx) {
- if (Idx == 0)
- ptr = ItemStr;
- else
- ptr = Range2;
- GetCellNum(ptr, &ScanRow[Idx], &ScanCol[Idx]);
- if (!RangeFlag)
- break;
- }
-
- *Row = ScanRow[0];
- *Col = ScanCol[0];
- if (!RangeFlag)
- return FALSE;
- *nRow = ScanRow[1] - ScanRow[0] + 1;
- *nCol = ScanCol[1] - ScanCol[0] + 1;
- return TRUE;
- }
-
-
-
- /* Get Row and col from "R3C1" cell item string. 0 means
- current row or col
- */
- VOID GetCellNum(char *CellStr, UINT *Row, UINT *Col)
- {
- char Chr;
- char *ptr;
-
- ptr = CellStr;
- while (Chr = *ptr++) {
- if (Chr == *ssrow || Chr == *sscol) {
- if (isdigit(*ptr)) {
- if (Chr == *ssrow)
- *Row = atoi(ptr);
- else if (Chr == *sscol)
- *Col = atoi(ptr);
- }
- else {
- if (Chr == *ssrow)
- *Row = 0;
- else if (Chr == *sscol)
- *Col = 0;
- }
- }
- }
- }
-
-
-
- /* Find number of rows and col's in data returned
- by a cell range, such as "R3C1:R12C2"
- */
- VOID GetCellDim(PHDATA DataStrm, UINT *nRow, UINT *nCol)
- {
- UINT Row = 0;
- UINT Col = 1;
- char Chr;
- short FirstRow = TRUE;
-
- while (Chr = *DataStrm++) {
- if (Chr == CR) {
- ++Row;
- FirstRow = FALSE;
- }
- else if (FirstRow && (Chr == FldSepChr))
- ++Col;
- }
- *nRow = Row;
- *nCol = Col;
- }
-
-
-
- /* end of file */
-
-