Freigeben über


Datenmanagement

Da Dynamic Data Exchange (DDE) Speicherobjekte verwendet, um Daten von einer Anwendung an eine andere zu übergeben, stellt die Dynamic Data Exchange Management Library (DDEML) eine Reihe von Funktionen bereit, mit denen DDE-Anwendungen DDE-Objekte erstellen und verwalten können.

Alle Transaktionen, die den Datenaustausch beinhalten, erfordern, dass die Anwendung die Daten angibt, um einen lokalen Puffer mit den Daten zu erstellen und dann die DdeCreateDataHandle--Funktion aufzurufen. Diese Funktion weist ein DDE-Objekt zu, kopiert die Daten aus dem Puffer in das Objekt und gibt ein Datenhandle zurück. Ein Datenhandle ist ein DWORD- Wert, den die DDEML zum Bereitstellen des Zugriffs auf Daten im DDE-Objekt verwendet. Um die Daten in einem DDE-Objekt freizugeben, übergibt eine Anwendung das Datenhandle an die DDEML, und die DDEML übergibt das Handle an die DDE-Rückruffunktion der Anwendung, die die Datentransaktion empfängt.

Das folgende Beispiel zeigt, wie Sie ein DDE-Objekt erstellen und ein Handle für das Objekt abrufen. Während der XTYP_ADVREQ Transaktion konvertiert die Rückruffunktion die aktuelle Uhrzeit in eine ASCII-Zeichenfolge, kopiert die Zeichenfolge in einen lokalen Puffer und erstellt dann ein DDE-Objekt, das die Zeichenfolge enthält. Die Rückruffunktion gibt das Handle an das DDE-Objekt (HDDEDATA) an die DDEML zurück, die das Handle an die Clientanwendung übergibt.

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

Die empfangende Anwendung ruft einen Zeiger auf das DDE-Objekt ab, indem das Datenhandle an die DdeAccessData--Funktion übergeben wird. Der von DdeAccessData zurückgegebene Zeiger bietet schreibgeschützten Zugriff. Die Anwendung sollte den Zeiger verwenden, um die Daten zu überprüfen, und rufen Sie dann die DdeUnaccessData--Funktion auf, um den Zeiger ungültig zu machen. Die Anwendung kann die Daten mithilfe der DdeGetData--Funktion in einen lokalen Puffer kopieren.

Im folgenden Beispiel wird ein Zeiger auf das DDE-Objekt abgerufen, das vom hData--Parameter identifiziert wird, den Inhalt in einen lokalen Puffer kopiert und dann den Zeiger ungültig macht.

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

Wenn eine Anwendung, die ein Datenhandle erstellt hat, diesen Handle an die DDEML übergibt, wird das Handle in der erstellungsanwendung ungültig. Diese Situation ist kein Problem, wenn die Anwendung Daten nur für eine einzelne Anwendung freigeben muss. Wenn eine Anwendung jedoch dieselben Daten für mehrere Anwendungen freigeben muss, sollte die erstellungsanwendung das HDATA_APPOWNED Flag in DdeCreateDataHandle-angeben. Dadurch wird der Besitz des DDE-Objekts an die erstellungsanwendung übertragen und verhindert, dass die DDEML das Datenhandle ungültig macht. Die Anwendung kann die Daten dann beliebig oft übergeben, nachdem DdeCreateDataHandle- nur einmal aufgerufen wurde.

Wenn eine Anwendung das HDATA_APPOWNED Flag im afCmd Parameter DdeCreateDataHandleangibt, muss sie die DdeFreeDataHandle--Funktion aufrufen, um das Speicherhandle freizugeben, unabhängig davon, ob es das Handle an die DDEML übergeben hat. Bevor sie beendet wird, muss eine Anwendung DdeFreeDataHandle- aufrufen, um alle erstellten Datenhandle frei zu geben, aber nicht an die DDEML übergeben.

Eine Anwendung, die das Handle noch nicht an ein DDE-Objekt an die DDEML übergeben hat, kann dem Objekt Daten hinzufügen oder Daten im Objekt mithilfe der DdeAddData--Funktion überschreiben. In der Regel verwendet eine Anwendung DdeAddData-, um ein nicht initialisiertes DDE-Objekt auszufüllen. Nachdem eine Anwendung ein Datenhandle an die DDEML übergeben hat, kann das durch das Handle identifizierte DDE-Objekt nicht geändert werden; es kann nur freigegeben werden.