Freigeben über


Unterhaltungsverwaltung

Eine Unterhaltung zwischen einem Client und einem Server wird immer auf Anforderung des Clients eingerichtet. Wenn eine Unterhaltung eingerichtet wird, erhält jeder Partner ein Handle, das die Unterhaltung identifiziert. Die Partner verwenden dieses Handle in anderen DDEML-Funktionen (Dynamic Data Exchange Management Library), um Transaktionen zu senden und die Unterhaltung zu verwalten. Ein Client kann eine Unterhaltung mit einem einzelnen Server anfordern oder mehrere Unterhaltungen mit einem oder mehreren Servern anfordern.

In den folgenden Themen wird beschrieben, wie eine Anwendung neue Unterhaltungen herstellt und Informationen zu vorhandenen Unterhaltungen abruft.

Einzelne Unterhaltungen

Eine Clientanwendung fordert eine einzelne Unterhaltung mit einem Server an, indem sie die DdeConnect-Funktion aufruft und Zeichenfolgenhandles angibt, die die Zeichenfolgen identifizieren, die den Dienstnamen der Serveranwendung und den Themennamen für die Unterhaltung enthalten. Die DDEML antwortet, indem die XTYP_CONNECT Transaktion an die DDE-Rückruffunktion (Dynamic Data Exchange) jeder Serveranwendung gesendet wird, die entweder einen Dienstnamen registriert hat, der dem in DdeConnect- angegebenen entspricht oder die Filterung des Dienstnamens deaktiviert hat, indem DdeNameServiceaufgerufen wird. Ein Server kann auch XTYP_CONNECT Transaktionen filtern, indem die CBF_FAIL_CONNECTIONS Filterkennzeichnung in der DdeInitialize-funktion angegeben wird. Während der XTYP_CONNECT Transaktion übergibt die DDEML den Dienstnamen und den Themennamen an den Server. Der Server muss die Namen untersuchen und TRUE- zurückgeben, wenn er das Dienstnamen- und Themennamenpaar unterstützt, oder FALSE- wenn dies nicht der Fall ist.

Wenn kein Server positiv auf die Anforderung des Clients zur Verbindung antwortet, empfängt der Client NULL- von DdeConnect- und es wird keine Unterhaltung hergestellt. Wenn ein Server TRUE-zurückgibt, wird eine Unterhaltung eingerichtet, und der Client erhält ein Unterhaltungshandle – einen DWORD- Wert, der die Unterhaltung identifiziert. Der Client verwendet das Handle in nachfolgenden DDEML-Aufrufen, um Daten vom Server abzurufen. Der Server empfängt die XTYP_CONNECT_CONFIRM Transaktion (es sei denn, der Server hat das CBF_SKIP_CONNECT_CONFIRMS Filterflagge angegeben). Diese Transaktion übergibt das Unterhaltungshandle an den Server.

Das folgende Beispiel fordert eine Unterhaltung im Thema "System" mit einem Server an, der den Dienstnamen MyServer erkennt. Die hszServName und hszSysTopic Parameter werden zuvor Zeichenfolgenhandles erstellt.

HCONV hConv;         // conversation handle 
HWND hwndParent;     // parent window handle 
HSZ hszServName;     // service name string handle 
HSZ hszSysTopic;     // System topic string handle 
 
hConv = DdeConnect( 
    idInst,               // instance identifier 
    hszServName,          // service name string handle 
    hszSysTopic,          // System topic string handle 
    (PCONVCONTEXT) NULL); // use default context 
 
if (hConv == NULL) 
{ 
    MessageBox(hwndParent, "MyServer is unavailable.", 
        (LPSTR) NULL, MB_OK); 
    return FALSE; 
} 

Im vorherigen Beispiel bewirkt DdeConnect-, dass die DDE-Rückruffunktion der MyServer-Anwendung eine XTYP_CONNECT Transaktion empfängt.

Im folgenden Beispiel antwortet der Server auf die XTYP_CONNECT Transaktion, indem die Themennamenzeichenfolge die DDEML vergleicht, die an den Server übergeben wird, wobei jedes Element im Array der Themennamenzeichenfolge den Server unterstützt. Wenn der Server eine Übereinstimmung findet, wird die Unterhaltung hergestellt.

#define CTOPICS 5 
 
HSZ hsz1;                  // string handle passed by DDEML 
HSZ ahszTopics[CTOPICS];   // array of supported topics 
int i;                     // loop counter 
 
// Use a switch statement to examine transaction types. 
// Here is the connect case.
 
    case XTYP_CONNECT: 
        for (i = 0; i < CTOPICS; i++) 
        { 
            if (hsz1 == ahszTopics[i]) 
                return TRUE;   // establish a conversation 
        } 
 
        return FALSE; // Topic not supported; deny conversation.  
 
// Process other transaction types. 

Wenn der Server als Reaktion auf die XTYP_CONNECT Transaktion TRUE zurückgibt, sendet die DDEML eine XTYP_CONNECT_CONFIRM Transaktion an die DDE-Rückruffunktion des Servers. Der Server kann das Handle für die Unterhaltung abrufen, indem diese Transaktion verarbeitet wird.

