Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2011.02.20;
Скачать: [xml.tar.bz2];

Вниз

Как отследить события в Internet Explorer   Найти похожие ветки 

 
hattak ©   (2010-11-09 17:28) [0]

Опять, господа, у меня вопрос про IE)))
Проблема - нужно отследить возникновение некоторых событий в Веб-странице, загруженной в IE. Например, в частности onPropertyChange на слое (DIV). Суть в том, что мне из программы нужно узнать, когда обновилось содержимое DIV через свойство innerHTML. Для этого как раз и нужно отследить возникновение onPropertyChange.
Как я сделал ... долго думал и искал и придумал только сделать часть своей программы ActiveX сервером и описать в нём метод, который будет вызывать событие onPropertyChange из Web-страницы, обработчик же onPropertyChange програмно вешать на этот DIV ...

Делаю так: получаю IHTMLDocument2 страницы, ну скажем:

IE.Document.QueryInterface(IHTMLDocument2, iDoc);

далее вешаю обработчик используя скрипт на javascript и метод attachEvent:

iDoc.parentWindow.execScript("function runc() { var coms = new ActiveXObject("MyProg.MyInterface"); coms.doDIVControl(); } document.getElementById("msg").attachEvent("onpropertychange", runc);","javascript");

т.е. я вызываю из своей программы скрипт на JS, который и вешает на DIV с ID"ом msg функцию runc(), при вызове которой, как видно, создаётся элемент ActiveX из моей программы и из него вызывается функция doDIVControl() - таким образом моя программа узнаёт, что в Web-странице возникло событие onpropertychange ... вот)))

а теперь вопрос, можно ли решить мою задачу каким-то иным путём?
например, у нитерфейса IHTMLDocument2 есть куча методов on..... onClick, скажем и т.п. а как ими пользоваться-то? я не понимаю никак, или они там только для "красоты" и через них можно только узнать есть ли обработчик событий вообще или нет ... ?))
Вот, подскажите, может есть у кого-то идеи, а то в моём варианте есть значительные минусы, требуется каждый раз приаттачивать обработчик, при обновлении страницы, требуется смена настроек безопасности, для создания activex элемента и т.п. ...


 
brand   (2010-11-09 17:46) [1]

>а как ими пользоваться-то?

Согласно документации, нужно имплементировать IDispatch с методом по умолчанию, который и будет обработчиком события (указатель на инстанс вашей реализации и нужно передать в метод onclick).

А вообще, дичайшей ересью вы, по-моему, занимаетесь.


 
hattak ©   (2010-11-09 17:59) [2]

ересь ... хммм, хорошо, посоветуйте ... есть копроративный чат, сделан так, что сообщения в него когда приходят обновляются не документы во фрейме, т.е. никаких FrameNavigateComplete и т.п. а именно обновляется документ внутри, через innerHTML. Требуется написать плагин, который будет перехватывать эти сообщения, в лог их складывать, когда приходит новое и оповещать об этом пользователя. Чат сделан именно в  вибе веб-страницы, в фрейме (повторяю, фрейм не обновляется), изменить код самого чата никак нельзя, т.е. это разработка зарубежного отделения компании ... как же это ещё решить, если не такой вот "ересью" ?))
я за другие варианты, дайте идею)))


 
hattak ©   (2010-11-09 19:59) [3]

не, не въезжаю, хоть убейте!)))
вообще, я нашёл в методах IHTMLDocument3 собственно функцию
attachEvent(const event WideString; pdisp:IDispatch):boolean;
т.е. если я получаю интерфейс

