View previous topic :: View next topic |
Author |
Message |
yidabu
Joined: 21 Apr 2007 Posts: 87
|
Posted: Sun Jul 29, 2007 12:21 am Post subject: Loading HTML content from stream |
|
|
I use juno to Loading HTML content from a Stream , Always got Access violation, no problem of juno, can you give me a hand?
Code: |
//use juno to Loading HTML content from a Stream
//c++ version http://msdn2.microsoft.com/en-us/library/Aa752047.aspx
//need help, IPersistStreamInit.Load( spStream ) always cause Access Violation
//http://bbs.yidabu.com/forum-10-1.html
// run tlbimpd.exe {EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B} /propput:put to got shdocvw type library
import dfl.application; //for application.doEvents();
import juno.com.shdocvw;
import juno.com.mshtml;
import std.utf : toUTF16;
import juno.com.client;
import juno.com.core;
extern (Windows) wchar * lstrcpyW(wchar *, wchar *);
extern (Windows) wchar * lstrcpynW(wchar *, wchar *, int);
extern (Windows) char * lstrcpynA(char *, char *, int);
extern (Windows) char * lstrcpyA(char *, char *);
extern (Windows) void * GlobalAlloc(uint, uint);
extern (Windows) void * GlobalFree(void *);
//from win32.winbase
enum : uint {
GMEM_FIXED = 0,
GMEM_MOVEABLE = 2,
GMEM_ZEROINIT = 64,
GPTR = 66,
// Used only for GlobalRealloc
GMEM_MODIFY = 128
/+ // Obselete flags (Win16 only)
GMEM_NOCOMPACT=16;
GMEM_NODISCARD=32;
GMEM_DISCARDABLE=256;
GMEM_NOT_BANKED=4096;
GMEM_LOWER=4096;
GMEM_SHARE=8192;
GMEM_DDESHARE=8192;
GMEM_LOCKCOUNT=255;
+/
}
extern(Windows) int CreateStreamOnHGlobal(
void* hGlobal,
int fDeleteOnRelease,
IStream** ppstm
);
interface IPersistStreamInit : IPersist {
static GUID IID_IPersistStreamInit = {0x8023D57F, 0x074E, 0x1B10, 0xAE, 0x2D, 0x08, 0x00, 0x2B, 0x2E, 0xC7, 0x13};
int IsDirty();
int Load(IStream*);
int Save(out IStream, int);
int GetSizeMax(out ulong);
int InitNew();
}
pragma(lib,"juno.lib");
pragma(lib,"dfl_debug.lib"); //for doEvents()
int main() {
try
{
browser();
}
catch(Exception e)
{
printf("catch %.*s\n",e.msg);
}
return 0;
}
int browser(char[] url = "about:blank")
{
try
{
//ExecutionContext.InProcessServer cause run time Access Violotion
IWebBrowser2 ie = InternetExplorer.coCreate!(IWebBrowser2)(ExecutionContext.LocalServer);
scope(exit)
{
ie.Quit();
tryRelease(ie);
}
ie.put_Width(800);
ie.put_Height(600);
ie.put_Visible(VARIANT_TRUE);
wchar* BStrURL = toBStr(url);
VARIANT vars[4];
auto hrie = ie.Navigate(BStrURL, &vars[0], &vars[1], &vars[2], &vars[3]);
freeBStr(BStrURL);
tagREADYSTATE rs;
while (rs != tagREADYSTATE.READYSTATE_COMPLETE)
{
Application.doEvents();// wait to complete, from dfl.application
ie.get_ReadyState(rs);
}
IDispatch doc;
IHTMLDocument2 hdoc;
scope(exit) tryRelease(doc);
scope(exit) tryRelease(hdoc);
hdoc = com_cast!(IHTMLDocument2) (doc);
IPersistStreamInit ip = com_cast!(IPersistStreamInit)(hdoc);
scope(exit) tryRelease(ip);
wchar[] s = "hello world"c.toUTF16() ~ "\0";
void* lpMem= GlobalAlloc(GPTR, s.length);
scope(exit) GlobalFree(lpMem);
if (!lpMem)
{
debug printf("failed GlobalAlloc \n");
return 1;
}
lstrcpyW(cast(wchar*)lpMem, s.ptr); //right?
IStream* spStream;
CreateStreamOnHGlobal( lpMem, 1, cast(IStream**)spStream );
hrie = ip.InitNew();
hrie = ip.Load( spStream ); //cause Access Violation
}//try
catch(Exception e)
{
printf("catch %.*s\n",e.msg);
return 1;
}
return 0;
}
|
Last edited by yidabu on Wed Aug 01, 2007 3:56 pm; edited 1 time in total |
|
Back to top |
|
![](templates/subSilver/images/spacer.gif) |
John
Joined: 17 Jan 2006 Posts: 75
|
Posted: Sun Jul 29, 2007 4:31 pm Post subject: |
|
|
In D, you don't declare interface references with pointer notation - for example, "IStream*" should just be "IStream". I imagine that's what's causing the problem.
1) Your declaration of CreateStreamOnHGlobal is incorrect. The ppstm parameter should be "out IStream", not "IStream**". Why don't you use the declaration from juno.com.core?
2) IPersistStreamInit.Load is also incorrectly declared (as is Save). They should be:
Code: | int Load(IStream pStm);
int Save(IStream pStm, int fClearDirty); |
3) Next, change the last few lines of your code to:
Code: |
IStream spStream;
if (CreateStreamOnHGlobal(lpMem, 1, spStream) == S_OK) {
hrie = ip.InitNew();
hrie = ip.Load(spStream);
}
|
By the way, mshtml and shdocvw aren't part of Juno's com package - but anyone reading your post might think otherwise. Best to use your own package names for other files. |
|
Back to top |
|
![](templates/subSilver/images/spacer.gif) |
yidabu
Joined: 21 Apr 2007 Posts: 87
|
Posted: Sun Jul 29, 2007 11:59 pm Post subject: InitNew(); //cause Access Violation (0xc0000005) at ntdll. |
|
|
InitNew(); //cause Access Violation (0xc0000005) at ntdll.dll (0x7c98cc82) (by ddbg.exe)
here is the entire code:
Code: |
//use juno to Loading HTML content from a Stream
//c++ version http://msdn2.microsoft.com/en-us/library/Aa752047.aspx
//need help, IPersistStreamInit.Load( spStream ) always cause Access Violation
// http://bbs.yidabu.com/forum-10-1.html
//tlbimpd {EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B} /propput:put to get shdocvw
//tlbimpd mshtml.tlb to get mshtml
import dfl.application; //for application.doEvents();
import ydb.shdocvw;
import ydb.mshtml;
import std.utf : toUTF16;
import std.date: getUTCtime;
import juno.base.core : Handle;
import juno.com.client;
import juno.com.core;
pragma(lib,"juno.lib");
pragma(lib,"dfl_debug.lib"); //for doEvents()
pragma(lib,"ydb.lib"); //for shdocvw, mshtml
extern (Windows) wchar * lstrcpyW(wchar *, wchar *);
extern (Windows) wchar * lstrcpynW(wchar *, wchar *, int);
extern (Windows) char * lstrcpynA(char *, char *, int);
extern (Windows) char * lstrcpyA(char *, char *);
extern (Windows) void * GlobalAlloc(uint, uint);
extern (Windows) void * GlobalFree(void *);
//from win32.winbase
enum : uint {
GMEM_FIXED = 0,
GMEM_MOVEABLE = 2,
GMEM_ZEROINIT = 64,
GPTR = 66,
// Used only for GlobalRealloc
GMEM_MODIFY = 128
/+ // Obselete flags (Win16 only)
GMEM_NOCOMPACT=16;
GMEM_NODISCARD=32;
GMEM_DISCARDABLE=256;
GMEM_NOT_BANKED=4096;
GMEM_LOWER=4096;
GMEM_SHARE=8192;
GMEM_DDESHARE=8192;
GMEM_LOCKCOUNT=255;
+/
}
interface IPersistStreamInit : IPersist {
//from regist {7FD52380-4E07-101B-AE2D-08002B2EC713}
static GUID IID_IPersistStreamInit = {0x7FD52380,0x4E07,0x101B,0xAE,0x2D,0x08,0x00,0x2B,0x2E,0xC7,0x13};
int IsDirty();
int Load(IStream pStm);
int Save(IStream pStm, int fClearDirty);
int GetSizeMax(out ulong);
int InitNew();
}
int main() {
try
{
browser();
}
catch(Exception e)
{
printf("catch %.*s\n",e.msg);
}
return 0;
}
int browser(char[] url = "about:blank")
{
try
{
IWebBrowser2 ie = InternetExplorer.coCreate!(IWebBrowser2)(ExecutionContext.LocalServer);
scope(exit)
{
ie.Quit();
tryRelease(ie);
}
ie.put_Width(800);
ie.put_Height(600);
ie.put_Visible(VARIANT_TRUE);
wchar* BStrURL = toBStr(url);
VARIANT vars[4];
auto hrie = ie.Navigate(BStrURL, &vars[0], &vars[1], &vars[2], &vars[3]);
freeBStr(BStrURL);
tagREADYSTATE rs;
while (rs != tagREADYSTATE.READYSTATE_COMPLETE)
{
Application.doEvents();// wait to complete, from dfl.application
ie.get_ReadyState(rs);
}
long t = getUTCtime();
while(getUTCtime() - t < 1000)
{
Application.doEvents();
}
IDispatch doc;
hrie = ie.get_Document(doc);
assert(SUCCEEDED(hrie), "failed, get_Document");
IHTMLDocument2 hdoc;
hdoc = com_cast!(IHTMLDocument2) (doc);
assert(hdoc, "failed, IHTMLDocument2");
tryRelease(doc);
IPersistStreamInit ip = com_cast!(IPersistStreamInit)(hdoc);
assert(ip, "failed, IPersistStreamInit");
scope(exit) tryRelease(hdoc);
scope(exit) tryRelease(ip);
wchar[] s = "hello world\0"c.toUTF16() ;
Handle lpMem=cast(Handle) GlobalAlloc(GPTR, s.length);
scope(exit) GlobalFree(lpMem);
assert( (lpMem !is null), "failed GlobalAlloc " );
lstrcpyW(cast(wchar*)lpMem, s.ptr); //right?
IStream spStream;
if (CreateStreamOnHGlobal( lpMem, 1, spStream) == S_OK) {
printf("createStreamOnHGlobal ok \n");
hrie = ip.InitNew(); //cause Access Violation (0xc0000005) at ntdll.dll (0x7c98cc82) (by ddbg.exe)
hrie = ip.Load(spStream);
}
//show the page
t = getUTCtime();
while(getUTCtime() - t < 5000)
{
Application.doEvents();
}
}//try
catch(Exception e)
{
printf("catch %.*s\n",e.msg);
return 1;
}
return 0;
}
|
Last edited by yidabu on Wed Aug 01, 2007 3:56 pm; edited 1 time in total |
|
Back to top |
|
![](templates/subSilver/images/spacer.gif) |
John
Joined: 17 Jan 2006 Posts: 75
|
Posted: Mon Jul 30, 2007 3:20 am Post subject: |
|
|
com_cast won't work as expected unless the interface has a static field named IID that contains the interface's uuid (this is how all COM interfaces are declared in Juno). But you've called it IID_IPersistStreamInit, so com_cast is taking the base interface's IID instead (IPersist) and returing a reference to an IPersist - which doesn't have an InitNew method, so you get an access violation.
Declare it like this:
Code: | interface IPersistStreamInit : IPersist {
static GUID IID = { 0x7FD52380, 0x4E07, 0x101B, 0xAE, 0x2D, 0x08, 0x00, 0x2B, 0x2E, 0xC7, 0x13 };
int IsDirty();
int Load(IStream pStm);
int Save(IStream pStm, int fClearDirty);
int GetSizeMax(out ulong pCbSize);
int InitNew();
} |
Also, you're not allocating enough memory for your string.
Code: | wchar[] s = "hello world\0";
void* lpMem = GlobalAlloc(GPTR, s.length * wchar.sizeof);
scope(exit) GlobalFree(lpMem);
memcpy(lpMem, s.ptr, s.length * wchar.sizeof); |
Actually, you can avoid all this by using Phobos's MemoryStream and Juno's COMStream:
Code: | import std.stream;
auto ms = new MemoryStream;
ms.writeString("Hello, world");
ms.position = 0;
auto s = new COMStream(ms);
scope(exit) tryRelease(s);
ip.InitNew();
ip.Load(s); |
And there's no need to bother with the IHTMLDocument2 cast. IPersistStreamInit can be retrieved from the document's IDispatch instead. |
|
Back to top |
|
![](templates/subSilver/images/spacer.gif) |
yidabu
Joined: 21 Apr 2007 Posts: 87
|
Posted: Mon Jul 30, 2007 6:13 am Post subject: Loading HTML content from a Stream |
|
|
thanks a million! john.
It works fine!
Code: |
/+
Loading HTML content from a Stream
c++ version http://msdn2.microsoft.com/en-us/library/Aa752047.aspx
tlbimpd {EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B} /propput:put to get shdocvw.d
tlbimpd mshtml.tlb to get mshtml.d
by john, yidabu ( http://bbs.yidabu.com/forum-10-1.html )
+/
import dfl.application; //for Application.doEvents();
import shdocvw;
import mshtml;
import std.date: getUTCtime;
import std.stream : MemoryStream;
import juno.com.client;
import juno.com.core;
pragma(lib,"juno.lib");
pragma(lib,"dfl_debug.lib"); //for doEvents()
interface IPersistStreamInit : IPersist {
//from regist {7FD52380-4E07-101B-AE2D-08002B2EC713}
static GUID IID = {0x7FD52380,0x4E07,0x101B,0xAE,0x2D,0x08,0x00,0x2B,0x2E,0xC7,0x13};
int IsDirty();
int Load(IStream pStm);
int Save(IStream pStm, int fClearDirty);
int GetSizeMax(out ulong);
int InitNew();
}
int main() {
try
{
browser();
}
catch(Exception e)
{
printf("catch %.*s\n",e.msg);
}
return 0;
}
int browser(char[] url = "about:blank")
{
try
{
IWebBrowser2 ie = InternetExplorer.coCreate!(IWebBrowser2)(ExecutionContext.LocalServer);
scope(exit)
{
ie.Quit();
tryRelease(ie);
}
ie.put_Width(800);
ie.put_Height(600);
ie.put_Visible(VARIANT_TRUE);
wchar* BStrURL = toBStr(url);
VARIANT vars[4];
auto hrie = ie.Navigate(BStrURL, &vars[0], &vars[1], &vars[2], &vars[3]);
freeBStr(BStrURL);
tagREADYSTATE rs;
while (rs != tagREADYSTATE.READYSTATE_COMPLETE)
{
Application.doEvents();// wait! from dfl.application
ie.get_ReadyState(rs);
}
IDispatch doc;
hrie = ie.get_Document(doc);
assert(SUCCEEDED(hrie), "failed, get_Document");
scope(exit) tryRelease(doc);
IPersistStreamInit ip = com_cast!(IPersistStreamInit)(doc);
assert(ip, "failed, IPersistStreamInit");
scope(exit) tryRelease(ip);
auto ms = new MemoryStream;
ms.writeString("Hello, world!");
ms.position = 0;
auto s = new COMStream(ms);
scope(exit) tryRelease(s);
ip.InitNew();
ip.Load(s);
//for show the result
long t = getUTCtime();
while(getUTCtime() - t < 5000)
{
Application.doEvents();
}
}//try
catch(Exception e)
{
printf("catch %.*s\n",e.msg);
return 1;
}
return 0;
}
|
|
|
Back to top |
|
![](templates/subSilver/images/spacer.gif) |
yidabu
Joined: 21 Apr 2007 Posts: 87
|
Posted: Sun Sep 02, 2007 2:42 am Post subject: how to keep the file's original url |
|
|
after load content from stream, the file's url changed to about:blank
how to keep the file's original url ?
Update: I found the solution by google group search! |
|
Back to top |
|
![](templates/subSilver/images/spacer.gif) |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|