IE控制问题,请各位DX帮忙 ( 积分: 200 )

  • 主题发起人 主题发起人 liuziwei_china
  • 开始时间 开始时间
把类的定义贴出来看
 
uses
Windows, Sysutils, Messages, Registry, Shellapi, ActiveX, Classes, ComObj,
Shlobj, Dialogs, Commctrl, ShDocVW, MSHTML,IEForm, StdVcl, Controls;
type
TGetMailBand = class(TComObject, IDeskBand, IObjectWithSite, IPersistStreamInit, IDispatch)
private
frmIE: TForm1;
m_pSite: IInputObjectSite;
m_hwndParent: HWND;
m_hWnd: HWND;
m_dwViewMode: Integer;
m_dwBandID: Integer;
IsComplete: boolean;
protected

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;


{声明IDeskBand方法}
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;

{声明IObjectWithSite方法}
function SetSite(const pUnkSite: IUnknown): HResult; stdcall;
function GetSite(const riid: TIID; out site: IUnknown): HResult; stdcall;

{声明IPersistStream方法}
function GetClassID(out classID: TCLSID): HResult; stdcall;
function IsDirty: HResult; stdcall;
function InitNew: 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 Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer;
Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult; stdcall;
end;

const
Class_GetMailBand: TGUID = '{954F618B-0DEC-4D1A-9317-E0FC96F87865}';
{以下是系统接口的IID}
IID_IUnknown: TGUID = (
D1: $00000000; D2: $0000; D3: $0000; D4: ($C0, $00, $00, $00, $00, $00, $00, $46));
IID_IOleObject: TGUID = (
D1: $00000112; D2: $0000; D3: $0000; D4: ($C0, $00, $00, $00, $00, $00, $00, $46));
IID_IOleWindow: TGUID = (
D1: $00000114; D2: $0000; D3: $0000; D4: ($C0, $00, $00, $00, $00, $00, $00, $46));

IID_IInputObjectSite: TGUID = (
D1: $F1DB8392; D2: $7331; D3: $11D0; D4: ($8C, $99, $00, $A0, $C9, $2D, $BF, $E8));
sSID_SInternetExplorer: TGUID = '{0002DF05-0000-0000-C000-000000000046}';
sIID_IWebBrowserApp: TGUID = '{0002DF05-0000-0000-C000-000000000046}';

{工具面板所允许的最小宽度和高度}
MIN_SIZE_X = 250;
MIN_SIZE_Y = 22;
EB_CLASS_NAME = 'GetMailAddress'; {工具的类名}

setsite方法:

function TGetMailBand.SetSite(const pUnkSite: IUnknown): HResult; stdcall;//设置现场
var
pOleWindow: IOleWindow;
pOLEcmd: IOleCommandTarget;
pSP: IServiceProvider;
CPC:IConnectionPointContainer;
CP:IConnectionPoint;
rc: TRect;
Cookie:Integer;
begin
IsComplete := false;
//如果pUnkSite不为NULL, 则表示要建立一个新的现场
if Assigned(pUnkSite) then
begin
m_hwndParent := 0;
m_pSite := pUnkSite as IInputObjectSite;
pOleWindow := PunkSIte as IOleWindow;
{获得父窗口IE面板窗口的句柄}
pOleWindow.GetWindow(m_hwndParent);
if (m_hwndParent = 0) then
begin
Result := E_FAIL;
exit;
end;
{获得父窗口区域}
GetClientRect(m_hwndParent, rc);
if not Assigned(frmIE) then //如果没有建立主窗口
begin
{建立TIEForm窗口,父窗口为m_hwndParent}
frmIE := TForm1.CreateParented(m_hwndParent);
m_Hwnd := frmIE.Handle; //保存主窗口句柄
SetWindowLong(frmIE.Handle, GWL_STYLE, GetWindowLong(frmIE.Handle,
GWL_STYLE) or WS_CHILD); //子窗口的风格
{根据父窗口区域设置窗口位置}
with frmIE do
begin
Left := rc.Left;
Top := rc.top;
Width := rc.Right - rc.Left;
Height := rc.Bottom - rc.Top;
end;
frmIE.Visible := True; //显示主窗口
{获得与浏览器相关联的Webbrowser对象}
pOLEcmd := pUnkSite as IOleCommandTarget;
pSP := pOLEcmd as IServiceProvider;
if Assigned(pSP) then
begin
{检索提供的服务}
pSP.QueryService(IWebbrowserApp, IWebbrowser2, frmIE.IEThis);