IE.Document.QueryInterface(IHTMLDocument3, iDoc);
то по идее
iDoc.attachEvent("onpropertychange",???); - должно делать тоже, что делаю я через JS, но там DISP функции ... я должен как указать, что должна вызываться моя функция doDIVControl; ? я что-то совсем запутался ((

unit MyInt;
{$WARN SYMBOL_PLATFORM OFF}
interface
uses ComObj, ActiveX, AspTlb, MyInterface_TLB, StdVcl, Dialogs;
type
 TMyInterface = class(TASPMTSObject, IMyInterface)
 protected
   procedure doDIVControl; safecall;
 end;
implementation
uses ComServ, MainForm_Unit;
procedure TMyInterface.doDIVControl;
begin
..............................
end;
initialization
 TAutoObjectFactory.Create(ComServer, THaddanInterface, Class_MyInterface, ciMultiInstance, tmApartment);
end.

unit MyInterface_TLB;
{$TYPEDADDRESS OFF}
{$WARN SYMBOL_PLATFORM OFF}
{$WRITEABLECONST ON}
{$VARPROPSETTER ON}
interface
uses Windows, ActiveX, Classes, Graphics, StdVCL, Variants;
const
 MyInterfaceMajorVersion = 1;
 MyInterfaceMinorVersion = 0;
 LIBID_MyInterface: TGUID = "{CFEA4581-435A-4175-8303-4AEC0D1599CC}";
 IID_IMyInterface: TGUID = "{79B819AC-A318-4FD6-9693-229032395110}";
 CLASS_MyInterface: TGUID = "{632190B3-ABFA-4B80-AFBA-B8F504680CB1}";
type
 IMyInterface = interface;
 IMyInterfaceDisp = dispinterface;
 MyInterface = IMyInterface;
 IMyInterface = interface(IDispatch)
   ["{79B819AC-A318-4FD6-9693-229032395110}"]
   procedure doDIVControl; safecall;
 end;
 IMyInterfaceDisp = dispinterface
   ["{79B819AC-A318-4FD6-9693-229032395110}"]
   procedure doDIVControl; dispid 201;
 end;

 CoMyInterface = class
   class function Create: IMyInterface;
   class function CreateRemote(const MachineName: string): IMyInterface;
 end;

implementation

uses ComObj;

class function CoMyInterface.Create: IMyInterface;
begin
 Result := CreateComObject(CLASS_MyInterface) as IMyInterface;
end;

class function CoMyInterface.CreateRemote(const MachineName: string): IMyInterface;
begin
 Result := CreateRemoteComObject(MachineName, CLASS_MyInterface) as IMyInterface;
end;

end.


 
DiamondShark ©   (2010-11-09 20:11) [4]


> hattak ©   (09.11.10 19:59) [3]

Пишешь класс , реализующий интерфейс IDispatch, в метод attachEvent передаёшь экземпляр этого класса.
Когда срабатывает событие, будет вызван метод Invoke.


 
hattak ©   (2010-11-09 20:38) [5]

хорошо:

type
 TMyN = class(TObject, IUnknown, IDispatch)
 private
  function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
  function _AddRef: Integer; stdcall;
  function _Release: Integer; stdcall;
  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;
 end;

var  TN:TMyN;

implementation

function TMyN._AddRef: Integer;
begin
Result := 1;
end;
function TMyN._Release: Integer;
begin
Result := 1;
end;
function TMyN.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
Result := S_OK;
end;
function TMyN.GetIDsOfNames(const IID: TGUID; Names: Pointer; NameCount, LocaleID: Integer; DispIDs: Pointer): HResult;
begin
Result := E_NOTIMPL;
end;
function TMyN.GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HResult;
begin
Pointer(TypeInfo) := nil;
Result := E_NOTIMPL;
end;
function TMyN.GetTypeInfoCount(out Count: Integer): HResult;
begin
Count := 0;
Result := S_OK;
end;
function TMyN.Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer; Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult;
begin
 showmessage("OK");
end;

........................

procedure TMainForm.ToolButton9Click(Sender: TObject);begin
begin
frmDoc3.attachEvent("onmousemove",TN);
end;

..............................

не работает событие, хотя результат attachEvent = true, типа повесилось, а не срабатывает (((( в чём дело может быть?


 
DiamondShark ©   (2010-11-09 21:15) [6]


>  в чём дело может быть?

Что-то не видно, где создаётся экземпляр TMyN


function TMyN._AddRef: Integer;
begin
Result := 1;
end;
function TMyN._Release: Integer;
begin
Result := 1;
end;
function TMyN.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
Result := S_OK;
end;


Бред.

type
TMyN = class(TIntefacedObject, IDispatch)
private
 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;
end;

procedure TMainForm.ToolButton9Click(Sender: TObject);begin
begin
frmDoc3.attachEvent("onmousemove",TMyN.Create as IDispatch);
end;


 
hattak ©   (2010-11-09 21:35) [7]

_AddRef, _Release, QueryInterface относится тут к IUnknown, это как бы не бред, просто не выкинул из кода, но они не на что тут и не влияют как бы

потомок должен быть от TIntefacedObject, а что это за класс, откуда он ? первый раз слышу и инфы не вижу нигде


 
hattak ©   (2010-11-09 21:44) [8]

так, голова кипит уже TMyN = class(TInteRfacedObject, IDispatch) ))))))))))))))))))


 
hattak ©   (2010-11-09 21:48) [9]

