📄 browserutils.cpp
字号:
/*
This file is part of KCeasy (http://www.kceasy.com)
Copyright (C) 2002-2004 Markus Kern <mkern@kceasy.com>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
//---------------------------------------------------------------------------
#include <vcl.h>
#include <KCeasy.h>
#pragma hdrstop
#include "BrowserUtils.h"
#include "SearchPage.h" // for P2PSearch
//---------------------------------------------------------------------------
#pragma package(smart_init)
/*
yes, COM sucks
http://msdn.microsoft.com/workshop/browser/webbrowser/reference/ifaces/iwebbrowser2/document.asp
http://msdn.microsoft.com/workshop/browser/webbrowser/tutorials/webocstream.asp
http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/prog_browser_node_entry.asp
http://www.dcjournal.com/com/htmldlg.html
http://www.codeproject.com/jscript/htmlgetshooked.asp
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/automat/htm/chap6_1tnl.asp
http://msdn.microsoft.com/workshop/database/databind/comdatasources.asp
http://community.borland.com/article/0,1410,28797,00.html
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/automat/htm/chap5_5wbz.asp
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/automat/htm/chap6_1tnl.asp
http://www.vttoth.com/ole.htm
http://www.tietovayla.fi/BORLAND/CPLUS/bcppbuilder/4/books/chapter17/
http://www.codeproject.com/com/jscalls.asp
http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/support/kb/articles/q185/1/27.htm&NoWebContent=1
*/
bool UrlSafeForExternal(const LPCWSTR WUrl)
{
char* EncodedUrl = WideToAnsi(WUrl);
string Url = UrlDecode(EncodedUrl);
Url = string_tolower(Url);
delete[] EncodedUrl;
// isolate host and scheme
string Host, Scheme;
int p1, p2;
// url can be "<scheme>://user:pwd@host:port/path"
if((p1 = Url.find("://")) == -1)
return false;
Scheme = Url.substr(0,p1);
if((p2 = Url.find("/",p1+3)) != -1)
Host = Url.substr(p1+3,p2-p1-3);
else
Host = Url.substr(p1+3);
// only pages stored in the exe and on BRAND_TRUSTED_DOMAIN are allowed to
// access window.external
if(Scheme == "res") {
char Path[MAX_PATH];
GetModuleFileName(NULL,Path,MAX_PATH);
if(stricmp(Host.c_str(),Path) == 0)
return true;
return false;
}
if(Scheme == "http") {
if(Host.find_first_of(":@") != -1)
return false;
string TrustedDomain = string_tolower(BRAND_TRUSTED_DOMAIN);
if(Host.length() < TrustedDomain.length())
return false;
if(Host.compare(Host.length() - TrustedDomain.length(),TrustedDomain.length(),TrustedDomain) != 0)
return false;
if(Host.length() == TrustedDomain.length() ||
Host[Host.length() - TrustedDomain.length() - 1] == '.')
{
return true;
}
}
return false;
}
/* global helper functions */
void BrowserLoadResource(TCppWebBrowser* Browser, const string& Resource)
{
char Path[MAX_PATH];
GetModuleFileName(NULL,Path,MAX_PATH);
WideString Url = WideString("res://") + Path + "/" + Resource.c_str();
Browser->Navigate(Url);
}
bool BrowserLoadString(TCppWebBrowser* Browser, const string& Html)
{
HRESULT hr;
IStream* pStream = NULL;
IDispatch* pHtmlDoc;
IPersistStreamInit* pPersistStreamInit = NULL;
HGLOBAL hHTMLText;
bool Success = false;
if((hHTMLText = GlobalAlloc(GPTR,Html.length() + 1)) == NULL)
return false;
strcpy((TCHAR*)hHTMLText, Html.c_str());
hr = CreateStreamOnHGlobal( hHTMLText, TRUE, &pStream );
if(SUCCEEDED(hr)) {
// get document interface
pHtmlDoc = Browser->Document;
if(pHtmlDoc == NULL) {
// try to load a page first
// this is asynchronous and we should really wait for the page loaded event
Browser->Navigate(WideString("about:blank"));
pHtmlDoc = Browser->Document;
}
if(pHtmlDoc) {
// Query for IPersistStreamInit.
hr = pHtmlDoc->QueryInterface(IID_IPersistStreamInit, (void**)&pPersistStreamInit);
if (SUCCEEDED(hr)) {
// Initialize the document.
hr = pPersistStreamInit->InitNew();
if(SUCCEEDED(hr)) {
// Load the contents of the stream.
hr = pPersistStreamInit->Load(pStream);
if(SUCCEEDED(hr))
Success = true;
}
pPersistStreamInit->Release();
}
}
pStream->Release(); // frees GlobalAlloc'ed string
}
return Success;
}
bool BrowserCallScript(TCppWebBrowser* Browser, const string& Func)
{
HRESULT hr;
bool Success = false;
if(!Browser->Document)
return false;
if(!UrlSafeForExternal(Browser->LocationURL))
return false;
// Query for IHTMLDocument2.
IHTMLDocument2* pHTMLDocument2 = NULL;
hr = Browser->Document->QueryInterface(IID_IHTMLDocument2, (void**)&pHTMLDocument2);
if(SUCCEEDED(hr)) {
IDispatch* pScript;
hr = pHTMLDocument2->get_Script(&pScript);
if(SUCCEEDED(hr)) {
DISPID FuncDispId;
WideString WideFunc(Func.c_str());
BSTR BStrFunc = WideFunc;
hr = pScript->GetIDsOfNames(IID_NULL, &BStrFunc, 1, LOCALE_SYSTEM_DEFAULT, &FuncDispId);
if(SUCCEEDED(hr)) {
DISPPARAMS DispParams;
memset(&DispParams, 0, sizeof(DispParams));
TVariant vaResult;
hr = pScript->Invoke(FuncDispId,IID_NULL,0,DISPATCH_METHOD,&DispParams,&vaResult,NULL,NULL);
if(SUCCEEDED(hr)) {
Success = true;
}
}
pScript->Release();
}
pHTMLDocument2->Release();
}
return Success;
}
bool BrowserExecScript(TCppWebBrowser* Browser, const string& Script)
{
HRESULT hr;
bool Success = false;
if(!Browser->Document)
return false;
if(!UrlSafeForExternal(Browser->LocationURL))
return false;
// Query for IHTMLDocument2.
IHTMLDocument2* pHTMLDocument2 = NULL;
hr = Browser->Document->QueryInterface(IID_IHTMLDocument2, (void**)&pHTMLDocument2);
if(SUCCEEDED(hr)) {
IHTMLWindow2* pIHTMLWindow2 = NULL;
hr = pHTMLDocument2->get_parentWindow(&pIHTMLWindow2);
if(SUCCEEDED(hr)) {
hr = pIHTMLWindow2->execScript(TOleString(Script.c_str()),TOleString("JScript"), TVariant());
if(SUCCEEDED(hr)) {
Success = true;
}
pIHTMLWindow2->Release();
}
pHTMLDocument2->Release();
}
return Success;
}
/* interface for access to kceasy stats from the DOM */
/*
static PARAMDATA rgpDataTest = { OLESTR("Test"), VT_BSTR };
*/
static PARAMDATA rgpP2PSearch[] =
{
{ OLESTR("Query"), VT_BSTR },
{ OLESTR("Realm"), VT_BSTR }
};
enum IMETH_ExtDisp
{
IMETH_getNetworks = 0,
IMETH_getOnlineStatus,
IMETH_getDaemonAddress,
IMETH_UpdateStats,
IMETH_getVersion,
IMETH_getBuildDate,
IMETH_P2PSearch
};
enum IDMEMBER_ExtDisp
{
IDMEMBER_getNetworks = DISPID_VALUE,
IDMEMBER_getOnlineStatus,
IDMEMBER_getDaemonAddress,
IDMEMBER_UpdateStats,
IDMEMBER_getVersion,
IDMEMBER_getBuildDate,
IDMEMBER_P2PSearch
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -