Handling script erros from TWebBrowser control


2008-02-13 04:13:07 AM
cppbuilder39
I was directed to a post from Mark Guerrieri showing how to modify
TOleControl and then TWebBrowser to allow script errors to be handled.
Could some please expand on the content of Mark's description as to how to
do this? I just cant seem to get started. I notice the steps do not show
what units to add to to the uses section.
thanks
daryl
Quote
The problem is: I don't know how to do it =(
How can I create a new WebBrowser control that derives from mi new
TOleControl?
Please, I really need help with this, I don't know how to implement it in
BCB5.
>>>>Original post>>>>
I believe that was my post, so I'll explain:
1- Create new package.
2- Add new unti to the package. In this unit, create a class that descends
from TOleControl and also implements IOleCommandTarget. In my case, I also
had it implement IDocHostShowUI, IDocHostUIHandler, IDocHostUIHandler2, and
IServiceProvider which allow total custom control over the browser, but only
IOleCommandTarget is needed in you case. I implemented this class in Delphi
(.PAS file) as it easier to implement multiple interfaces in a class than in
C++:
interface
type
TScriptErrorEvent = procedure(Sender: TObject; ErrorLine, ErrorCharacter,
ErrorCode, ErrorMessage, ErrorUrl: string;
var ContinueScript: Boolean; var Showdialog: Boolean) of object;
TMyOleControl = class(TOleControl, IDocHostShowUI, IDocHostUIHandler,
IDocHostUIHandler2, IDispatch, IServiceProvider, IOleControlSite,
IOleCommandTarget)
...
protected
FOnScriptError: TScriptErrorEvent;
...
//IOleCommandTarget
function QueryStatus(CmdGroup: PGUID; cCmds: Cardinal;
prgCmds: POleCmd; CmdText: POleCmdText): HResult; stdcall;
function Exec(CmdGroup: PGUID; nCmdID, nCmdexecopt: DWORD;
const vaIn: OleVariant; var vaOut: OleVariant): HResult; virtual;
stdcall;
...
public
...
published
property OnScriptError: TScriptErrorEvent read FOnScriptError write
FOnScriptError;
...
end;
implementation
function TMyOleControl.Exec(CmdGroup: PGUID; nCmdID, nCmdexecopt: DWORD;
const vaIn: OleVariant; var vaOut: OleVariant): HResult;
begin
result := S_OK;
end;
function TMyOleControl.QueryStatus(CmdGroup: PGUID; cCmds: Cardinal;
prgCmds: POleCmd; CmdText: POleCmdText): HResult;
begin
result := S_OK;
end;
Note that only the parts relevent to IOleCommandTarget have been shown...
3- Make a copy of ShDocVw_OCX.cpp/.h, rename and add to your package. In
this unit, change the name of the Web Browser control class to something new
and change it to derive from TMyOleControl instead of TOleControl.
4- Override Exec in your browser control with the following protected
method:
HRESULT __stdcall TMyWebBrowser::Exec(PGUID CmdGroup, unsigned nCmdID,
unsigned nCmdexecopt, const OleVariant &vaIn, OleVariant &vaOut)
{
if(CmdGroup == NULL)
return OLECMDERR_E_UNKNOWNGROUP;
HRESULT hr = OLECMDERR_E_NOTSUPPORTED;
if(IsEqualGUID(*CmdGroup, CGID_DocHostCommandHandler))
{
switch(nCmdID)
{
case OLECMDID_SHOWSCRIPTERROR:
{
_di_IDispatch doc = Document;
if(doc != NULL && FOnScriptError != NULL)
{
_di_IHTMLDocument2 hdoc;
doc->QueryInterface(IID_IHTMLDocument2, (LPVOID*)&hdoc);
if(hdoc)
{
_di_IHTMLWindow2 hwin;
hdoc->get_parentWindow(&hwin);
if(hwin)
{
_di_IHTMLEventObj pEventObj;
hwin->get_event(&pEventObj);
if(pEventObj)
{
bool FContinueScript = true;
bool FShowDialog = true;
FOnScriptError(this,
InternalGetProperty(pEventObj, "errorline"),
InternalGetProperty(pEventObj, "errorCharacter"),
InternalGetProperty(pEventObj, "errorCode"),
InternalGetProperty(pEventObj, "errorMessage"),
InternalGetProperty(pEventObj, "errorUrl"),
FContinueScript, FShowDialog);
((TVariantArg)vaOut).vt = VT_BOOL;
((TVariantArg)vaOut).boolVal = (FContinueScript) ?
VARIANT_TRUE : VARIANT_FALSE;
if(!FShowDialog)
hr = S_OK;
}
}
}
}
}
break;
}
}
return hr;
}
4- Compile and install your new Web Browser control to the tool pallete.
Drop one on a form, add an event handler for OnScriptError, and off you go.
Note that the above was done in BCB6; there may be differences using BCB5,
but I'm not sure.
Mark
Quote
>>>>>>>>>>