AutoHotkey Community

It is currently May 25th, 2012, 7:27 am

All times are UTC [ DST ]




Post new topic This topic is locked, you cannot edit posts or make further replies.  [ 156 posts ]  Go to page Previous  1 ... 3, 4, 5, 6, 7, 8, 9 ... 11  Next
Author Message
 Post subject:
PostPosted: June 1st, 2007, 7:15 am 
Offline

Joined: December 4th, 2006, 10:35 am
Posts: 561
Location: Galil, Israel
Quote:
I'm curious why you became interested in variant.
IMHO, it's useless, and no real need of the dedicated functions although VariantClear can be handy sometimes.


if am understanding things correctly...

1. The code earlier in this thread that was 'problematic' is sending info in a TYPICAL COM way... via the variant...

the perlscript simply constructed the varient... and that's why it works!

BUT**.... here is where my brain is smooshed... how do we CREATE the variant ?????

2. Data is passed TO Com objects very must via the variants... *MANY* com controls (excel, word. etc. etc. etc, even browser), are via variant...

3. Your very cool CGID_MSHTML function... is ... well.... incompleted without the final two elements... the sending & receive back Variants...


you're ability to grasp and understand the philosphy & workings of the MS design... is ... well... amazing...



am not seeing the complete Variant pic...


Code:
   pItm := SysAllocString(sItm)
   VarSetCapacity(var2, 8 * 2, 0)
   EncodeInteger(&var2 + 0, 8)
   EncodeInteger(&var2 + 8, pItm)


as a substitute for variant use ??


Code:
AllocBString(ByRef Key, ByRef Var, sString) {
   Ansi2Unicode(sString, wString)
   Key := DllCall("oleaut32\SysAllocString", Str,wString)
   VarSetCapacity(Var, 16, 0)
   DllCall("ntdll\RtlFillMemoryUlong", UInt,&Var,  UInt,4, UInt,8)
   DllCall("ntdll\RtlFillMemoryUlong", UInt,&Var+8,UInt,4, UInt,Key)
}


as the same thing ??

Code:
SysAllocString(sValue)
VariantInitiate(ByRef var, pValue)


seems correct as a start... but not used anywhere! ?

also... once variant is initiated... is it readily useable ??


and does the function end up something like this ??:

Code:
CGID_MSHTML_S(pwb, nCmd, nOpt = 0, sVal = "0") ; added sVal
{
   GUID4String(CGID_MSHTML          , "{DE4BA900-59CA-11CF-9592-444553540000}")
   GUID4String(IID_IOleCommandTarget, "{B722BCCB-4E68-101B-A2BC-00AA00404770}")
   pct := QueryInterface(pwb, IID_IOleCommandTarget)
   if SVal {
   psVal := SysAllocString(sVal)
   DllCall("VariantInit", "UINT", pSVal,"UINT",8)
   ;VarSetCapacity(bstr1, 8 * 2, 0)
   ;EncodeInteger(&SVal, 0x08,2)
}
   DllCall(VTable(pct, 4), "Uint", pct, "str", CGID_MSHTML, "Uint", nCmd, "Uint", nOpt, "UINT", pSVal, "UINT", 0) ; end was UINT, 0
   Release(pct)
   if SVal
   SysFreeString(psVal)
   return   ; RetVal
}


or is it missing a converstion from unicode (?)...

_________________
Joyce Jamce


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 1st, 2007, 8:11 am 
Offline

Joined: February 12th, 2007, 7:54 am
Posts: 2462
Joy2DWorld wrote:
the perlscript simply constructed the varient... and that's why it works!

No, I don't think so.
First, when I used variant instead (:after CoTaskMemAlloc, i.e., sort of Global Alloc), it output access violation. It means that the function regarded the first part of the variant as memory address. How do I know? Variant type parameter has a value of range 0 ~ 0xffff, which is equal to the so called "Null-Pointer Assignment Partition" by "Jeffrey Richter" in his famous book "Programming Applications for Microsoft Windows, 4th edition", i.e., off-limit. So, an accessible memory address should be given here.
Second, at first I assumed so, but there was no evidence that Perl does any sort of Global Alloc with the variant, which is absolutely necessary here if trying to use a variant, at least as far as I can tell.

