⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 client.c

📁 Wine-20031016
💻 C
📖 第 1 页 / 共 3 页
字号:
        pXAct->hDdeData = (HDDEDATA)1;    }    return WDML_QS_HANDLED;}/****************************************************************** *		WDML_ClientQueueRequest * * */static WDML_XACT*	WDML_ClientQueueRequest(WDML_CONV* pConv, UINT wFmt, HSZ hszItem){    WDML_XACT*	pXAct;    ATOM	atom;    TRACE("XTYP_REQUEST transaction\n");    atom = WDML_MakeAtomFromHsz(hszItem);    if (!atom) return NULL;    pXAct = WDML_AllocTransaction(pConv->instance, WM_DDE_REQUEST, wFmt, hszItem);    if (!pXAct)    {	GlobalDeleteAtom(atom);	return NULL;    }    pXAct->lParam = PackDDElParam(WM_DDE_REQUEST, wFmt, atom);    return pXAct;}/****************************************************************** *		WDML_HandleRequestReply * * */static WDML_QUEUE_STATE WDML_HandleRequestReply(WDML_CONV* pConv, MSG* msg, WDML_XACT* pXAct){    DDEACK		ddeAck;    WINE_DDEHEAD	wdh;    UINT_PTR		uiLo, uiHi;    HSZ			hsz;    if (WIN_GetFullHandle((HWND)msg->wParam) != pConv->hwndServer)	return WDML_QS_PASS;    switch (msg->message)    {    case WM_DDE_ACK:        UnpackDDElParam(WM_DDE_ACK, msg->lParam, &uiLo, &uiHi);        FreeDDElParam(WM_DDE_ACK, msg->lParam);	GlobalDeleteAtom(uiHi);	WDML_ExtractAck(uiLo, &ddeAck);	pXAct->hDdeData = 0;	if (ddeAck.fAck)	    ERR("Positive answer should appear in NACK for a request, assuming negative\n");	TRACE("Negative answer...\n");	break;    case WM_DDE_DATA:        UnpackDDElParam(WM_DDE_DATA, msg->lParam, &uiLo, &uiHi);	TRACE("Got the result (%08x)\n", uiLo);	hsz = WDML_MakeHszFromAtom(pConv->instance, uiHi);	if (DdeCmpStringHandles(hsz, pXAct->hszItem) != 0)	    return WDML_QS_PASS;	pXAct->hDdeData = WDML_Global2DataHandle((HGLOBAL)uiLo, &wdh);	if (wdh.fRelease)	{	    GlobalFree((HGLOBAL)uiLo);	}	if (wdh.fAckReq)	{	    WDML_PostAck(pConv, WDML_CLIENT_SIDE, 0, FALSE, TRUE, uiHi, msg->lParam, WM_DDE_DATA);	}	else	{	    GlobalDeleteAtom(uiHi);            FreeDDElParam(WM_DDE_ACK, msg->lParam);	}	break;    default:        FreeDDElParam(msg->message, msg->lParam);	return WDML_QS_PASS;    }    return WDML_QS_HANDLED;}/****************************************************************** *		WDML_BuildExecuteCommand * * Creates a DDE block suitable for sending in WM_DDE_COMMAND * It also takes care of string conversion between the two window procedures */static	HGLOBAL	WDML_BuildExecuteCommand(WDML_CONV* pConv, LPCVOID pData, DWORD cbData){    HGLOBAL	hMem;    BOOL	clientUnicode, serverUnicode;    DWORD	memSize;    clientUnicode = IsWindowUnicode(pConv->hwndClient);    serverUnicode = IsWindowUnicode(pConv->hwndServer);    if (clientUnicode == serverUnicode)    {	memSize = cbData;    }    else    {	if (clientUnicode)	{	    memSize = WideCharToMultiByte( CP_ACP, 0, pData, cbData, NULL, 0, NULL, NULL);	}	else	{	    memSize = MultiByteToWideChar( CP_ACP, 0, pData, cbData, NULL, 0);	}    }    hMem = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, memSize);    if (hMem)    {	LPBYTE	pDst;	pDst = GlobalLock(hMem);	if (pDst)	{	    if (clientUnicode == serverUnicode)	    {		memcpy(pDst, pData, cbData);	    }	    else	    {		if (clientUnicode)		{		    WideCharToMultiByte( CP_ACP, 0, pData, cbData, pDst, memSize, NULL, NULL);		}		else		{		    MultiByteToWideChar( CP_ACP, 0, pData, cbData, (LPWSTR)pDst, memSize);		}	    }	    GlobalUnlock(hMem);	}	else	{	    GlobalFree(hMem);	    hMem = 0;	}    }    return hMem;}/****************************************************************** *		WDML_ClientQueueExecute * * */static WDML_XACT*	WDML_ClientQueueExecute(WDML_CONV* pConv, LPCVOID pData, DWORD cbData){    WDML_XACT*	pXAct;    TRACE("XTYP_EXECUTE transaction\n");    pXAct = WDML_AllocTransaction(pConv->instance, WM_DDE_EXECUTE, 0, 0);    if (!pXAct)	return NULL;    if (cbData == (DWORD)-1)    {	HDDEDATA	hDdeData = (HDDEDATA)pData;	pData = DdeAccessData(hDdeData, &cbData);	if (pData)	{	    pXAct->hMem = WDML_BuildExecuteCommand(pConv, pData, cbData);	    DdeUnaccessData(hDdeData);	}    }    else    {	pXAct->hMem = WDML_BuildExecuteCommand(pConv, pData, cbData);    }    pXAct->lParam = (LPARAM)pXAct->hMem;    return pXAct;}/****************************************************************** *		WDML_HandleExecuteReply * * */static WDML_QUEUE_STATE WDML_HandleExecuteReply(WDML_CONV* pConv, MSG* msg, WDML_XACT* pXAct){    DDEACK	ddeAck;    UINT_PTR	uiLo, uiHi;    if (msg->message != WM_DDE_ACK || WIN_GetFullHandle((HWND)msg->wParam) != pConv->hwndServer)    {	return WDML_QS_PASS;    }    UnpackDDElParam(WM_DDE_ACK, msg->lParam, &uiLo, &uiHi);    FreeDDElParam(WM_DDE_ACK, msg->lParam);    if ((HANDLE)uiHi != pXAct->hMem)    {        return WDML_QS_PASS;    }    WDML_ExtractAck(uiLo, &ddeAck);    pXAct->hDdeData = (HDDEDATA)(UINT_PTR)ddeAck.fAck;    return WDML_QS_HANDLED;}/****************************************************************** *		WDML_ClientQueuePoke * * */static WDML_XACT*	WDML_ClientQueuePoke(WDML_CONV* pConv, LPCVOID pData, DWORD cbData,					     UINT wFmt, HSZ hszItem){    WDML_XACT*	pXAct;    ATOM	atom;    TRACE("XTYP_POKE transaction\n");    atom = WDML_MakeAtomFromHsz(hszItem);    if (!atom) return NULL;    pXAct = WDML_AllocTransaction(pConv->instance, WM_DDE_POKE, wFmt, hszItem);    if (!pXAct)    {	GlobalDeleteAtom(atom);	return NULL;    }    if (cbData == (DWORD)-1)    {	pXAct->hMem = (HDDEDATA)pData;    }    else    {	DDEPOKE*	ddePoke;	pXAct->hMem = GlobalAlloc(GHND | GMEM_DDESHARE, sizeof(DDEPOKE) + cbData);	ddePoke = GlobalLock(pXAct->hMem);	if (ddePoke)	{	    memcpy(ddePoke->Value, pData, cbData);	    ddePoke->fRelease = FALSE; /* FIXME: app owned ? */	    ddePoke->cfFormat = wFmt;	    GlobalUnlock(pXAct->hMem);	}    }    pXAct->lParam = PackDDElParam(WM_DDE_POKE, (UINT_PTR)pXAct->hMem, atom);    return pXAct;}/****************************************************************** *		WDML_HandlePokeReply * * */static WDML_QUEUE_STATE WDML_HandlePokeReply(WDML_CONV* pConv, MSG* msg, WDML_XACT* pXAct){    DDEACK	ddeAck;    UINT_PTR	uiLo, uiHi;    HSZ		hsz;    if (msg->message != WM_DDE_ACK && WIN_GetFullHandle((HWND)msg->wParam) != pConv->hwndServer)    {	return WDML_QS_PASS;    }    UnpackDDElParam(WM_DDE_ACK, msg->lParam, &uiLo, &uiHi);    hsz = WDML_MakeHszFromAtom(pConv->instance, uiHi);    if (DdeCmpStringHandles(hsz, pXAct->hszItem) != 0)    {	return WDML_QS_PASS;    }    FreeDDElParam(WM_DDE_ACK, msg->lParam);    GlobalDeleteAtom(uiHi);    WDML_ExtractAck(uiLo, &ddeAck);    GlobalFree(pXAct->hMem);    pXAct->hDdeData = (HDDEDATA)TRUE;    return TRUE;}/****************************************************************** *		WDML_ClientQueueTerminate * * Creates and queue an WM_DDE_TERMINATE transaction */static WDML_XACT*	WDML_ClientQueueTerminate(WDML_CONV* pConv){    WDML_XACT*		pXAct;    pXAct = WDML_AllocTransaction(pConv->instance, WM_DDE_TERMINATE, 0, 0);    if (!pXAct)	return NULL;    pXAct->lParam = 0;    pConv->wStatus &= ~ST_CONNECTED;    return pXAct;}/****************************************************************** *		WDML_HandleTerminateReply * * handles the reply to a terminate request */static WDML_QUEUE_STATE WDML_HandleTerminateReply(WDML_CONV* pConv, MSG* msg, WDML_XACT* pXAct){    if (msg->message != WM_DDE_TERMINATE)    {	/* FIXME: should delete data passed here */	return WDML_QS_SWALLOWED;    }    if (WIN_GetFullHandle((HWND)msg->wParam) != pConv->hwndServer)    {	FIXME("hmmm shouldn't happen\n");	return WDML_QS_PASS;    }    if (!pConv->instance->CBFflags & CBF_SKIP_DISCONNECTS)    {	WDML_InvokeCallback(pConv->instance, XTYP_DISCONNECT, 0, (HCONV)pConv,			    0, 0, 0, 0, (pConv->wStatus & ST_ISSELF) ? 1 : 0);    }    WDML_RemoveConv(pConv, WDML_CLIENT_SIDE);    return WDML_QS_HANDLED;}/****************************************************************** *		WDML_HandleReplyData * * */static WDML_QUEUE_STATE WDML_HandleIncomingData(WDML_CONV* pConv, MSG* msg, HDDEDATA* hdd){    UINT_PTR		uiLo, uiHi;    HDDEDATA		hDdeDataIn, hDdeDataOut;    WDML_LINK*		pLink;    WINE_DDEHEAD	wdh;    HSZ			hsz;    TRACE("WM_DDE_DATA message received in the Client Proc!\n");    /* wParam -- sending window handle	*/    /* lParam -- hDdeData & item HSZ	*/    UnpackDDElParam(WM_DDE_DATA, msg->lParam, &uiLo, &uiHi);    hsz = WDML_MakeHszFromAtom(pConv->instance, uiHi);    hDdeDataIn = WDML_Global2DataHandle((HGLOBAL)uiLo, &wdh);    /* billx:     *  For hot link, data should be passed to its callback with     * XTYP_ADVDATA and callback should return the proper status.     */    pLink = WDML_FindLink(pConv->instance, (HCONV)pConv, WDML_CLIENT_SIDE, hsz,                          uiLo ? TRUE : FALSE, wdh.cfFormat);    if (!pLink)    {	WDML_DecHSZ(pConv->instance, hsz);        DdeFreeDataHandle(hDdeDataIn);	return WDML_QS_PASS;    }    if (hDdeDataIn != 0 && wdh.fAckReq)    {	WDML_PostAck(pConv, WDML_CLIENT_SIDE, 0, FALSE, TRUE, uiHi, msg->lParam, WM_DDE_DATA);	if (msg->lParam)	    msg->lParam = 0;    }    else    {	GlobalDeleteAtom(uiHi);    }    hDdeDataOut = WDML_InvokeCallback(pConv->instance, XTYP_ADVDATA, pLink->uFmt, pLink->hConv,				      pConv->hszTopic, pLink->hszItem, hDdeDataIn, 0, 0);    if (hDdeDataOut != (HDDEDATA)DDE_FACK || wdh.fRelease)    {        if (uiLo) GlobalFree((HANDLE)uiLo);    }    DdeFreeDataHandle(hDdeDataIn);    WDML_DecHSZ(pConv->instance, hsz);    if (msg->lParam)	FreeDDElParam(WM_DDE_DATA, msg->lParam);    return WDML_QS_HANDLED;}/****************************************************************** *		WDML_HandleIncomingTerminate * * */static WDML_QUEUE_STATE WDML_HandleIncomingTerminate(WDML_CONV* pConv, MSG* msg, HDDEDATA* hdd){    if (pConv->hwndServer != WIN_GetFullHandle((HWND)msg->wParam))	return WDML_QS_PASS;    pConv->wStatus |= ST_TERMINATED;    if (!pConv->instance->CBFflags & CBF_SKIP_DISCONNECTS)    {	WDML_InvokeCallback(pConv->instance, XTYP_DISCONNECT, 0, (HCONV)pConv,			    0, 0, 0, 0, (pConv->wStatus & ST_ISSELF) ? 1 : 0);    }    if (pConv->wStatus & ST_CONNECTED)    {	/* don't care about result code (if server exists or not) */	PostMessageA(pConv->hwndServer, WM_DDE_TERMINATE, (WPARAM)pConv->hwndClient, 0L);	pConv->wStatus &= ~ST_CONNECTED;    }    /* have to keep connection around to allow reconnection */    return WDML_QS_HANDLED;}/****************************************************************** *		WDML_HandleReply * * handles any incoming reply, and try to match to an already sent request */static WDML_QUEUE_STATE	WDML_HandleReply(WDML_CONV* pConv, MSG* msg, HDDEDATA* hdd){    WDML_XACT*		pXAct = pConv->transactions;    WDML_QUEUE_STATE	qs;    if (pConv->transactions)    {	/* first check message against a pending transaction, if any */	switch (pXAct->ddeMsg)	{	case WM_DDE_ADVISE:	    qs = WDML_HandleAdviseReply(pConv, msg, pXAct);	    break;	case WM_DDE_UNADVISE:	    qs = WDML_HandleUnadviseReply(pConv, msg, pXAct);	    break;	case WM_DDE_EXECUTE:	    qs = WDML_HandleExecuteReply(pConv, msg, pXAct);	    break;	case WM_DDE_REQUEST:	    qs = WDML_HandleRequestReply(pConv, msg, pXAct);	    break;	case WM_DDE_POKE:	    qs = WDML_HandlePokeReply(pConv, msg, pXAct);	    break;	case WM_DDE_TERMINATE:	    qs = WDML_HandleTerminateReply(pConv, msg, pXAct);	    break;	default:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -