|
| БЕСПЛАТНАЯ ежедневная online лотерея! Выигрывай каждый день БЕСПЛАТНО! |
|
|
Data Management
Because DDE uses memory objects to pass data from one application to another, the DDEML provides a set of functions that DDE applications can use to create and manage DDE objects.
All transactions that involve the exchange of data require the application supplying the data to create a local buffer containing the data and then to call the DdeCreateDataHandle function. This function allocates a DDE object, copies the data from the buffer to the object, and returns a data handle. A data handle is a doubleword value that the DDEML uses to provide access to data in the DDE object. To share the data in a DDE object, an application passes the data handle to the DDEML, and the DDEML passes the handle to the DDE callback function of the application that is receiving the data transaction.
The following example shows how to create a DDE object and obtain a handle of the object. During the XTYP_ADVREQ transaction, the callback function converts the current time to an ASCII string, copies the string to a local buffer, and then creates a DDE object that contains the string. The callback function returns the handle of the DDE object (HDDEDATA) to the DDEML, which passes the handle to the client application.
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]; 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); lstrcat(szBuf, ":"); if (tmTime.minute < 10) lstrcat(szBuf, "0"); itoa(tmTime.minute, &szBuf[lstrlen(szBuf)], 10); lstrcat(szBuf, ":");
if (tmTime.second < 10) strcat(szBuf, "0"); itoa(tmTime.second, &szBuf[lstrlen(szBuf)], 10); szBuf[lstrlen(szBuf)] = '\0'; /* Create a global object and return its data handle. */ return (DdeCreateDataHandle( idInst, (LPBYTE) szBuf, /* instance identifier */ lstrlen(szBuf) + 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. */ . } }
The receiving application obtains a pointer to the DDE object by passing the data handle to the DdeAccessData function. The pointer returned by DdeAccessData provides read-only access. The application should use the pointer to review the data and then call the DdeUnaccessData function to invalidate the pointer. The application can copy the data to a local buffer by using the DdeGetData function. The following example obtains a pointer to the DDE object identified by the hData parameter, copies the contents to a local buffer, and then invalidates the pointer.
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; . . .
Usually, when an application that created a data handle passes that handle to the DDEML, the handle becomes invalid in the creating application. This situation is not a problem if the application must share data with only a single application. If an application must share the same data with multiple applications, however, the creating application should specify the HDATA_APPOWNED flag in DdeCreateDataHandle. Doing so gives ownership of the DDE object to the creating application and prevents the DDEML from invalidating the data handle. The application can then pass the data handle any number of times after calling DdeCreateDataHandle only once.
If an application specifies the HDATA_APPOWNED flag in the afCmd parameter of DdeCreateDataHandle, it must call the DdeFreeDataHandle function to free the memory handle, regardless of whether it passed the handle to the DDEML. Before it terminates, an application must call DdeFreeDataHandle to free any data handle that it created but did not pass to the DDEML. An application that has not yet passed the handle of a DDE object to the DDEML can add data to the object or overwrite data in the object by using the DdeAddData function. Typically, an application uses DdeAddData to fill an uninitialized DDE object. After an application passes a data handle to the DDEML, the DDE object identified by the handle cannot be changed; it can only be freed.
| Пригласи друзей и счет твоего мобильника всегда будет положительным! |
| Пригласи друзей и счет твоего мобильника всегда будет положительным! |
Управление Данных
Поскольку DDE использует объекты памяти против данных прохода из одного приложения другому, DDEML обеспечивает установку функций, которые приложения DDE могут использовать, чтобы создавать и управлять объектами DDE.
Все сделки, которые включают обмен данных требовать приложение, поставляющее данные, чтобы создавать локальный буфер, содержащий данные и затем, чтобы называть функцию DdeCreateDataHandle. Эта функция распределяет объект DDE, копирует данные от буфера до объекта и возвращает ручку данных. Ручка данных является величиной двойного слова, что DDEML используется, чтобы обеспечивать доступ к данным на объекте DDE. Для того, чтобы распространять данные на объект DDE, приложение передает ручку данных на DDEML, и DDEML передает ручку в функцию возврата DDE приложения, которая получает сделку данных.
Следующий пример показывает как, чтобы создавать объект DDE и получать ручку объекта. В течение сделки XTYP_ADVREQ, функция возврата преобразовывает текущее время в строку ASCII, копирует строку в локальный буфер, затем создает объект DDE, который содержит строку. Функция возврата возвращает ручку объекта DDE (HDDEDATA) на DDEML, которое передает ручку в приложение клиента.
typedef struct tagTIME { ЧАС INT; /* 0 - 11 часов для аналоговых часов */ hour12 INT; /* 12- часовой формат */ hour24 INT; /* 24- часовой формат */ минута INT; СЕКУНДА INT; INT ampm; /* 0 - - , 1 - ПОСЛЕ ПОЛУДНЯ */ } ВРЕМЯ; HDDEDATA EXPENTRY DdeCallback(uType, uFmt, hconv, hsz1, hsz2, hdata, dwData1, dwData2) UINT uType; UINT uFmt; HCONV hconv; hsz1 HSZ; hsz2 HSZ; HDDEDATA hdata; DWORD dwData1; DWORD dwData2;
{ СИМВОЛ szBuf[32]; ключ (uType) { случай XTYP_ADVREQ: если ((hsz1 == hszTime && hsz2 == hszNow) && (uFmt == CF_TEXT)) { /* Скопируйте форматированную строку в buffer. */ itoa(tmTime.hour, szBuf, 10); lstrcat(szBuf, ":"); если (tmTime.minute < 10) lstrcat(szBuf, "0"); itoa(tmTime.minute, &szBuf[lstrlen(szBuf)], 10); lstrcat(szBuf, ":");
если (tmTime.second < 10) strcat(szBuf, "0"); itoa(tmTime.second, &szBuf[lstrlen(szBuf)], 10); szBuf[lstrlen(szBuf)] = '\0; /* Создайте глобальный объект и возвращайте свои данные handle. */ возврат (DdeCreateDataHandle( idInst, (LPBYTE) szBuf, /* ИДЕНТИФИКАТОР примера */ lstrlen(szBuf) + 1, /* исходная буферная длина */ 0, /* смещение из начала */
hszNow, /* Строка имени пункта */ CF_TEXT, /* буфер формата */ 0)); /* никакое создание не сигнализирует */ } еще возврат (HDDEDATA) НЕДЕЙСТВИТЕЛЬНЫЙ; . . /* Обработайте другой transactions. */ . } }
Получающее приложение получает указатель на DDE возражать передавая ручку данных в функцию DdeAccessData. Указатель возвращанный DdeAccessData обеспечивает только для чтения доступ. Приложение должно использовать указатель, чтобы просматривать данные затем называть функцию DdeUnaccessData, чтобы аннулировать указатель. Приложение может скопировать данные в локальный буфер используя функцию DdeGetData. Следующий пример получает указатель на объект DDE идентифицированный параметром hData, копирует содержание в локальный буфер, затем аннулирует указатель.
HDDEDATA hdata; LPBYTE lpszAdviseData; DWORD cbDataLen; i DWORD; символ szData[32]; . . . случай XTYP_ADVDATA: lpszAdviseData = DdeAccessData(hdata, &cbDataLen); для (i = 0; я < cbDataLen; я++) szData[i] = *lpszAdviseData++; DdeUnaccessData(hdata); возврат ИСТИНЫ (HDDEDATA); . . .
Обычно, когда приложение, которое создавало ручку данных передает эту ручку на DDEML, ручка становится инвалидом в создающем приложении. Эта ситуация не является проблемой если приложение должно распространить данные с только единственным приложением. Если приложение должно распространить те же данные со многочисленными приложениями, тем не менее, создающее приложение должно определить флаг HDATA_APPOWNED в DdeCreateDataHandle. Делая так дает собственность на объект DDE против создающего приложения и мешает DDEML чтобы аннулировать ручку данных. Приложение может затем передавать ручку данных любое раз (а) после вызова DdeCreateDataHandle только как только.
Если приложение определяет флаг HDATA_APPOWNED в параметре afCmd DdeCreateDataHandle, оно должно назвать функцию DdeFreeDataHandle, чтобы освобождать ручку памяти, независимо от того, что это прошло ручку на DDEML. Прежде, чем это завершится, приложение должно назвать DdeFreeDataHandle, чтобы освобождать любую ручку данных, которую он создан но не был пройден на DDEML. Приложение, которое еще не прошло ручку объекта DDE против DDEML может добавить данные к объекту или перезаписывать данные на объект используя функцию DdeAddData. Обычно, приложение использует DdeAddData, чтобы заполнять неинициализированный объект DDE. После того, как приложение передаст ручку данных на DDEML, объект DDE идентифицированный ручкой не может быть измениться; это может только освобождено.
|
|
|
|
| |