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

Вниз

проблема с 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.041 c
2-1142493748
KyRo
2006-03-16 10:22
2006.04.02
Доступ к файлу


15-1141722985
superoberon
2006-03-07 12:16
2006.04.02
Shelltreeview


15-1141957486
grisme
2006-03-10 05:24
2006.04.02
Математика


4-1136977878
Free0n
2006-01-11 14:11
2006.04.02
Нужно обнаружить одну хитрую программу....


2-1142848749
Ivanov
2006-03-20 12:59
2006.04.02
Работа с клавиатурой.





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский