Data Management
Because DDE uses memory objects to pass data from one application to another,
the DDEML provides a set of functions that DDE applications can use to create
and manage DDE objects.
All transactions that involve the exchange of data require the application
supplying the data to create a local buffer containing the data and then to call
the
DdeCreateDataHandle function. This function allocates a DDE object, copies the data from the
buffer to the object, and returns a data handle. A data handle is a doubleword
value that the DDEML uses to provide access to data in the DDE object. To share the
data in a DDE object, an application passes the data handle to the DDEML, and
the DDEML passes the handle to the DDE callback function of the application
that is receiving the data transaction.
The following example shows how to create a DDE object and obtain a handle of
the object. During the
XTYP_ADVREQ transaction, the callback function converts the current time to an ASCII
string, copies the string to a local buffer, and then creates a DDE object that
contains the string. The callback function returns the handle of the DDE object
(HDDEDATA) to the DDEML, which passes the handle to the client application.
typedef struct tagTIME
{
INT hour; /* 0 - 11 hours for analog clock */
INT hour12; /* 12-hour format */
INT hour24; /* 24-hour format */
INT minute;
INT second;
INT ampm; /* 0 - AM , 1 - PM */
} TIME;
HDDEDATA EXPENTRY DdeCallback(uType, uFmt, hconv, hsz1, hsz2,
hdata, dwData1, dwData2)
UINT uType;
UINT uFmt;
HCONV hconv;
HSZ hsz1;
HSZ hsz2;
HDDEDATA hdata;
DWORD dwData1;
DWORD dwData2;
{
CHAR szBuf[32];
switch (uType) {
case XTYP_ADVREQ:
if ((hsz1 == hszTime && hsz2 == hszNow) &&
(uFmt == CF_TEXT)) {
/* Copy the formatted string to a buffer. */
itoa(tmTime.hour, szBuf, 10);
lstrcat(szBuf, ":");
if (tmTime.minute < 10)
lstrcat(szBuf, "0");
itoa(tmTime.minute, &szBuf[lstrlen(szBuf)], 10);
lstrcat(szBuf, ":");
if (tmTime.second < 10)
strcat(szBuf, "0");
itoa(tmTime.second, &szBuf[lstrlen(szBuf)], 10);
szBuf[lstrlen(szBuf)] = '\0';
/* Create a global object and return its data handle. */
return (DdeCreateDataHandle(
idInst,
(LPBYTE) szBuf, /* instance identifier */
lstrlen(szBuf) + 1, /* source buffer length */
0, /* offset from beginning */
hszNow, /* item name string */
CF_TEXT, /* clipboard format */
0)); /* no creation flags */
} else
return (HDDEDATA) NULL;
.
. /* Process other transactions. */
.
}
}
The receiving application obtains a pointer to the DDE object by passing the
data handle to the
DdeAccessData function. The pointer returned by
DdeAccessData provides read-only access. The application should use the pointer to review
the data and then call the
DdeUnaccessData function to invalidate the pointer. The application can copy the data to a
local buffer by using the
DdeGetData function.
The following example obtains a pointer to the DDE object identified by the
hData parameter, copies the contents to a local buffer, and then invalidates the
pointer.
HDDEDATA hdata;
LPBYTE lpszAdviseData;
DWORD cbDataLen;
DWORD i;
char szData[32];
.
.
.
case XTYP_ADVDATA:
lpszAdviseData = DdeAccessData(hdata, &cbDataLen);
for (i = 0; i < cbDataLen; i++)
szData[i] = *lpszAdviseData++;
DdeUnaccessData(hdata);
return (HDDEDATA) TRUE;
.
.
.
Usually, when an application that created a data handle passes that handle to
the DDEML, the handle becomes invalid in the creating application. This
situation is not a problem if the application must share data with only a single
application. If an application must share the same data with multiple applications,
however, the creating application should specify the HDATA_APPOWNED flag in
DdeCreateDataHandle. Doing so gives ownership of the DDE object to the creating application and
prevents the DDEML from invalidating the data handle. The application can then
pass the data handle any number of times after calling
DdeCreateDataHandle only once.
If an application specifies the HDATA_APPOWNED flag in the
afCmd parameter of
DdeCreateDataHandle, it must call the
DdeFreeDataHandle function to free the memory handle, regardless of whether it passed the
handle to the DDEML. Before it terminates, an application must call
DdeFreeDataHandle to free any data handle that it created but did not pass to the DDEML.
An application that has not yet passed the handle of a DDE object to the DDEML
can add data to the object or overwrite data in the object by using the
DdeAddData function. Typically, an application uses
DdeAddData to fill an uninitialized DDE object. After an application passes a data
handle to the DDEML, the DDE object identified by the handle cannot be changed; it
can only be freed.
- Software for developers
-
Delphi Components
.Net Components
Software for Android Developers
- More information resources
-
MegaDetailed.Net
Unix Manual Pages
Delphi Examples
- Databases for Amazon shops developers
-
Amazon Categories Database
Browse Nodes Database