Dela via


Datahantering

Eftersom DDE (Dynamic Data Exchange) använder minnesobjekt för att skicka data från ett program till ett annat, tillhandahåller DDEML (Dynamic Data Exchange Management Library) en uppsättning funktioner som DDE-program kan använda för att skapa och hantera DDE-objekt.

Alla transaktioner som omfattar utbyte av data kräver att programmet tillhandahåller data för att skapa en lokal buffert som innehåller data och sedan anropa funktionen DdeCreateDataHandle. Den här funktionen allokerar ett DDE-objekt, kopierar data från bufferten till objektet och returnerar ett datahandtag. En datareferens är ett DWORD- värde som DDEML använder för att ge åtkomst till data i DDE-objektet. Om du vill dela data i ett DDE-objekt skickar ett program datahandtaget till DDEML och DDEML skickar handtaget till funktionen DDE-motringning i det program som tar emot datatransaktionen.

I följande exempel visas hur du skapar ett DDE-objekt och hämtar ett handtag till objektet. Under den XTYP_ADVREQ transaktionen konverterar återanropsfunktionen den aktuella tiden till en ASCII-sträng, kopierar strängen till en lokal buffert och skapar sedan ett DDE-objekt som innehåller strängen. Återanropsfunktionen returnerar handtaget till DDE-objektet (HDDEDATA) till DDEML, som skickar handtaget till klientprogrammet.

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. 
    } 
} 

Det mottagande programmet hämtar en pekare till DDE-objektet genom att skicka datahandtaget till funktionen DdeAccessData. Pekaren som returneras av DdeAccessData ger skrivskyddad åtkomst. Programmet bör använda pekaren för att granska data och sedan anropa funktionen DdeUnaccessData för att ogiltigförklara pekaren. Programmet kan kopiera data till en lokal buffert med hjälp av funktionen DdeGetData.

I följande exempel hämtas en pekare till DDE-objektet som identifieras av parametern hData, kopierar innehållet till en lokal buffert och ogiltigförklarar pekaren.

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; 
//

Vanligtvis blir handtaget ogiltigt i det skapande programmet när ett program som skapade ett datahandtag skickar handtaget till DDEML. Den här situationen är inte ett problem om programmet bara måste dela data med ett enda program. Om ett program måste dela samma data med flera program bör dock det skapande programmet ange flaggan HDATA_APPOWNED i DdeCreateDataHandle. Detta ger ägarskap för DDE-objektet till det skapande programmet och förhindrar att DDEML ogiltigförklarar datahandtaget. Programmet kan sedan skicka datahandtaget valfritt antal gånger efter att det anropat DdeCreateDataHandle bara en gång.

Om ett program anger flaggan HDATA_APPOWNED i parametern afCmd för DdeCreateDataHandlemåste den anropa funktionen DdeFreeDataHandle för att frigöra minneshandtaget, oavsett om det skickade handtaget till DDEML. Innan det avslutas måste ett program anropa DdeFreeDataHandle för att frigöra alla datareferenser som skapats men som inte har överförts till DDEML.

Ett program som ännu inte har skickat handtaget till ett DDE-objekt till DDEML kan lägga till data i objektet eller skriva över data i objektet med hjälp av funktionen DdeAddData. Vanligtvis använder ett program DdeAddData- för att fylla ett onitialiserat DDE-objekt. När ett program har överfört ett datahandtag till DDEML kan DDE-objektet som identifieras av handtaget inte ändras. Det kan bara frigöras.