Initial community commit
This commit is contained in:
parent
537bcbc862
commit
fc06254474
16440 changed files with 4239995 additions and 2 deletions
637
Src/Wasabi/api/skin/widgets/mb/iebrowser.cpp
Normal file
637
Src/Wasabi/api/skin/widgets/mb/iebrowser.cpp
Normal file
|
@ -0,0 +1,637 @@
|
|||
#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
|
Loading…
Add table
Add a link
Reference in a new issue