/****************************************************************** * WDML_ServerHandleRequest * * */ static WDML_QUEUE_STATE WDML_ServerHandleRequest(WDML_CONV* pConv, WDML_XACT* pXAct) { HDDEDATA hDdeData = 0; BOOL fAck = TRUE; if (!(pConv->instance->CBFflags & CBF_FAIL_REQUESTS)) { hDdeData = WDML_InvokeCallback(pConv->instance, XTYP_REQUEST, pXAct->wFmt, (HCONV)pConv, pConv->hszTopic, pXAct->hszItem, 0, 0, 0); } switch ((ULONG_PTR)hDdeData) { case 0: TRACE("No data returned from the Callback\n"); fAck = FALSE; break; case (ULONG_PTR)CBR_BLOCK: return WDML_QS_BLOCK; default: { HGLOBAL hMem = WDML_DataHandle2Global(hDdeData, TRUE, FALSE, FALSE, FALSE); if (!PostMessageW(pConv->hwndClient, WM_DDE_DATA, (WPARAM)pConv->hwndServer, ReuseDDElParam(pXAct->lParam, WM_DDE_REQUEST, WM_DDE_DATA, (UINT_PTR)hMem, (UINT_PTR)pXAct->atom))) { pConv->instance->lastError = DMLERR_POSTMSG_FAILED; DdeFreeDataHandle(hDdeData); GlobalFree(hMem); fAck = FALSE; } } break; } WDML_PostAck(pConv, WDML_SERVER_SIDE, 0, FALSE, fAck, pXAct->atom, pXAct->lParam, WM_DDE_REQUEST); WDML_DecHSZ(pConv->instance, pXAct->hszItem); return WDML_QS_HANDLED; }
bool DDEWidget::ddeExecute(MSG* message, long* result) // ---------------------------------------------------------------------------- // Process a Windows WM_DDE_EXECUTE message // ---------------------------------------------------------------------------- { // unpack the DDE message UINT_PTR unused; HGLOBAL hData; bool ok; //IA64: Assume DDE LPARAMs are still 32-bit ok = (::UnpackDDElParam(WM_DDE_EXECUTE, message->lParam, &unused, (UINT_PTR*)&hData) != 0); XL_ASSERT(ok); if (!ok) return false; QString command = QString::fromWCharArray((LPCWSTR)::GlobalLock(hData)); ::GlobalUnlock(hData); // acknowledge now - before attempting to execute ::PostMessage((HWND)message->wParam, WM_DDE_ACK, (WPARAM)winId(), //IA64: Assume DDE LPARAMs are still 32-bit ReuseDDElParam(message->lParam, WM_DDE_EXECUTE, WM_DDE_ACK, (UINT)0x8000, (UINT_PTR)hData)); // don't execute the command when the window is disabled if (!isEnabled()) { *result = 0; return true; } QRegExp regCommand("^\\[(\\w+)\\((.*)\\)\\]$"); if(regCommand.exactMatch(command)) { executeDdeCommand(regCommand.cap(1), regCommand.cap(2)); } *result = 0; return true; }
LRESULT OnDDExecute(HWND hwnd, WPARAM wparam, LPARAM lparam) { UINT_PTR lo, hi; UnpackDDElParam(WM_DDE_EXECUTE, lparam, &lo, &hi); ScopedMem<WCHAR> cmd; DDEACK ack = { 0 }; LPVOID command = GlobalLock((HGLOBAL)hi); if (!command) goto Exit; if (IsWindowUnicode((HWND)wparam)) cmd.Set(str::Dup((const WCHAR*)command)); else cmd.Set(str::conv::FromAnsi((const char*)command)); const WCHAR *currCmd = cmd; while (!str::IsEmpty(currCmd)) { const WCHAR *nextCmd = NULL; if (!nextCmd) nextCmd = HandleSyncCmd(currCmd, ack); if (!nextCmd) nextCmd = HandleOpenCmd(currCmd, ack); if (!nextCmd) nextCmd = HandleGotoCmd(currCmd, ack); if (!nextCmd) nextCmd = HandlePageCmd(currCmd, ack); if (!nextCmd) nextCmd = HandleSetViewCmd(currCmd, ack); if (!nextCmd) { ScopedMem<WCHAR> tmp; nextCmd = str::Parse(currCmd, L"%S]", &tmp); } currCmd = nextCmd; } Exit: GlobalUnlock((HGLOBAL)hi); lparam = ReuseDDElParam(lparam, WM_DDE_EXECUTE, WM_DDE_ACK, *(WORD *)&ack, hi); PostMessage((HWND)wparam, WM_DDE_ACK, (WPARAM)hwnd, lparam); return 0; }
/****************************************************************** * WDML_ServerHandleRequest * * */ static WDML_QUEUE_STATE WDML_ServerHandleRequest(WDML_CONV* pConv, WDML_XACT* pXAct) { HDDEDATA hDdeData = 0; WDML_QUEUE_STATE ret = WDML_QS_HANDLED; if (!(pConv->instance->CBFflags & CBF_FAIL_REQUESTS)) { hDdeData = WDML_InvokeCallback(pConv->instance, XTYP_REQUEST, pXAct->wFmt, (HCONV)pConv, pConv->hszTopic, pXAct->hszItem, 0, 0, 0); } switch ((DWORD)hDdeData) { case 0: WDML_PostAck(pConv, WDML_SERVER_SIDE, 0, FALSE, FALSE, pXAct->atom, pXAct->lParam, WM_DDE_REQUEST); break; case CBR_BLOCK: ret = WDML_QS_BLOCK; break; default: { HGLOBAL hMem = WDML_DataHandle2Global(hDdeData, FALSE, FALSE, FALSE, FALSE); if (!PostMessageA(pConv->hwndClient, WM_DDE_DATA, (WPARAM)pConv->hwndServer, ReuseDDElParam(pXAct->lParam, WM_DDE_REQUEST, WM_DDE_DATA, (UINT)hMem, (UINT)pXAct->atom))) { DdeFreeDataHandle(hDdeData); GlobalFree(hMem); } } break; } WDML_DecHSZ(pConv->instance, pXAct->hszItem); return ret; }
static LRESULT CALLBACK DdeMessageWindow(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_DDE_INITIATE: { ATOM hSzApp = LOWORD(lParam); /* no UnpackDDElParam() here */ ATOM hSzTopic = HIWORD(lParam); if ((hSzApp == GlobalFindAtom(DDEAPP) && hSzTopic == GlobalFindAtom(DDETOPIC)) || !hSzApp) { hSzApp = GlobalAddAtom(DDEAPP); hSzTopic = GlobalAddAtom(DDETOPIC); if (hSzApp && hSzTopic) /* PackDDElParam() only for posted msgs */ SendMessage((HWND)wParam, WM_DDE_ACK, (WPARAM)hwnd, MAKELPARAM(hSzApp, hSzTopic)); if (hSzApp) GlobalDeleteAtom(hSzApp); if (hSzTopic) GlobalDeleteAtom(hSzTopic); } } return 0; case WM_DDE_EXECUTE: /* posted message */ HGLOBAL hCommand; if (UnpackDDElParam(msg, lParam, NULL, (PUINT_PTR)&hCommand)) { /* ANSI execute command can't happen for shell */ if (IsWindowUnicode((HWND)wParam)) { TCHAR *pszCommand = (TCHAR*)GlobalLock(hCommand); if (pszCommand != NULL) { TCHAR *pszAction = GetExecuteParam(&pszCommand); TCHAR *pszArg = GetExecuteParam(&pszCommand); if (pszArg != NULL) { /* we are inside miranda here, we make it async so the shell does * not timeout regardless what the plugins try to do. */ if (!mir_tstrcmpi(pszAction, _T("file"))) CallFunctionAsync(FileActionAsync, mir_tstrdup(pszArg)); else if (!mir_tstrcmpi(pszAction, _T("url"))) CallFunctionAsync(UrlActionAsync, mir_tstrdup(pszArg)); } GlobalUnlock(hCommand); } } DDEACK ack; memset(&ack, 0, sizeof(ack)); lParam = ReuseDDElParam(lParam, msg, WM_DDE_ACK, *(PUINT)&ack, (UINT_PTR)hCommand); if (!PostMessage((HWND)wParam, WM_DDE_ACK, (WPARAM)hwnd, lParam)) { GlobalFree(hCommand); FreeDDElParam(WM_DDE_ACK, lParam); } } return 0; case WM_DDE_TERMINATE: PostMessage((HWND)wParam, msg, (WPARAM)hwnd, 0); /* ack reply */ return 0; case WM_DDE_REQUEST: case WM_DDE_ADVISE: case WM_DDE_UNADVISE: case WM_DDE_POKE: /* fail safely for those to avoid memory leak in lParam */ { ATOM hSzItem; DDEACK ack; memset(&ack, 0, sizeof(ack)); if (UnpackDDElParam(msg, lParam, NULL, (PUINT_PTR)&hSzItem)) { lParam = ReuseDDElParam(lParam, msg, WM_DDE_ACK, *(PUINT)&ack, (UINT)hSzItem); if (!PostMessage((HWND)wParam, WM_DDE_ACK, (WPARAM)hwnd, lParam)) { if (hSzItem) GlobalDeleteAtom(hSzItem); FreeDDElParam(WM_DDE_ACK, lParam); } } return 0; } } return DefWindowProc(hwnd, msg, wParam, lParam); }
static long ProcessShellDDE(HWND w, UINT msg, WPARAM wp, LPARAM lp) { char *command; ATOM app,top,a; WPARAM hi,lo; unsigned short ack; char buffer[256]; switch (msg) { case WM_DDE_INITIATE: /* * Initiate DDE command */ a = (ATOM)LOWORD(lp); if (a == NULL) return 0; ::GlobalGetAtomName(a,buffer,sizeof(buffer)); if (::strcmp(_GDDEAppName,buffer)) return 0; a = (ATOM)HIWORD(lp); if (a != NULL) { ::GlobalGetAtomName(a,buffer,sizeof(buffer)); if (::strcmp(_GDDETopicName,buffer)) return 0; } /* * Respond with ACK of only conversation I do */ app = ::GlobalAddAtom(_GDDEAppName); top = ::GlobalAddAtom(_GDDETopicName); ::SendMessage((HWND)wp,WM_DDE_ACK,(WPARAM)w,MAKELPARAM(app,top)); ::GlobalDeleteAtom(app); ::GlobalDeleteAtom(top); return 0; case WM_DDE_TERMINATE: /* * Terminate DDE connection */ ::PostMessage((HWND)wp,WM_DDE_TERMINATE,(WPARAM)w,0); return 0; case WM_DDE_EXECUTE: /* * Extract command string */ command = (char *)GlobalLock((HANDLE)lp); ExecuteDDE(command); ::GlobalUnlock((HANDLE)lp); ack = 1; lo = *(WPARAM *)&ack; lp = PackDDElParam(WM_DDE_ACK,lo,lp); PostMessage((HWND)wp,WM_DDE_ACK,(LPARAM)w,lp); return 0; case WM_DDE_UNADVISE: case WM_DDE_ADVISE: case WM_DDE_DATA: case WM_DDE_POKE: case WM_DDE_REQUEST: /* * Don't do 'em, don't ack 'em! */ UnpackDDElParam(msg,lp,&lo,&hi); if ((msg == WM_DDE_ADVISE) || (msg == WM_DDE_DATA) || (msg == WM_DDE_POKE)) { ::GlobalFree((HANDLE)lo); } ack = 0; lo = *(WPARAM *)(&ack); ReuseDDElParam(lp,msg,WM_DDE_ACK,lo,hi); PostMessage((HWND)wp,WM_DDE_ACK,(WPARAM)w,lp); return 0; default: return -1; } }