#include "hdr/modern_commonheaders.h" #include "hdr/modern_sync.h" typedef struct tagSYNCCALLITEM { WPARAM wParam; LPARAM lParam; int nResult; HANDLE hDoneEvent; PSYNCCALLBACKPROC pfnProc; } SYNCCALLITEM; static void CALLBACK _SyncCallerUserAPCProc(ULONG_PTR dwParam) { SYNCCALLITEM* item = (SYNCCALLITEM*) dwParam; item->nResult = item->pfnProc(item->wParam, item->lParam); SetEvent(item->hDoneEvent); } static INT_PTR SyncCaller(WPARAM proc, LPARAM lParam) { typedef int (*P0PARAMFUNC)(); typedef int (*P1PARAMFUNC)(WPARAM); typedef int (*P2PARAMFUNC)(WPARAM, LPARAM); typedef int (*P3PARAMFUNC)(WPARAM, LPARAM, LPARAM); typedef int (*P4PARAMFUNC)(WPARAM, LPARAM, LPARAM, LPARAM); LPARAM * params=(LPARAM *)lParam; int count=params[0]; switch (count) { case 0: { P0PARAMFUNC pfnProc=(P0PARAMFUNC)proc; return pfnProc(); } case 1: { P1PARAMFUNC pfnProc=(P1PARAMFUNC)proc; return pfnProc((WPARAM)params[1]); } case 2: { P2PARAMFUNC pfnProc=(P2PARAMFUNC)proc; return pfnProc((WPARAM)params[1],(LPARAM)params[2]); } case 3: { P3PARAMFUNC pfnProc=(P3PARAMFUNC)proc; return pfnProc((WPARAM)params[1],(LPARAM)params[2], (LPARAM)params[3]); } case 4: { P4PARAMFUNC pfnProc=(P4PARAMFUNC)proc; return pfnProc((WPARAM)params[1],(LPARAM)params[2], (LPARAM)params[3], (LPARAM)params[4]); } } return 0; } int SyncCall(void * vproc, int count, ... ) { LPARAM params[5]; va_list va; int i; params[0]=(LPARAM)count; va_start(va, count); for (i=0; ihwndContactList == NULL ) return E_FAIL; SYNCCALLITEM item={0}; item.wParam = wParam; item.lParam = lParam; item.pfnProc = pfnProc; nReturn = SendMessage(pcli->hwndContactList, UM_SYNCCALL, (WPARAM)&item,0); return S_OK; } HRESULT SyncCallAPCProxy( PSYNCCALLBACKPROC pfnProc, WPARAM wParam, LPARAM lParam, int& hReturn ) { hReturn = 0; if (g_hMainThread==NULL || pfnProc==NULL) return E_FAIL; SYNCCALLITEM item={0}; if (GetCurrentThreadId()!=g_dwMainThreadID) { item.wParam = wParam; item.lParam = lParam; item.pfnProc = pfnProc; item.hDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL); QueueUserAPC(_SyncCallerUserAPCProc, g_hMainThread, (ULONG_PTR) &item); PostMessage(pcli->hwndContactList,WM_NULL,0,0); // let this get processed in its own time WaitForSingleObject(item.hDoneEvent, INFINITE); CloseHandle(item.hDoneEvent); hReturn = item.nResult; return S_OK; } /* else */ hReturn = pfnProc(wParam, lParam); return S_OK; } LRESULT SyncOnWndProcCall( WPARAM wParam ) { SYNCCALLITEM *psci=(SYNCCALLITEM *)wParam; if (psci) return psci->pfnProc( psci->wParam, psci->lParam ); return 0; } int DoCall( PSYNCCALLBACKPROC pfnProc, WPARAM wParam, LPARAM lParam ) { return SyncCallProxy( pfnProc, 0, lParam ); }