Ein Client kann eine Wildcardunterhaltung einrichten, indem NULL- für das Zeichenfolgenhandle des Dienstnamens, das Themennamen-Zeichenfolgenhandle oder beide in einem Aufruf von DdeConnect-angegeben wird. Wenn mindestens einer der Zeichenfolgenhandles NULL-ist, sendet die DDEML die XTYP_WILDCONNECT Transaktion an die Rückruffunktionen aller DDE-Anwendungen (mit Ausnahme derJenigen, die die XTYP_WILDCONNECT Transaktion filtern). Jede Serveranwendung sollte reagieren, indem ein Datenhandle zurückgegeben wird, das ein null-beendetes Array von HSZPAIR- Strukturen identifiziert. Wenn die Serveranwendung nicht DdeNameService- aufgerufen hat, um die Dienstnamen zu registrieren und wenn die Filterung aktiviert ist, empfängt der Server keine XTYP_WILDCONNECT Transaktionen. Weitere Informationen zu Datenhandles finden Sie unter Datenverwaltung.

Das Array muss eine Struktur für jedes Dienstnamen- und Themennamenpaar enthalten, das mit dem vom Client angegebenen Paar übereinstimmt. Die DDEML wählt eines der Paare aus, um eine Unterhaltung herzustellen, und kehrt zum Client ein Handle zurück, mit dem die Unterhaltung identifiziert wird. Die DDEML sendet die XTYP_CONNECT_CONFIRM Transaktion an den Server (es sei denn, der Server filtert diese Transaktion). Das folgende Beispiel zeigt eine typische Serverantwort auf die XTYP_WILDCONNECT Transaktion.

#define CTOPICS 2 
 
UINT uType; 
HSZPAIR ahszp[(CTOPICS + 1)]; 
HSZ ahszTopicList[CTOPICS]; 
HSZ hszServ, hszTopic; 
WORD i, j; 
 
if (uType == XTYP_WILDCONNECT) 
{ 
    // Scan the topic list and create an array of HSZPAIR structures. 
 
    j = 0; 
    for (i = 0; i < CTOPICS; i++) 
    { 
        if (hszTopic == (HSZ) NULL || 
                hszTopic == ahszTopicList[i]) 
        { 
            ahszp[j].hszSvc = hszServ; 
            ahszp[j++].hszTopic = ahszTopicList[i]; 
        } 
    } 
 
    // End the list with an HSZPAIR structure that contains NULL 
    // string handles as its members. 
 
    ahszp[j].hszSvc = NULL; 
    ahszp[j++].hszTopic = NULL; 
 
    // Return a handle to a global memory object containing the 
    // HSZPAIR structures. 
 
    return DdeCreateDataHandle( 
        idInst,          // instance identifier 
        (LPBYTE) &ahszp, // pointer to HSZPAIR array 
        sizeof(HSZ) * j, // length of the array 
        0,               // start at the beginning 
        (HSZ) NULL,      // no item name string 
        0,               // return the same format 
        0);              // let the system own it 
} 

Entweder der Client oder der Server können eine Unterhaltung jederzeit beenden, indem die DdeDisconnect-Funktion aufgerufen wird. Diese Funktion bewirkt, dass die Rückruffunktion des Partners in der Unterhaltung die XTYP_DISCONNECT Transaktion empfängt (es sei denn, der Partner hat das CBF_SKIP_DISCONNECTS Filterflagge angegeben). In der Regel antwortet eine Anwendung auf die XTYP_DISCONNECT Transaktion mithilfe der DdeQueryConvInfo--Funktion, um Informationen über die unterhaltung abzurufen, die beendet wurde. Nachdem die Rückruffunktion von der Verarbeitung der XTYP_DISCONNECT Transaktion zurückgegeben wurde, ist der Unterhaltungshandle nicht mehr gültig.

Eine Clientanwendung, die eine XTYP_DISCONNECT Transaktion in der DDE-Rückruffunktion empfängt, kann versuchen, die Unterhaltung erneut herzustellen, indem sie die DdeReconnect-Funktion aufruft. Der Client muss DdeReconnect- innerhalb der DDE-Rückruffunktion aufrufen.

Mehrere Unterhaltungen

Eine Clientanwendung kann die DdeConnectList--Funktion verwenden, um zu bestimmen, ob im System interessante Server verfügbar sind. Ein Client gibt einen Dienstnamen und einen Themennamen an, wenn er DdeConnectList-aufruft, wodurch die DDEML die XTYP_WILDCONNECT Transaktion an die DDE-Rückruffunktionen aller Server sendet, die dem Dienstnamen entsprechen (mit Ausnahme derjenigen, die die Transaktion filtern). Die Rückruffunktion eines Servers sollte ein Datenhandle zurückgeben, das ein null-beendetes Array von HSZPAIR- Strukturen identifiziert. Das Array sollte eine Struktur für jedes Dienstnamen- und Themennamenpaar enthalten, das mit dem vom Client angegebenen Paar übereinstimmt. Die DDEML richtet eine Unterhaltung für jede HSZPAIR Struktur ein, die vom Server gefüllt ist, und gibt einen Unterhaltungslistenhandle an den Client zurück. Der Server empfängt das Unterhaltungshandle über die XTYP_CONNECT Transaktion (es sei denn, der Server filtert diese Transaktion).

