章
章慧
Unregistered / Unconfirmed
GUEST, unregistred user!
多方测试只有全系统启动的第一个IE能工作。仔细研究发现是SetSite只有第一次IE启动带来的pUnkSite不是Nil。这个问题怎么解决?
能够理解,这个BAND启动1次就挂在后面,不需要反复创建了;但是对于多次启动的IE,需要
不断将UIHandler指代到新的IWebbrowser2;才能在所有窗口都能使用window.external的扩展。
那位高人来解决下?
修改自Borland的源码如下:
能够理解,这个BAND启动1次就挂在后面,不需要反复创建了;但是对于多次启动的IE,需要
不断将UIHandler指代到新的IWebbrowser2;才能在所有窗口都能使用window.external的扩展。
那位高人来解决下?
修改自Borland的源码如下:
代码:
Unit unitDemoDeskBand;
Interface
Uses
Windows, Messages, Classes, ActiveX, ComServ, ComObj, ShlObj, SHDocVw_TLB, IEConst, IEDocHostUIHandler,
Graphics, formVisibleBand, SysUtils, Dialogs, Variants, Forms, MSHTML_TLB;
Const
REGKEY_DESK_BAND = '{00021492-0000-0000-C000-000000000046}';
CLSID_DEMO_DESK_BAND: TGUID = '{979FFB24-20EC-4479-909E-929A48BF9023}';
EXPLORER_MENU_CAPTION = 'Kirikawa eBand';
BAR_DATA: Array [0..15] Of Byte = ($24, $fb, $9f, $97, $ec, $20, $79, $44, $90, $9e, $92, $9a, $48, $bf, $90, $23);
BAND_TITLE = 'Kirikawa News';
MENU_TITLE_ABOUT = 'About...';
DEFAULT_WEB: String = 'http://www.kirikawa.com';
Type
TDemoDeskBandFactory = class(TComObjectFactory)
Private
Protected
Public
Procedure UpdateRegistry(Register: Boolean);
override;
end;
TDemoDeskBand = class(TComObject, IDeskBand, IPersist, IPersistStream,
IPersistStreamInit, IObjectWithSite, IContextMenu, IInputObject, IDispatch)
Private
FHasFocus: Boolean;
FBandID: DWORD;
FParentWnd: HWND;
FSite: IInputObjectSite;
FMenuItemCount: Integer;
FCommandTarget: IOleCommandTarget;
FIE: IWebbrowser2;
FBandForm: TfrmVisibleBand;
FSavedWndProc: TWndMethod;
Cookie: Integer;
do
cHostUIHandler: TDocHostUIHandler;
procedure HideBandForm;
Protected
property MenuItemCount: Integer read FMenuItemCount;
property HasFocus: Boolean read FHasFocus;
property BandID: DWORD read FBandID;
property SavedWndProc: TWndMethod read FSavedWndProc;
property ParentWnd: HWND read FParentWnd;
property Site: IInputObjectSite read FSite;
property CommandTarget: IOleCommandTarget read FCommandTarget;
property BandForm: TfrmVisibleBand read FBandForm;
property IE: IWebbrowser2 read FIE;
Protected
procedure FocusChange(bHasFocus: Boolean);
procedure UpdateBandInfo;
procedure BandWndProc(var Message: TMessage);
Public
Function GetTypeInfoCount(Out Count: integer): HResult;
Stdcall;
Function GetTypeInfo(Index, LocaleID: integer;
Out TypeInfo): HResult;
Stdcall;
Function GetIDsOfNames(const iid: TGUID;
names: pointer;
namecount, localeid: integer;
dispids: pointer): hresult;
stdcall;
Function Invoke(DispID: Integer;
Const iid: tguid;
localeid: integer;
flags: word;
var params;
varresult, excepinfo, argerr: pointer): hresult;
stdcall;
Destructor Destroy;
override;
Procedure Initialize;
override;
Function GetBandInfo(dwBandID, dwViewMode: DWORD;
var pdbi: TDeskBandInfo): HResult;
stdcall;
Function ShowDW(fShow: BOOL): HResult;
stdcall;
Function CloseDW(dwReserved: DWORD): HResult;
stdcall;
Function ResizeBorderDW(var prcBorder: TRect;
punkToolbarSite: IUnknown;
fReserved: BOOL): HResult;
stdcall;
Function GetWindow(Out wnd: HWnd): HResult;
stdcall;
Function ContextSensitiveHelp(fEnterMode: BOOL): HResult;
stdcall;
Function GetClassID(out classID: TCLSID): HResult;
stdcall;
Function IsDirty: HResult;
stdcall;
Function Load(const stm: IStream): HResult;
stdcall;
Function Save(const stm: IStream;
fClearDirty: BOOL): HResult;
stdcall;
Function GetSizeMax(out cbSize: Largeint): HResult;
stdcall;
Function InitNew: HResult;
stdcall;
Function SetSite(const pUnkSite: IUnknown): HResult;
stdcall;
Function GetSite(const riid: TIID;
out site: IUnknown): HResult;
stdcall;
Function QueryContextMenu(Menu: HMENU;
indexMenu, idCmdFirst, idCmdLast, uFlags: UINT): HResult;
stdcall;
Function InvokeCommand(var lpici: TCMInvokeCommandInfo): HResult;
stdcall;
Function GetCommandString(idCmd, uType: UINT;
pwReserved: PUINT;
pszName: LPSTR;
cchMax: UINT): HResult;
stdcall;
Function UIActivateIO(fActivate: BOOL;
var lpMsg: TMsg): HResult;
stdcall;
Function HasFocusIO: HResult;
stdcall;
Function TranslateAcceleratorIO(var lpMsg: TMsg): HResult;
stdcall;
end;
Implementation
Uses
Registry;
Procedure SleepX(r: Cardinal = 3000);
Var
d: Cardinal;
begin
d := GetTickCount;
Repeat
Application.ProcessMessages;
Sleep(100);
Until GetTickCount - d > r;
end;
Procedure ShowMyBar;
Var
IE: OleVariant;
d: Cardinal;
begin
Try
IE := CreateOleObject('internetexplorer.application');
IE.Visible := 1;
SleepX;
IE.ShowBrowserBar(GUIDToString(CLSID_DEMO_DESK_BAND), True, 0);
IE.Navigate(DEFAULT_WEB);
Except
On E: Exceptiondo
MessageBox(0, pChar(e.Message), EXPLORER_MENU_CAPTION, MB_OK Or MB_ICONWARNING);
end;
IE := UnAssigned;
end;
{ TDemoDeskBandFactory }
Procedure TDemoDeskBandFactory.UpdateRegistry(Register: Boolean);
Var
GUID: String;
c: Array [0..15] Of Byte;
d: Cardinal;
begin
Inherited UpdateRegistry(Register);
GUID := GUIDToString(CLSID_DEMO_DESK_BAND);
With TRegistry.Createdo
Try
If Register then
begin
RootKey := HKEY_CLASSES_ROOT;
If OpenKey('CLSID/' + GUID, True) then
Try
WriteString('', EXPLORER_MENU_CAPTION);
Finally
CloseKey;
end;
If OpenKey('CLSID/' + GUID + '/InProcServer32', True) then
Try
WriteString('ThreadingModel', 'Apartment');
Finally
CloseKey;
end;
If OpenKey('CLSID/' + GUID + '/Implemented Categories/' + REGKEY_DESK_BAND, True) then
CloseKey;
RootKey := HKEY_LOCAL_MACHINE;
If OpenKey('SOFTWARE/Microsoft/Internet Explorer/Toolbar', True) then
Try
WriteString(GUID, EXPLORER_MENU_CAPTION);
Finally
CloseKey;
end;
RootKey := HKEY_CURRENT_USER;
If OpenKey('SOFTWARE/Microsoft/Internet Explorer/Toolbar/WebBrowser', True) then
Try
Move(BAR_DATA[0], c[0], 16);
WriteBinaryData(GUID, c[0], 16);
Finally
CloseKey;
end;
SleepX;
ShowMyBar;
End
else
begin
RootKey := HKEY_CLASSES_ROOT;
DeleteKey('Component Categories/' + REGKEY_DESK_BAND + '/Enum');
DeleteKey('CLSID/' + GUID + '/Implemented Categories/' + REGKEY_DESK_BAND);
DeleteKey('CLSID/' + GUID + '/InProcServer32');
DeleteKey('CLSID/' + GUID);
CloseKey;
RootKey := HKEY_LOCAL_MACHINE;
If OpenKey('Software/Microsoft/Internet Explorer/Toolbar', False) then
Try
DeleteValue(GUID);
Finally
CloseKey;
end;
RootKey := HKEY_CURRENT_USER;
If OpenKey('Software/Microsoft/Internet Explorer/Toolbar/WebBrowser', False) then
Try
DeleteValue(GUID);
Finally
CloseKey;
end;
end;
Finally
Free;
end;
end;
{ TDemoDeskBand }
Procedure TDemoDeskBand.BandWndProc(var Message: TMessage);
begin
If Message.Msg = WM_PARENTNOTIFY then
begin
FHasFocus := True;
FocusChange(HasFocus);
end;
SavedWndProc(Message);
end;
Function TDemoDeskBand.CloseDW(dwReserved: DWORD): HResult;
begin
HideBandForm;
Result := S_OK;
end;
Function TDemoDeskBand.ContextSensitiveHelp(fEnterMode: BOOL): HResult;
begin
Result := E_NOTIMPL;
end;
Destructor TDemoDeskBand.Destroy;
begin
Try
FIE := Nil;
Except
end;
If BandForm <> Nil then
Try
FBandForm.Free;
FBandForm := Nil;
Except
end;
Try
FSite := Nil;
Except
end;
Try
FCommandTarget := Nil;
Except
end;
Inherited Destroy;
end;
Procedure TDemoDeskBand.FocusChange(bHasFocus: Boolean);
begin
If Site <> Nil then
Site.OnFocusChangeIS(Self, bHasFocus);
end;
Procedure TDemoDeskBand.HideBandForm;
begin
BandForm.Hide;
end;
Function TDemoDeskBand.GetBandInfo(dwBandID, dwViewMode: DWORD;
var pdbi: TDeskBandInfo): HResult;
begin
FBandId := dwBandID;
if pdbi.dwMask or DBIM_MINSIZE <> 0 then
begin
pdbi.ptMinSize.x := 80;
pdbi.ptMinSize.y := 22;
end;
if pdbi.dwMask or DBIM_MAXSIZE <> 0 then
begin
pdbi.ptMaxSize.x := -1;
pdbi.ptMaxSize.y := 22;
end;
if pdbi.dwMask or DBIM_INTEGRAL <> 0 then
begin
pdbi.ptIntegral.x := 25;
pdbi.ptIntegral.y := 22;
end;
if pdbi.dwMask or DBIM_ACTUAL <> 0 then
begin
pdbi.ptActual.x := 390;
pdbi.ptActual.y := 22;
end;
if pdbi.dwMask or DBIM_MODEFLAGS <> 0 then
begin
pdbi.dwModeFlags := DBIMF_NORMAL or DBIMF_VARIABLEHEIGHT;
// pdbi.dwModeFlags := DBIMF_NORMAL or DBIMF_VARIABLEHEIGHT or DBIMF_BKCOLOR;
end;
if pdbi.dwMask or DBIM_BKCOLOR <> 0 then
begin
pdbi.crBkgnd := clGreen;
end;
if Pdbi.dwMask and DBIM_TITLE <> 0 then
begin
FillChar(pdbi.wszTitle, Length(pdbi.wszTitle) * SizeOf(pdbi.wszTitle[0]), #0);
FillChar(pdbi.wszTitle, SizeOf(BAND_TITLE) + 1, ' ');
StringToWideChar(BAND_TITLE, @pdbi.wszTitle, Length(BAND_TITLE) + 1);
end;
Result := NOERROR;
end;
Function TDemoDeskBand.GetClassID(out classID: TCLSID): HResult;
begin
classID := CLSID_DEMO_DESK_BAND;
Result := S_OK;
end;
Function TDemoDeskBand.GetCommandString(idCmd, uType: UINT;
pwReserved: PUINT;
pszName: LPSTR;
cchMax: UINT): HResult;
begin
Result := NOERROR;
end;
Function TDemoDeskBand.GetSite(const riid: TIID;
out site: IInterface): HResult;
begin
If Site <> Nil then
Result := Site.QueryInterface(riid, site)
else
Result := E_FAIL;
end;
Function TDemoDeskBand.GetSizeMax(out cbSize: Largeint): HResult;
begin
cbSize := 256;
Result := S_OK;
end;
Function TDemoDeskBand.GetWindow(Out wnd: HWnd): HResult;
begin
If BandForm = Nil then
begin
FBandForm := TfrmVisibleBand.CreateParented(ParentWnd);
FBandForm.IE := IE;
end;
Wnd := BandForm.Handle;
FSavedWndProc := BandForm.WindowProc;
BandForm.WindowProc := BandWndProc;
Result := S_OK;
end;
Function TDemoDeskBand.HasFocusIO: HResult;
begin
Result := Integer(Not HasFocus);
end;
Procedure TDemoDeskBand.Initialize;
begin
Inherited Initialize;
end;
Function TDemoDeskBand.InitNew: HResult;
begin
Result := S_OK;
end;
Function TDemoDeskBand.InvokeCommand(Var lpici: TCMInvokeCommandInfo): HResult;
begin
If (HiWord(Integer(lpici.lpVerb)) <> 0) Or (LoWord(lpici.lpVerb) > Pred(MenuItemCount)) then
begin
Result := E_FAIL;
Exit;
end;
Case LoWord(lpici.lpVerb) Of
0: MessageBox(ParentWnd, 'Borland Demo Desk-Band', '躡er', 0);
end;
Result := NO_ERROR;
end;
Function TDemoDeskBand.IsDirty: HResult;
begin
Result := S_OK;
end;
Function TDemoDeskBand.Load(const stm: IStream): HResult;
begin
Result := S_OK;
end;
Function TDemoDeskBand.QueryContextMenu(Menu: HMENU;
indexMenu, idCmdFirst, idCmdLast, uFlags: UINT): HResult;
begin
FMenuItemCount := 1;
AppendMenu(Menu, MF_STRING, idCmdFirst + 0, PChar(MENU_TITLE_ABOUT));
Result := MenuItemCount;
end;
Function TDemoDeskBand.ResizeBorderDW(var prcBorder: TRect;
punkToolbarSite: IInterface;
fReserved: BOOL): HResult;
begin
Result := E_NOTIMPL;
end;
Function TDemoDeskBand.Save(const stm: IStream;
fClearDirty: BOOL): HResult;
begin
Result := S_OK;
end;
Function TDemoDeskBand.SetSite(Const pUnkSite: IInterface): HResult;
Var
cmdtarget: iolecommandtarget;
sp: iserviceprovider;
cpc: iconnectionpointcontainer;
cp: iconnectionpoint;
hr: HResult;
CustDoc: ICustomDoc;
iDoc: IHTMLDocument2;
begin
If Assigned(pUnkSite) then
Try
FSite := pUnkSite As IInputObjectSite;
(pUnkSite As IOleWindow).GetWindow(FParentWnd);
FCommandTarget := pUnkSite As IOleCommandTarget;
(CommandTarget As IServiceProvider).QueryService(IWebbrowserApp, IWebbrowser2, FIE);
do
cHostUIHandler := TDocHostUIHandler.Create;
do
cHostUIHandler.ObjAddRef;
hr := FIE.Document.QueryInterface(ICustomDoc, CustDoc);
If hr = S_OK then
begin
CustDoc.SetUIHandler(DocHostUIHandler);
CustDoc._AddRef;
end;
Except
end;
If Assigned(pUnkSite) then
Try
cmdtarget := punksite As iolecommandtarget;
sp := cmdtarget as iserviceprovider;
If assigned(sp) then
sp.queryservice(iwebbrowserapp, iwebbrowser2, FIE);
If assigned(ie) then
Try
FIE.queryinterface(iconnectionpointcontainer, cpc);
cpc.findconnectionpoint(dwebbrowserevents2, cp);
cp.advise(self, cookie);
Except
end;
Except
end;
Result := S_OK;
end;
Function TDemoDeskBand.ShowDW(fShow: BOOL): HResult;
begin
FHasFocus := fShow;
FocusChange(HasFocus);
Result := S_OK;
end;
Function TDemoDeskBand.TranslateAcceleratorIO(var lpMsg: TMsg): HResult;
begin
If lpMsg.WParam <> VK_TAB then
begin
TranslateMessage(lpMSg);
DispatchMessage(lpMsg);
Result := S_OK;
End
else
Result := S_FALSE;
end;
Function TDemoDeskBand.UIActivateIO(fActivate: BOOL;
var lpMsg: TMsg): HResult;
begin
Try
FHasFocus := fActivate;
FocusChange(HasFocus);
If HasFocus then
If BandForm <> Nil then
BandForm.SetFocus;
Result := S_OK;
Except
end;
end;
Procedure TDemoDeskBand.UpdateBandInfo;
Var
vain, vaOut: OleVariant;
PtrGuid: PGUID;
begin
Try
vaIn := Variant(BandID);
New(PtrGUID);
PtrGUID^ := IDESKBAND;
CommandTarget.Exec(PtrGUID, DBID_BANDINFOCHANGED, OLECMDEXECOPT_DODEFAULT, vaIn, vaOut);
Dispose(PtrGUID);
Except
end;
end;
{ BHO Method }
Proceduredo
StatusTextChange(Const Text: Widestring);
begin
end;
Proceduredo
ProgressChange(progress: integer;
progressmax: integer);
begin
end;
Proceduredo
CommandStateChange(command: integer;
enable: wordbool);
begin
end;
Proceduredo
Downloadbegin
;
begin
end;
Proceduredo
DownloadComplete;
begin
end;
Proceduredo
TitleChange(Const Text: WideString);
begin
end;
Proceduredo
PropertyChange(Const szProperty: WideString);
begin
end;
Proceduredo
BeforeNavigate2(const pdisp: idispatch;
var url: olevariant;
var flags: olevariant;
var targetframename: olevariant;
var postdata: olevariant;
var headers: olevariant;
var cancel: wordbool);
begin
{If url<> 'http://www.applevb.com/' then
begin
showmessage('你不可以浏览其它站点');
cancel:=true;
url:='http://www.applevb.com';
(pdisp as iwebbrowser2).navigate2(url,flags,targetframename,postdata,headers);
end;
}
end;
Proceduredo
NewWindow2(var ppdisp: idispatch;
var cancel: wordbool);
begin
end;
Proceduredo
NavigateComplete2(const pdisp: idispatch;
var url: olevariant);
//Var
//iDoc1: IHTMLDocument2;
//z: IHTMLElement;
begin
//ShowMessage(URL);
//(pdisp as iwebbrowser2).Document.QueryInterface(IHTMLDocument2, iDoc1);
//iDoc1.all.item(0, 0).QueryInterface(IHTMLElement, z);
//ShowMessage(z.innerHTML);
end;
Proceduredo
DocumentComplete(const pdisp: idispatch;
var url: olevariant);
//Var
//iDoc1: IHTMLDocument2;
//z: IHTMLElement;
begin
//ShowMessage(URL);
//(pdisp as iwebbrowser2).Document.QueryInterface(IHTMLDocument2, iDoc1);
// iDoc1.all.item(0, 0).QueryInterface(IHTMLElement, z);
//ShowMessage(z.outerHTML);
end;
Proceduredo
OnQuit;
begin
end;
Proceduredo
OnVisible(visible: wordbool);
begin
end;
Proceduredo
OnToolbar(toolbar: wordbool);
begin
end;
Proceduredo
OnMenuBar(menubar: wordbool);
begin
end;
Proceduredo
OnStatusBar(statusbar: wordbool);
begin
end;
Proceduredo
OnFullScreen(fullscreen: wordbool);
begin
end;
Proceduredo
OnTheaterMode(theatermode: wordbool);
begin
end;
Procedure BuildPositionalDispIDs(pdispids: pdispidlist;
const dps: tdispparams);
Var
i: integer;
begin
Assert(pdispids <> nil);
For i := 0 to dps.cargs - 1do
pdispids^[i] := dps.cargs - 1 - i;
If dps.cnamedargs <= 0 then
exit;
For i := 0 to dps.cnamedargs - 1do
pdispids^[dps.rgdispidnamedargs^[i]] := i;
end;
Function TDemoDeskBand.getidsofnames(const iid: tguid;
names: pointer;
namecount, localeid: integer;
dispids: pointer): hresult;
begin
Result := e_notimpl;
end;
Function TDemoDeskBand.gettypeinfo(index, localeid: integer;
Out typeinfo): hresult;
begin
Result := e_notimpl;
pointer(typeinfo) := nil;
end;
Function TDemoDeskBand.gettypeinfocount(Out count: integer): hresult;
begin
Result := e_notimpl;
count := 0;
end;
Function TDemoDeskBand.invoke(dispid: integer;
const iid: tguid;
localeid: integer;
flags: word;
var params;
varresult, excepinfo, argerr: pointer): hresult;
Type
polevariant = ^olevariant;
Var
dps: tdispparams Absolute params;
bhasparams: boolean;
pdispids: pdispidlist;
idispidssize: integer;
begin
result := disp_e_membernotfound;
pdispids := nil;
idispidssize := 0;
bhasparams := (dps.cargs > 0);
if (bhasparams) then
begin
idispidssize := dps.cargs * sizeof(tdispid);
getmem(pdispids, idispidssize);
end;
try
if (bhasparams) then
buildpositionaldispids(pdispids, dps);
case dispid of
102:
begin
do
statustextchange(dps.rgvarg^[pdispids^[0]].bstrval);
result := s_ok;
end;
108:
begin
do
progresschange(dps.rgvarg^[pdispids^[0]].lval, dps.rgvarg^[pdispids^[1]].lval);
result := s_ok;
end;
105:
begin
do
commandstatechange(dps.rgvarg^[pdispids^[0]].lval, dps.rgvarg^[pdispids^[1]].vbool);
result := s_ok;
end;
106:
begin
do
downloadbegin
();
result := s_ok;
end;
104:
begin
do
downloadcomplete();
result := s_ok;
end;
113:
begin
do
titlechange(dps.rgvarg^[pdispids^[0]].bstrval);
result := s_ok;
end;
112:
begin
do
propertychange(dps.rgvarg^[pdispids^[0]].bstrval);
result := s_ok;
end;
250:
begin
do
beforenavigate2(idispatch(dps.rgvarg^[pdispids^[0]].dispval),
polevariant(dps.rgvarg^[pdispids^[1]].pvarval)^, polevariant(dps.rgvarg^[pdispids^[2]].pvarval)^,
polevariant(dps.rgvarg^[pdispids^[3]].pvarval)^,
polevariant(dps.rgvarg^[pdispids^[4]].pvarval)^,
polevariant(dps.rgvarg^[pdispids^[5]].pvarval)^,
dps.rgvarg^[pdispids^[6]].pbool^);
result := s_ok;
end;
251:
begin
do
newwindow2(idispatch(dps.rgvarg^[pdispids^[0]].pdispval^), dps.rgvarg^[pdispids^[1]].pbool^);
result := s_ok;
end;
252:
begin
do
navigatecomplete2( idispatch(dps.rgvarg^[pdispids^[0]].dispval), polevariant(dps.rgvarg^[pdispids^[1]].pvarval)^);
result := s_ok;
end;
259:
begin
do
documentcomplete(idispatch(dps.rgvarg^[pdispids^[0]].dispval), polevariant(dps.rgvarg^[pdispids^[1]].pvarval)^);
result := s_ok;
end;
253:
begin
do
onquit();
result := s_ok;
end;
254:
begin
do
onvisible(dps.rgvarg^[pdispids^[0]].vbool);
result := s_ok;
end;
255:
begin
do
ontoolbar(dps.rgvarg^[pdispids^[0]].vbool);
result := s_ok;
end;
256:
begin
do
onmenubar(dps.rgvarg^[pdispids^[0]].vbool);
result := s_ok;
end;
257:
begin
do
onstatusbar(dps.rgvarg^[pdispids^[0]].vbool);
result := s_ok;
end;
258:
begin
do
onfullscreen(dps.rgvarg^[pdispids^[0]].vbool);
result := s_ok;
end;
260:
begin
do
ontheatermode(dps.rgvarg^[pdispids^[0]].vbool);
result := s_ok;
end;
end;
Finally
If bhasparams then
FreeMem(pdispids, idispidssize);
end;
end;
Initialization
TDemoDeskBandFactory.Create(ComServer, TDemoDeskBand, CLSID_DEMO_DESK_BAND, '', BAND_TITLE, ciMultiInstance);
end.