Board index » delphi » IHTMLDocument from Service/DLL

IHTMLDocument from Service/DLL


2006-02-21 06:42:56 AM
delphi120
Hello All,
I have some code that grabs an instance of IHTMLDocument2 from a HWND,
and I am able to examine/modify the document from that point. It works
from a normal Win32 Delphi Application. However, I am interested in
moving this code to a non-visible process, such as a Win32 service or a
DLL.
My problem is that the code below always evaluates my document as nil,
when I send the message to IE to get the document (called pDoc in my
code). It fails in a service that is set to interact with the desktop
(and even running under my username), or as a DLL using rundll32.
I am able to get the valid window handle for the document in all cases,
but the retrieval of the document fails unless it is from a GUI app. Is
there an alternate way to get the document that I don't know about
(I've searched and searched), or a trick/code that will give my app
access to the document if it is not a GUI app?)
I have the feeling it is either a COM restriction, or I don't have full
access to UI elements that aren't running "side by side" my
application. Any ideas would be appreciated. The code I have is
below... it does work, but only in the GUI app so I am confident it's
not necessarily "buggy"
--------------------
function GetIEFromHWND(WHandle: HWND): IHTMLDocument2;
var
hInst: DWORD;
lRes, lRes2: cardinal;
MSG: integer;
pDoc: IHTMLDocument2;
ObjectFromLresult: TObjectFromLresult;
IE: IWebbrowser2;
begin
CoInitialize(nil);
hInst := LoadLibrary('Oleacc.dll');
Result := nil;
try
@ObjectFromLresult :=
GetProcAddress(hInst, PChar('ObjectFromLresult'));
if @ObjectFromLresult <>nil then
begin
try
MSG := RegisterWindowMessage(PChar('WM_HTML_GETOBJECT'));
SendMessageTimeOut(WHandle, MSG, 0, 0, SMTO_ABORTIFHUNG, 1000,
DWORD(Pointer(lRes)));
lRes2 := ObjectFromLresult(lRes, IHTMLDocument2, 0, pDoc);
if Succeeded(lRes2) then
begin
if (Assigned(pDoc)) and (pDoc <>nil) then // <--- nil here,
from a service or DLL
begin
(pDoc.parentWindow as
IServiceprovider).QueryService(IWebbrowserApp,
IWebbrowser2, IE);
end;
end;
Result := pDoc;
except
end;
end;
finally
FreeLibrary(hInst);
end;
CoUninitialize;
end;
Thanks!
Chris
 
 

Re:IHTMLDocument from Service/DLL

Hi Chris,
"WebBrowser doesnt work if not visible?" (thread 05/10/2005) : XMLHTTP COM
object / Indy / JVCL solutions...
pascal
"Chris Kuske" <XXXX@XXXXX.COM>a écrit dans le message de news:
43fa44f3$XXXX@XXXXX.COM...
Quote
Hello All,

I have some code that grabs an instance of IHTMLDocument2 from a HWND,
and I am able to examine/modify the document from that point. It works
from a normal Win32 Delphi Application. However, I am interested in
moving this code to a non-visible process, such as a Win32 service or a
DLL.


My problem is that the code below always evaluates my document as nil,
when I send the message to IE to get the document (called pDoc in my
code). It fails in a service that is set to interact with the desktop
(and even running under my username), or as a DLL using rundll32.


I am able to get the valid window handle for the document in all cases,
but the retrieval of the document fails unless it is from a GUI app. Is
there an alternate way to get the document that I don't know about
(I've searched and searched), or a trick/code that will give my app
access to the document if it is not a GUI app?)


I have the feeling it is either a COM restriction, or I don't have full
access to UI elements that aren't running "side by side" my
application. Any ideas would be appreciated. The code I have is
below... it does work, but only in the GUI app so I am confident it's
not necessarily "buggy"


--------------------
function GetIEFromHWND(WHandle: HWND): IHTMLDocument2;
var
hInst: DWORD;
lRes, lRes2: cardinal;
MSG: integer;
pDoc: IHTMLDocument2;
ObjectFromLresult: TObjectFromLresult;
IE: IWebbrowser2;
begin
CoInitialize(nil);
hInst := LoadLibrary('Oleacc.dll');
Result := nil;
try
@ObjectFromLresult :=
GetProcAddress(hInst, PChar('ObjectFromLresult'));
if @ObjectFromLresult <>nil then
begin
try
MSG := RegisterWindowMessage(PChar('WM_HTML_GETOBJECT'));
SendMessageTimeOut(WHandle, MSG, 0, 0, SMTO_ABORTIFHUNG, 1000,
DWORD(Pointer(lRes)));
lRes2 := ObjectFromLresult(lRes, IHTMLDocument2, 0, pDoc);
if Succeeded(lRes2) then
begin
if (Assigned(pDoc)) and (pDoc <>nil) then // <--- nil here,
from a service or DLL
begin
(pDoc.parentWindow as
IServiceprovider).QueryService(IWebbrowserApp,
IWebbrowser2, IE);
end;
end;
Result := pDoc;
except
end;
end;
finally
FreeLibrary(hInst);
end;
CoUninitialize;
end;


Thanks!
Chris


 

Re:IHTMLDocument from Service/DLL

Hi Pascal,
This won't work for me, unfortuantely. The content is not on a remote
website, it is in an IHTMLDocument that is dynamically created (no URL can be
used to load the HTML using XMLHTTP)
Chris
"Pascal Chapuis" <XXXX@XXXXX.COM>writes
Quote
Hi Chris,

"WebBrowser doesnt work if not visible?" (thread 05/10/2005) : XMLHTTP COM
object / Indy / JVCL solutions...

pascal

"Chris Kuske" <XXXX@XXXXX.COM>a écrit dans le message de news:
43fa44f3$XXXX@XXXXX.COM...

>Hello All,
>
>I have some code that grabs an instance of IHTMLDocument2 from a HWND,
>and I am able to examine/modify the document from that point. It works
>from a normal Win32 Delphi Application. However, I am interested in
>moving this code to a non-visible process, such as a Win32 service or a
>DLL.
>
>
>My problem is that the code below always evaluates my document as nil,
>when I send the message to IE to get the document (called pDoc in my
>code). It fails in a service that is set to interact with the desktop
>(and even running under my username), or as a DLL using rundll32.
>
>
>I am able to get the valid window handle for the document in all cases,
>but the retrieval of the document fails unless it is from a GUI app. Is
>there an alternate way to get the document that I don't know about
>(I've searched and searched), or a trick/code that will give my app
>access to the document if it is not a GUI app?)
>
>
>I have the feeling it is either a COM restriction, or I don't have full
>access to UI elements that aren't running "side by side" my
>application. Any ideas would be appreciated. The code I have is
>below... it does work, but only in the GUI app so I am confident it's
>not necessarily "buggy"
>
>
>--------------------
>function GetIEFromHWND(WHandle: HWND): IHTMLDocument2;
>var
>hInst: DWORD;
>lRes, lRes2: cardinal;
>MSG: integer;
>pDoc: IHTMLDocument2;
>ObjectFromLresult: TObjectFromLresult;
>IE: IWebbrowser2;
>begin
>CoInitialize(nil);
>hInst := LoadLibrary('Oleacc.dll');
>Result := nil;
>try
>@ObjectFromLresult :=
>GetProcAddress(hInst, PChar('ObjectFromLresult'));
>if @ObjectFromLresult <>nil then
>begin
>try
>MSG := RegisterWindowMessage(PChar('WM_HTML_GETOBJECT'));
>SendMessageTimeOut(WHandle, MSG, 0, 0, SMTO_ABORTIFHUNG, 1000,
>DWORD(Pointer(lRes)));
>lRes2 := ObjectFromLresult(lRes, IHTMLDocument2, 0, pDoc);
>if Succeeded(lRes2) then
>begin
>if (Assigned(pDoc)) and (pDoc <>nil) then // <--- nil here,
>from a service or DLL
>begin
>(pDoc.parentWindow as
>IServiceprovider).QueryService(IWebbrowserApp,
>IWebbrowser2, IE);
>end;
>end;
>Result := pDoc;
>except
>end;
>end;
>finally
>FreeLibrary(hInst);
>end;
>CoUninitialize;
>end;
>
>
>Thanks!
>Chris
>
>


 

