Manajemen Data

Karena Dynamic Data Exchange (DDE) menggunakan objek memori untuk meneruskan data dari satu aplikasi ke aplikasi lain, Dynamic Data Exchange Management Library (DDEML) menyediakan serangkaian fungsi yang dapat digunakan aplikasi DDE untuk membuat dan mengelola objek DDE.

Semua transaksi yang melibatkan pertukaran data memerlukan aplikasi yang menyediakan data untuk membuat buffer lokal yang berisi data dan kemudian untuk memanggil fungsi DdeCreateDataHandle. Fungsi ini mengalokasikan objek DDE, menyalin data dari buffer ke objek, dan mengembalikan handel data. Handel data adalah nilai DWORD yang digunakan DDEML untuk menyediakan akses ke data di objek DDE. Untuk berbagi data dalam objek DDE, aplikasi meneruskan handel data ke DDEML, dan DDEML meneruskan handel ke fungsi panggilan balik DDE aplikasi yang menerima transaksi data.

Contoh berikut menunjukkan cara membuat objek DDE dan mendapatkan handel ke objek. Selama transaksi XTYP_ADVREQ, fungsi panggilan balik mengonversi waktu saat ini menjadi string ASCII, menyalin string ke buffer lokal, lalu membuat objek DDE yang berisi string. Fungsi panggilan balik mengembalikan handel ke objek DDE (HDDEDATA) ke DDEML, yang meneruskan handel ke aplikasi klien.

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

Aplikasi penerima memperoleh penunjuk ke objek DDE dengan meneruskan handel data ke fungsi DdeAccessData. Penunjuk yang dikembalikan oleh DdeAccessData menyediakan akses baca-saja. Aplikasi harus menggunakan penunjuk untuk meninjau data lalu memanggil fungsi DdeUnaccessData untuk membatalkan penunjuk. Aplikasi dapat menyalin data ke buffer lokal dengan menggunakan fungsi DdeGetData.

Contoh berikut mendapatkan penunjuk ke objek DDE yang diidentifikasi oleh parameter hData , menyalin konten ke buffer lokal, lalu membatalkan penunjuk.

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

Biasanya, ketika aplikasi yang membuat handel data melewati handel yang menangani ke DDEML, handel menjadi tidak valid dalam aplikasi pembuatan. Situasi ini tidak menjadi masalah jika aplikasi harus berbagi data hanya dengan satu aplikasi. Namun, jika aplikasi harus berbagi data yang sama dengan beberapa aplikasi, aplikasi pembuatan harus menentukan bendera HDATA_APPOWNED di DdeCreateDataHandle. Melakukannya memberikan kepemilikan objek DDE ke aplikasi pembuatan dan mencegah DDEML membatalkan handel data. Aplikasi kemudian dapat meneruskan handel data berapa kali setelah memanggil DdeCreateDataHandle hanya sekali.

Jika aplikasi menentukan bendera HDATA_APPOWNED dalam parameter afCmd DdeCreateDataHandle, aplikasi harus memanggil fungsi DdeFreeDataHandle untuk membebaskan handel memori, terlepas dari apakah itu meneruskan handel ke DDEML. Sebelum dihentikan, aplikasi harus memanggil DdeFreeDataHandle untuk membebaskan penanganan data apa pun yang dibuatnya tetapi tidak diteruskan ke DDEML.

Aplikasi yang belum meneruskan handel ke objek DDE ke DDEML dapat menambahkan data ke objek atau menimpa data dalam objek dengan menggunakan fungsi DdeAddData. Biasanya, aplikasi menggunakan DdeAddData untuk mengisi objek DDE yang tidak diinisialisasi. Setelah aplikasi meneruskan handel data ke DDEML, objek DDE yang diidentifikasi oleh handel tidak dapat diubah; itu hanya dapat dibebaskan.