aboutsummaryrefslogtreecommitdiff
path: root/Src/omBrowser/browserHost.cpp
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/omBrowser/browserHost.cpp
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/omBrowser/browserHost.cpp')
-rw-r--r--Src/omBrowser/browserHost.cpp1232
1 files changed, 1232 insertions, 0 deletions
diff --git a/Src/omBrowser/browserHost.cpp b/Src/omBrowser/browserHost.cpp
new file mode 100644
index 00000000..368dd43f
--- /dev/null
+++ b/Src/omBrowser/browserHost.cpp
@@ -0,0 +1,1232 @@
+#include "main.h"
+#include "./browser.h"
+#include "./browserHost.h"
+//#include "./browserPopup.h"
+#include "./graphics.h"
+
+//#include "../winamp/wa_dlg.h"
+#include "../Plugins/General/gen_ml/colors.h"
+
+#include "./browserThread.h"
+
+#include "../winamp/IWasabiDispatchable.h"
+#include "../winamp/JSAPI_Info.h"
+
+#include "./service.h"
+//#include "./menu.h"
+
+#include "./obj_ombrowser.h"
+#include "./ifc_skinhelper.h"
+#include "./ifc_skinnedbrowser.h"
+#include "./ifc_omservice.h"
+#include "./ifc_travelloghelper.h"
+#include "./ifc_wasabihelper.h"
+#include <exdispid.h>
+#include <strsafe.h>
+
+#define NWC_OMBROWSERHOST L"Nullsoft_omBrowserHost"
+
+typedef struct __BROWSERHOSTCREATEPARAM
+{
+ HWND hParent;
+ INT controlId;
+ UINT fStyle;
+ INT x;
+ INT y;
+ INT cx;
+ INT cy;
+ HINSTANCE hInstance;
+ HACCEL hAccel;
+ obj_ombrowser *browserManager;
+} BROWSERHOSTCREATEPARAM;
+
+typedef struct __BROWSERHOST
+{
+ Browser *container;
+ HACCEL hAccel;
+ obj_ombrowser *browserManager;
+} BROWSERHOST;
+
+
+#define BHT_CONTAINERDOWNLOAD 27
+#define BHT_ACTIVATECONTAINER_DELAY 15
+#define BHT_DEACTIVATECONTAINER_DELAY 75
+
+#define GetHost(__hwnd) ((BROWSERHOST*)(LONG_PTR)(LONGX86)GetWindowLongPtr((__hwnd), 0))
+
+static LRESULT CALLBACK BrowserHost_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+static void CALLBACK BrowserHost_OnDocumentReady(Browser *browser, IDispatch *pDispatch, VARIANT *URL);
+static void CALLBACK BrowserHost_OnNavigateComplete(Browser *browser, IDispatch *pDispatch, VARIANT *URL);
+static void CALLBACK BrowserHost_OnContainerDestroy(Browser *browser);
+static void CALLBACK BrowserHost_OnDownloadBegin(Browser *browser);
+static void CALLBACK BrowserHost_OnDownloadComplete(Browser *browser);
+static void CALLBACK BrowserHost_OnCommandStateChange(Browser *browser, INT commandId, BOOL fEnabled);
+static void CALLBACK BrowserHost_OnStatusChange(Browser *browser, LPCWSTR pszText);
+static void CALLBACK BrowserHost_OnTitleChange(Browser *browser, LPCWSTR pszText);
+static void CALLBACK BrowserHost_OnSecureLockIconChange(Browser *browser);
+static void CALLBACK BrowserHost_OnCreatePopup(Browser *browser, IDispatch **ppDisp, VARIANT_BOOL *Cancel);
+static void CALLBACK BrowserHost_OnVisibleChange(Browser *browser, VARIANT_BOOL fVisible);
+static void CALLBACK BrowserHost_OnSetResizable(Browser *browser, VARIANT_BOOL fAllow);
+static void CALLBACK BrowserHost_OnSetFullScreen(Browser *browser, VARIANT_BOOL fAllow);
+static void CALLBACK BrowserHost_OnWindowClosing(Browser *browser, VARIANT_BOOL fIsChild, VARIANT_BOOL *fCancel);
+static void CALLBACK BrowserHost_OnShowUiElenent(Browser *browser, UINT elementId, VARIANT_BOOL fShow);
+static void CALLBACK BrowserHost_OnClientToHost(Browser *browser, LONG *cx, LONG *cy);
+static void CALLBACK BrowserHost_OnSetWindowPos(Browser *browser, UINT Flags, LONG x, LONG y, LONG cx, LONG cy);
+static void CALLBACK BrowserHost_OnFocusChange(Browser *browser, VARIANT_BOOL *fAllow);
+static void CALLBACK BrowserHost_OnClosePopup(Browser *browser);
+
+static HRESULT CALLBACK BrowserHost_GetOmService(Browser *browser, ifc_omservice **ppService);
+static LRESULT CALLBACK BrowserHost_RedirectKey(Browser *browser, MSG *pMsg);
+
+static BOOL BrowserHost_RegisterClass(HINSTANCE hInstance)
+{
+ WNDCLASS wc = {0};
+ if (GetClassInfo(hInstance, NWC_OMBROWSERHOST, &wc)) return TRUE;
+
+ ZeroMemory(&wc, sizeof(WNDCLASS));
+ wc.hInstance = hInstance;
+ wc.lpszClassName = NWC_OMBROWSERHOST;
+ wc.lpfnWndProc = BrowserHost_WindowProc;
+ wc.style = CS_DBLCLKS;
+ wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wc.hbrBackground = NULL;
+ wc.cbWndExtra = sizeof(BROWSERHOST*);
+
+ return ( 0 != RegisterClassW(&wc));
+}
+
+static HWND CALLBACK BrowserHost_CreateHostWindow(ULONG_PTR user)
+{
+ BROWSERHOSTCREATEPARAM *param = (BROWSERHOSTCREATEPARAM*)user;
+ if (NULL == param) return NULL;
+
+ return CreateWindowEx(WS_EX_NOPARENTNOTIFY | WS_EX_CONTROLPARENT,
+ NWC_OMBROWSERHOST, NULL,
+ WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | (0x00000FFF & param->fStyle),
+ param->x, param->y, param->cx, param->cy,
+ param->hParent, (HMENU)(INT_PTR)param->controlId,
+ param->hInstance, param);
+}
+
+static BOOL CALLBACK BrowserHost_KeyFilter(HWND hwnd, MSG *pMsg)
+{
+ BROWSERHOST *host = GetHost(hwnd);
+ if (NULL == host) return FALSE;
+
+ UINT vKey = (UINT)pMsg->wParam;
+ switch(vKey)
+ {
+ case VK_CONTROL:
+ case VK_MENU:
+ case VK_SHIFT:
+ return TRUE;
+ }
+
+ if (NULL != host->hAccel && (hwnd == pMsg->hwnd || IsChild(hwnd, pMsg->hwnd)))
+ {
+ HWND hParent = GetParent(hwnd);
+ if (NULL != hParent && 0 != TranslateAccelerator(hParent, host->hAccel, pMsg))
+ return TRUE;
+ }
+
+ return (NULL != host->container &&
+ FALSE != host->container->TranslateKey(pMsg));
+}
+
+HWND BrowserHost_CreateWindow(obj_ombrowser *browserManager, HWND hParent, UINT fStyle, INT x, INT y, INT cx, INT cy, INT controlId, HACCEL hAccel)
+{
+ if (FALSE == BrowserHost_RegisterClass(Plugin_GetInstance()))
+ return NULL;
+
+ BROWSERHOSTCREATEPARAM param = {0};
+
+ param.hParent = hParent;
+ param.controlId = controlId;
+ param.hInstance = Plugin_GetInstance();
+ param.x = x;
+ param.y = y;
+ param.cx = cx;
+ param.cy = cy;
+ param.fStyle = fStyle;
+ param.hAccel = hAccel;
+ param.browserManager = browserManager;
+
+ HWND hWinamp = NULL;
+ if (FAILED(Plugin_GetWinampWnd(&hWinamp)))
+ hWinamp = NULL;
+
+ HWND hHost = NULL;
+ HANDLE hThread = BrowserThread_Create(hWinamp, BrowserHost_CreateHostWindow, (ULONG_PTR)&param, BrowserHost_KeyFilter, &hHost, NULL);
+ if (NULL != hThread)
+ CloseHandle(hThread);
+
+ return hHost;
+}
+
+static LRESULT BrowserHost_SendBrowserNotification(Browser *browser, INT code, NMHDR *pnmh)
+{
+ HWND hHost = (NULL != browser) ? browser->GetParentHWND() : NULL;
+ if (NULL == hHost || NULL == pnmh)
+ return 0;
+
+ HWND hParent = GetParent(hHost);
+ if (NULL == hParent)
+ return 0;
+
+ pnmh->code = code;
+ pnmh->hwndFrom = hHost;
+ pnmh->idFrom = GetDlgCtrlID(hHost);
+
+ return SendMessage(hParent, WM_NOTIFY, (WPARAM)pnmh->idFrom, (LPARAM)pnmh);
+}
+
+static LRESULT BrowserHost_SendNotification(HWND hwnd, NMHDR *phdr)
+{
+ HWND hParent = GetParent(hwnd);
+ if (NULL == hParent || NULL == phdr || !IsWindow(hParent))
+ return 0;
+
+ return SendMessage(hParent, WM_NOTIFY, (WPARAM)phdr->idFrom, (LPARAM)phdr);
+}
+
+static void BrowserHost_UpdateLayout(HWND hwnd, BOOL fRedraw)
+{
+ BROWSERHOST *host = GetHost(hwnd);
+ if (NULL == host) return;
+
+ RECT clientRect;
+ if (!GetClientRect(hwnd, &clientRect))
+ return;
+
+ if (NULL != host->container)
+ {
+ host->container->SetLocation(clientRect.left, clientRect.top,
+ clientRect.right - clientRect.left,
+ clientRect.bottom - clientRect.top);
+ }
+}
+
+static COLORREF BrwoserHost_GetBackColor(HWND hwnd)
+{
+ COLORREF rgb;
+
+ ifc_skinnedbrowser *skinnedBrowser = NULL;
+ if (SUCCEEDED(Plugin_GetBrowserSkin(&skinnedBrowser)) && skinnedBrowser != NULL)
+ {
+ rgb = skinnedBrowser->GetBackColor();
+ skinnedBrowser->Release();
+ }
+ else
+ rgb = GetSysColor(COLOR_WINDOW);
+
+ return rgb;
+}
+
+static void BrowserHost_Paint(HWND hwnd, HDC hdc, const RECT *prcPaint, BOOL fErase)
+{
+ SetBkColor(hdc, BrwoserHost_GetBackColor(hwnd));
+ ExtTextOut(hdc, 0, 0, ETO_OPAQUE, prcPaint, NULL, 0, NULL);
+}
+
+static LRESULT BrowserHost_OnCreate(HWND hwnd, CREATESTRUCT *pcs)
+{
+ BROWSERHOST *host= (BROWSERHOST*)calloc(1, sizeof(BROWSERHOST));
+ if (NULL != host)
+ {
+ SetLastError(ERROR_SUCCESS);
+ if (!SetWindowLongPtr(hwnd, 0, (LONGX86)(LONG_PTR)host) && ERROR_SUCCESS != GetLastError())
+ {
+ free(host);
+ host = NULL;
+ }
+ }
+
+ if (NULL == host)
+ {
+ DestroyWindow(hwnd);
+ return -1;
+ }
+
+ BROWSERHOSTCREATEPARAM *param = (BROWSERHOSTCREATEPARAM*)pcs->lpCreateParams;
+ host->hAccel = param->hAccel;
+ host->browserManager = param->browserManager;
+ if (NULL != host->browserManager)
+ host->browserManager->AddRef();
+
+ return 0;
+}
+
+static void BrowserHost_OnDestroy(HWND hwnd)
+{
+ BROWSERHOST *host = GetHost(hwnd);
+ /*if (NULL != host->container)
+ {
+ // SendMessage(hwnd, BTM_RELEASECONTAINER, 0, 0L);
+ // BrowserThread_SetFlags(BHTF_BEGINDESTROY, BHTF_BEGINDESTROY, FALSE);
+ }*/
+
+ SetWindowLongPtr(hwnd, 0, 0L);
+
+ if (NULL != host)
+ {
+ if (NULL != host->browserManager)
+ {
+ host->browserManager->Release();
+ }
+ free(host);
+ }
+
+#ifdef _DEBUG
+ aTRACE_FMT("[%d] %S: host window destroyed\r\n", GetCurrentThreadId(), OMBROWSER_NAME);
+#endif // _DEBUG
+}
+
+static void BrowserHost_OnPaint(HWND hwnd)
+{
+ PAINTSTRUCT ps = {0};
+ if (BeginPaint(hwnd, &ps))
+ {
+ if (ps.rcPaint.left != ps.rcPaint.right)
+ BrowserHost_Paint(hwnd, ps.hdc, &ps.rcPaint, ps.fErase);
+ EndPaint(hwnd, &ps);
+ }
+}
+
+static void BrowserHost_OnPrintClient(HWND hwnd, HDC hdc, UINT options)
+{
+ RECT clientRect;
+ if (GetClientRect(hwnd, &clientRect))
+ BrowserHost_Paint(hwnd, hdc, &clientRect, 0 != (PRF_ERASEBKGND & options));
+}
+
+static void BrowserHost_OnWindowPosChanged(HWND hwnd, WINDOWPOS *pwp)
+{
+ if (SWP_NOSIZE == ((SWP_NOSIZE | SWP_FRAMECHANGED) & pwp->flags))
+ return;
+ BrowserHost_UpdateLayout(hwnd, 0 == (SWP_NOREDRAW & pwp->flags));
+}
+
+static void BrowserHost_OnCommand(HWND hwnd, INT controlId, INT eventId, HWND hControl)
+{
+}
+
+static HRESULT BrowserHost_AssociateDispatch(HWND hwnd, IDispatch *pDispatch)
+{
+ if (NULL == pDispatch)
+ return E_INVALIDARG;
+
+ IWasabiDispatchable *pWasabi = NULL;
+ HRESULT hr = pDispatch->QueryInterface(IID_IWasabiDispatchable, (void**)&pWasabi);
+ if (SUCCEEDED(hr) && pWasabi != NULL)
+ {
+ JSAPI::ifc_info *pInfo = NULL;
+ hr = pWasabi->QueryDispatchable(JSAPI::IID_JSAPI_ifc_info, (Dispatchable**)&pInfo);
+ if (SUCCEEDED(hr) && pInfo != NULL)
+ {
+ HWND hParent = GetParent(hwnd);
+ if (NULL == hParent) hParent = hwnd;
+
+ pInfo->SetHWND(hParent);
+
+ WCHAR szBuffer[512] = {0};
+ BROWSERHOST *host = GetHost(hwnd);
+ if (NULL != host && NULL != host->container)
+ {
+ ifc_omservice *service = NULL;
+ if (SUCCEEDED(BrowserHost_GetOmService(host->container, &service)) && service != NULL)
+ {
+ if (FAILED(service->GetName(szBuffer, ARRAYSIZE(szBuffer))))
+ szBuffer[0]= L'\0';
+ service->Release();
+ }
+ }
+
+ pInfo->SetName(szBuffer);
+ pInfo->Release();
+ }
+ pWasabi->Release();
+ }
+ return hr;
+}
+
+static void BrowserHost_OnContainerInit(HWND winampWindow, HWND hwnd)
+{
+ BROWSERHOST *host = GetHost(hwnd);
+ if (NULL == host) return;
+
+ if (NULL != host->container) return; // we're alredy running
+
+ DWORD windowStyle = GetWindowStyle(hwnd);
+
+ HTMLContainer2_Initialize();
+
+ Browser *container = Browser::CreateInstance(host->browserManager, winampWindow, hwnd);
+ host->container = container;
+ if (NULL != container)
+ {
+ ifc_omservice *service = NULL;
+ if (SUCCEEDED(BrowserHost_GetOmService(container, &service)) && service != NULL)
+ {
+ IDispatch *pDispatch = NULL;
+ if (SUCCEEDED(service->GetExternal(&pDispatch)) && NULL != pDispatch)
+ {
+ BrowserHost_AssociateDispatch(hwnd, pDispatch);
+ container->SetExternal(pDispatch);
+ pDispatch->Release();
+ }
+ service->Release();
+ }
+
+ container->EventDocumentReady = BrowserHost_OnDocumentReady;
+ container->EventNavigateComplete = BrowserHost_OnNavigateComplete;
+ container->EventContainerDestroyed = BrowserHost_OnContainerDestroy;
+ container->EventDownloadBegin = BrowserHost_OnDownloadBegin;
+ container->EventDownloadComplete = BrowserHost_OnDownloadComplete;
+ container->EventCommandStateChange = BrowserHost_OnCommandStateChange;
+ container->EventStatusChange = BrowserHost_OnStatusChange;
+ container->EventTitleChange = BrowserHost_OnTitleChange;
+ container->EventSecureLockIconChange = BrowserHost_OnSecureLockIconChange;
+ container->EventCreatePopup = BrowserHost_OnCreatePopup;
+ container->EventFocusChange = BrowserHost_OnFocusChange;
+ container->EventWindowClosing = BrowserHost_OnWindowClosing;
+
+ if (0 != (NBHS_POPUP & windowStyle))
+ {
+ container->EventVisible = BrowserHost_OnVisibleChange;
+ container->EventSetResizable = BrowserHost_OnSetResizable;
+ container->EventSetFullscreen = BrowserHost_OnSetFullScreen;
+ container->EventShowUiElement = BrowserHost_OnShowUiElenent;
+ container->EventClientToHost = BrowserHost_OnClientToHost;
+ container->EventSetWindowPos = BrowserHost_OnSetWindowPos;
+ container->EventClosePopup = BrowserHost_OnClosePopup;
+ }
+
+ container->CallbackGetOmService = BrowserHost_GetOmService;
+ container->CallbackRedirectKey = BrowserHost_RedirectKey;
+
+ UINT uiFlags = 0;
+ if (0 != (NBHS_DISABLECONTEXTMENU & windowStyle)) uiFlags |= Browser::flagUiDisableContextMenu;
+ if (0 != (NBHS_DIALOGMODE & windowStyle)) uiFlags |= Browser::flagUiDialogMode;
+ if (0 != (NBHS_DISABLEHOSTCSS & windowStyle)) uiFlags |= Browser::flagUiDisableHostCss;
+
+ if (0 != uiFlags)
+ container->SetUiFlags(uiFlags, uiFlags);
+
+ HRESULT hr = container->Initialize(0 != (NBHS_POPUP & windowStyle));
+ if (SUCCEEDED(hr) && 0 == (NBHS_SCRIPTMODE & windowStyle))
+ {
+ // we need to do this to allow script error disabling
+ hr = container->NavigateToName(NULL, 0);
+ }
+
+ if (FAILED(hr) || 0 != (NBHS_SCRIPTMODE & windowStyle))
+ {
+ if (0 == (NBHS_BROWSERREADY & windowStyle))
+ {
+ SetWindowLongPtr(hwnd, GWL_STYLE, windowStyle | NBHS_BROWSERREADY);
+
+ NMHDR hdr;
+ BrowserHost_SendBrowserNotification(container, NBHN_READY, &hdr);
+ }
+ }
+ }
+
+ HWND hParent = GetParent(hwnd);
+ if (NULL != hParent)
+ {
+ DWORD threadMine = 0, threadParent = 0;
+ threadMine = GetCurrentThreadId();
+ threadParent = GetWindowThreadProcessId(hParent, NULL);
+ if (0 != threadMine && threadMine != threadParent)
+ {
+ AttachThreadInput(threadMine, threadParent, TRUE);
+
+ HKL hkl = GetKeyboardLayout(threadParent);
+ if (NULL != hkl)
+ ActivateKeyboardLayout(hkl, 0);
+ }
+ }
+}
+
+static void BrowserHost_OnContainerRelease(HWND hwnd)
+{
+ BROWSERHOST *host = GetHost(hwnd);
+ if (NULL == host) return;
+
+ Browser *container = host->container;
+ host->container = NULL;
+ if (NULL == container) return;
+
+ container->EventDocumentReady = NULL;
+ container->EventNavigateComplete = NULL;
+ container->EventDownloadBegin = NULL;
+ container->EventDownloadComplete = NULL;
+ container->EventCommandStateChange = NULL;
+ container->EventStatusChange = NULL;
+ container->EventTitleChange = NULL;
+ container->EventSecureLockIconChange = NULL;
+ container->EventCreatePopup = NULL;
+ container->EventVisible = NULL;
+ container->EventSetResizable = NULL;
+ container->EventSetFullscreen = NULL;
+ container->EventWindowClosing = NULL;
+ container->EventShowUiElement = NULL;
+ container->EventClientToHost = NULL;
+ container->EventSetWindowPos = NULL;
+ container->EventFocusChange = NULL;
+ container->CallbackGetOmService = NULL;
+ container->CallbackRedirectKey = NULL;
+
+ if (SUCCEEDED(container->SendCommand(Browser::commandStop)) &&
+ SUCCEEDED(container->NavigateToName(NULL, navNoHistory | navNoWriteToCache)))
+ {
+ IWebBrowser2 *pWeb2 = NULL;
+ if (SUCCEEDED(container->GetIWebBrowser2(&pWeb2)) && pWeb2 != NULL)
+ {
+ ReplyMessage(0);
+ BrowserThread_WaitNavigateComplete(pWeb2, 30000);
+ pWeb2->Release();
+ }
+ }
+ else
+ {
+ }
+
+ container->Finish();
+ container->Release();
+
+ HWND hParent = GetParent(hwnd);
+ if (NULL != hParent)
+ {
+ DWORD threadMine = 0, threadParent = 0;
+ threadMine = GetCurrentThreadId();
+ threadParent = GetWindowThreadProcessId(hParent, NULL);
+ if (0 != threadMine && threadMine != threadParent)
+ {
+ AttachThreadInput(threadMine, threadParent, FALSE);
+ }
+ }
+}
+
+static LRESULT BrowserHost_OnNiceDestroy(HWND hwnd, BOOL fImmediate)
+{
+ DWORD windowStyle = GetWindowStyle(hwnd);
+ if (0 != (WS_VISIBLE & windowStyle))
+ SetWindowLongPtr(hwnd, GWL_STYLE, windowStyle & ~WS_VISIBLE);
+
+ BROWSERHOST *host = GetHost(hwnd);
+ if (NULL != host && NULL != host->container && FALSE == fImmediate)
+ {
+ HWND hWinamp = NULL;
+ if (FAILED(Plugin_GetWinampWnd(&hWinamp)))
+ hWinamp = NULL;
+
+ if (hWinamp != GetParent(hwnd))
+ {
+ SetParent(hwnd, hWinamp);
+ SetWindowLongPtr(hwnd, GWLP_HWNDPARENT, (LONGX86)(LONG_PTR)hWinamp);
+ }
+
+ SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST);
+
+ if (FALSE != BrowserThread_PostDestroy(hwnd))
+ return TRUE;
+ }
+
+ BrowserThread_SetFlags(BHTF_BEGINDESTROY, BHTF_BEGINDESTROY, FALSE);
+ BrowserHost_OnContainerRelease(hwnd);
+ return (0 != DestroyWindow(hwnd));
+}
+
+static void BrowserHost_OnContainerCommand(HWND hwnd, INT commandId)
+{
+ BROWSERHOST *host = GetHost(hwnd);
+ if (NULL == host) return;
+
+ if (NULL == host->container) return;
+ host->container->SendCommand(commandId);
+}
+
+static void BrowserHost_OnUpdateSkin(HWND hwnd)
+{
+ BROWSERHOST *host = GetHost(hwnd);
+ if (NULL == host) return;
+
+ if (NULL != host->container)
+ {
+ //HWND hWinamp;
+ //if (NULL == host->browserManager || FAILED(host->browserManager->GetWinampWindow(&hWinamp)))
+ // hWinamp = NULL;
+
+ //HCURSOR cursor = (HCURSOR)SENDWAIPC(hWinamp, IPC_GETSKINCURSORS, WACURSOR_NORMAL);
+ //if (NULL != cursor)
+ //{
+ // host->container->RegisterBrowserCursor(/*OCR_NORMAL*/32512, CopyCursor(cursor));
+ //}
+ }
+
+ UINT windowStyle = GetWindowStyle(hwnd);
+ if (NBHS_BROWSERREADY == ((NBHS_BROWSERREADY | NBHS_BROWSERACTIVE) & windowStyle))
+ {
+ PostMessage(hwnd, NBHM_CONTAINERCOMMAND, (WPARAM)Browser::commandRefresh, 0L);
+ }
+}
+
+static void BrowserHost_OnNavigate(HWND hwnd, BSTR url, UINT flags)
+{
+ BROWSERHOST *host = GetHost(hwnd);
+ if (NULL != host &&
+ NULL != host->container &&
+ FALSE == BrowserThread_IsQuiting())
+ {
+ host->container->NavigateToName(url, flags);
+ }
+ if (NULL != url)
+ {
+ SysFreeString(url);
+ }
+}
+
+static void BrowserHost_OnEnableContainerUpdate(HWND hwnd, BOOL fEnable, BOOL fRedraw)
+{
+ BROWSERHOST *host = GetHost(hwnd);
+ if (NULL == host || NULL == host->container) return;
+
+ HWND hContainer = host->container->GetHostHWND();
+ if (NULL == hContainer) return;
+
+ SendMessage(hContainer, WM_SETREDRAW, fEnable, 0L);
+ if (fEnable && fRedraw)
+ RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_UPDATENOW | RDW_NOERASE | RDW_NOFRAME | RDW_NOINTERNALPAINT | RDW_VALIDATE | RDW_ERASENOW );
+}
+
+static void BrowserHost_OnQueueAPC(HWND hwnd, PAPCFUNC pfnApc, ULONG_PTR param)
+{
+ if (NULL == pfnApc) return;
+ pfnApc(param);
+}
+
+static void BrowserHost_OnShowHistoryPopup(HWND hwnd, UINT fuFlags, POINTS pts)
+{
+ BROWSERHOST *host = GetHost(hwnd);
+ if (NULL != host && NULL != host->container)
+ {
+ ifc_travelloghelper *travelLog;
+ if (SUCCEEDED(host->container->GetTravelLog(&travelLog)))
+ {
+ travelLog->ShowPopup(fuFlags, pts.x, pts.y, hwnd, NULL);
+ travelLog->Release();
+ }
+ }
+}
+
+static void BrowserHost_OnGetDispatchApc(HWND hwnd, DISPATCHAPC callback, ULONG_PTR param)
+{
+ if (NULL == callback) return;
+
+ IDispatch *pDisp = NULL;
+ BROWSERHOST *host = GetHost(hwnd);
+ if (NULL != host && NULL != host->container)
+ {
+ IWebBrowser2 *pWeb2 = NULL;
+ if (SUCCEEDED(host->container->GetIWebBrowser2(&pWeb2)) && pWeb2 != NULL)
+ {
+ pWeb2->get_Application(&pDisp);
+ pWeb2->Release();
+ }
+ }
+
+ callback(pDisp, param);
+
+ if (NULL != pDisp)
+ pDisp->Release();
+}
+
+static void BrowserHost_OnActivate(HWND hwnd)
+{
+ BROWSERHOST *host = GetHost(hwnd);
+ if (NULL != host && NULL != host->container)
+ {
+ host->container->SetFocus(TRUE);
+ }
+}
+
+static void BrowserHost_OnQueryTitle(HWND hwnd)
+{
+ BSTR bstrName = NULL;
+ BROWSERHOST *host = GetHost(hwnd);
+ if (NULL != host && NULL != host->container)
+ {
+ IWebBrowser2 *pWeb2 = NULL;
+ if (SUCCEEDED(host->container->GetIWebBrowser2(&pWeb2)) && pWeb2 != NULL)
+ {
+ if (FAILED(pWeb2->get_LocationName(&bstrName)))
+ bstrName = NULL;
+ pWeb2->Release();
+ }
+ }
+
+ BHNTEXTCHANGE textChange = {0};
+ textChange.hdr.code = NBHN_TITLECHANGE;
+ textChange.hdr.hwndFrom = hwnd;
+ textChange.hdr.idFrom = GetDlgCtrlID(hwnd);
+ textChange.pszText = bstrName;
+
+ BrowserHost_SendNotification(hwnd, (NMHDR*)&textChange);
+
+ SysFreeString(bstrName);
+}
+
+static void BrowserHost_OnToggleFullscreen(HWND hwnd)
+{
+ BROWSERHOST *host = GetHost(hwnd);
+ if (NULL == host || NULL == host->container)
+ return;
+
+ host->container->ToggleFullscreen();
+}
+
+static void BrowserHost_OnWriteDocument(HWND hwnd, BSTR documentData)
+{
+ BROWSERHOST *host = GetHost(hwnd);
+ if (NULL == host ||
+ NULL == host->container ||
+ FAILED(host->container->WriteDocument(documentData)))
+ {
+ SysFreeString(documentData);
+ }
+}
+
+static void BrowserHost_OnEnableWindow(HWND hwnd, BOOL fEnable)
+{
+ EnableWindow(hwnd, fEnable);
+}
+
+static void BrowserHost_OnUpdateExternal(HWND hwnd)
+{
+ BROWSERHOST *host = GetHost(hwnd);
+ if (NULL == host) return;
+
+ if (NULL != host->container)
+ {
+ ifc_omservice *service = NULL;
+ if (SUCCEEDED(BrowserHost_GetOmService(host->container, &service)) && service != NULL)
+ {
+ IDispatch *pDispatch = NULL;
+ if (SUCCEEDED(service->GetExternal(&pDispatch)) && NULL != pDispatch)
+ {
+ BrowserHost_AssociateDispatch(hwnd, pDispatch);
+ host->container->SetExternal(pDispatch);
+ pDispatch->Release();
+ }
+ service->Release();
+ }
+ }
+}
+
+static LRESULT CALLBACK BrowserHost_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch(uMsg)
+ {
+ case WM_CREATE:
+ return BrowserHost_OnCreate(hwnd, (CREATESTRUCT*)lParam);
+ case WM_DESTROY:
+ BrowserHost_OnDestroy(hwnd);
+ break;
+ case WM_ERASEBKGND:
+ return 0;
+ case WM_PAINT:
+ BrowserHost_OnPaint(hwnd);
+ return 0;
+ case WM_PRINTCLIENT:
+ BrowserHost_OnPrintClient(hwnd, (HDC)wParam, (UINT)lParam);
+ return 0;
+ case WM_WINDOWPOSCHANGED:
+ BrowserHost_OnWindowPosChanged(hwnd, (WINDOWPOS*)lParam);
+ return 0;
+ case WM_COMMAND:
+ BrowserHost_OnCommand(hwnd, LOWORD(wParam), HIWORD(wParam), (HWND)lParam);
+ break;
+ case BTM_INITCONTAINER:
+ BrowserHost_OnContainerInit((HWND)wParam, hwnd);
+ return 0;
+ case BTM_RELEASECONTAINER:
+ BrowserHost_OnContainerRelease(hwnd);
+ return 0;
+ case NBHM_DESTROY:
+ return BrowserHost_OnNiceDestroy(hwnd, (BOOL)wParam);
+ case NBHM_CONTAINERCOMMAND:
+ BrowserHost_OnContainerCommand(hwnd, (INT)wParam);
+ return 0;
+ case NBHM_UPDATESKIN:
+ BrowserHost_OnUpdateSkin(hwnd);
+ return 0;
+ case NBHM_NAVIGATE:
+ BrowserHost_OnNavigate(hwnd, (BSTR)lParam, (UINT)wParam);
+ return 0;
+ case NBHM_ENABLECONTAINERUPDATE:
+ BrowserHost_OnEnableContainerUpdate(hwnd, (BOOL)wParam, (BOOL)lParam);
+ return 0;
+ case NBHM_QUEUEAPC:
+ BrowserHost_OnQueueAPC(hwnd, (PAPCFUNC)lParam, (ULONG_PTR)wParam);
+ return 0;
+ case NBHM_SHOWHISTORYPOPUP:
+ BrowserHost_OnShowHistoryPopup(hwnd, (UINT)wParam, MAKEPOINTS(lParam));
+ return 0;
+ case NBHM_GETDISPATCHAPC:
+ BrowserHost_OnGetDispatchApc(hwnd, (DISPATCHAPC)lParam, (ULONG_PTR)wParam);
+ return 0;
+ case NBHM_ACTIVATE:
+ BrowserHost_OnActivate(hwnd);
+ return 0;
+ case NBHM_QUERYTITLE:
+ BrowserHost_OnQueryTitle(hwnd);
+ return 0;
+ case NBHM_TOGGLEFULLSCREEN:
+ BrowserHost_OnToggleFullscreen(hwnd);
+ return 0;
+ case NBHM_WRITEDOCUMENT:
+ BrowserHost_OnWriteDocument(hwnd, (BSTR)lParam);
+ return 0;
+ case NBHM_ENABLEWINDOW:
+ BrowserHost_OnEnableWindow(hwnd, (BOOL)lParam);
+ return 0;
+ case NBHM_UPDATEEXTERNAL:
+ BrowserHost_OnUpdateExternal(hwnd);
+ return 0;
+ }
+
+ return DefWindowProcW(hwnd, uMsg, wParam, lParam);
+}
+
+static DWORD BrowserHost_GetBrowserFlags(Browser *browser)
+{
+ if (NULL == browser) return 0;
+ HWND hHost = browser->GetParentHWND();
+ if (NULL == hHost) return 0;
+
+ DWORD windowStyle = GetWindowStyle(hHost);
+ return (NBHS_BROWSERMASK & windowStyle);
+}
+
+static void CALLBACK BrowserHost_OnDocumentReady(Browser *browser, IDispatch *pDispatch, VARIANT *URL)
+{
+ HWND hHost = browser->GetParentHWND();
+ if (NULL == hHost) return;
+
+ DWORD windowStyle = GetWindowStyle(hHost);
+ if (0 == (NBHS_BROWSERREADY & windowStyle))
+ {
+ SetWindowLongPtr(hHost, GWL_STYLE, windowStyle | NBHS_BROWSERREADY);
+
+ NMHDR hdr = {0};
+ BrowserHost_SendBrowserNotification(browser, NBHN_READY, &hdr);
+ }
+ else
+ {
+ BHNNAVCOMPLETE document = {0};
+ document.pDispatch = pDispatch;
+ document.URL = URL;
+ document.fTopFrame = TRUE;
+ BrowserHost_SendBrowserNotification(browser, NBHN_DOCUMENTREADY, (NMHDR*)&document);
+ }
+}
+
+static void CALLBACK BrowserHost_OnNavigateComplete(Browser *browser, IDispatch *pDispatch, VARIANT *URL)
+{
+ HWND hHost = browser->GetParentHWND();
+ if (NULL == hHost) return;
+
+ DWORD windowStyle = GetWindowStyle(hHost);
+ if (0 == (NBHS_BROWSERREADY & windowStyle))
+ return;
+
+ IWebBrowser2 *pWeb1 = NULL, *pWeb2 = NULL;
+
+ if (FAILED(browser->GetIWebBrowser2(&pWeb1)))
+ pWeb1 = NULL;
+
+ if (NULL == pDispatch || FAILED(pDispatch->QueryInterface(IID_IWebBrowser2, (void**)&pWeb2)))
+ pWeb2 = NULL;
+
+ if (NULL != pWeb1) pWeb1->Release();
+ if (NULL != pWeb2) pWeb2->Release();
+
+ BHNNAVCOMPLETE document = {0};
+ document.pDispatch = pDispatch;
+ document.URL = URL;
+ document.fTopFrame = (NULL != pWeb1 && pWeb1 == pWeb2);
+ BrowserHost_SendBrowserNotification(browser, NBHN_NAVIGATECOMPLETE, (NMHDR*)&document);
+}
+
+static void CALLBACK BrowserHost_OnContainerDestroy(Browser *browser)
+{
+ BrowserThread_SetFlags(BHTF_BEGINDESTROY, BHTF_BEGINDESTROY, FALSE);
+ PostMessage(NULL, WM_QUIT, 0, 0L);
+}
+
+static void BrowserHost_NotifyContainerActive(HWND hwnd, BOOL fActive, UINT_PTR timerId)
+{
+ if (0 != timerId)
+ KillTimer(hwnd, timerId);
+
+ DWORD windowStyle = GetWindowStyle(hwnd);
+ if ((FALSE == fActive) != (0 == (NBHS_BROWSERACTIVE & windowStyle)))
+ return;
+
+ if (0 == (NBHS_BROWSERREADY & windowStyle))
+ fActive = FALSE;
+
+ BHNACTIVE active = {0};
+ active.hdr.code = NBHN_BROWSERACTIVE;
+ active.hdr.hwndFrom = hwnd;
+ active.hdr.idFrom = GetDlgCtrlID(hwnd);
+ active.fActive = fActive;
+ BrowserHost_SendNotification(hwnd, (NMHDR*)&active);
+
+ BROWSERHOST *host = GetHost(hwnd);
+ INT commandState = 0;
+ if (NULL != host &&
+ NULL != host->container &&
+ SUCCEEDED(host->container->QueryCommandState(Browser::commandStop, &commandState)))
+ {
+ BOOL fEnable = (0 != (Browser::commandStateEnabled & commandState));
+ BrowserHost_OnCommandStateChange(host->container, Browser::commandStop, fEnable);
+ }
+}
+
+static void CALLBACK BrowserHost_ActivateContainerTimer(HWND hwnd, UINT uMsg, UINT_PTR eventId, DWORD time)
+{
+ BrowserHost_NotifyContainerActive(hwnd, TRUE, eventId);
+}
+
+static void CALLBACK BrowserHost_DeactivateContainerTimer(HWND hwnd, UINT uMsg, UINT_PTR eventId, DWORD time)
+{
+ BrowserHost_NotifyContainerActive(hwnd, FALSE, eventId);
+}
+
+static void CALLBACK BrowserHost_OnDownloadBegin(Browser *browser)
+{
+ HWND hHost = browser->GetParentHWND();
+ if (NULL == hHost) return;
+
+ DWORD windowStyle = GetWindowStyle(hHost);
+ if (NBHS_BROWSERREADY == ((NBHS_BROWSERACTIVE | NBHS_BROWSERREADY) & windowStyle))
+ {
+ SetWindowLongPtr(hHost, GWL_STYLE, windowStyle | NBHS_BROWSERACTIVE);
+ SetTimer(hHost, BHT_CONTAINERDOWNLOAD, BHT_ACTIVATECONTAINER_DELAY, BrowserHost_ActivateContainerTimer);
+ }
+}
+
+static void CALLBACK BrowserHost_OnDownloadComplete(Browser *browser)
+{
+ HWND hHost = browser->GetParentHWND();
+ if (NULL == hHost) return;
+
+ DWORD windowStyle = GetWindowStyle(hHost);
+ if (0 != (NBHS_BROWSERACTIVE & windowStyle))
+ {
+ SetWindowLongPtr(hHost, GWL_STYLE, windowStyle & ~NBHS_BROWSERACTIVE);
+ SetTimer(hHost, BHT_CONTAINERDOWNLOAD, BHT_DEACTIVATECONTAINER_DELAY, BrowserHost_DeactivateContainerTimer);
+ }
+}
+
+static void CALLBACK BrowserHost_OnCommandStateChange(Browser *browser, INT commandId, BOOL fEnabled)
+{
+ if (Browser::commandStop == commandId && FALSE != fEnabled &&
+ NBHS_BROWSERREADY == ((NBHS_BROWSERACTIVE | NBHS_BROWSERREADY) & BrowserHost_GetBrowserFlags(browser)))
+ {
+ fEnabled = FALSE;
+ }
+
+ BHNCMDSTATE commandState = {0};
+ commandState.commandId = commandId;
+ commandState.fEnabled = fEnabled;
+ BrowserHost_SendBrowserNotification(browser, NBHN_COMMANDSTATECHANGE, (NMHDR*)&commandState);
+}
+
+static void CALLBACK BrowserHost_OnStatusChange(Browser *browser, LPCWSTR pszText)
+{
+ if (0 == (NBHS_BROWSERREADY & BrowserHost_GetBrowserFlags(browser)))
+ return;
+
+ BHNTEXTCHANGE textChange = {0};
+ textChange.pszText = pszText;
+ BrowserHost_SendBrowserNotification(browser, NBHN_STATUSCHANGE, (NMHDR*)&textChange);
+}
+
+static void CALLBACK BrowserHost_OnTitleChange(Browser *browser, LPCWSTR pszText)
+{
+ if (0 == (NBHS_BROWSERREADY & BrowserHost_GetBrowserFlags(browser)))
+ return;
+
+ BHNTEXTCHANGE textChange = {0};
+ textChange.pszText = pszText;
+ BrowserHost_SendBrowserNotification(browser, NBHN_TITLECHANGE, (NMHDR*)&textChange);
+}
+
+static void CALLBACK BrowserHost_OnSecureLockIconChange(Browser *browser)
+{
+ BHNSECUREICON icon = {0};
+ icon.iconId = browser->GetSecueLockIcon();
+ BrowserHost_SendBrowserNotification(browser, NBHN_SECUREICONCHANGE, (NMHDR*)&icon);
+}
+
+typedef struct __POPUPCALLBACKPARAM
+{
+ IDispatch **ppDisp;
+ HANDLE readyEvent;
+ HWND hHost;
+} POPUPCALLBACKPARAM;
+
+typedef struct __DISPATCHMARSHALPARAM
+{
+ LPSTREAM pStream;
+ IDispatch *pDisp;
+ HRESULT hr;
+} DISPATCHMARSHALPARAM;
+
+static void CALLBACK BrowserHost_DispatchMarshalApc(ULONG_PTR user)
+{
+ DISPATCHMARSHALPARAM *param = (DISPATCHMARSHALPARAM*)user;
+ if (NULL == param) return;
+
+ param->hr = CoGetInterfaceAndReleaseStream(param->pStream, IID_IDispatch, (void**)&param->pDisp);
+ //if (SUCCEEDED(param->hr) && NULL != param->pDisp)
+ // param->pDisp->AddRef();
+}
+
+static void CALLBACK BrowserHost_DispatchCallbackApc(IDispatch *pDisp, ULONG_PTR user)
+{
+ POPUPCALLBACKPARAM *param = (POPUPCALLBACKPARAM*)user;
+ if (NULL == param) return;
+
+ if (NULL != pDisp)
+ {
+ LPSTREAM pStream = NULL;
+ if (SUCCEEDED(CoMarshalInterThreadInterfaceInStream(IID_IDispatch, pDisp, &pStream)))
+ { // switch
+ DISPATCHMARSHALPARAM marshal = {0};
+ marshal.pStream = pStream;
+ SendMessage(param->hHost, NBHM_QUEUEAPC, (WPARAM)&marshal, (LPARAM)BrowserHost_DispatchMarshalApc);
+ if (SUCCEEDED(marshal.hr) && NULL != marshal.pDisp)
+ {
+ *param->ppDisp = marshal.pDisp;
+ }
+ }
+ }
+
+ if (NULL != param->readyEvent)
+ SetEvent(param->readyEvent);
+}
+
+static HRESULT BrowserHost_GetSecurityApi(JSAPI2::api_security **securityApi)
+{
+ if (NULL == securityApi)
+ return E_POINTER;
+
+ *securityApi = NULL;
+
+ ifc_wasabihelper *wasabiHelper = NULL;
+ HRESULT hr = Plugin_GetWasabiHelper(&wasabiHelper);
+ if (SUCCEEDED(hr) && wasabiHelper != NULL)
+ {
+ hr = wasabiHelper->GetSecurityApi(securityApi);
+ wasabiHelper->Release();
+ }
+ return hr;
+}
+
+static BOOL BrowserHost_IsPopupAllowed(HWND hwnd, Browser *browser)
+{
+ ifc_omservice *service = NULL;
+ if (FAILED(BrowserHost_GetOmService(browser, &service)) || NULL == service)
+ return TRUE;
+
+ BOOL fAllowed = TRUE;
+
+ JSAPI::ifc_info *pInfo = NULL;
+ WCHAR szKey[64] = {0};
+
+ if (FAILED(StringCchPrintfW(szKey, ARRAYSIZE(szKey), L"%u", service->GetId())))
+ szKey[0] = L'\0';
+
+ IDispatch *pDispatch = NULL;
+ if (SUCCEEDED(browser->GetExternal(&pDispatch)) && NULL != pDispatch)
+ {
+ IWasabiDispatchable *pWasabi = NULL;
+ if (SUCCEEDED(pDispatch->QueryInterface(IID_IWasabiDispatchable, (void**)&pWasabi)) && pWasabi != NULL)
+ {
+ if (FAILED(pWasabi->QueryDispatchable(JSAPI::IID_JSAPI_ifc_info, (Dispatchable**)&pInfo)))
+ pInfo = NULL;
+ pWasabi->Release();
+ }
+ pDispatch->Release();
+ }
+
+ if (NULL != pInfo && L'\0' != szKey)
+ {
+ JSAPI2::api_security *security = NULL;
+ if (SUCCEEDED(BrowserHost_GetSecurityApi(&security)) && security != NULL)
+ {
+ if (security->GetActionAuthorization(L"application", L"launchurl", szKey, pInfo,
+ JSAPI2::api_security::ACTION_PROMPT) != JSAPI2::api_security::ACTION_ALLOWED)
+ {
+ fAllowed = FALSE;
+ }
+ security->Release();
+ }
+ }
+
+ if (NULL != pInfo)
+ pInfo->Release();
+
+ service->Release();
+ return fAllowed;
+}
+
+static void CALLBACK BrowserHost_OnCreatePopup(Browser *browser, IDispatch **ppDisp, VARIANT_BOOL *Cancel)
+{
+ HWND hHost = browser->GetParentHWND();
+
+ if (FALSE == BrowserHost_IsPopupAllowed(hHost, browser))
+ {
+ if (NULL != Cancel) *Cancel = VARIANT_TRUE;
+ return;
+ }
+
+ POPUPCALLBACKPARAM param = {0};
+ param.hHost = browser->GetParentHWND();
+ if (NULL == param.hHost) return;
+
+ param.readyEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ param.ppDisp = ppDisp;
+
+ BHNCREATEPOPUP popup = {0};
+ popup.callback = BrowserHost_DispatchCallbackApc;
+ popup.param = (ULONG_PTR)&param;
+
+ if (FALSE != BrowserHost_SendBrowserNotification(browser, NBHN_CREATEPOPUP, (NMHDR*)&popup))
+ {
+ BrowserThread_ModalLoop(param.hHost, param.readyEvent, 30000);
+ }
+
+ if (NULL != param.readyEvent)
+ CloseHandle(param.readyEvent);
+}
+
+static void CALLBACK BrowserHost_OnVisibleChange(Browser *browser, VARIANT_BOOL fVisible)
+{
+ BHNVISIBLE visible = {0};
+ visible.fVisible = (VARIANT_FALSE != fVisible);
+ BrowserHost_SendBrowserNotification(browser, NBHN_VISIBLECHANGE, (NMHDR*)&visible);
+}
+
+static void CALLBACK BrowserHost_OnSetResizable(Browser *browser, VARIANT_BOOL fAllow)
+{
+ BHNRESIZABLE resizable = {0};
+ resizable.fEnabled = (VARIANT_FALSE != fAllow);
+ BrowserHost_SendBrowserNotification(browser, NBHN_RESIZABLE, (NMHDR*)&resizable);
+}
+
+static void CALLBACK BrowserHost_OnSetFullScreen(Browser *browser, VARIANT_BOOL fEnable)
+{
+ BHNFULLSCREEN fullscreen = {0};
+ fullscreen.fEnable = (VARIANT_FALSE != fEnable);
+ BrowserHost_SendBrowserNotification(browser, NBHN_FULLSCREEN, (NMHDR*)&fullscreen);
+}
+
+static void CALLBACK BrowserHost_OnWindowClosing(Browser *browser, VARIANT_BOOL fIsChild, VARIANT_BOOL *fCancel)
+{
+ BHNCLOSING closing = {0};
+ closing.isChild = (VARIANT_FALSE != fIsChild);
+ closing.cancel = FALSE;
+
+ BrowserHost_SendBrowserNotification(browser, NBHN_CLOSING, (NMHDR*)&closing);
+
+ if (FALSE != closing.cancel && NULL != fCancel)
+ *fCancel = VARIANT_TRUE;
+}
+
+static void CALLBACK BrowserHost_OnShowUiElenent(Browser *browser, UINT elementId, VARIANT_BOOL fShow)
+{
+ BHNSHOWUI ui = {0};
+ ui.elementId = elementId;
+ ui.fShow = fShow;
+
+ BrowserHost_SendBrowserNotification(browser, NBHN_SHOWUI, (NMHDR*)&ui);
+}
+
+static void CALLBACK BrowserHost_OnClientToHost(Browser *browser, LONG *cx, LONG *cy)
+{
+ BHNCLIENTTOHOST convert = {0};
+ convert.cx = *cx;
+ convert.cy = *cy;
+ BrowserHost_SendBrowserNotification(browser, NBHN_CLIENTTOHOST, (NMHDR*)&convert);
+
+ *cx = convert.cx;
+ *cy = convert.cy;
+}
+
+static void CALLBACK BrowserHost_OnSetWindowPos(Browser *browser, UINT flags, LONG x, LONG y, LONG cx, LONG cy)
+{
+ BHNSETWINDOWPOS windowPos = {0};
+ windowPos.flags = flags;
+ windowPos.x = x;
+ windowPos.y = y;
+ windowPos.cx = cx;
+ windowPos.cy = cy;
+
+ BrowserHost_SendBrowserNotification(browser, NBHN_SETWINDOWPOS, (NMHDR*)&windowPos);
+}
+
+static void CALLBACK BrowserHost_OnFocusChange(Browser *browser, VARIANT_BOOL *fAllow)
+{
+ BHNFOCUSCHANGE focus = {0};
+ focus.fAllow = (VARIANT_FALSE != *fAllow);
+
+ BrowserHost_SendBrowserNotification(browser, NBHN_FOCUSCHANGE, (NMHDR*)&focus);
+
+ *fAllow = (FALSE != focus.fAllow) ? VARIANT_TRUE : VARIANT_FALSE;
+}
+
+static void CALLBACK BrowserHost_OnClosePopup(Browser *browser)
+{
+ NMHDR hdr = {0};
+ BrowserHost_SendBrowserNotification(browser, NBHN_CLOSEPOPUP, &hdr);
+
+}
+static HRESULT CALLBACK BrowserHost_GetOmService(Browser *browser, ifc_omservice **ppService)
+{
+ if (NULL == ppService) return E_POINTER;
+
+ BHNSERVICE service = {0};
+
+ if (FALSE != BrowserHost_SendBrowserNotification(browser, NBHN_GETOMSERVICE, (NMHDR*)&service) &&
+ NULL != service.instance)
+ {
+ *ppService = (ifc_omservice*)service.instance;
+ return S_OK;
+ }
+
+ *ppService = NULL;
+ return E_NOTIMPL;
+}
+
+
+static LRESULT CALLBACK BrowserHost_RedirectKey(Browser *browser, MSG *pMsg)
+{
+ HWND hHost = browser->GetParentHWND();
+ HWND hParent = GetParent(hHost);
+
+ if (NULL == hParent)
+ {
+ BROWSERHOST *host = GetHost(hHost);
+
+ if (NULL != host && FAILED(Plugin_GetWinampWnd(&hParent)))
+ hParent = NULL;
+ }
+
+ return PostMessage(hParent, pMsg->message, pMsg->wParam, pMsg->lParam);
+} \ No newline at end of file