Quote:
Code:
   pItm := SysAllocString(sItm)
   VarSetCapacity(var2, 8 * 2, 0)
   EncodeInteger(&var2 + 0, 8)
   EncodeInteger(&var2 + 8, pItm)

as a substitute for variant use ??

It's a variant, not a mere substitute. It's only created without ever using the dedicated functions for a variant.

Quote:
Code:
AllocBString(ByRef Key, ByRef Var, sString) {
   Ansi2Unicode(sString, wString)
   Key := DllCall("oleaut32\SysAllocString", Str,wString)
   VarSetCapacity(Var, 16, 0)
   DllCall("ntdll\RtlFillMemoryUlong", UInt,&Var,  UInt,4, UInt,8)
   DllCall("ntdll\RtlFillMemoryUlong", UInt,&Var+8,UInt,4, UInt,Key)
}

as the same thing ??

Sure.

Quote:
Code:
SysAllocString(sValue)
VariantInitiate(ByRef var, pValue)

seems correct as a start... but not used anywhere! ?
also... once variant is initiated... is it readily useable ??

If you used VariantInitiate, you have to specify the type-parameter again with the correct one.


Quote:
and does the function end up something like this ??:

The last two (variant) parameters are optional.
There is already one example in IEControl.ahk where the parameters really needed:

Code:
IE_DoFontSize(pwb, s)
{
   VarSetCapacity(var, 8 * 2, 0)
   EncodeInteger(&var + 0, 3)
   EncodeInteger(&var + 8, s)
   DllCall(VTable(pwb, 54), "Uint", pwb, "Uint", 19, "Uint", 2, "Uint", &var, "Uint", &var)
}

This function is essentially the same with CGID_MSHTML.
The first one is IN, the second one is OUT (variant) parameters, i.e., different ones, but I just used the same one for both, i.e., recycled it.


Last edited by Sean on June 1st, 2007, 8:26 am, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 1st, 2007, 8:24 am 
Offline

Joined: December 4th, 2006, 10:35 am
Posts: 561
Location: Galil, Israel
@Sean

thanks for the enlightenment...


ok, some 'stupid questions'...

how come in once case we need a " Ansi2Unicode(sString, wString) " which seems right,

but in other case, not needed "pItm := SysAllocString(sItm)
VarSetCapacity(var2, 8 * 2, 0) " that seems different ? where did I miss the thing I missed ?....

just curios.. if only a structure is needed... how come MS warns over and over... about making sure first to call variant Init... ?

and all a basic "Variant" is... is a Three byte pointer (?) with the first byte a 'type' ?

_________________
Joyce Jamce


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 1st, 2007, 8:34 am 
Offline

Joined: February 12th, 2007, 7:54 am
Posts: 2462
Joy2DWorld wrote:
how come in once case we need a " Ansi2Unicode(sString, wString) " which seems right,

but in other case, not needed "pItm := SysAllocString(sItm)
VarSetCapacity(var2, 8 * 2, 0) " that seems different ? where did I miss the thing I missed ?....

The wrapper SysAllocString() really consists of two parts:
Ansi2Unicode() -> SysAllocString API

Quote:
just curios.. if only a structure is needed... how come MS warns over and over... about making sure first to call variant Init... ?

I take it as a warning to the VB programmers.

Quote:
and all a basic "Variant" is... is a Three byte pointer (?) with the first byte a 'type' ?

It's a 16byte struct, aligned on 8byte.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 1st, 2007, 10:54 am 
Offline

Joined: February 12th, 2007, 7:54 am
Posts: 2462
I forgot to tell about my opinion on why BookCat works on Perl, but not with this ComCall via DllCall, if you are interested in it.
It's mere guess, but I suspect the COM implementation of BookCat was tested only with IDispatch type invoke, i.e., VBS like method.
It involves some indirections, so sufficiently slow down the whole process.
As this can be mimicked with this VTable method too, may test it if curious enough.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 2nd, 2007, 11:51 am 
Offline
User avatar

Joined: August 11th, 2004, 1:47 am
Posts: 5346
Location: UK
How can I get the id of a named reference, there is no __uuidof operator?

_________________
GitHubScriptsIronAHK Contact by email not private message.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 2nd, 2007, 12:54 pm 
Offline

Joined: February 12th, 2007, 7:54 am
Posts: 2462
Titan wrote:
How can I get the id of a named reference, there is no __uuidof operator?

