Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Ponieważ dynamiczna wymiana danych (DDE) używa obiektów pamięci do przekazywania danych z jednej aplikacji do innej, biblioteka dynamicznego zarządzania wymianą danych (DDEML) udostępnia zestaw funkcji, których aplikacje DDE mogą używać do tworzenia obiektów DDE i zarządzania nimi.
Wszystkie transakcje obejmujące wymianę danych wymagają, aby aplikacja dostarczająca dane utworzyła bufor lokalny zawierający dane, a następnie wywołać funkcję DdeCreateDataHandle. Ta funkcja przydziela obiekt DDE, kopiuje dane z buforu do obiektu i zwraca uchwyt danych. Dojście danych jest wartością DWORD używaną przez DDEML w celu zapewnienia dostępu do danych w obiekcie DDE. Aby udostępnić dane w obiekcie DDE, aplikacja przekazuje dojście danych do DDEML, a DDEML przekazuje dojście do funkcji wywołania zwrotnego DDE aplikacji, która odbiera transakcję danych.
W poniższym przykładzie pokazano, jak utworzyć obiekt DDE i uzyskać uchwyt do obiektu. Podczas transakcji XTYP_ADVREQ funkcja wywołania zwrotnego konwertuje bieżący czas na ciąg ASCII, kopiuje ciąg do buforu lokalnego, a następnie tworzy obiekt DDE zawierający ciąg. Funkcja wywołania zwrotnego zwraca uchwyt do obiektu DDE (HDDEDATA) do DDEML, który przekazuje dojście do aplikacji klienckiej.
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.
}
}
Aplikacja odbierający uzyskuje wskaźnik do obiektu DDE, przekazując dojście danych do funkcji DdeAccessData. Wskaźnik zwrócony przez DdeAccessData zapewnia dostęp tylko do odczytu. Aplikacja powinna użyć wskaźnika, aby przejrzeć dane, a następnie wywołać funkcję DdeUnaccessData, aby unieważnić wskaźnik. Aplikacja może skopiować dane do buforu lokalnego przy użyciu funkcji DdeGetData.
Poniższy przykład uzyskuje wskaźnik do obiektu DDE zidentyfikowanego przez parametr hData, kopiuje zawartość do buforu lokalnego, a następnie unieważnia wskaźnik.
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;
//
Zwykle gdy aplikacja, która utworzyła dojście danych, przekazuje ten uchwyt do DDEML, uchwyt staje się nieprawidłowy w tworzonej aplikacji. Taka sytuacja nie jest problemem, jeśli aplikacja musi udostępniać dane tylko jednej aplikacji. Jeśli aplikacja musi udostępniać te same dane wielu aplikacjom, jednak tworzenie aplikacji powinno określać flagę HDATA_APPOWNED w DdeCreateDataHandle. Dzięki temu obiekt DDE jest własnością tworzonej aplikacji i uniemożliwia DDEML unieważnienie uchwytu danych. Aplikacja może następnie przekazać uchwyt danych dowolną liczbę razy po wywołaniu DdeCreateDataHandle tylko raz.
Jeśli aplikacja określa flagę HDATA_APPOWNED w afCmd parametru DdeCreateDataHandle, musi wywołać funkcję DdeFreeDataHandle, aby zwolnić uchwyt pamięci, niezależnie od tego, czy przekazano uchwyt do DDEML. Zanim zakończy działanie, aplikacja musi wywołać DdeFreeDataHandle, aby zwolnić wszystkie utworzone przez nią dojścia danych, ale nie zostały przekazane do DDEML.
Aplikacja, która nie przekazała jeszcze dojścia do obiektu DDE do obiektu DDEML, może dodać dane do obiektu lub zastąpić dane w obiekcie za pomocą funkcji DdeAddData. Zazwyczaj aplikacja używa DdeAddData do wypełnienia niezainicjowanego obiektu DDE. Po przejściu przez aplikację do uchwytu danych do DDEML nie można zmienić obiektu DDE zidentyfikowanego przez uchwyt; można go uwolnić tylko.