Re:IHTMLDocument from Service/DLL

Hi Chris,
"UI-less HTML parser Demo" :
www.euromind.com/iedelphi/uilessparser.htm
Pascal
"Chris Kuske" <XXXX@XXXXX.COM>a écrit dans le message de news:
43fcc686$XXXX@XXXXX.COM...
Quote
Hi Pascal,

This won't work for me, unfortuantely. The content is not on a remote
website, it is in an IHTMLDocument that is dynamically created (no URL can
be used to load the HTML using XMLHTTP)

Chris

"Pascal Chapuis" <XXXX@XXXXX.COM>writes
news:43fc2b63$XXXX@XXXXX.COM...
>Hi Chris,
>
>"WebBrowser doesnt work if not visible?" (thread 05/10/2005) : XMLHTTP
>COM object / Indy / JVCL solutions...
>
>pascal
>
>"Chris Kuske" <XXXX@XXXXX.COM>a écrit dans le message de news:
>43fa44f3$XXXX@XXXXX.COM...
>
>>Hello All,
>>
>>I have some code that grabs an instance of IHTMLDocument2 from a HWND,
>>and I am able to examine/modify the document from that point. It works
>>from a normal Win32 Delphi Application. However, I am interested in
>>moving this code to a non-visible process, such as a Win32 service or a
>>DLL.
>>
>>
>>My problem is that the code below always evaluates my document as nil,
>>when I send the message to IE to get the document (called pDoc in my
>>code). It fails in a service that is set to interact with the desktop
>>(and even running under my username), or as a DLL using rundll32.
>>
>>
>>I am able to get the valid window handle for the document in all cases,
>>but the retrieval of the document fails unless it is from a GUI app. Is
>>there an alternate way to get the document that I don't know about
>>(I've searched and searched), or a trick/code that will give my app
>>access to the document if it is not a GUI app?)
>>
>>
>>I have the feeling it is either a COM restriction, or I don't have full
>>access to UI elements that aren't running "side by side" my
>>application. Any ideas would be appreciated. The code I have is
>>below... it does work, but only in the GUI app so I am confident it's
>>not necessarily "buggy"
>>
>>
>>--------------------
>>function GetIEFromHWND(WHandle: HWND): IHTMLDocument2;
>>var
>>hInst: DWORD;
>>lRes, lRes2: cardinal;
>>MSG: integer;
>>pDoc: IHTMLDocument2;
>>ObjectFromLresult: TObjectFromLresult;
>>IE: IWebbrowser2;
>>begin
>>CoInitialize(nil);
>>hInst := LoadLibrary('Oleacc.dll');
>>Result := nil;
>>try
>>@ObjectFromLresult :=
>>GetProcAddress(hInst, PChar('ObjectFromLresult'));
>>if @ObjectFromLresult <>nil then
>>begin
>>try
>>MSG := RegisterWindowMessage(PChar('WM_HTML_GETOBJECT'));
>>SendMessageTimeOut(WHandle, MSG, 0, 0, SMTO_ABORTIFHUNG, 1000,
>>DWORD(Pointer(lRes)));
>>lRes2 := ObjectFromLresult(lRes, IHTMLDocument2, 0, pDoc);
>>if Succeeded(lRes2) then
>>begin
>>if (Assigned(pDoc)) and (pDoc <>nil) then // <--- nil here,
>>from a service or DLL
>>begin
>>(pDoc.parentWindow as
>>IServiceprovider).QueryService(IWebbrowserApp,
>>IWebbrowser2, IE);
>>end;
>>end;
>>Result := pDoc;
>>except
>>end;
>>end;
>>finally
>>FreeLibrary(hInst);
>>end;
>>CoUninitialize;
>>end;
>>
>>
>>Thanks!
>>Chris
>>
>>
>
>