关于webbrowser控件浏览时产生脚本错误的问题(600分) (300分)

  • 主题发起人 主题发起人 txfzr
  • 开始时间 开始时间
T

txfzr

Unregistered / Unconfirmed
GUEST, unregistred user!
我在用webbrowser控件做网页浏览的程序时,遇到这样一个问题,经常在浏览了几页后会产生脚本错误的提示。我可以侦测到它,并自动关闭,但有些网页程序也会因此中断正常的执行。因此,我希望能够找到一个彻底的解决方案,具体点就是:能够让webbrowser控件不再产生脚本错误的事件,而不在他产生后我来自动关闭他。 方法不限,请各位高手指点,如果答案让我觉得满意,我再送300分,一共600分!!!
 
Silent 设置成 True 试一下!!!
 
用TEmbeddedWB,或者自己实现IOleCommandTarget接口,编写Exec方法。
下面的代码是从MSDN中摘录的。

STDMETHODIMP CMyBrowser::Exec( const GUID* pguidCmdGroup, DWORD nCmdID,
DWORD nCmdexecopt, VARIANTARG* pvaIn, VARIANTARG* pvaOut )
{

HRESULT hr = S_OK;

if (pguidCmdGroup && IsEqualGUID(*pguidCmdGroup, CGID_DocHostCommandHandler))
{

switch (nCmdID)
{

case OLECMDID_SHOWSCRIPTERROR:
{
IHTMLDocument2* pDoc = NULL;
IHTMLWindow2* pWindow = NULL;
IHTMLEventObj* pEventObj = NULL;
BSTR rgwszNames[5] =
{
SysAllocString(L"errorLine"),
SysAllocString(L"errorCharacter"),
SysAllocString(L"errorCode"),
SysAllocString(L"errorMessage"),
SysAllocString(L"errorUrl")
};
DISPID rgDispIDs[5];
VARIANT rgvaEventInfo[5];
DISPPARAMS params;
BOOL fContinueRunningScripts = true;
int i;

params.cArgs = 0;
params.cNamedArgs = 0;

// Get the document that is currently being viewed.
hr = pvaIn->punkVal->QueryInterface(IID_IHTMLDocument2, (void **) &pDoc);
// Get document.parentWindow.
hr = pDoc->get_parentWindow(&pWindow);
pDoc->Release();
// Get the window.event object.
hr = pWindow->get_event(&pEventObj);
// Get the error info from the window.event object.
for (i = 0; i < 5; i++)
{
// Get the property's dispID.
hr = pEventObj->GetIDsOfNames(IID_NULL, &rgwszNames, 1,
LOCALE_SYSTEM_DEFAULT, &rgDispIDs);
// Get the value of the property.
hr = pEventObj->Invoke(rgDispIDs, IID_NULL,
LOCALE_SYSTEM_DEFAULT,
DISPATCH_PROPERTYGET, &params, &rgvaEventInfo,
NULL, NULL);
SysFreeString(rgwszNames);
}

// At this point, you would normally alert the user with
// the information about the error, which is now contained
// in rgvaEventInfo[]. Or, you could just exit silently.

(*pvaOut).vt = VT_BOOL;
if (fContinueRunningScripts)
{
// Continue running scripts on the page.
(*pvaOut).boolVal = VARIANT_TRUE;
}
else
{
// Stop running scripts on the page.
(*pvaOut).boolVal = VARIANT_FALSE;
}
break;
}
default:
hr = OLECMDERR_E_NOTSUPPORTED;
break;
}
}
else
{
hr = OLECMDERR_E_UNKNOWNGROUP;
}
return (hr);
}
 
在控制面板中的“添加、删除程序”,把windows已安装的组件----脚本调试删除取消掉,不妨一试
 
to CathyEagle:
我用的就是TEmbeddedWB,我需要知道具体的设置或者方法来使脚本错误的事件不再触发,请说详细一点。 接口的方法我也想过,但我对C不熟悉,所以MSDN我的利用率不高,希望你能帮我写出DELPHI的代码,只要能够达到脚本错误事件不再发生的目的,马上给分,这儿300,再开一贴也是300 :)

to:另外两位朋友:
 我希望是能在程序里实现这个目的,slient设了好像并没有用,脚本错误还是会发生,禁止脚本调试我也已经选择了
 
