共用方式為


資料管理

因為動態數據交換 (DDE) 會使用記憶體物件將數據從一個應用程式傳遞至另一個應用程式,因此動態數據交換管理連結庫 (DDEML) 會提供一組 DDE 應用程式可用來建立和管理 DDE 物件的函式。

涉及交換數據的所有交易都需要應用程式提供數據來建立包含數據的本機緩衝區,然後呼叫 DdeCreateDataHandle 函式。 此函式會配置 DDE 物件、將數據從緩衝區複製到 物件,並傳回數據句柄。 數據句柄是 DDEML 用來提供 DDE 物件中數據的存取權的 DWORD 值。 若要共用 DDE 對象中的數據,應用程式會將數據句柄傳遞至 DDEML,而 DDEML 會將句柄傳遞至接收數據交易之應用程式的 DDE 回呼函式。

下列範例示範如何建立 DDE 物件,並取得 物件的句柄。 在 XTYP_ADVREQ 交易期間,回呼函式會將目前時間轉換為 ASCII 字串、將字串複製到本機緩衝區,然後建立包含字串的 DDE 物件。 回呼函式會將 DDE 物件 (HDDEDATA) 的句柄傳回給 DDEML,此句柄會將句柄傳遞至用戶端應用程式。

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

接收應用程式會藉由將數據句柄傳遞至 DdeAccessData 函式,以取得 DDE 物件的指標。 DdeAccessData傳回的指標提供唯讀存取權。 應用程式應該使用指標來檢閱數據,然後呼叫 DdeUnaccessData 函式來使指標失效。 應用程式可以使用 DdeGetData 函式將數據複製到本機緩衝區

下列範例會取得 hData 參數所識別之 DDE 物件的指標、將內容複製到本機緩衝區,然後使指標失效。

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

通常,當建立數據句柄的應用程式將該句柄傳遞至 DDEML 時,句柄在建立應用程式中會變成無效。 如果應用程式只能與單一應用程式共用數據,這種情況就不是問題。 不過,如果應用程式必須與多個應用程式共用相同的數據,則建立應用程式應該在 DdeCreateDataHandle指定HDATA_APPOWNED旗標。 這樣做會將 DDE 對象的擁有權授與建立應用程式,並防止 DDEML 使數據句柄失效。 接著,應用程式可以在只呼叫 DdeCreateDataHandle 之後,傳遞任何次數的數據句柄。

如果應用程式在 DdeCreateDataHandle afCmd 參數中指定HDATA_APPOWNED旗標,則不論它是否將句柄傳遞至 DDEML,都必須呼叫 DdeFreeDataHandle 函式來釋放記憶體句柄。 在終止之前,應用程式必須呼叫 DdeFreeDataHandle ,以釋放它建立但未傳遞至 DDEML 的任何數據處理。

尚未將句柄傳遞至 DDEML 的應用程式可以將數據新增至物件,或使用 DdeAddData 函式覆寫物件中的數據。 一般而言,應用程式會使用 DdeAddData 來填滿未初始化的 DDE 物件。 應用程式將數據句柄傳遞至 DDEML 之後,無法變更句柄所識別的 DDE 物件;它只能釋放。