/*************************************************************************** * * * FUNCTION : ProcessTransaction() taken from ddeml sample app * * * * PURPOSE : Processes synchronous transactions entirely and starts * * async transactions. Pass in the handle to the URL string. * * * * RETURNS : TRUE - If successful. * * FALSE - otherwise. * * * ****************************************************************************/ URLProcessorRetCode CConv::ProcessTransaction(DWORD idInst,HSZ hszItem) { HWND hwndInfoCtrl = 0; /* * Disable callbacks for this conversation now if the XOPT_DISABLEFIRST * option is set. This tests disabling asynchronous transactions * before they are completed. */ if (fsOptions & XOPT_DISABLEFIRST) DdeEnableCallback(idInst, hConv, EC_DISABLE); /* * Adjust the timeout for asynchronous transactions. */ if (fsOptions & XOPT_ASYNC) ulTimeout = (DWORD)TIMEOUT_ASYNC; /* * start transaction with DDEML here */ //note: for future use, pass in value for first parameter to retrieve data from transaction. // ** Future DDE may not support Result Parameter ** ret = DdeClientTransaction(NULL, (DWORD)-1,hConv, hszItem, wFmt,wType, ulTimeout, (LPDWORD)&Result); //UINT Error = DdeGetLastError(idInst); if(!ret) return enURLErrorDdeProcessTrans;//use DdeGetLastError(idInst) to get more details. else if (fsOptions & XOPT_ASYNC) { /* * asynchronous successful start - link transaction to window. */ //DdeSetUserHandle(hConv, Result, (DWORD)hwndInfoCtrl); /* * Abandon started async transaction after initiated if * XOPT_ABANDONAFTERSTART is chosen. This tests the mid-transaction * abandoning code. */ if (fsOptions & XOPT_ABANDONAFTERSTART) DdeAbandonTransaction(idInst, hConv, Result); } return enURLErrorNone; }
/***************************************************************** * DdeEnableCallback (DDEML.26) */ BOOL16 WINAPI DdeEnableCallback16(DWORD idInst, HCONV hConv, UINT16 wCmd) { return DdeEnableCallback(idInst, hConv, wCmd); }
/**************************************************************************** * * * FUNCTION : ProcessTransaction() * * * * PURPOSE : Processes synchronous transactions entirely and starts * * async transactions. Transaction attempts result in a * * transaction window being created which displays the state * * or results of the transaction. (the callback function * * updates these windows as it gets calls) Transaction * * windows stay around until abandoned by the user or until * * the conversation is disconnected. Advise Data and Advise * * Stop transactions are special. We don't create a new * * window if the associated advise start transaction window * * can be found. * * * * RETURNS : TRUE - If successful. * * FALSE - otherwise. * * * ****************************************************************************/ BOOL ProcessTransaction( XACT *pxact) { CONVINFO ci; HWND hwndInfoCtrl = 0; /* create transaction window to show we tried (except in ADVSTOP case) */ pxact = (XACT *)memcpy(MyAlloc(sizeof(XACT)), (PSTR)pxact, sizeof(XACT)); ci.cb = sizeof(CONVINFO); DdeQueryConvInfo(pxact->hConv, (DWORD)QID_SYNC, &ci); // ci.hUser==hConv if (pxact->wType == XTYP_ADVSTOP) { hwndInfoCtrl = FindAdviseChild((HWND)ci.hUser, pxact->hszItem, pxact->wFmt); if (hwndInfoCtrl) { SendMessage(hwndInfoCtrl, ICM_SETSTRING, ICSID_UL, (DWORD)(LPSTR)Type2String(pxact->wType, pxact->fsOptions)); DdeFreeStringHandle(idInst, pxact->hszItem); } } /* * If we still need to create a transaction window, do so here. */ if (!hwndInfoCtrl) { hwndInfoCtrl = CreateXactionWindow((HWND)ci.hUser, pxact); if (!hwndInfoCtrl) { MyFree(pxact); return 0; } SetFocus(hwndInfoCtrl); } /* * Disable callbacks for this conversation now if the XOPT_DISABLEFIRST * option is set. This tests disabling asynchronous transactions * before they are completed. */ if (pxact->fsOptions & XOPT_DISABLEFIRST) DdeEnableCallback(idInst, pxact->hConv, EC_DISABLE); /* * Adjust the timeout for asynchronous transactions. */ if (pxact->fsOptions & XOPT_ASYNC) pxact->ulTimeout = (DWORD)TIMEOUT_ASYNC; /* * start transaction with DDEML here */ pxact->ret = DdeClientTransaction((LPBYTE)pxact->hDdeData, (DWORD)-1, pxact->hConv, pxact->hszItem, pxact->wFmt, pxact->wType, pxact->ulTimeout, (LPDWORD)&pxact->Result); /* * show return value in transaction window */ wsprintf(szT, "ret=%lx", pxact->ret); SendMessage(hwndInfoCtrl, ICM_SETSTRING, ICSID_UR, (DWORD)(LPSTR)szT); /* * show result or ID value in transaction window */ wsprintf(szT, pxact->fsOptions & XOPT_ASYNC ? "ID=%ld" : "result=0x%lx", pxact->Result); SendMessage(hwndInfoCtrl, ICM_SETSTRING, ICSID_LR, (DWORD)(LPSTR)szT); if ((pxact->fsOptions & XOPT_ASYNC) && pxact->ret) { /* * asynchronous successful start - link transaction to window. */ DdeSetUserHandle(pxact->hConv, pxact->Result, (DWORD)hwndInfoCtrl); /* * Abandon started async transaction after initiated if * XOPT_ABANDONAFTERSTART is chosen. This tests the mid-transaction * abandoning code. */ if (pxact->fsOptions & XOPT_ABANDONAFTERSTART) DdeAbandonTransaction(idInst, pxact->hConv, pxact->Result); /* * show actual status */ ci.cb = sizeof(CONVINFO); DdeQueryConvInfo(pxact->hConv, pxact->Result, &ci); SendMessage(hwndInfoCtrl, ICM_SETSTRING, ICSID_LL, (DWORD)(LPSTR)State2String(ci.wConvst)); } else { /* * Synchronous transactions are completed already so pass on to * CompleteTransaction right away. */ CompleteTransaction(hwndInfoCtrl, pxact); } return TRUE; }