Текущий архив: 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.47 MB
Время: 0.06 c