I think you meant this:
http://msdn2.microsoft.com/en-us/library/ms221306.aspx


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 2nd, 2007, 1:15 pm 
Offline
User avatar

Joined: August 11th, 2004, 1:47 am
Posts: 5346
Location: UK
I tried the following but I get function not found error:

Code:
VarSetCapacity(dispid, 8, 0)
hres := DllCall("GetIDsOfNames", "UInt", 0, "UInt", &member, "UInt", 1, "UInt", 2048, "UInt", &dispid)
MsgBox, %hres%`n%ErrorLevel%

_________________
GitHubScriptsIronAHK Contact by email not private message.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 2nd, 2007, 1:30 pm 
Offline

Joined: February 12th, 2007, 7:54 am
Posts: 2462
Try this, e.g., in WebControl:

Code:
MsgBox, % GetIDsOfNames(pwb, "Visible")

GetIDsOfNames(pdisp, sName, LCID = 0)
{
   Ansi2Unicode(sName, wName)
   GUID4String(IID_NULL, "{00000000-0000-0000-0000-000000000000}")
   DllCall(VTable(pdisp,5), "Uint", pdisp, "str", IID_NULL, "UintP", &wName, "Uint", 1, "Uint", LCID, "UintP", dispID)
   Return dispID
}


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 3rd, 2007, 2:58 am 
Offline

Joined: December 4th, 2006, 10:35 am
Posts: 561
Location: Galil, Israel
@Sean,

thanks for the very lucid insight.




mod to code (w/ example):

Code:
IE_BColor(color = "Red") {
   return CGID_MSHTML(pwb, 51,0, color )
}



CGID_MSHTML(pwb, nCmd, nOpt = 0, sVal = ":~Null~:", sValT = 8)  {  ; added sVal
   GUID4String(CGID_MSHTML          , "{DE4BA900-59CA-11CF-9592-444553540000}")
   GUID4String(IID_IOleCommandTarget, "{B722BCCB-4E68-101B-A2BC-00AA00404770}")
   pct := QueryInterface(pwb, IID_IOleCommandTarget)
   if (sVal = ":~Null~:")
   Var := DllCall(VTable(pct, 4), "Uint", pct, "str", CGID_MSHTML, "Uint", nCmd, "Uint", nOpt, "UINT", 0 , "UINT", 0)
   else {
   VarSetCapacity(var, 8 * 2)          ; VariantInit(sVal, sValT)
   psVal := SysAllocString(sVal)       ; converts to unicode & allocates
   EncodeInteger(&var + 0, sValT)     ;     Variant Type
   EncodeInteger(&var + 8, psVal)    ;
   DllCall(VTable(pct, 4), "Uint", pct, "str", CGID_MSHTML, "Uint", nCmd, "Uint", nOpt, "UINT", &Var, "UINT", &Var)
   SysFreeString(psVal)

}
  Release(pct)
   return Var
}





btw, the IE_LoadURL() seems to accept only 512 bytes max...

likely a MS limitation (?)



tried to understand this:


Code:
Loading HTML content from a Stream
The IPersistStreamInit interface, and its associated methods, can be used to load HTML content from a stream using the WebBrowser control and Microsoft Visual C++.

This article discusses the steps required to load HTML content from a stream and is divided into the following sections.


Navigating to about:blank
The IWebBrowser2::Navigate2 method of the IWebBrowser2 interface enables you to navigate the browser to a URL. In the following sample code, the IWebBrowser2::Navigate2 method is used to navigate to the about:blank page. Navigating to this empty page ensures that MSHTML is loaded and that the HTML elements are available through the Dynamic HTML (DHTML) Object Model.

This example demonstrates how to navigate the WebBrowser control to an empty page. The variable m_pBrowser contains the IWebBrowser2 interface pointer obtained from the WebBrowser control.


m_pBrowser->Navigate2( _T("about:blank"), NULL, NULL, NULL, NULL );
Availability of the DHTML Object Model
The DHTML Object Model is used to access and manipulate the contents of an HTML page and is not available until the page is loaded. Your application determines that a page is loaded by handling the DWebBrowserEvents2::DocumentComplete event of the WebBrowser control. This event may be fired once for each frame in the page, and once when the top frame of the document is loaded. You can determine if the DWebBrowserEvents2::DocumentComplete event is for the top frame by comparing the IDispatch interface pointer passed by this event with that of the WebBrowser control.

This sample handler code for the WebBrowser DWebBrowserEvents2::DocumentComplete event demonstrates how to determine if this event is for the top frame, which indicates that the HTML page has loaded. This sample also demonstrates how to create a stream from a block of memory—in this case a string that contains the HTML content to be displayed.



void myObject::DocumentComplete(LPDISPATCH pDisp, VARIANT* URL)
{
    HRESULT hr;
    IUnknown* pUnkBrowser = NULL;
    IUnknown* pUnkDisp = NULL;
    IStream* pStream = NULL;
    HGLOBAL hHTMLText;
    static TCHAR szHTMLText[] = "<html><h1>Stream Test</h1><p>This HTML content is/
       being loaded from a stream.</html>";

    // Is this the DocumentComplete event for the top frame window?
    // Check COM identity: compare IUnknown interface pointers.
    hr = m_pBrowser->QueryInterface( IID_IUnknown,  (void**)&pUnkBrowser );
    if ( SUCCEEDED(hr) )
    {
        hr = pDisp->QueryInterface( IID_IUnknown,  (void**)&pUnkDisp );
        if ( SUCCEEDED(hr) )
        {
            if ( pUnkBrowser == pUnkDisp )
            {   // This is the DocumentComplete event for the top
                //   frame - page is loaded!
                // Create a stream containing the HTML.
                // Alternatively, this stream may have been passed to us.
         
                size_t = cchLength;
                //  TODO: Safely determine the length of szHTMLText in TCHAR.
                hHTMLText = GlobalAlloc( GPTR, cchLength+1 );
            
                if ( hHTMLText )
                {
                    size_t cchMax = 256;
                    StringCchCopy((TCHAR*)hHTMLText, cchMax + 1, szHTMLText);
                    //  TODO: Add error handling code here.

                    hr = CreateStreamOnHGlobal( hHTMLText, TRUE, &pStream );
                    if ( SUCCEEDED(hr) )
                    {
                       // Call the helper function to load the browser from the stream.
                       LoadWebBrowserFromStream( m_pBrowser, pStream  );
                       pStream->Release();
                    }
                    GlobalFree( hHTMLText );
                }
            }
            pUnkDisp->Release();
        }
        pUnkBrowser->Release();
    }
}
Using QueryInterface to Obtain the IPersistStreamInit Interface
The IWebBrowser2::get_Document property on the WebBrowser control retrieves the document object that represents the DHTML Object Model for the top frame. MSHTML implements the IPersistStreamInit interface to provide the ability to load and save HTML using a stream, through the document object. The IDispatch interface for the document object can be queried for the IPersistStreamInit interface pointer using QueryInterface with an identifier of IID_IPersistStreamInit, as shown in the following code example.


HRESULT LoadWebBrowserFromStream(IWebBrowser* pWebBrowser, IStream* pStream)
{
HRESULT hr;
IDispatch* pHtmlDoc = NULL;
IPersistStreamInit* pPersistStreamInit = NULL;

    // Retrieve the document object.
    hr = pWebBrowser->get_Document( &pHtmlDoc );
    if ( SUCCEEDED(hr) )
    {
        // Query for IPersistStreamInit.
        hr = pHtmlDoc->QueryInterface( IID_IPersistStreamInit,  (void**)&pPersistStreamInit );
        if ( SUCCEEDED(hr) )
        {
            // Initialize the document.
            hr = pPersistStreamInit->InitNew();
            if ( SUCCEEDED(hr) )
            {
                // Load the contents of the stream.
                hr = pPersistStreamInit->Load( pStream );
            }
            pPersistStreamInit->Release();
        }
    }
}
Using the IPersistStreamInit Interface to Load HTML Content
The IPersistStreamInit interface has InitNew and Load methods that are used to initialize and load an HTML document from a stream. The InitNew method initializes the stream to a known state and the Load method loads the HTML content from the stream.

In the previous sample code, the HTML document is initialized and the HTML content is loaded from the stream.

Note  In Microsoft Internet Explorer 5, more than one call to the Load method of the IPersist interfaces is supported. In earlier versions, only one call to Load per instance of MSHTML is supported.


from: http://msdn2.microsoft.com/en-us/library/aa752047.aspx


but... am unclear about where/how this can be called...

_________________
Joyce Jamce


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 3rd, 2007, 4:24 am 
Offline

Joined: October 28th, 2006, 2:14 am
Posts: 297
Location: US
Still bored on the linux and I decided to try this system so uh...

Image

8)

_________________
Changed siggy at request of ahklerner :D


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 3rd, 2007, 9:57 am 
Offline

Joined: February 12th, 2007, 7:54 am
Posts: 2462
Joy2DWorld wrote:
tried to understand this:

You seem to try to access/manipulate DOM, so, you're in a whole new world. ;)

Navigate2 is nearly identical to IE_LoadURL() whose original name is indeed Navigate.
And, you can obtain the DOM interface using IE_Document().


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 3rd, 2007, 11:33 pm 
Offline

Joined: December 4th, 2006, 10:35 am
Posts: 561
Location: Galil, Israel
@Sean,


your insight is incredibly helpful.


seems being able to load html DIRECTLY FROM MEMORY, could be a neat and powerful trick in your browser function... so...



hopefully these q's are not too too low in level....


1. pPersistStreamInit->Load( pStream ) seems to be the key to loading the stream. How specifically do we determine the call for this ?

2. am not clear about exactly what pHtmlDoc->QueryInterface( IID_IPersistStreamInit, (void**)&pPersistStreamInit ) is actually giving us... the index to the call ??


3. pWebBrowser->get_Document( &pHtmlDoc ) is giving an instance #??


4. CreateStreamOnHGlobal( hHTMLText, TRUE, &pStream ) is the stream creation call... are there any 'tricks'/prereqs that are especially necessary to call this ?


5. an not really understanding the bigger picture behind how we find & call this function... m_pBrowser->Navigate2( _T("about:blank"), NULL, NULL, NULL, NULL ).






assumes if have understood the MS directives that
Code:
m_pBrowser->Navigate2( _T("about:blank"), NULL, NULL, NULL, NULL )
CreateStreamOnHGlobal( hHTMLText, TRUE, &pStream )
pWebBrowser->get_Document( &pHtmlDoc )
pHtmlDoc->QueryInterface( IID_IPersistStreamInit,  (void**)&pPersistStreamInit )
 pPersistStreamInit->Load( pStream )



is the basic structure for loading html from memory ?

_________________
Joyce Jamce


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 4th, 2007, 2:07 am 
Offline

Joined: February 12th, 2007, 7:54 am
Posts: 2462
Joy2DWorld wrote:
seems being able to load html DIRECTLY FROM MEMORY

There is already one: IE_LoadHTML().
There could be a length limit to it, but I don't know of the value.

Quote:
assumes if have understood the MS directives that
Code:
m_pBrowser->Navigate2( _T("about:blank"), NULL, NULL, NULL, NULL )
CreateStreamOnHGlobal( hHTMLText, TRUE, &pStream )
pWebBrowser->get_Document( &pHtmlDoc )
pHtmlDoc->QueryInterface( IID_IPersistStreamInit,  (void**)&pPersistStreamInit )
 pPersistStreamInit->Load( pStream )

Although I haven't tried it, it appears to be straightforward to do it.
So, you may implement it as an alternative to IE_LoadHTML().


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 6th, 2007, 2:29 am 
Offline

Joined: December 4th, 2006, 10:35 am
Posts: 561
Location: Galil, Israel
1. Confirmed design limitation of Iexplore. depending on version, Limit is 512 bytes to in ver. 7, 2048 bytes. (there is a thread on that somewhere here...)

so...

ABOUT: cannot be used as method for passing more than basic (very short) html.


2.
Quote:
it appears to be straightforward to do it.
So, you may implement it as an alternative to IE_LoadHTML().


Somehow my mind does not want to take in the MS structure details. attempts with this seemingly straightfoward code.. have *not* been successful. Unlike coding errors of logic, which can debug.. 'Conformity' to the MS structure/procedural order, etc. mind just is not seeming to want to absorb....


any help/guidance appreciated, streaming feed to the html from var seems like a valueable function... anyhow...

_________________
Joyce Jamce


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic This topic is locked, you cannot edit posts or make further replies.  [ 156 posts ]  Go to page Previous  1 ... 3, 4, 5, 6, 7, 8, 9 ... 11  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: Bing [Bot], nightson, S0und and 17 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group