¿Cómo utilizar VC para implementar el servicio DDE? ¿Es mejor tener el código original? ¡Gracias, se necesita con urgencia!
Para el método anterior, el cliente envía un mensaje WM_DDE_REQUSET a la ventana del servidor una vez, solicitando un elemento de datos para cada elemento de datos que necesita, estableciendo así un enlace de datos fríos. La Figura 1 muestra el flujo de mensajes del servidor cuando puede proporcionar elementos de datos y cuando no puede proporcionar elementos de datos:
Figura 1 La respuesta del servidor al cliente en diferentes circunstancias
El cliente pasa lo siguiente El código del programa completa el envío del mensaje WM_DDE_REQUEST. Estos códigos especifican principalmente el identificador atómico y el formato de datos del elemento de datos:
HWND hwndClient = GetSafeHwnd() // Obtener el identificador de ventana de. la aplicación donde se encuentra el servidor
ATOM atomItem = GlobalAddAtom("Item A" // Obtener el valor del identificador del átomo
if (atomItem != 0) // Enviar un mensaje de solicitud de datos al servidor
::PostMessage(m_hwndServer, WM_DDE_REQUEST, (WPARAM)hwndClient, (LPARAM)MAKELONG(CF_TEXT, atomItem));
Preparación del servidor DDE y procesamiento de mensajes
La ventana del servidor DDE debe prepararse en el momento de la creación asignando y configurando un bloque de memoria de disfrute global en formato DDEDATA y especificando los campos de formato y el contenido del elemento de datos que se utilizarán cuando se reciba un mensaje de solicitud de elemento de datos. desde el cliente, envíe el identificador del bloque ****-enjoyment al cliente junto con el mensaje de respuesta.
m_hwndServer = hwndServer; // Guarda la ventana del servicio DDE creada
CString sDataItem = "¡HOLA MUNDO!" // Contenido del elemento de datos del servidor
// Asignar global *** Disfrute del bloque de memoria en formato DDEDATA
m_hDDEData = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, (LONG)sizeof(DDEDATA) sDataItem.GetLength() 2);
// Bloquear dirección de bloque de memoria
DDEDATA * lpDDEData = (DDEDATA*)GlobalLock(m_hDDEData);
lpDDEData-gt; cfFormat = CF_TEXT; // Establecer campo de formato
::strcpy((LPSTR) lpDDEData-gt; Valor, sDataItem); // Complete el contenido del elemento de datos
::strcat((LPSTR)lpDDEData-gt; Valor, "\r \n" ); // Agrega el carácter de terminación
GlobalUnlock(m_hDDEData); // Desbloquea el bloque de memoria
En la función de respuesta del proceso del servidor al mensaje WM_DDE_REQUEST, primero del parámetro de mensaje lParam Extrae el valor de identificación atómica y el formato de datos del elemento de datos solicitado. Si el formato de datos solicitado coincide con el formato del elemento de datos proporcionado por el servidor, se realiza la comparación de enumeración hasta que se encuentre el elemento de datos solicitado. Dado que los identificadores de bloques de memoria con formato DDEDATA y los valores de identificación atómica de elementos de datos se transmiten al cliente a través del parámetro de mensaje lParam, continuar usando MAKELONG() para manejar combinaciones de palabras altas y bajas inevitablemente resultará en la corrupción del valor del identificador de 32 bits. . En este caso, se debe utilizar la función PackDDElParam() para la composición. Tenga en cuenta que la función PostMessage() solo se puede utilizar para enviar mensajes WM_DDE_DATA al cliente, no para enviar mensajes (SendMessage()). Si el servidor no encuentra una coincidencia después de enumerar todos los elementos de datos que proporcionó, considerará que la solicitud del cliente ha fallado y le enviará un mensaje WM_DDE_ACK como respuesta negativa, con la palabra baja del parámetro de mensaje lParam que contiene información de estado. .
La lista completa de código en esta parte es la siguiente:
int ITEM_NUM = 3; //El número de elementos de datos proporcionados por el servidor
CString ItemName[3] = {" Item A", "Item B", "Item C"}; //El nombre del elemento de datos proporcionado por el servidor
char szItemNameClient[255]; //El nombre del elemento de datos solicitado por el cliente
HWND hwndClient = (HWND)wParam; // El identificador de la ventana del cliente
short cfFormat = LOWORD(lParam); // El formato de datos pasado por el cliente
if (cfFormat == CF_TEXT) { // Si los formatos son iguales, vaya al siguiente paso
// Obtenga el nombre del elemento de datos solicitado por el cliente p>
GlobalGetAtomName(HIWORD(lParam), szItemNameClient, sizeof( szItemNameClient)) ;
for (int i = 0; i lt; ITEM_NUM; i ){// Recuperar qué elemento de datos coincide con el uno proporcionado por el servidor
if (strcmp(szItemNameClient, ItemName [i]) == 0) // si se recupera, omita
break;
}
ATOM atomItem = GlobalAddAtom(ItemName[i]);/ / Obtener el valor del identificador atómico
//Si se recupera el elemento, envíe el mensaje WM_DDE_DATA; de lo contrario, envíe el mensaje WM_DDE_ACK
if (strcmp(szItemNameClient, ItemName[i]) == 0 ) // Si se recupera el artículo, envía el mensaje WM_DDE_DATA
if (i lt;ITEM_NUM) {
LONG lDataPack = PackDDElParam(WM_DDE_DATA, (UINT)m_hDDEData, atomItem); // Parámetros de mensaje combinados lParam
: .PostMessage(hwndClient, WM_DDE_DATA, (WPARAM)m_hwndServer, ( LPARAM)lDataPack); // Publicar mensaje WM_DDE_DATA
} p>
else {
DDEACK DDEAck // completar la estructura DDEACK
DDEAck.bAppReturnCode = 0;
DDEAck.reserved = 0;
DDEAck.fBusy = FALSE;
DDEAck.fAck = FALSE
WORD wStatus = *(WORD*)amp;DDEAck;
::PostMessage(hwndClient, WM_DDE_ACK, (WPARAM)hwndServer, MAKELONG(wSt
atus, atomItem)); // mail WM_DDE_ACK niega el mensaje de respuesta
}
GlobalDeleteAtom(atomItem); // Eliminar atom
GlobalFree(m_hDDEData); // Libera la memoria solicitada
}