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

📄 misc.c

📁 Wine-20031016
💻 C
📖 第 1 页 / 共 5 页
字号:
        GlobalUnlock((HGLOBAL)hData);    }    return ret;}/* ================================================================ * *                  Global <=> Data handle management * * ================================================================ *//* Note: we use a DDEDATA, but layout of DDEDATA, DDEADVISE and DDEPOKE structures is similar: *    offset	  size *    (bytes)	 (bits)	comment *	0	   16	bit fields for options (release, ackreq, response...) *	2	   16	clipboard format *	4	   ?	data to be used */HDDEDATA        WDML_Global2DataHandle(HGLOBAL hMem, WINE_DDEHEAD* p){    DDEDATA*    pDd;    HDDEDATA	ret = 0;    DWORD       size;    if (hMem)    {        pDd = GlobalLock(hMem);        size = GlobalSize(hMem) - sizeof(WINE_DDEHEAD);        if (pDd)        {	    if (p) memcpy(p, pDd, sizeof(WINE_DDEHEAD));            switch (pDd->cfFormat)            {            default:                FIXME("Unsupported format (%d) for data... assuming raw information\n",                      pDd->cfFormat);                /* fall thru */            case 0:            case CF_TEXT:                ret = DdeCreateDataHandle(0, pDd->Value, size, 0, 0, pDd->cfFormat, 0);                break;            case CF_BITMAP:                if (size >= sizeof(BITMAP))                {                    BITMAP*     bmp = (BITMAP*)pDd->Value;                    int         count = bmp->bmWidthBytes * bmp->bmHeight * bmp->bmPlanes;                    if (size >= sizeof(BITMAP) + count)                    {                        HBITMAP hbmp;                        if ((hbmp = CreateBitmap(bmp->bmWidth, bmp->bmHeight,                                                 bmp->bmPlanes, bmp->bmBitsPixel,                                                 pDd->Value + sizeof(BITMAP))))                        {                            ret = DdeCreateDataHandle(0, (LPBYTE)&hbmp, sizeof(hbmp),                                                      0, 0, CF_BITMAP, 0);                        }                        else ERR("Can't create bmp\n");                    }                    else                    {                        ERR("Wrong count: %lu / %d\n", size, sizeof(BITMAP) + count);                    }                } else ERR("No bitmap header\n");                break;            }            GlobalUnlock(hMem);        }    }    return ret;}/****************************************************************** *		WDML_DataHandle2Global * * */HGLOBAL WDML_DataHandle2Global(HDDEDATA hDdeData, BOOL fResponse, BOOL fRelease,			       BOOL fDeferUpd, BOOL fAckReq){    DDE_DATAHANDLE_HEAD*	pDdh;    DWORD                       dwSize;    HGLOBAL                     hMem = 0;    dwSize = GlobalSize((HGLOBAL)hDdeData) - sizeof(DDE_DATAHANDLE_HEAD);    pDdh = (DDE_DATAHANDLE_HEAD*)GlobalLock((HGLOBAL)hDdeData);    if (dwSize && pDdh)    {        WINE_DDEHEAD*    wdh = NULL;        switch (pDdh->cfFormat)        {        default:            FIXME("Unsupported format (%d) for data... passing raw information\n", pDdh->cfFormat);            /* fall thru */        case 0:        case CF_TEXT:            hMem = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, sizeof(WINE_DDEHEAD) + dwSize);            if (hMem && (wdh = GlobalLock(hMem)))            {                memcpy(wdh + 1, pDdh + 1, dwSize);            }            break;        case CF_BITMAP:            if (dwSize >= sizeof(HBITMAP))            {                BITMAP  bmp;                DWORD   count;                HBITMAP hbmp = *(HBITMAP*)(pDdh + 1);                if (GetObjectA(hbmp, sizeof(bmp), &bmp))                {                    count = bmp.bmWidthBytes * bmp.bmHeight;                    hMem = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,                                       sizeof(WINE_DDEHEAD) + sizeof(bmp) + count);                    if (hMem && (wdh = GlobalLock(hMem)))                    {                        memcpy(wdh + 1, &bmp, sizeof(bmp));                        GetBitmapBits(hbmp, count, ((char*)(wdh + 1)) + sizeof(bmp));                    }                }            }            break;        }        if (wdh)        {            wdh->unused = 0;            wdh->fResponse = fResponse;            wdh->fRelease = fRelease;            wdh->fDeferUpd = fDeferUpd;            wdh->fAckReq = fAckReq;            wdh->cfFormat = pDdh->cfFormat;            GlobalUnlock(hMem);        }        GlobalUnlock((HGLOBAL)hDdeData);    }    return hMem;}/* ================================================================ * * 			Server management * * ================================================================ *//****************************************************************** *		WDML_AddServer * * */WDML_SERVER*	WDML_AddServer(WDML_INSTANCE* pInstance, HSZ hszService, HSZ hszTopic){    WDML_SERVER* 	pServer;    char		buf1[256];    char		buf2[256];    pServer = (WDML_SERVER*)HeapAlloc(GetProcessHeap(), 0, sizeof(WDML_SERVER));    if (pServer == NULL) return NULL;    WDML_IncHSZ(pInstance, pServer->hszService = hszService);    DdeQueryStringA(pInstance->instanceID, hszService, buf1, sizeof(buf1), CP_WINANSI);    snprintf(buf2, sizeof(buf2), "%s(0x%08lx)", buf1, GetCurrentProcessId());    pServer->hszServiceSpec = DdeCreateStringHandleA(pInstance->instanceID, buf2, CP_WINANSI);    pServer->atomService = WDML_MakeAtomFromHsz(pServer->hszService);    pServer->atomServiceSpec = WDML_MakeAtomFromHsz(pServer->hszServiceSpec);    pServer->filterOn = TRUE;    pServer->next = pInstance->servers;    pInstance->servers = pServer;    return pServer;}/****************************************************************** *		WDML_RemoveServer * * */void WDML_RemoveServer(WDML_INSTANCE* pInstance, HSZ hszService, HSZ hszTopic){    WDML_SERVER*	pPrev = NULL;    WDML_SERVER*	pServer = NULL;    WDML_CONV*		pConv;    WDML_CONV*		pConvNext;    pServer = pInstance->servers;    while (pServer != NULL)    {	if (DdeCmpStringHandles(pServer->hszService, hszService) == 0)	{	    WDML_BroadcastDDEWindows(WDML_szEventClass, WM_WDML_UNREGISTER,				     pServer->atomService, pServer->atomServiceSpec);	    /* terminate all conversations for given topic */	    for (pConv = pInstance->convs[WDML_SERVER_SIDE]; pConv != NULL; pConv = pConvNext)	    {		pConvNext = pConv->next;		if (DdeCmpStringHandles(pConv->hszService, hszService) == 0)		{		    WDML_RemoveConv(pConv, WDML_SERVER_SIDE);		    /* don't care about return code (whether client window is present or not) */		    PostMessageA(pConv->hwndClient, WM_DDE_TERMINATE, (WPARAM)pConv->hwndServer, 0L);		}	    }	    if (pServer == pInstance->servers)	    {		pInstance->servers = pServer->next;	    }	    else	    {		pPrev->next = pServer->next;	    }	    DestroyWindow(pServer->hwndServer);	    WDML_DecHSZ(pInstance, pServer->hszServiceSpec);	    WDML_DecHSZ(pInstance, pServer->hszService);	    GlobalDeleteAtom(pServer->atomService);	    GlobalDeleteAtom(pServer->atomServiceSpec);	    HeapFree(GetProcessHeap(), 0, pServer);	    break;	}	pPrev = pServer;	pServer = pServer->next;    }}/***************************************************************************** *	WDML_FindServer * *	generic routine to return a pointer to the relevant ServiceNode *	for a given service name, or NULL if the entry does not exist * */WDML_SERVER*	WDML_FindServer(WDML_INSTANCE* pInstance, HSZ hszService, HSZ hszTopic){    WDML_SERVER*	pServer;    for (pServer = pInstance->servers; pServer != NULL; pServer = pServer->next)    {	if (hszService == pServer->hszService)	{	    return pServer;	}    }    TRACE("Service name missing\n");    return NULL;}/* ================================================================ * * 		Conversation management * * ================================================================ *//****************************************************************** *		WDML_AddConv * * */WDML_CONV*	WDML_AddConv(WDML_INSTANCE* pInstance, WDML_SIDE side,			     HSZ hszService, HSZ hszTopic, HWND hwndClient, HWND hwndServer){    WDML_CONV*	pConv;    /* no converstation yet, add it */    pConv = HeapAlloc(GetProcessHeap(), 0, sizeof(WDML_CONV));    if (!pConv) return NULL;    pConv->instance = pInstance;    WDML_IncHSZ(pInstance, pConv->hszService = hszService);    WDML_IncHSZ(pInstance, pConv->hszTopic = hszTopic);    pConv->hwndServer = hwndServer;    pConv->hwndClient = hwndClient;    pConv->transactions = NULL;    pConv->hUser = 0;    pConv->wStatus = (side == WDML_CLIENT_SIDE) ? ST_CLIENT : 0L;    /* check if both side of the conversation are of the same instance */    if (GetWindowThreadProcessId(hwndClient, NULL) == GetWindowThreadProcessId(hwndServer, NULL) &&	WDML_GetInstanceFromWnd(hwndClient) == WDML_GetInstanceFromWnd(hwndServer))    {	pConv->wStatus |= ST_ISSELF;    }    pConv->wConvst = XST_NULL;    pConv->next = pInstance->convs[side];    pInstance->convs[side] = pConv;    return pConv;}/****************************************************************** *		WDML_FindConv * * */WDML_CONV*	WDML_FindConv(WDML_INSTANCE* pInstance, WDML_SIDE side,			      HSZ hszService, HSZ hszTopic){    WDML_CONV*	pCurrent = NULL;    for (pCurrent = pInstance->convs[side]; pCurrent != NULL; pCurrent = pCurrent->next)    {	if (DdeCmpStringHandles(pCurrent->hszService, hszService) == 0 &&	    DdeCmpStringHandles(pCurrent->hszTopic, hszTopic) == 0)	{	    return pCurrent;	}    }    return NULL;}/****************************************************************** *		WDML_RemoveConv * * */void WDML_RemoveConv(WDML_CONV* pRef, WDML_SIDE side){    WDML_CONV*	pPrev = NULL;    WDML_CONV* 	pCurrent;    WDML_XACT*	pXAct;    WDML_XACT*	pXActNext;    HWND	hWnd;    if (!pRef)	return;    /* remove any pending transaction */    for (pXAct = pRef->transactions; pXAct != NULL; pXAct = pXActNext)    {	pXActNext = pXAct->next;	WDML_FreeTransaction(pRef->instance, pXAct, TRUE);    }    WDML_RemoveAllLinks(pRef->instance, pRef, side);    /* FIXME: should we keep the window around ? it seems so (at least on client side     * to let QueryConvInfo work after conv termination, but also to implement     * DdeReconnect...     */    /* destroy conversation window, but first remove pConv from hWnd.     * this would help the wndProc do appropriate handling upon a WM_DESTROY message     */    hWnd = (side == WDML_CLIENT_SIDE) ? pRef->hwndClient : pRef->hwndServer;    SetWindowLongA(hWnd, GWL_WDML_CONVERSATION, 0);    DestroyWindow((side == WDML_CLIENT_SIDE) ? pRef->hwndClient : pRef->hwndServer);    WDML_DecHSZ(pRef->instance, pRef->hszService);    WDML_DecHSZ(pRef->instance, pRef->hszTopic);    for (pCurrent = pRef->instance->convs[side]; pCurrent != NULL; pCurrent = (pPrev = pCurrent)->next)    {	if (pCurrent == pRef)	{	    if (pCurrent == pRef->instance->convs[side])	    {		pRef->instance->convs[side] = pCurrent->next;	    }	    else	    {		pPrev->next = pCurrent->next;	    }	    HeapFree(GetProcessHeap(), 0, pCurrent);	    break;	}    }}/****************************************************************** *              WDML_EnableCallback */static BOOL WDML_EnableCallback(WDML_CONV *pConv, UINT wCmd){    if (wCmd == EC_DISABLE)    {        FIXME("EC_DISABLE is not implemented\n");        return TRUE;    }    if (wCmd == EC_QUERYWAITING)        return pConv->transactions ? TRUE : FALSE;    if (wCmd != EC_ENABLEALL && wCmd != EC_ENABLEONE)    {        FIXME("Unknown command code %04x\n", wCmd);        return FALSE;    }    while (pConv->transactions)    {        WDML_XACT *pXAct = pConv->transactions;        WDML_UnQueueTransaction(pConv, pXAct);        if (pConv->wStatus & ST_CLIENT)        {            /*WDML_ClientHandle(pConv, pXAct);*/            FIXME("Client delayed transaction queue handling is not supported\n");        }        else            WDML_ServerHandle(pConv, pXAct);        WDML_FreeTransaction(pConv->instance, pXAct, TRUE);        if (wCmd == EC_ENABLEONE) break;    }    return TRUE;}/***************************************************************** *            DdeEnableCallback (USER32.@) */BOOL WINAPI DdeEnableCallback(DWORD idInst, HCONV hConv, UINT wCmd){    BOOL ret = FALSE;    WDML_CONV *pConv;    TRACE("(%ld, %p, %04x)\n", idInst, hConv, wCmd);    EnterCriticalSection(&WDML_CritSect);    pConv = WDML_GetConv(hConv, TRUE);    if (pConv && pConv->instance->instanceID == idInst)        ret = WDML_EnableCallback(pConv, wCmd);    LeaveCriticalSection(&WDML_CritSect);    return ret;}/****************************************************************** *		WDML_GetConv * * */WDML_CONV*	WDML_GetConv(HCONV hConv, BOOL checkConnected){    WDML_CONV*	pConv = (WDML_CONV*)hConv;    /* FIXME: should do better checking */    if (pConv == NULL) return NULL;    if (checkConnected && !(pConv->wStatus & ST_CONNECTED))    {	FIXME("found conv but ain't connected\n");	return NULL;    }    if (GetCurrentThreadId() != pConv->instance->threadID)    {	FIXME("wrong thread ID\n");	return NULL;    }    return pConv;}/****************************************************************** *		WDML_GetConvFromWnd * * */WDML_CONV*	WDML_GetConvFromWnd(HWND hWnd){    return (WDML_CONV*)GetWindowLongA(hWnd, GWL_WDML_CONVERSATION);}/****************************************************************** *		WDML_PostAck * * */BOOL		WDML_PostAck(WDML_CONV* pConv, WDML_SIDE side, WORD appRetCode,			     BOOL fBusy, BOOL fAck, UINT pmt, LPARAM lParam, UINT oldMsg){    DDEACK	ddeAck;    HWND	from, to;    if (side == WDML_SERVER_SIDE)    {	from = pConv->hwndServer;

⌨️ 快捷键说明

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