да, так работает, спасибо!

хотя задача основная так и остаётся не решённой,
слой (DIV) же нельзя получить как IHTMLDocument3, а значит на него нельзя таким образом повесить и обработчик ... или опять же я что-то упустил?)))


 
brand   (2010-11-09 21:57) [10]

hattak ©   (09.11.10 21:48) [9]

GUI эвенты от нодов должны через эвент бабблинг всплывать до документа, и теоретически обработчик документа должен отрабатывать. Но неизвестно, всплывают ли DOM эевенты, нужно экспериментировать.


 
hattak ©   (2010-11-09 22:11) [11]

у меня вполне заработало вот так
frmDoc3.getElementById("msg").onclick := TMyN.Create as IDispatch;
именно на слой событие, но там нет нужного onpropertychange ... может его назвали как-то иначе, щас все перекопаю))


 
brand   (2010-11-09 22:22) [12]

hattak ©   (09.11.10 22:11) [11]

Можно попробовать прицепить onPropertyChange к самому документу, если DOM эвенты всплывают, то это должно работать.

А по поводу альтернативных идей, если можно изменять javascript (а насколько я понимаю, можно) то в плагине можно устроить локальный сервер на NNNN порту, и сабмитить туда скрытую форму из обработчика javascript, javascript-ом же вставленную в документ (но опять же не ручаюсь насколько это будет работать касательно настроек безопасности).


 
hattak ©   (2010-11-09 23:02) [13]

не, не всплывает, однако нашёл решение
var e:IHTMLElement2;

e := HaddanFrames[1].frmDoc3.getElementById("msg") as IHTMLElement2;
e.onpropertychange := TMyN.Create as IDispatch;

вот так всё работает!
всем большое спасибо!


 
hattak ©   (2010-11-11 00:27) [14]

в продолжение темы ... чтоб не открывать нову тему ...

у меня получается странная вещь, сделал я плагин для IE, всё вроде нормально, до тех пор пока открыта одно копия IE, когда открывается вторая или нажимаю на ссылке и она открывается во внешнем окне, то значения всех переменных в главном окне сбрасываются, т.е. такое ощущение, что все окна (ну копии плагина в них т.е.) используют одни и те же переменные оО Разве при создании нового экземпляра переменные не должны также новые создаваться. как сделать так, чтоб при запуске каждого окна IE запускалась как бы новая копия плагина, чтоб переменные в них были "изолированы" друг от друга?

з.ы. пытался при создании плагина - т.е. com сервера, создавать его с ciSingleInstance вместо ciMultiInstance ... всё тоже самое (((


 
hattak ©   (2010-11-11 00:43) [15]

даже ещё интереснее, есть гланое окно ... в нём ссылка, нажимаю, открывается в новом окне - значения переменных разные в главном и в открывшемся ... в открывшемся ещё ссылка ... открываю в новом окне и опа ... это новое окно имеет все значения переменных из главного и сбрасывает все переменные в главном оО



Страницы: 1 вся ветка

Форум: "Прочее";
Текущий архив: 2011.02.20;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.004 c
2-1290774813
Scott Storch
2010-11-26 15:33
2011.02.20
интерфейсы и осбождение памяти


3-1253187389
harisma
2009-09-17 15:36
2011.02.20
Помогите оптимизировать скрипт


15-1289683791
Юрий
2010-11-14 00:29
2011.02.20
С днем рождения ! 14 ноября 2010 воскресенье


2-1290952548
delpilamer
2010-11-28 16:55
2011.02.20


6-1234984194
d@vinchi
2009-02-18 22:09
2011.02.20
Как прослушивать определенный ТСР порт?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский