123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413 |
- #include "main.h"
- #include "./browserThread.h"
- #include "../nu/threadname.h"
- #include <exdisp.h>
- typedef struct __BROWSERTHREADCRAEATEPARAM
- {
- BTCREATEWNDPROC fnCreateWnd;
- BTKEYFILTERPROC fnKeyFilter;
- ULONG_PTR user;
- HANDLE readyEvent;
- HWND hHost;
- HWND hWinamp;
- } BROWSERTHREADCREATEPARAM;
- typedef struct __BROWSERTHREAD
- {
- HHOOK messageHook;
- HANDLE wakeupEvent;
- UINT flags;
- } BROWSERTHREAD;
- #define NAVIGATE_WAITTIMEOUT 30
- static size_t tlsIndex = TLS_OUT_OF_INDEXES;
- static UINT BHTM_DESTROY = 0xFEFE;
- static DWORD CALLBACK BrowserThread_MainLoop(LPVOID param);
- #define GetThreadInstance() ((TLS_OUT_OF_INDEXES != tlsIndex) ? (BROWSERTHREAD*)Plugin_TlsGetValue(tlsIndex) : NULL)
- BOOL BrowserThread_IsQuiting()
- {
- BROWSERTHREAD *thread = GetThreadInstance();
- return (NULL == thread || 0 != ((BHTF_BEGINDESTROY | BHTF_QUITLOOP) & thread->flags));
- }
- BOOL BrowserThread_SetFlags(UINT flags, UINT flagsMask, BOOL fAlarm)
- {
- BROWSERTHREAD *thread = GetThreadInstance();
- if (NULL == thread) return FALSE;
-
- thread->flags = ((thread->flags & flagsMask) | flags);
- if (FALSE == fAlarm)
- return TRUE;
- return (NULL != thread->wakeupEvent && SetEvent(thread->wakeupEvent));
- }
- HANDLE BrowserThread_Create(HWND hWinamp, BTCREATEWNDPROC fnCreateWnd, ULONG_PTR user, BTKEYFILTERPROC fnKeyFilter, HWND *pWnd, DWORD *pThreadId)
- {
- if (NULL == fnCreateWnd)
- return NULL;
- if (TLS_OUT_OF_INDEXES == tlsIndex)
- {
- tlsIndex = Plugin_TlsAlloc();
- if (TLS_OUT_OF_INDEXES == tlsIndex)
- return NULL;
- }
- DWORD threadId;
-
- BROWSERTHREADCREATEPARAM param;
- ZeroMemory(¶m, sizeof(BROWSERTHREADCREATEPARAM));
- param.fnCreateWnd = fnCreateWnd;
- param.fnKeyFilter = fnKeyFilter;
- param.user = user;
- param.readyEvent = CreateEvent(0, TRUE, FALSE, 0);
- param.hWinamp = hWinamp;
- HANDLE hThread = CreateThread(NULL, 0, BrowserThread_MainLoop, (LPVOID)¶m, 0, &threadId);
-
- if (NULL != hThread)
- {
- if (NULL != param.readyEvent)
- WaitForSingleObject(param.readyEvent, INFINITE);
- }
- else
- {
- if (NULL != param.hHost)
- {
- DestroyWindow(param.hHost);
- param.hHost = NULL;
- }
- threadId = 0;
- }
- if (NULL != param.readyEvent)
- CloseHandle(param.readyEvent);
- if (NULL != pThreadId)
- *pThreadId = threadId;
- if (NULL != pWnd)
- *pWnd = param.hHost;
- return hThread;
- }
- BOOL BrowserThread_PostDestroyEx(DWORD threadId, HWND hHost)
- {
- if (0 == BHTM_DESTROY)
- BHTM_DESTROY = RegisterWindowMessage(L"omBrowserDestroyMsg");
- if (0 == BHTM_DESTROY ||
- FALSE == PostThreadMessage(threadId, BHTM_DESTROY, 0, (LPARAM)hHost))
- {
- return FALSE;
- }
- BrowserThread_SetFlags(BHTF_BEGINDESTROY, BHTF_BEGINDESTROY, FALSE);
- return TRUE;
- }
- BOOL BrowserThread_PostDestroy(HWND hHost)
- {
- return BrowserThread_PostDestroyEx(GetCurrentThreadId(), hHost);
- }
- BOOL BrowserThread_WaitNavigateComplete(IWebBrowser2 *pWeb2, UINT waitMax)
- {
- MSG msg;
- READYSTATE state;
- if (NULL == pWeb2)
- return FALSE;
- BOOL resultOk = FALSE;
- DWORD tickStart = GetTickCount();
- for(;;)
- {
- if (FAILED(pWeb2->get_ReadyState(&state)))
- break;
- if (READYSTATE_INTERACTIVE <= state)
- {
- resultOk = TRUE;
- break;
- }
- else
- {
- DWORD tickNow = GetTickCount();
- if (tickNow < tickStart || (tickNow - tickStart) >= waitMax)
- {
- break; // time out
- }
- }
- DWORD status = MsgWaitForMultipleObjectsEx(0, NULL, NAVIGATE_WAITTIMEOUT, QS_POSTMESSAGE | QS_TIMER | QS_SENDMESSAGE, MWMO_ALERTABLE);
- switch(status)
- {
- case (WAIT_OBJECT_0 + 0):
- while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
- {
- if (!CallMsgFilter(&msg, MSGF_BROWSERLOOP))
- {
- DispatchMessageW(&msg);
- }
- }
- break;
- }
- }
- return resultOk;
- }
- static BOOL BrowserThread_HandleMessage(MSG *pMsg)
- {
- switch(pMsg->message)
- {
- case WM_QUIT:
- BrowserThread_SetFlags(BHTF_QUITLOOP, BHTF_QUITLOOP, TRUE);
- return TRUE;
- }
- if (0 != BHTM_DESTROY && BHTM_DESTROY == pMsg->message)
- {
- HWND hHost = (HWND)pMsg->lParam;
- if (NULL != hHost)
- {
- BrowserThread_SetFlags(BHTF_BEGINDESTROY, BHTF_BEGINDESTROY, FALSE);
- SendMessage(hHost, BTM_RELEASECONTAINER, 0, 0L);
- DestroyWindow(hHost);
- }
- return TRUE;
- }
- return FALSE;
- }
- static LRESULT CALLBACK BrowserThread_MessageFilterProc(INT code, WPARAM wParam, LPARAM lParam)
- {
- BROWSERTHREAD *thread = GetThreadInstance();
- if (code >= 0)
- {
- if (BrowserThread_HandleMessage((MSG*)lParam))
- {
- return TRUE;
- }
- }
- return (NULL != thread && NULL != thread->messageHook) ?
- CallNextHookEx(thread->messageHook, code, wParam, lParam) :
- FALSE;
- }
- static BOOL CALLBACK BrowserThread_DefaultKeyFilter(HWND hwnd, MSG *pMsg)
- {
- return FALSE;
- }
- inline static BOOL BrowserThread_ProcessMessage(HWND hHost, HWND hWinamp, MSG *pMsg, BTKEYFILTERPROC IsHostMessage)
- {
- if (hHost != pMsg->hwnd && FALSE == IsChild(hHost, pMsg->hwnd))
- return FALSE;
- if (pMsg->message >= WM_KEYFIRST && pMsg->message <= WM_KEYLAST)
- {
- if (FALSE != IsHostMessage(hHost, pMsg))
- return TRUE;
- switch(pMsg->wParam)
- {
- case VK_TAB:
- {
- HWND hOwner = (HWND)(LONG_PTR)GetWindowLongPtr(hHost, GWLP_HWNDPARENT);
- if (NULL == hOwner || hWinamp == hOwner)
- hOwner = hHost;
- return IsDialogMessageW(hOwner, pMsg);
- }
- break;
- }
- }
- if (pMsg->message == WM_MOUSEWHEEL)
- {
- POINT cursor;
- HWND targetWindow;
- POINTSTOPOINT(cursor, pMsg->lParam);
- targetWindow = WindowFromPoint(cursor);
- if (NULL != targetWindow &&
- FALSE == IsChild(hHost, targetWindow ) &&
- GetWindowThreadProcessId(targetWindow, NULL) != GetWindowThreadProcessId(hHost, NULL))
- {
- PostMessage(hWinamp, pMsg->message, pMsg->wParam, pMsg->lParam);
- return TRUE;
- }
- }
- return FALSE;
- }
- static void BrowserThread_FinishThread(BROWSERTHREAD *thread)
- {
- if (NULL != thread)
- {
- if (NULL != thread->messageHook)
- {
- UnhookWindowsHookEx(thread->messageHook);
- thread->messageHook = NULL;
- }
- if (NULL != thread->wakeupEvent)
- {
- CloseHandle(thread->wakeupEvent);
- thread->wakeupEvent = NULL;
- }
- }
- if (TLS_OUT_OF_INDEXES != tlsIndex)
- Plugin_TlsSetValue(tlsIndex, NULL);
- OleUninitialize();
- #ifdef _DEBUG
- aTRACE_FMT("[%d] %S: thread exit\r\n", GetCurrentThreadId(), OMBROWSER_NAME);
- #endif // _DEBUG
- }
- static DWORD CALLBACK BrowserThread_MainLoop(LPVOID param)
- {
- #ifdef _DEBUG
- SetThreadName(GetCurrentThreadId(), "omBrowserThread");
- aTRACE_FMT("[%d] %S: thread created\r\n", GetCurrentThreadId(), OMBROWSER_NAME);
- #endif //_DEBUG
- BROWSERTHREADCREATEPARAM *createParam = (BROWSERTHREADCREATEPARAM*)param;
- HWND hWinamp = createParam->hWinamp;
- BROWSERTHREAD thread;
- ZeroMemory(&thread, sizeof(BROWSERTHREAD));
- if (TLS_OUT_OF_INDEXES != tlsIndex)
- Plugin_TlsSetValue(tlsIndex, &thread);
- MSG msg;
- PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
- BTKEYFILTERPROC IsHostMessage = (NULL != createParam->fnKeyFilter) ? createParam->fnKeyFilter : BrowserThread_DefaultKeyFilter;
- thread.messageHook = SetWindowsHookEx(WH_MSGFILTER, BrowserThread_MessageFilterProc, NULL, GetCurrentThreadId());
- thread.wakeupEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
- HWND hHost = createParam->fnCreateWnd(createParam->user);
- createParam->hHost = hHost;
- #ifdef _DEBUG
- if (NULL != hHost)
- aTRACE_FMT("[%d] %S: host created\r\n", GetCurrentThreadId(), OMBROWSER_NAME);
- else
- aTRACE_FMT("[%d] %S: host creation fialed\r\n", GetCurrentThreadId(), OMBROWSER_NAME);
- #endif //_DEBUG
- if (NULL != createParam->readyEvent)
- SetEvent(createParam->readyEvent);
- if (NULL != hHost && FAILED(OleInitialize(0)))
- {
- DestroyWindow(hHost);
- hHost = NULL;
- }
- if (NULL == hHost)
- {
- BrowserThread_FinishThread(&thread);
- return -1;
- }
- SendMessage(hHost, BTM_INITCONTAINER, (WPARAM)hWinamp, 0L);
- SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
- while (0 == (BHTF_QUITLOOP & thread.flags))
- {
- DWORD status = MsgWaitForMultipleObjectsEx(1, &thread.wakeupEvent, INFINITE,
- QS_ALLPOSTMESSAGE | QS_ALLINPUT, MWMO_ALERTABLE | MWMO_INPUTAVAILABLE);
- switch(status)
- {
- case (WAIT_OBJECT_0 + 0):
- // wake up!!!
- break;
- case (WAIT_OBJECT_0 + 1):
- while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
- {
- if (!CallMsgFilter(&msg, MSGF_BROWSERLOOP) && NULL != msg.hwnd)
- {
- if (0 == (BHTF_BEGINDESTROY & thread.flags))
- {
- if (FALSE == BrowserThread_ProcessMessage(hHost, hWinamp, &msg, IsHostMessage))
- {
- TranslateMessage(&msg);
- DispatchMessageW(&msg);
- }
- }
- else
- {
- DispatchMessageW(&msg);
- }
- }
- }
- break;
- }
- }
- BrowserThread_FinishThread(&thread);
- return 0;
- }
- INT BrowserThread_ModalLoop(HWND hwnd, HANDLE hCancel, DWORD timeout)
- {
- MSG msg;
- for (;;)
- {
- DWORD status = MsgWaitForMultipleObjectsEx(1, &hCancel, timeout, QS_ALLINPUT, MWMO_ALERTABLE | MWMO_INPUTAVAILABLE);
- if (WAIT_OBJECT_0 == status)
- {
- return 0;
- }
- else if ((WAIT_OBJECT_0 + 1) == status)
- {
- while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE))
- {
- if (msg.message == WM_QUIT)
- {
- PostQuitMessage((INT)msg.wParam);
- return (INT)msg.wParam;
- }
- if (!IsDialogMessageW(hwnd, &msg))
- {
- TranslateMessage(&msg);
- DispatchMessageW(&msg);
- }
- }
- }
- }
- return 0;
- }
|