Ein Client kann NULL- für den Dienstnamen, den Themennamen oder beide angeben, wenn er DdeConnectList-aufruft. Wenn der Dienstname NULL-ist, antworten alle Server im System, die den angegebenen Themennamen unterstützen. Eine Unterhaltung wird mit jedem Antwortserver eingerichtet, einschließlich mehrerer Instanzen desselben Servers. Wenn der Themenname NULL-ist, wird für jedes Thema eine Unterhaltung eingerichtet, die von jedem Server erkannt wird, der dem Dienstnamen entspricht.

Ein Client kann die funktionen DdeQueryNextServer und DdeQueryConvInfo verwenden, um die Server zu identifizieren, die auf DdeConnectList-reagieren. DdeQueryNextServer das nächste Unterhaltungshandle in einer Unterhaltungsliste zurück, und DdeQueryConvInfo eine CONVINFO- Struktur mit Informationen zur Unterhaltung ausfüllt. Der Client kann die benötigten Unterhaltungshandles behalten und den Rest aus der Unterhaltungsliste verwerfen.

Im folgenden Beispiel wird DdeConnectList- verwendet, um Unterhaltungen mit allen Servern herzustellen, die das Systemthema unterstützen, und verwendet dann die DdeQueryNextServer und DdeQueryConvInfo-funktionen, um die Dienstnamenzeichenfolgenhandles der Server abzurufen und sie in einem Puffer zu speichern.

HCONVLIST hconvList; // conversation list 
DWORD idInst;        // instance identifier 
HSZ hszSystem;       // System topic 
HCONV hconv = NULL;  // conversation handle 
CONVINFO ci;         // holds conversation data 
UINT cConv = 0;      // count of conv. handles 
HSZ *pHsz, *aHsz;    // point to string handles 
 
// Connect to all servers that support the System topic. 
 
hconvList = DdeConnectList(idInst, NULL, hszSystem, NULL, NULL); 
 
// Count the number of handles in the conversation list. 
 
while ((hconv = DdeQueryNextServer(hconvList, hconv)) != NULL) 
    cConv++; 
 
// Allocate a buffer for the string handles. 
 
hconv = NULL; 
aHsz = (HSZ *) LocalAlloc(LMEM_FIXED, cConv * sizeof(HSZ)); 
 
// Copy the string handles to the buffer. 
 
pHsz = aHsz; 
while ((hconv = DdeQueryNextServer(hconvList, hconv)) != NULL) 
{ 
    DdeQueryConvInfo(hconv, QID_SYNC, (PCONVINFO) &ci); 
    DdeKeepStringHandle(idInst, ci.hszSvcPartner); 
    *pHsz++ = ci.hszSvcPartner; 
} 
 
// Use the handles; converse with the servers. 
 
// Free the memory and terminate the conversations. 
 
LocalFree((HANDLE) aHsz); 
DdeDisconnectList(hconvList); 

Eine Anwendung kann eine einzelne Unterhaltung in einer Unterhaltungsliste beenden, indem sie die funktion DdeDisconnect aufruft. Eine Anwendung kann alle Unterhaltungen in einer Unterhaltungsliste beenden, indem sie die funktion DdeDisconnectList aufrufen. Beide Funktionen führen dazu, dass die DDEML XTYP_DISCONNECT Transaktionen an die DDE-Rückruffunktion jedes Partners sendet. DdeDisconnectList sendet eine XTYP_DISCONNECT Transaktion für jedes Unterhaltungshandle in der Liste.

Ein Client kann eine Liste der Unterhaltungshandles in einer Unterhaltungsliste abrufen, indem ein vorhandenes Unterhaltungslistenhandle an DdeConnectListübergeben wird. Der Enumerationsprozess entfernt die Handles von beendeten Unterhaltungen aus der Liste, und nichtduplizierte Unterhaltungen, die dem angegebenen Dienstnamen und dem Angegebenen Themennamen entsprechen, werden hinzugefügt.

Wenn DdeConnectList- ein vorhandenes Unterhaltungslistenhandle angibt, erstellt die Funktion eine neue Unterhaltungsliste, die die Handles aller neuen Unterhaltungen und die Handles aus der vorhandenen Liste enthält.

Wenn doppelte Unterhaltungen vorhanden sind, DdeConnectList versucht, doppelte Unterhaltungshandles in der Unterhaltungsliste zu verhindern. Eine duplizierte Unterhaltung ist eine zweite Unterhaltung mit demselben Server mit demselben Dienstnamen und Themennamen. Zwei solche Unterhaltungen hätten unterschiedliche Ziehpunkte, aber sie würden dieselbe Unterhaltung identifizieren.