Gegevensbeheer
Omdat Dynamic Data Exchange (DDE) geheugenobjecten gebruikt om gegevens van de ene toepassing naar de andere door te geven, biedt de DDEML (Dynamic Data Exchange Management Library) een set functies die DDE-toepassingen kunnen gebruiken om DDE-objecten te maken en te beheren.
Alle transacties die betrekking hebben op de uitwisseling van gegevens, vereisen dat de toepassing de gegevens levert om een lokale buffer met de gegevens te maken en vervolgens de DdeCreateDataHandle--functie aan te roepen. Met deze functie wordt een DDE-object toegewezen, worden de gegevens uit de buffer gekopieerd naar het object en wordt een gegevensgreep geretourneerd. Een gegevensgreep is een DWORD- waarde die de DDEML gebruikt om toegang te bieden tot gegevens in het DDE-object. Als u de gegevens in een DDE-object wilt delen, geeft een toepassing de gegevensgreep door aan de DDEML en geeft de DDEML de handle door aan de DDE-callback-functie van de toepassing die de gegevenstransactie ontvangt.
In het volgende voorbeeld ziet u hoe u een DDE-object maakt en een ingang voor het object ophaalt. Tijdens de XTYP_ADVREQ transactie converteert de callback-functie de huidige tijd naar een ASCII-tekenreeks, kopieert de tekenreeks naar een lokale buffer en maakt vervolgens een DDE-object dat de tekenreeks bevat. De callback-functie retourneert de ingang naar het DDE-object (HDDEDATA) naar de DDEML, die de ingang doorgeeft aan de clienttoepassing.
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];
HRESULT hResult;
size_t * pcch;
HRESULT hResult;
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);
hResult = StringCchCat(szBuf, 32/sizeof(TCHAR), ":");
if (FAILED(hResult))
{
// TO DO: Write error handler.
return;
}
if (tmTime.minute < 10)
hResult = StringCchCat(szBuf, 32/sizeof(TCHAR), "0");
if (FAILED(hResult)
{
// TO DO: Write error handler.
return;
}
hResult = StringCchLength(szBuf, 32/sizeof(TCHAR), pcch);
if (FAILED(hResult))
{
// TO DO: Write error handler.
return;
}
itoa(tmTime.minute, &szBuf[*pcch], 10);
hResult = StringCchCat(szBuf, 32/sizeof(TCHAR), ":");
if (FAILED(hResult)
{
// TO DO: Write error handler.
return;
}
if (tmTime.second < 10)
hResult = StringCchCat(szBuf, 32/sizeof(TCHAR), "0");
if (FAILED(hResult)
{
// TO DO: Write error handler.
return;
}
hResult = StringCchLength(szBuf, 32/sizeof(TCHAR), pcch);
if (FAILED(hResult))
{
// TO DO: Write error handler.
return;
}
itoa(tmTime.second, &szBuf[*pcch], 10);
hResult = StringCchLength(szBuf, 32/sizeof(TCHAR), pcch);
if (FAILED(hResult))
{
// TO DO: Write error handler.
return;
}
szBuf[*pcch] = '\0';
// Create a global object and return its data handle.
hResult = StringCchLength(szBuf, 32/sizeof(TCHAR), pcch);
if (FAILED(hResult))
{
// TO DO: Write error handler.
return;
}
return (DdeCreateDataHandle(
idInst,
(LPBYTE) szBuf, // instance identifier
*pcch + 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.
}
}
De ontvangende toepassing verkrijgt een aanwijzer naar het DDE-object door de gegevensgreep door te geven aan de DdeAccessData functie. De aanwijzer die wordt geretourneerd door DdeAccessData- biedt alleen-lezentoegang. De toepassing moet de aanwijzer gebruiken om de gegevens te controleren en vervolgens de functie DdeUnaccessData aanroepen om de aanwijzer ongeldig te maken. De toepassing kan de gegevens naar een lokale buffer kopiëren met behulp van de functie DdeGetData.
In het volgende voorbeeld wordt een aanwijzer opgehaald naar het DDE-object dat is geïdentificeerd door de parameter hData, wordt de inhoud gekopieerd naar een lokale buffer en wordt de aanwijzer ongeldig gemaakt.
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;
//
Wanneer een toepassing die een gegevensgreep heeft gemaakt, deze handle doorgeeft aan de DDEML, wordt de ingang meestal ongeldig in de makende toepassing. Deze situatie is geen probleem als de toepassing gegevens met slechts één toepassing moet delen. Als een toepassing dezelfde gegevens moet delen met meerdere toepassingen, moet de makende toepassing echter de vlag HDATA_APPOWNED opgeven in DdeCreateDataHandle-. Dit geeft het eigendom van het DDE-object aan de makende toepassing en voorkomt dat de DDEML de gegevensingang ongeldig maakt. De toepassing kan de gegevensafhandeling vervolgens een willekeurig aantal keren doorgeven nadat DdeCreateDataHandle slechts één keer is aangeroepen.
Als een toepassing de vlag HDATA_APPOWNED opgeeft in de afCmd parameter van DdeCreateDataHandle, moet deze de DdeFreeDataHandle-functie aanroepen om de geheugengreep vrij te maken, ongeacht of deze de ingang aan de DDEML heeft doorgegeven. Voordat deze wordt beëindigd, moet een toepassing DdeFreeDataHandle- aanroepen om een gegevensgreep vrij te maken die het heeft gemaakt, maar niet is doorgegeven aan de DDEML.
Een toepassing die de ingang nog niet heeft doorgegeven aan een DDE-object aan de DDEML, kan gegevens toevoegen aan het object of gegevens in het object overschrijven met behulp van de functie DdeAddData. Normaal gesproken gebruikt een toepassing DdeAddData- om een niet-geïnitialiseerd DDE-object te vullen. Nadat een toepassing een gegevensgreep doorgeeft aan de DDEML, kan het DDE-object dat door de ingang wordt geïdentificeerd, niet meer worden gewijzigd; het kan alleen worden vrijgemaakt.