123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637 |
- #include <precomp.h>
- #include "iebrowser.h"
- #include "mbsvc.h"
- #include "main.h"
- #include "../nu/ns_wc.h"
- #include "../Winamp/buildtype.h"
- #include <api/config/items/cfgitem.h>
- #include <wa2frontend.h>
- #include <windows.h>
- #include <Mshtml.h>
- #include "minibrowserCOM.h"
- class BrowserMsgProc: public ifc_messageprocessor
- {
- public:
- BrowserMsgProc(BrowserWnd *pBrowser) : pTarget(pBrowser) {}
- ~BrowserMsgProc(void) {}
- public:
- bool ProcessMessage(MSG *pMsg)
- {
- if (WM_KEYFIRST <= pMsg->message && WM_KEYLAST >= pMsg->message)
- {
- HWND hwndHost;
- hwndHost = pTarget->gethWnd();
- if ((hwndHost == pMsg->hwnd || IsChild(hwndHost, pMsg->hwnd)) && IsWindowVisible(pMsg->hwnd))
- {
- if (!(GetAsyncKeyState(VK_CONTROL)&0x8000) && !(GetAsyncKeyState(VK_MENU)&0x8000))
- {
- if (pTarget->TranslateKey(pMsg)) return true;
- }
- switch(pMsg->message)
- {
- case WM_KEYDOWN:
- case WM_SYSKEYDOWN:
- case WM_KEYUP:
- case WM_SYSKEYUP:
- switch(pMsg->wParam)
- {
- case VK_F1:
- if (!(GetAsyncKeyState(VK_SHIFT)&0x8000)) pMsg->hwnd = plugin.hwndParent;
- break;
- case VK_F4:
- if ((pMsg->message == WM_KEYDOWN || pMsg->message == WM_SYSKEYDOWN) && (GetAsyncKeyState(VK_MENU)&0x8000))
- SendMessageW(plugin.hwndParent, WM_CLOSE, 0, 0);
- pMsg->message = WM_NULL;
- break;
- case 'P':
- case 'K':
- case 'H':
- case VK_TAB:
- if ((GetAsyncKeyState(VK_CONTROL)&0x8000) && !(GetAsyncKeyState(VK_MENU)&0x8000)) pMsg->hwnd = plugin.hwndParent;
- break;
- case '3':
- case VK_UP:
- case VK_DOWN:
- break;
- default:
- if ((GetAsyncKeyState(VK_MENU)&0x8000) && !(GetAsyncKeyState(VK_CONTROL)&0x8000)) pMsg->hwnd = plugin.hwndParent;
- break;
- }
- break;
- }
-
- }
- }
- return /*(IsDialogMessageW(pTarget->gethWnd(), pMsg)) ? true :*/ false;
- }
- protected:
- BrowserWnd *pTarget;
- RECVS_DISPATCH;
- };
- extern HINSTANCE hInstance;
- STDAPI WriteBSTR(BSTR *pstrDest, LPCWSTR szSrc)
- {
- *pstrDest = SysAllocString( szSrc );
- if ( !(*pstrDest) ) return E_OUTOFMEMORY;
- return NOERROR;
- }
- STDAPI FreeBSTR(BSTR* pstr)
- {
- if ( *pstr == NULL ) return S_FALSE;
- SysFreeString( *pstr );
- return NOERROR;
- }
- HRESULT writeBString(BSTR* psz, const char *str)
- {
- WCHAR WideStr[WA_MAX_PATH] = {0};
- String s = str;
- if (s.isempty()) s = "";
- MultiByteToWideCharSZ(CP_ACP, 0, s, -1, WideStr, WA_MAX_PATH);
- return WriteBSTR(psz, WideStr);
- }
- BrowserWnd::BrowserWnd() : HTMLContainer2(NULL, NULL), processor(NULL)
- {
- setVirtual(0);
- oleOk = FALSE;
- homepage = L"about:blank";
- timerset1 = 0;
- timerset2 = 0;
- cancelIEErrorPage = false;
- scrollbarsflag = BROWSER_SCROLLBARS_DEFAULT;
- }
- BrowserWnd::~BrowserWnd()
- {
- if (processor)
- {
- if (WASABI_API_APP) WASABI_API_APP->app_removeMessageProcessor(processor);
- free(processor);
- processor = NULL;
- }
- if (timerset1)
- {
- killTimer(MB_TIMERID1);
- timerset1 = 0;
- }
- if (timerset2)
- {
- killTimer(MB_TIMERID2);
- timerset2 = 0;
- }
- freeBrowserStuff();
- }
- bool BrowserWnd::InitializeLibrary()
- {
- return (FALSE != HTMLContainer2_Initialize());
- }
- void BrowserWnd::UninitializeLibrary()
- {
- HTMLContainer2_Uninitialize();
- }
- int BrowserWnd::onInit()
- {
- BROWSER_PARENT::onInit();
- if (isVisible())
- onSetVisible(1);
- updateScrollbars();
- return 1;
- }
- void BrowserWnd::onSetVisible(int show)
- {
- if (show) initBrowserStuff();
- }
- int BrowserWnd::initBrowserStuff()
- {
- if (pUnk) return 1;
-
- if (SUCCEEDED(OleInitialize(NULL))) oleOk = TRUE;
- if (!oleOk) return 1;
- // {280876CF-48C0-40bc-8E86-73CE6BB462E5}
- const GUID options_guid =
- { 0x280876cf, 0x48c0, 0x40bc, { 0x8e, 0x86, 0x73, 0xce, 0x6b, 0xb4, 0x62, 0xe5 } };
- hParent = gethWnd();
- int usemozilla = 0;
- #ifdef WASABI_COMPILE_CONFIG
- usemozilla = _intVal(WASABI_API_CONFIG->config_getCfgItemByGuid(options_guid), L"Use Mozilla instead of IE for minibrowser");
- #endif
- if (SUCCEEDED(Initialize()))
- {
- HRESULT hr;
- IWebBrowser2 *pWeb2;
-
- hr = GetIWebBrowser2(&pWeb2);
- if (SUCCEEDED(hr))
- {
- pWeb2->put_RegisterAsBrowser(VARIANT_TRUE);
-
- if (deferednavigate.isempty())
- {
- if (!homepage.isempty())
- minibrowser_navigateUrl(homepage);
- else
- minibrowser_navigateUrl(L"about:blank");
- }
- else minibrowser_navigateUrl(deferednavigate);
- }
- }
- if (!processor && WASABI_API_APP)
- {
- processor = new BrowserMsgProc(this);
- WASABI_API_APP->app_addMessageProcessor(processor);
-
- }
- ShowWindow(hParent, SW_SHOWNA);
-
- return 1;
- }
- void BrowserWnd::freeBrowserStuff()
- {
- if (oleOk)
- {
- Finish();
- OleUninitialize();
- oleOk = FALSE;
- #ifndef WASABINOMAINAPI
- api->hint_garbageCollect();
- #endif
- }
- }
- int BrowserWnd::minibrowser_navigateUrl(const wchar_t *url)
- {
- HRESULT hr;
-
- curpage = url;
- hr = NavigateToName(url, 0);
- if (FAILED(hr))
- {
- deferednavigate = url;
- return 0;
- }
- return 1;
- }
- int BrowserWnd::minibrowser_back()
- {
- HRESULT hr;
- IWebBrowser2 *pWeb2;
- hr = GetIWebBrowser2(&pWeb2);
- if (SUCCEEDED(hr))
- {
- pWeb2->GoBack();
- pWeb2->Release();
- }
- return 1;
- }
- int BrowserWnd::minibrowser_forward()
- {
- HRESULT hr;
- IWebBrowser2 *pWeb2;
- hr = GetIWebBrowser2(&pWeb2);
- if (SUCCEEDED(hr))
- {
- pWeb2->GoForward();
- pWeb2->Release();
- }
- return 1;
- }
- int BrowserWnd::minibrowser_refresh()
- {
- HRESULT hr;
- IWebBrowser2 *pWeb2;
- hr = GetIWebBrowser2(&pWeb2);
- if (SUCCEEDED(hr))
- {
- pWeb2->Refresh();
- pWeb2->Release();
- }
- return 1;
- }
- int BrowserWnd::minibrowser_home()
- {
- minibrowser_navigateUrl(homepage);
- return 1;
- }
- int BrowserWnd::minibrowser_stop()
- {
- HRESULT hr;
- IWebBrowser2 *pWeb2;
- hr = GetIWebBrowser2(&pWeb2);
- if (SUCCEEDED(hr))
- {
- pWeb2->Stop();
- pWeb2->Release();
- }
- return 1;
- }
- HWND BrowserWnd::getOSHandle()
- {
- return ::GetWindow(gethWnd(), GW_CHILD); // assumes setVirtual(0) in constructor
- }
- void BrowserWnd::onTargetNameTimer()
- {
- updateTargetName();
- }
- void BrowserWnd::onScrollbarsFlagTimer()
- {
- updateScrollbars();
- }
- void BrowserWnd::timerCallback(int id)
- {
- switch (id)
- {
- case MB_TIMERID1:
- onTargetNameTimer();
- return ;
- case MB_TIMERID2:
- onScrollbarsFlagTimer();
- return ;
- }
- BROWSER_PARENT::timerCallback(id);
- }
- void BrowserWnd::minibrowser_setTargetName(const wchar_t *name)
- {
- targetname = name;
- updateTargetName();
- }
- void BrowserWnd::updateTargetName()
- {
- if (!doSetTargetName(targetname))
- {
- if (!timerset1) { setTimer(MB_TIMERID1, 100); timerset1 = 1; }
- return ;
- }
- else
- {
- if (timerset1) { killTimer(MB_TIMERID1); timerset1 = 0; }
- }
- }
- int BrowserWnd::doSetTargetName(const wchar_t *name)
- {
- HRESULT hr;
- IWebBrowser2 *pWeb2;
- IDispatch *id;
- hr = GetIWebBrowser2(&pWeb2);
- if (FAILED(hr)) return FALSE;
- if (SUCCEEDED(pWeb2->get_Document(&id)) && id)
- {
- IHTMLDocument2 *doc;
- if (SUCCEEDED(id->QueryInterface(IID_IHTMLDocument2, (void **)&doc)) && doc)
- {
- IHTMLWindow2 *w;
- if (SUCCEEDED(doc->get_parentWindow(&w)) && w)
- {
- w->put_name(SysAllocString(targetname.getValue()));
- w->Release();
- doc->Release();
- id->Release();
- pWeb2->Release();
- return 1;
- }
- doc->Release();
- }
- id->Release();
- }
- pWeb2->Release();
- return 0;
- }
- const wchar_t *BrowserWnd::minibrowser_getTargetName()
- {
- return targetname;
- }
- void BrowserWnd::OnBeforeNavigate(IDispatch *pDispatch, VARIANT *URL, VARIANT *Flags, VARIANT *TargetFrameName, VARIANT *PostData, VARIANT *Headers, VARIANT_BOOL *Cancel)
- {
- int i = 0;
- foreach(callbacks)
- int r = callbacks.getfor()->minibrowsercb_onBeforeNavigate(URL->bstrVal, Flags->intVal, TargetFrameName->bstrVal);
- if (i++ == 0) *Cancel = (r) ? VARIANT_TRUE : VARIANT_FALSE;
- endfor;
- updateScrollbars();
- }
- void BrowserWnd::minibrowser_setScrollbarsFlag(int a)
- {
- scrollbarsflag = a;
- updateScrollbars();
- }
- void BrowserWnd::updateScrollbars()
- {
- if (!doSetScrollbars())
- {
- if (!timerset2) { setTimer(MB_TIMERID2, 100); timerset2 = 1; }
- return ;
- }
- else
- {
- if (timerset2) { killTimer(MB_TIMERID2); timerset2 = 0; }
- }
- }
- void BrowserWnd::OnDocumentComplete(IDispatch *pDispatch, VARIANT *URL)
- {
- if (!targetname.isempty())
- minibrowser_setTargetName(targetname);
- foreach(callbacks)
- callbacks.getfor()->minibrowsercb_onDocumentComplete(URL->bstrVal);
- endfor;
- updateScrollbars();
- }
- void BrowserWnd::OnDocumentReady(IDispatch *pDispatch, VARIANT *URL)
- {
- if (!targetname.isempty())
- minibrowser_setTargetName(targetname);
- foreach(callbacks)
- callbacks.getfor()->minibrowsercb_onDocumentReady(URL->bstrVal);
- endfor;
- updateScrollbars();
- }
- void BrowserWnd::OnNavigateError(IDispatch *pDispatch, VARIANT *URL, VARIANT *TargetFrameName, VARIANT *StatusCode, VARIANT_BOOL *Cancel)
- {
- if (TargetFrameName->bstrVal != NULL)
- return; //TODO: send targetframe via api to script
- foreach(callbacks)
- callbacks.getfor()->minibrowsercb_onNavigateError(URL->bstrVal, StatusCode->intVal);
- endfor;
- if (cancelIEErrorPage) *Cancel = -1;
- }
- const wchar_t* BrowserWnd::messageToMaki(wchar_t* str1, wchar_t* str2, int i1, int i2, int i3)
- {
- const wchar_t* ret = 0;
- foreach(callbacks)
- ret = callbacks.getfor()->minibrowsercb_messageToMaki(str1, str2, i1, i2, i3);
- if (ret) break;
- endfor;
- return ret;
- }
- const wchar_t* BrowserWnd::minibrowser_messageToJS(const wchar_t* str1, const wchar_t* str2, int i1, int i2, int i3)
- {
- // TODO feed JS w/ this info
- return 0;
- }
- void BrowserWnd::minibrowser_scrape()
- {
- IWebBrowser2 *browser=0;
- GetIWebBrowser2(&browser);
- IDispatch *docDisp=0;
- IHTMLDocument2 *document = 0;
- if (browser)
- {
- browser->get_Document(&docDisp);
- if (docDisp)
- {
- docDisp->QueryInterface(&document);
- docDisp->Release();
- }
- browser->Release();
- }
- if (document)
- {
- IHTMLElementCollection *links=0;
- document->get_all(&links);
-
- if (links)
- {
- IDispatch *anchorDisp=0;
- VARIANT index;
- VariantInit(&index);
- index.vt = VT_I4;
- index.intVal = 0;
- links->item(index, index, &anchorDisp);
- while (anchorDisp)
- {
- IHTMLAnchorElement *anchor=0;
- anchorDisp->QueryInterface(&anchor);
- if (anchor)
- {
- BSTR href=0;
- anchor->get_href(&href);
- if (href && (wa2.CanPlay(href) || wa2.IsPlaylist(href)))
- {
- foreach(callbacks)
- callbacks.getfor()->minibrowsercb_onMediaLink(href);
- endfor;
- }
- SysFreeString(href);
- anchor->Release();
- }
- index.intVal++;
- anchorDisp->Release();
- links->item(index, index, &anchorDisp);
- }
- links->Release();
- }
- document->Release();
- }
- }
- void BrowserWnd::minibrowser_getDocumentTitle(wchar_t *str, size_t len)
- {
- IWebBrowser2 *browser=0;
- GetIWebBrowser2(&browser);
- IDispatch *docDisp=0;
- IHTMLDocument2 *document = 0;
- if (browser)
- {
- browser->get_Document(&docDisp);
- if (docDisp)
- {
- docDisp->QueryInterface(&document);
- docDisp->Release();
- }
- browser->Release();
- }
- if (document)
- {
- BSTR title_bstr;
- document->get_title(&title_bstr);
- document->Release();
- WCSCPYN(str, title_bstr, len);
- // the COM object SysAllocString'd this for us, so we need to free it via COM also
- SysFreeString(title_bstr);
- }
- else
- str[0]=0;
- }
- void BrowserWnd::minibrowser_setCancelIEErrorPage (bool cancel)
- {
- cancelIEErrorPage = cancel;
- }
- int BrowserWnd::doSetScrollbars()
- {
- HRESULT hr;
- IWebBrowser2 *pWeb2;
- IDispatch *id;
- hr = GetIWebBrowser2(&pWeb2);
- if (FAILED(hr)) return 0;
- if (scrollbarsflag == BROWSER_SCROLLBARS_DEFAULT) return 1;
- if (SUCCEEDED(pWeb2->get_Document(&id)) && id)
- {
- IHTMLDocument2 *doc;
- if (SUCCEEDED(id->QueryInterface(IID_IHTMLDocument2, (void **)&doc)) && doc)
- {
- IHTMLElement *e;
- if (SUCCEEDED(doc->get_body(&e)))
- {
- IHTMLStyle *s;
- if (SUCCEEDED(e->get_style(&s)))
- {
- BSTR a;
- switch (scrollbarsflag)
- {
- case BROWSER_SCROLLBARS_ALWAYS:
- writeBString(&a, "scroll");
- break;
- case BROWSER_SCROLLBARS_AUTO:
- writeBString(&a, "auto");
- break;
- case BROWSER_SCROLLBARS_NEVER:
- writeBString(&a, "hidden");
- break;
- default:
- a = NULL;
- break;
- }
- if (a) s->put_overflow(a);
- FreeBSTR(&a);
- s->Release();
- pWeb2->Release();
- return 1;
- }
- e->Release();
- }
- doc->Release();
- }
- id->Release();
- }
- pWeb2->Release();
- return 0;
- }
- const wchar_t *BrowserWnd::minibrowser_getCurrentUrl()
- {
- return curpage;
- }
- STDMETHODIMP BrowserWnd::GetExternal(IDispatch __RPC_FAR *__RPC_FAR *ppDispatch)
- {
- *ppDispatch = (IDispatch*) new MinibrowserCOM(this); //TODO we might need to delete this as well!
- return S_OK;
- }
- DWORD BrowserWnd::OnGetDownlodFlags(void)
- {
- return DLCTL_DLIMAGES | DLCTL_VIDEOS | DLCTL_PRAGMA_NO_CACHE
- #ifdef WINAMP_FINAL_BUILD
- |DLCTL_SILENT
- #endif
- ;
- }
- #define CBCLASS BrowserMsgProc
- START_DISPATCH;
- CB(IFC_MESSAGEPROCESSOR_PROCESS_MESSAGE, ProcessMessage)
- END_DISPATCH;
- #undef CBCLASS
|