下面是TEmbeddedWB实现的Exec方法。
function TEmbeddedWB.Exec(CmdGroup: PGUID; nCmdID, nCmdexecopt: DWORD;
const vaIn: OleVariant; var vaOut: OleVariant): HResult;
var
FCancel, FContinueScript, FShowDialog: Boolean;
pEventObj: IHTMLEventObj;
function GetProperty(const PropName: WideString): OLEVariant;
var
Dispparams: TDispParams;
Disp, Status: Integer;
ExcepInfo: TExcepInfo;
PPropName: PWideChar;
begin
Dispparams.rgvarg := nil;
Dispparams.rgdispidNamedArgs := nil;
Dispparams.cArgs := 0;
Dispparams.cNamedArgs := 0;
PPropName := PWideChar(PropName);
Status := pEventObj.GetIDsOfNames(GUID_NULL, @PPropname, 1,
LOCALE_SYSTEM_DEFAULT, @Disp);
if Status = 0 then
begin
Status := pEventObj.Invoke(disp, GUID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET,
Dispparams, @Result, @ExcepInfo, nil);
if Status <> 0 then DispatchInvokeError(Status, ExcepInfo);
end else
if Status = DISP_E_UNKNOWNNAME then
raise EOleError.CreateFmt('''%s'' not supported.', [PropName])
else
OleCheck(Status);
end;
begin
if (CmdGroup = nil) then
begin
Result := OLECMDERR_E_UNKNOWNGROUP;
exit;
end;
Result := OLECMDERR_E_NOTSUPPORTED;
if (ncmdID = OLECMDID_ONUNLOAD) and IsEqualGuid(cmdGroup^, CGID_EXPLORER) and
Assigned(FOnUnload) then FOnUnload(Self);

if IsEqualGuid(cmdGroup^, CGID_DocHostCommandHandler) then
begin
if Assigned(FOnRefresh) and ((nCmdID = 6041 {F5}) or (nCmdID = 6042 {ContextMenu}) or (nCmdID = 2300)) then
begin
FCancel := False;
FOnRefresh(self, nCmdID, FCancel);
if FCancel then Result := S_OK;
end else
case nCmdID of
OLECMDID_SHOWSCRIPTERROR:
if Assigned(FOnScriptError)
then begin
pEventObj := (Document as IHTMLDocument2).parentWindow.event;
if pEventObj <> nil then
begin
FContinueScript := True;
FShowDialog := True;
FOnScriptError(self,
GetProperty('errorline'),
GetProperty('errorCharacter'),
GetProperty('errorCode'),
GetProperty('errorMessage'),
GetProperty('errorUrl'),
FContinueScript, FShowDialog);
TVariantArg(vaOut).vt := VT_BOOL;
TVariantArg(vaOut).vbool := FContinueScript;
if not FShowDialog then Result := S_OK;
end;
end;
end;
end;
end;

注意其中触发OnScriptError事件的语句,你只需要编写OnScriptError事件处理函数就行了。
procedure TMainForm.EmbeddedWBScriptError(Sender: TObject; ErrorLine, ErrorCharacter, ErrorCode, ErrorMessage, ErrorUrl: string;
var ContinueScript: Boolean; var Showdialog: Boolean);
begin
ContinueScript :=true;//继续执行脚本,和你点按钮一样
Showdialog :=false;//不显示脚本错误对话框
end;

That's it.

Good Luck.

 
嗯,我要的就是这样的答案:)
ContinueScript :=true;//继续执行脚本,和你点按钮一样
Showdialog :=false;//不显示脚本错误对话框
这个我自己已经设了,但发现从未执行过,现在知道了,原来还要去触发他,下班回去就测试。
 
to CathyEagle:
不好意思,我实在太笨了,Exec方法是如何用的,我在事件里找不到啊
 
提前一下,CathyEagle看到了请帮我讲讲,或者QQ上说话:),我的QQ:172844933
 
注意我说的是“下面是TEmbeddedWB实现的Exec方法”,也就是说TEmbeddedWB已经实现了
Exec方法,而不是你自己去实现。你只需要编写它触发的OnScriptError就可以了。

还有你的TEmbeddedWB可能版本低了,没有Exec实现,去下面的地址找最新的就行了。
http://www.euromind.com/iedelphi
 
to CathyEagle:
加我QQ好吗,172844933
 
我用的TEmbeddedWB好象是1.16,还有更新的版本吗?
 
这个我会。留下email,我给你原码。。。。。
 
实现 IDocHostShowUI 接口。
实现ShowMessage方法。


 
1.16已经最新了。
我不上QQ的,大富翁联系吧。
 
to BeginDelphi:
我的email: gold88pp@yahoo.com

to CathyEagle:
帮我再解释一下啊,onstripterror事件我一开始就设的,可脚本错误对话框仍然出现,什么问题???
 
CathyEagle:
  为什么不给我答复???
 
提前一下!!!

to BeginDelphi:
给我发邮件啊,我的email: gold88pp@yahoo.com

 
后退
顶部