📄 misc.c
字号:
to = pConv->hwndClient; } else { to = pConv->hwndServer; from = pConv->hwndClient; } ddeAck.bAppReturnCode = appRetCode; ddeAck.reserved = 0; ddeAck.fBusy = fBusy; ddeAck.fAck = fAck; TRACE("Posting a %s ack\n", ddeAck.fAck ? "positive" : "negative"); lParam = (lParam) ? ReuseDDElParam(lParam, oldMsg, WM_DDE_ACK, *(WORD*)&ddeAck, pmt) : PackDDElParam(WM_DDE_ACK, *(WORD*)&ddeAck, pmt); if (!PostMessageA(to, WM_DDE_ACK, (WPARAM)from, lParam)) { pConv->wStatus &= ~ST_CONNECTED; FreeDDElParam(WM_DDE_ACK, lParam); return FALSE; } return TRUE;}/***************************************************************** * DdeSetUserHandle (USER32.@) */BOOL WINAPI DdeSetUserHandle(HCONV hConv, DWORD id, DWORD hUser){ WDML_CONV* pConv; BOOL ret = TRUE; TRACE("(%p,%lx,%lx)\n", hConv, id, hUser); EnterCriticalSection(&WDML_CritSect); pConv = WDML_GetConv(hConv, FALSE); if (pConv == NULL) { ret = FALSE; goto theError; } if (id == QID_SYNC) { pConv->hUser = hUser; } else { WDML_XACT* pXAct; pXAct = WDML_FindTransaction(pConv, id); if (pXAct) { pXAct->hUser = hUser; } else { pConv->instance->lastError = DMLERR_UNFOUND_QUEUE_ID; ret = FALSE; } } theError: LeaveCriticalSection(&WDML_CritSect); return ret;}/****************************************************************** * WDML_GetLocalConvInfo * * */static BOOL WDML_GetLocalConvInfo(WDML_CONV* pConv, CONVINFO* ci, DWORD id){ BOOL ret = TRUE; WDML_LINK* pLink; WDML_SIDE side; ci->hConvPartner = (pConv->wStatus & ST_ISLOCAL) ? (HCONV)((DWORD)pConv | 1) : 0; ci->hszSvcPartner = pConv->hszService; ci->hszServiceReq = pConv->hszService; /* FIXME: they shouldn't be the same, should they ? */ ci->hszTopic = pConv->hszTopic; ci->wStatus = pConv->wStatus; side = (pConv->wStatus & ST_CLIENT) ? WDML_CLIENT_SIDE : WDML_SERVER_SIDE; for (pLink = pConv->instance->links[side]; pLink != NULL; pLink = pLink->next) { if (pLink->hConv == (HCONV)pConv) { ci->wStatus |= ST_ADVISE; break; } } /* FIXME: non handled status flags: ST_BLOCKED ST_BLOCKNEXT ST_INLIST */ ci->wConvst = pConv->wConvst; /* FIXME */ ci->wLastError = 0; /* FIXME: note it's not the instance last error */ ci->hConvList = 0; ci->ConvCtxt = pConv->convContext; if (ci->wStatus & ST_CLIENT) { ci->hwnd = pConv->hwndClient; ci->hwndPartner = pConv->hwndServer; } else { ci->hwnd = pConv->hwndServer; ci->hwndPartner = pConv->hwndClient; } if (id == QID_SYNC) { ci->hUser = pConv->hUser; ci->hszItem = 0; ci->wFmt = 0; ci->wType = 0; } else { WDML_XACT* pXAct; pXAct = WDML_FindTransaction(pConv, id); if (pXAct) { ci->hUser = pXAct->hUser; ci->hszItem = pXAct->hszItem; ci->wFmt = pXAct->wFmt; ci->wType = pXAct->wType; } else { ret = 0; pConv->instance->lastError = DMLERR_UNFOUND_QUEUE_ID; } } return ret;}/****************************************************************** * DdeQueryConvInfo (USER32.@) * */UINT WINAPI DdeQueryConvInfo(HCONV hConv, DWORD id, PCONVINFO lpConvInfo){ UINT ret = lpConvInfo->cb; CONVINFO ci; WDML_CONV* pConv; TRACE("(%p,%lx,%p)\n", hConv, id, lpConvInfo); if (!hConv) { FIXME("hConv is NULL\n"); return 0; } EnterCriticalSection(&WDML_CritSect); pConv = WDML_GetConv(hConv, FALSE); if (pConv != NULL && !WDML_GetLocalConvInfo(pConv, &ci, id)) { ret = 0; } else if ((DWORD)hConv & 1) { pConv = WDML_GetConv((HCONV)((DWORD)hConv & ~1), FALSE); if (pConv != NULL) { FIXME("Request on remote conversation information is not implemented yet\n"); ret = 0; } } LeaveCriticalSection(&WDML_CritSect); if (ret != 0) memcpy(lpConvInfo, &ci, min((size_t)lpConvInfo->cb, sizeof(ci))); return ret;}/* ================================================================ * * Link (hot & warm) management * * ================================================================ *//****************************************************************** * WDML_AddLink * * */void WDML_AddLink(WDML_INSTANCE* pInstance, HCONV hConv, WDML_SIDE side, UINT wType, HSZ hszItem, UINT wFmt){ WDML_LINK* pLink; pLink = HeapAlloc(GetProcessHeap(), 0, sizeof(WDML_LINK)); if (pLink == NULL) { ERR("OOM\n"); return; } pLink->hConv = hConv; pLink->transactionType = wType; WDML_IncHSZ(pInstance, pLink->hszItem = hszItem); pLink->uFmt = wFmt; pLink->next = pInstance->links[side]; pInstance->links[side] = pLink;}/****************************************************************** * WDML_RemoveLink * * */void WDML_RemoveLink(WDML_INSTANCE* pInstance, HCONV hConv, WDML_SIDE side, HSZ hszItem, UINT uFmt){ WDML_LINK* pPrev = NULL; WDML_LINK* pCurrent = NULL; pCurrent = pInstance->links[side]; while (pCurrent != NULL) { if (pCurrent->hConv == hConv && DdeCmpStringHandles(pCurrent->hszItem, hszItem) == 0 && pCurrent->uFmt == uFmt) { if (pCurrent == pInstance->links[side]) { pInstance->links[side] = pCurrent->next; } else { pPrev->next = pCurrent->next; } WDML_DecHSZ(pInstance, pCurrent->hszItem); HeapFree(GetProcessHeap(), 0, pCurrent); break; } pPrev = pCurrent; pCurrent = pCurrent->next; }}/* this function is called to remove all links related to the conv. It should be called from both client and server when terminating the conversation.*//****************************************************************** * WDML_RemoveAllLinks * * */void WDML_RemoveAllLinks(WDML_INSTANCE* pInstance, WDML_CONV* pConv, WDML_SIDE side){ WDML_LINK* pPrev = NULL; WDML_LINK* pCurrent = NULL; WDML_LINK* pNext = NULL; pCurrent = pInstance->links[side]; while (pCurrent != NULL) { if (pCurrent->hConv == (HCONV)pConv) { if (pCurrent == pInstance->links[side]) { pInstance->links[side] = pCurrent->next; pNext = pCurrent->next; } else { pPrev->next = pCurrent->next; pNext = pCurrent->next; } WDML_DecHSZ(pInstance, pCurrent->hszItem); HeapFree(GetProcessHeap(), 0, pCurrent); pCurrent = NULL; } if (pCurrent) { pPrev = pCurrent; pCurrent = pCurrent->next; } else { pCurrent = pNext; } }}/****************************************************************** * WDML_FindLink * * */WDML_LINK* WDML_FindLink(WDML_INSTANCE* pInstance, HCONV hConv, WDML_SIDE side, HSZ hszItem, BOOL use_fmt, UINT uFmt){ WDML_LINK* pCurrent = NULL; for (pCurrent = pInstance->links[side]; pCurrent != NULL; pCurrent = pCurrent->next) { /* we don't need to check for transaction type as it can be altered */ if (pCurrent->hConv == hConv && DdeCmpStringHandles(pCurrent->hszItem, hszItem) == 0 && (!use_fmt || pCurrent->uFmt == uFmt)) { break; } } return pCurrent;}/* ================================================================ * * Transaction management * * ================================================================ *//****************************************************************** * WDML_AllocTransaction * * Alloc a transaction structure for handling the message ddeMsg */WDML_XACT* WDML_AllocTransaction(WDML_INSTANCE* pInstance, UINT ddeMsg, UINT wFmt, HSZ hszItem){ WDML_XACT* pXAct; static WORD tid = 1; /* FIXME: wrap around */ pXAct = HeapAlloc(GetProcessHeap(), 0, sizeof(WDML_XACT)); if (!pXAct) { pInstance->lastError = DMLERR_MEMORY_ERROR; return NULL; } pXAct->xActID = tid++; pXAct->ddeMsg = ddeMsg; pXAct->hDdeData = 0; pXAct->hUser = 0; pXAct->next = NULL; pXAct->wType = 0; pXAct->wFmt = wFmt; if ((pXAct->hszItem = hszItem)) WDML_IncHSZ(pInstance, pXAct->hszItem); pXAct->atom = 0; pXAct->hMem = 0; pXAct->lParam = 0; return pXAct;}/****************************************************************** * WDML_QueueTransaction * * Adds a transaction to the list of transaction */void WDML_QueueTransaction(WDML_CONV* pConv, WDML_XACT* pXAct){ WDML_XACT** pt; /* advance to last in queue */ for (pt = &pConv->transactions; *pt != NULL; pt = &(*pt)->next); *pt = pXAct;}/****************************************************************** * WDML_UnQueueTransaction * * */BOOL WDML_UnQueueTransaction(WDML_CONV* pConv, WDML_XACT* pXAct){ WDML_XACT** pt; for (pt = &pConv->transactions; *pt; pt = &(*pt)->next) { if (*pt == pXAct) { *pt = pXAct->next; return TRUE; } } return FALSE;}/****************************************************************** * WDML_FreeTransaction * * */void WDML_FreeTransaction(WDML_INSTANCE* pInstance, WDML_XACT* pXAct, BOOL doFreePmt){ /* free pmt(s) in pXAct too. check against one for not deleting TRUE return values */ if (doFreePmt && (DWORD)pXAct->hMem > 1) { GlobalFree(pXAct->hMem); } if (pXAct->hszItem) WDML_DecHSZ(pInstance, pXAct->hszItem); HeapFree(GetProcessHeap(), 0, pXAct);}/****************************************************************** * WDML_FindTransaction * * */WDML_XACT* WDML_FindTransaction(WDML_CONV* pConv, DWORD tid){ WDML_XACT* pXAct; tid = HIWORD(tid); for (pXAct = pConv->transactions; pXAct; pXAct = pXAct->next) { if (pXAct->xActID == tid) break; } return pXAct;}/* ================================================================ * * Information broadcast across DDEML implementations * * ================================================================ */struct tagWDML_BroadcastPmt{ LPCSTR clsName; UINT uMsg; WPARAM wParam; LPARAM lParam;};/****************************************************************** * WDML_BroadcastEnumProc * * */static BOOL CALLBACK WDML_BroadcastEnumProc(HWND hWnd, LPARAM lParam){ struct tagWDML_BroadcastPmt* s = (struct tagWDML_BroadcastPmt*)lParam; char buffer[128]; if (GetClassNameA(hWnd, buffer, sizeof(buffer)) > 0 && strcmp(buffer, s->clsName) == 0) { PostMessageA(hWnd, s->uMsg, s->wParam, s->lParam); } return TRUE;}/****************************************************************** * WDML_BroadcastDDEWindows * * */void WDML_BroadcastDDEWindows(const char* clsName, UINT uMsg, WPARAM wParam, LPARAM lParam){ struct tagWDML_BroadcastPmt s; s.clsName = clsName; s.uMsg = uMsg; s.wParam = wParam; s.lParam = lParam; EnumWindows(WDML_BroadcastEnumProc, (LPARAM)&s);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -