Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.04.02;
Скачать: CL | DM;

Вниз

проблема с ActiveX dll   Найти похожие ветки 

 
ga3   (2006-03-19 02:20) [0]

добрый вечер
написал дллку активХ сервер для ИЕ. используется шняга под названием Browser Helper Object
после регистрации она подгружается к каждому процессу iexplore.exe и explorer.exe (ядро-то у них одно и тоже походу дела), ловит события и обрабатывает их к примеру так:


library IEBrowserHelper;

uses
 ComServ,
 mshtml_tlb, // это я импортировал через Component->Import ActiveX Control === Microsoft HTML Library version 4.0
 dialogs, sysutils, shdocvw, registry,strutils,  Windows, ActiveX, ComObj, wininet,Variants;

 exports
 DllGetClassObject,
 DllCanUnloadNow,
 DllRegisterServer,
 DllUnregisterServer;

 const
...
DISPID_FILEDOWNLOAD = 270; // начало загрузки файла
DISPID_BEFORENAVIGATE2 = 250; // клик по линку, нажатие сабмита итп
...
список неполный, полный список событий ИЕ см. shdocvw.pas

type
....
тут обьявляем ком обьект присоединяющийся к бровзеру и функции его присоединения
....

const
 Class_IEBrowserHelper: TGUID = "{FCADDC14-BD46-408A-9842-CDBE1C6D37EB}"; //идентификатор интерфейса

var
 IE: IWebbrowser2; //обьект от которого приходят извещения о событиях
 Cookie: Integer; //идентификатор для того чтоб не путать окна ИЕ между собой
 CP: IConnectionPoint;

....
здесь регистрируем дллку, пишем в реестр итп (код неполный)
function TIEBrowserHelper.SetSite(const pUnkSite: IUnknown): HResult; //собсно присоединение
var
 CPC: IConnectionPointContainer;
begin
 if Assigned(pUnkSite) then
 begin
   IE := pUnkSite as IWebbrowser2;
   CPC := IE as IConnectionPointContainer;
   CPC.FindConnectionPoint(DWebBrowserEvents2, CP);
   CP.Advise(Self, Cookie);
 end;
 Result := S_OK
end;
....
function TIEBrowserHelper.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
 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);
   Result := S_OK;
   case DispId of
.....
.....
     DISPID_DOCUMENTCOMPLETE: DoDocumentComplete(IDispatch(dps.rgvarg^[pDispIds^[0]].dispval), POleVariant(dps.rgvarg^[pDispIds^[1]].pvarval)^); // при окончании загрузки документа вызвать процедуру DoDocumentComplete (см ниже)
     DISPID_ONQUIT:  CP.Unadvise(Cookie);
   else
     Result := DISP_E_MEMBERNOTFOUND;
   end;
 finally
   if (bHasParams) then FreeMem(pDispIds, iDispIdsSize);
 end;
end;

.....
тут обработка окончания загрузки документа
procedure DoDocumentComplete(const pDisp: IDispatch; var URL: OleVariant);
var iDoc:IHtmlDocument2;
   i:integer;
   ov:OleVariant;
   iDisp: IDispatch;
   iEl:IHTMLElement;
   iColl:IHTMLElementCollection;
begin
ov:="td";
ie.document.QueryInterface(IHtmlDocument2,iDoc);
IDisp:=iDoc.all.tags(ov);
if assigned(IDisp) then begin
   IDisp.QueryInterface(IHTMLElementCollection,iColl);
   if assigned(iColl) then begin
     for i:=1 to iColl.Get_length do begin
       iDisp:=iColl.item(pred(i),0);
       iDisp.QueryInterface(IHTMLElement,iel);
       if assigned(iel) then begin
        if i=6 then begin
       showmessage(iel.InnerHTML);// вывести сообщение с содержимым 6-го обьекта в таблице
        end;
end;
end;
end;
end;
end;
.....

begin //точка входа
 TIEBrowserHelperFactory.Create(ComServer, TIEBrowserHelper, Class_IEBrowserHelper,
   "", "", ciMultiInstance, tmApartment);
end.


все нормально работает, глюков нет, при компиляции только один Warning выскакивает что символ DWebBrowserEvents2 платформозависимый, вобщем компилится, регистрируется и подгружается на ура. при закрытии окна ИЕ ресурсы освобождаются корректно, короче шоколад, НО:
при переносе на другой комп все так же шоколадно кроме одной маленькой вещи: DoDocumentComplete не срабатывает. точнее процедура вызывается якобы без ошибок(нет никаких ексепшенов), но сообщение не выводится. путем пошаговой модификации удалось установить что дллка не может получить доступ к содержимому HTML документа. проект собирается с отключенным RuntIme packages, версии виндов и ИЕ одинаковые, заплатки с микросовта все скачаны и установлены на всех испытуемых компах. а теперь вопрос: какого ъця эта тварь не хочет читать хтмл на любом компутере кроме того на котором ее компилировали? мужики я в шоке, никогда такого не видел и бошка уже как церковный колокол гудит, помогите плиз найти место где надо + на - исправить чтоб запахало.


 
ga3   (2006-03-19 03:59) [1]

испытания продолжаются
если обработать событие BeforeNavigate2 след образом:

procedure DoBeforeNavigate2(const pDisp: IDispatch; var URL: OleVariant; var Flags: OleVariant; var TargetFrameName: OleVariant; var PostData: OleVariant; var Headers: OleVariant; var Cancel: WordBool);
var pdata: string;
begin
pdata:=variant2str(postdata); //переводим в строку (не показано)
модифицируем строчку
postdata:=str2variant(pdata); //переводим обратно (не показано)
cancel:=true;
ie.Navigate2(URL,Flags,TargetFrameName,Postdata,Headers);
end;


то ИЕ просто вываливается без обьяснения причин. причем повторяю: у меня на компе все работает и при отладке изпод делфи, и при ручной регистрации типа regsvr32 aaa.dll

ЧЕ ДЕЛАТЬ-ТО, МАСТЕРА?????


 
ga3   (2006-03-19 04:03) [2]

пардон, в предыдущем сообщении удалил из процедуры 2 строчки котоыре там были чтоб она не зацикливалась. оригинал должен выглядеть так:
var changed: boolean;


procedure DoBeforeNavigate2(const pDisp: IDispatch; var URL: OleVariant; var Flags: OleVariant; var TargetFrameName: OleVariant; var PostData: OleVariant; var Headers: OleVariant; var Cancel: WordBool);
var pdata: string;
begin
if not changed then begin
pdata:=variant2str(postdata); //переводим в строку (не показано)
модифицируем строчку
postdata:=str2variant(pdata); //переводим обратно (не показано)
cancel:=true;
ie.Navigate2(URL,Flags,TargetFrameName,Postdata,Headers);
changed:=true;
end;
end;


 
ga3   (2006-03-19 04:05) [3]

пойду-ка я наверное обкурюсь дабы расслабить мозг от непосильной нагрузки
я зделал букмарк, продолжение следует завтра не переключайтесь:-)


 
tesseract ©   (2006-03-19 12:12) [4]


> то ИЕ просто вываливается без обьяснения причин.


Да OLE/COM вообще не любят показывать accessviolation.

пишешь везде

try
///
except
   on E:Exception do  MessageBox(0, PChar("конкретно невосстановимый трабл в функции ля-ля-ля")   , "Error", MB_ICONSTOP or MB_OK);
end;



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

Текущий архив: 2006.04.02;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.087 c
15-1141977108
начинающий
2006-03-10 10:51
2006.04.02
UI исключительно при помощи COM


15-1141970086
Ega23
2006-03-10 08:54
2006.04.02
С Днём рождения! 10 марта


15-1142009403
Новичоккк
2006-03-10 19:50
2006.04.02
Почему может тормозить копирование и прочее?


15-1141746878
Pazitron_Brain
2006-03-07 18:54
2006.04.02
В чем проблема?


15-1141829808
Dimedrol
2006-03-08 17:56
2006.04.02
На кухне вытяжка и 2 оголенных провода...