Hello,
I have write this piece of code.
Quote
InterrogeFeuille PROC
;/////// feuille /////////////////////////////////////
Local ppvIHTMLElementCollection:DWORD,NombreElements,ppvIHTMLOptionElement,ppvIHTMLSelectElement
Local Uphrase[256]:WORD
Local phrase[256]:BYTE
;Local index:VARIANT
;Local nom:VARIANT
;Local ppvIDispatch:DWORD
Local OptText[256]:WORD
Local retour:DWORD
ZEROLOCALES retour
invoke VariantInit,addr index
invoke VariantInit,addr nom
;[in] VARIANT of type VT_I4 or VT_BSTR that specifies the object or
;collection to retrieve. If this parameter is an integer, it is the
;zero-based index of the object. If this parameter is a string, all
;objects with matching name or id properties are retrieved, and a
;collection is returned if more than one match is made.
mov nom.n1.n2.vt,VT_I4
mov nom.n1.n2.n3.lVal,0
mov index.n1.n2.vt,VT_I4
mov index.n1.n2.n3.lVal,0
;mov varCommand.n1.n2.vt,VT_BSTR
;mov varCommand.n1.n2.n3.bstrVal,FUNC(CreateBstr,SADR("notepad.exe"))
IHTMLDocument2 get_forms,addr ppvIHTMLElementCollection
.if eax != S_OK
jmp FindeInterrogeFeuille
.endif
IHTMLElementCollection get_length,addr NombreElements
.while(NombreElements)
;ACCESS VIOLATION HERE ???????????????????
IHTMLElementCollection item,nom,index,addr ppvIDispatch
.if ppvIDispatch != 0
IDispatch QueryInterface,addr IID_IHTMLOptionElement,addr ppvIHTMLOptionElement
IDispatch Release
mov ppvIDispatch,0
IHTMLOptionElement get_text,addr OptText
invoke WideCharToMultiByte,CP_ACP,NULL,addr OptText,\
-1,addr buffer,LENGTHOF buffer,NULL,NULL
invoke MessageBox,NULL,ADDR buffer,SADR("Trouvé IHTMLOptionElement"),MB_OK
lea edx,OptText
IHTMLOptionElement Release
mov ppvIHTMLOptionElement,0
.endif
inc nom.n1.n2.n3.lVal
inc index.n1.n2.n3.lVal
dec NombreElements
.endw
IHTMLElementCollection Release
mov retour,1
FindeInterrogeFeuille:
mov eax,retour
ret
Who can help ?
First, you can remove both VariantInit at the top because you are initializing both variants.
Now to enumerate all the items, query item count by calling IHTMLElementCollection::get_length method.
Set index.vt to VT_EMPTY
Set nom.vt to VT_I4
Enter a loop, where nom.lVal is set to 0 ... NombreElements-1.
Call IHTMLElementCollection::item in each iteration. Even if the 'item' method returns S_OK (S_OK=zero), the returned IDispatch* pointer can be set to NULL, you must check it. This applies to ALL mshtml methods, even for those returning BSTR.
Be sure the prototype (or your macro) IHTMLElementCollection::item passes both variants by value - 4 DWORD's on stack for each variant. The raw call should be similar to:
; push uses nasm syntax
push addr pDispatch
; push the index variant - VT_EMPTY
push dword [index+0] ; or push 0 ; .vt and .wReserved1
push dword [index+4] ; or push 0 ; .wReserved2 and .wReserved3
push dword [index+8] ; or push 0
push dword [index+12] ; or push 0
; push the name variant - VT_I4
push dword [nom+0] ; or push 3 ; VT_I4=3
push dword [nom+4] ; or push 0
push dword [nom+8] ; or push index_of_element
push dword [nom+12] ; or push 0
; push this
mov eax, ppvIHTMLElementCollection
push eax
; call IHTMLElementCollection::item
mov eax,[eax]
call dword[eax+4*11]
test eax,eax ; check HRESULT
jz failure
cmp pDispatch,0 ; important: check pDispatch
jz failure
Hello,
I found what is it.
It's a joke of microsoft with IE8.
Quote
Internet Explorer 8 and later. In IE8 mode, the index parameter is not used. For more information, see Defining Document Compatibility.
This mean that the prototype IHTMLElementCollection item must be modify as this
Quote
;proto for IE8
PROTO :DWORD ,:VARIANT ,:DWORD
;normal proto
PROTO :DWORD ,:VARIANT,:VARIANT ,:DWORD
But now i have another problem.
Quote
IDispatch QueryInterface,addr IID_IHTMLOptionElement,addr ppvIHTMLOptionElement
Put 0 in ppvIHTMLOptionElement
??????????