if(Assigned(frmIE.IEThis))then
begin
//frmIE.IEThis.QueryInterface(IConnectionPointContainer,CPC);//寻找连接点
//CPC.FindConnectionPoint(DWEBBrowserEvents2,CP);
//CPC.FindConnectionPoint(HTMLDocumentEvents2,CP);
InterfaceConnect(frmIE.IEThis, HTMLDocumentEvents, Self, Cookie);
//CP.Advise(Self,Cookie);//通过Advise方法建立Com自身与连接点的连接

end;

end;
end;
end;
Result := S_OK;
end;
 
估计你的frmIE.IEThis为空,没有连接上.仔细检查下.
 
InterfaceConnect(frmIE.IEThis.document, HTMLDocumentEvents, Self, Cookie);
改成
 
我看了,是走了上面的代码的,不过想了一下,觉得好象有点问题,因为SETSITE的方法是在一启动IE的时候就执行了,那么当IE打开不同的网页的时候是不是就会自己断开这种连接呢?
 
放到documentcomplete里,别放setsite就没这个问题.
 
frmIE.IEThis这个不为空,但是frmIE.IEThis.document这个是个NIL,
是不是每个网页加载完成的时候都要来做这个连接啊,
但是INVOKE又只有一个方法,该怎么写啊?
 
所以叫你放到wb的ondocumentcomplete里面去连接
 
是这样的么?
1、在setsite里面写成这样InterfaceConnect(frmIE.IEThis, DWEBBrowserEvents2, Self, Cookie);
2、在INVOKE里面
if Dispid = 259 then
begin
frmIE.DocumentComplete(self);
showmessage('ok');

end;
if dispid = -600 then
begin
//我要做的事
end;
Result:=S_OK;
finally
if(bHasParams)then
FreeMem(pDispIDs,iDispIDsSize);
end;
3、在DocumentComplete(self);事件中
在写如下代码:
if(Assigned(frmIE.IEThis))then
begin
//frmIE.IEThis.QueryInterface(IConnectionPointContainer,CPC);//寻找连接点
//CPC.FindConnectionPoint(DWEBBrowserEvents2,CP);
//CPC.FindConnectionPoint(HTMLDocumentEvents2,CP);
InterfaceConnect(frmIE.IEThis, HTMLDocumentEvents, Self, Cookie);
//CP.Advise(Self,Cookie);//通过Advise方法建立Com自身与连接点的连接

是这个意思么
 
if Dispid = 259 then
begin
InterfaceConnect(frmIE.IEThis.document, HTMLDocumentEvents, Self, Cookie);

end;
这样就可以了不用单独弄成一个函数
 
呵呵,测试了一下,好象在一个类里不能那么做,
害的我只好弄把窗体类也继承了IUNKOWN接口,呵呵,比较苯的办法

点击事件是出来了,可以还有个小问题,它怎么点一下要触发三次的,
satanmonkey 遇到过这个问题么?
 
一个类肯定可以的.我做过.

触发多次是正常的.ie的事件是冒泡传递的,好像是从子元素传递到父元素,或者反过来.

你判断下是哪个元素被触发,然后丢弃不要的就可以了
 
我是做了判断了
if IHTMLEventObj(dps.rgvarg^[pDispIds^[0]].dispval).srcElement.ID = 'button2' then
begin
Button1Click(nil);
end;
这个还不够么?
 
郁闷啊, 现在退出IE报非法错误,,satanmonkey 知道是怎么回事么?[:(!]
 
什么地方访问了空指针
 
已经解决了,是事件这个HTMLDocumentEvents写错了,应该是HTMLDocumentEvents2

但是弹出对话框这个还是有问题,用代码追踪就只显示一次,如果不用代码跟踪就弹出两次,
有什么办法解决么?
 
这个贴结束了,多谢satanmonkey和Beyondbill, bjyplbx的帮助,
to satanmonkey: 我的MSN在上面,如何有兴趣,希望交个朋友,呵呵
另: 在开个帖,问问弹出两次提示框的问题,还请大家多多关注
 
后退
顶部