FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Loading HTML content from stream

 
Post new topic   Reply to topic     Forum Index -> Juno
View previous topic :: View next topic  
Author Message
yidabu



Joined: 21 Apr 2007
Posts: 87

PostPosted: Sun Jul 29, 2007 12:21 am    Post subject: Loading HTML content from stream Reply with quote

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
View user's profile Send private message
John



Joined: 17 Jan 2006
Posts: 75

PostPosted: Sun Jul 29, 2007 4:31 pm    Post subject: Reply with quote

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
View user's profile Send private message
yidabu



Joined: 21 Apr 2007
Posts: 87

PostPosted: Sun Jul 29, 2007 11:59 pm    Post subject: InitNew(); //cause Access Violation (0xc0000005) at ntdll. Reply with quote

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
View user's profile Send private message
John



Joined: 17 Jan 2006
Posts: 75

PostPosted: Mon Jul 30, 2007 3:20 am    Post subject: Reply with quote

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
View user's profile Send private message
yidabu



Joined: 21 Apr 2007
Posts: 87

PostPosted: Mon Jul 30, 2007 6:13 am    Post subject: Loading HTML content from a Stream Reply with quote

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
View user's profile Send private message
yidabu



Joined: 21 Apr 2007
Posts: 87

PostPosted: Sun Sep 02, 2007 2:42 am    Post subject: how to keep the file's original url Reply with quote

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
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic     Forum Index -> Juno All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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