Solved

Need help with IID_IHTMLElement

Posted on 2001-08-07
15
1,418 Views
Last Modified: 2007-11-27
I found this code in newsgroup. The author made comment in russian. Don't understand anything. But this code fails on:
pdisp->QueryInterface (IID_IHTMLElement, (LPVOID *) &pItem);

And i'm new to this but i relly want to know what it does.

Please help me.

Regards
Andreas
   








#include <windows.h>
#include <mshtml.h>
#include <exdisp.h>

int main (void)
{
    CLSID clsid;
    LPUNKNOWN punk;
    IWebBrowser2 *pWB;
    IHTMLDocument2 *pHTML;
    IHTMLElementCollection *pElement;
    IHTMLElement *pItem;
    LPDISPACH pdisp;
    DISPID dispid, dispidNamed = DISPID_PROPERTYPUT;
    DISPPARAMS dispparams;
    UINT uArgErr;
    VARIANTARG vArg;
    VARIANT_BOOL bBusy;
    VARIANT varName, varIndex, var;
    BSTR bstr;

    OleInitialize (NULL);
    CLSIDFromProgID (OLESTR("InternetExplorer.Application"), &clsid);
    CoCreateInstance (clsid, NULL, CLSCTX_SERVER, IID__IUnknown,
                      (LPVOID *) &punk);
    punk->QueryInterface (IID_IWebBrowser2, (LPVOID *) &pWB);
    punk->Release();
    pWB->put_Visible (TRUE);
    BSTR bstrVal = SysAllocString (L"C:\\TEMP\\DHTML.HTM");
    var.vt = VT_I4;
    var.lVal = 0;
    pWB->Navigate (bstrVal, &var, &var, &var, &var);
    SysFreeString (bstrVal);
    do
    {
        Sleep (500);
        pWB->get_Busy (&bBusy);
    }
    while (bBusy);
    pWB->get_Document (&pdisp);
    pWB->Release();
    pdisp->QueryInterface (IID_IHTMLDocument2, (LPVOID *) &pHTML);
    pdisp->Release();
    pHTML->get_all (&pElements);
    varName.vt = VT_BSTR;
    varName.bstrVal = SysAllocString (L"mytitle");
    varIndex.vt = VT_I4;
    varIndex.lVal = 0;
    pElements->item (varName, varIndex, &pdisp);
    SysFreeString (varName.bstrVal);
//fails here
    pdisp->QueryInterface (IID_IHTMLElement, (LPVOID *) &pItem);
    pdisp->Release();
    bstr = SysAllocString (L"Hello from C++!");
    pItem->put_innerText (bstr);
    SysFreeString (bstr);
    pItem->Release();
    OleUninitialize ();
}
0
Comment
Question by:andla
  • 8
  • 5
  • 2
15 Comments
 
LVL 30

Expert Comment

by:Axter
Comment Utility
You should do a test to see if pdisp is Null.
Example:
pElements->item (varName, varIndex, &pdisp);
if (pdisp == NULL)
{
//report error here, and back out
}
   SysFreeString (varName.bstrVal);
//fails here
   pdisp->QueryInterface (IID_IHTMLElement, (LPVOID *) &pItem);
0
 
LVL 30

Expert Comment

by:Axter
Comment Utility
Every time you do a QueryInterface(IDD_???,(LPVOID*) &pSomeVar),
you should check to see if the variable (pSomeVar) is NULL.
0
 
LVL 1

Author Comment

by:andla
Comment Utility
I'm sorry i took an unfiltered code. I have done some fixes and it should work now. I don't se any variables that is NULL after a function call. Please test this code and help me find the error.



#include <windows.h>
#include <mshtml.h>
#include <exdisp.h>

int main (void)
{
   CLSID clsid;
   LPUNKNOWN punk=NULL;
   IWebBrowser2 *pWB;
   IHTMLDocument2 *pHTML;
   IHTMLElementCollection *pElement;
   IHTMLElement *pItem;
   IDispatch *pdisp;
   DISPID dispid, dispidNamed = DISPID_PROPERTYPUT;
   DISPPARAMS dispparams;
   UINT uArgErr;
   VARIANTARG vArg;
   VARIANT_BOOL bBusy;
   VARIANT varName, varIndex, var;
   BSTR bstr;

   OleInitialize (NULL);
   CLSIDFromProgID (OLESTR("InternetExplorer.Application"), &clsid);
   CoCreateInstance (clsid, NULL, CLSCTX_SERVER, IID_IUnknown,
                     (LPVOID *) &punk);
   punk->QueryInterface (IID_IWebBrowser2, (LPVOID *) &pWB);
   punk->Release();
   pWB->put_Visible (TRUE);
   BSTR bstrVal = SysAllocString (L"C:\\TEMP\\DHTML.HTM");
   var.vt = VT_I4;
   var.lVal = 0;
   pWB->Navigate (bstrVal, &var, &var, &var, &var);
   SysFreeString (bstrVal);
   do
   {
       Sleep (500);
       pWB->get_Busy (&bBusy);
   }
   while (bBusy);
   pWB->get_Document (&pdisp);
   if (pdisp == NULL)
{
return 0;
}

   pWB->Release();
   pdisp->QueryInterface (IID_IHTMLDocument2, (LPVOID *) &pHTML);
   pdisp->Release();
   pHTML->get_all (&pElement);
   varName.vt = VT_BSTR;
   varName.bstrVal = SysAllocString (L"mytitle");
   varIndex.vt = VT_I4;
   varIndex.lVal = 0;
   pElement->item (varName, varIndex, &pdisp);
   SysFreeString (varName.bstrVal);
//fails here
   pdisp->QueryInterface (IID_IHTMLElement, (LPVOID *) &pItem);
   pdisp->Release();
   bstr = SysAllocString (L"Hello from C++!");
   pItem->put_innerText (bstr);
   SysFreeString (bstr);
   pItem->Release();
   OleUninitialize ();
}



Cheers
Andla
0
 
LVL 1

Author Comment

by:andla
Comment Utility
I run the debugger but i will put up the null checker routines laiter. To bad there are not much source code on this. :-(

/Andla
0
 
LVL 1

Expert Comment

by:RideOn
Comment Utility
seems to be interesting code...
let's see
before the exception occurs, the pdisp is NULL
0
 
LVL 1

Expert Comment

by:RideOn
Comment Utility
pdisp is NULL after this Line:

  pElement->item (varName, varIndex, &pdisp);

so, somthing has to be wrong here
0
 
LVL 1

Author Comment

by:andla
Comment Utility
I think the mytitle is missing but i don't know how to make a reverse enginering on this. ?


 varName.vt = VT_BSTR;
  varName.bstrVal = SysAllocString (L"mytitle");
  varIndex.vt = VT_I4;
  varIndex.lVal = 0;


/Andla
0
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 30

Expert Comment

by:Axter
Comment Utility
Exactly what are you trying to do with this code?
I might be able to help you get to the end result if I know what you want out of it.
0
 
LVL 30

Expert Comment

by:Axter
Comment Utility
#include <windows.h>
#include <mshtml.h>
#include <exdisp.h>

#pragma warning(disable:4786)
#include <vector>
#include <string>

int function1 (void)
{
     CLSID clsid;
     LPUNKNOWN punk=NULL;
     IWebBrowser2 *pWB = NULL;
     IHTMLDocument2 *pHTML = NULL;
     IHTMLElementCollection *pElement = NULL;
     IDispatch *pdisp = NULL;
     DISPID  dispidNamed = DISPID_PROPERTYPUT;
     VARIANT_BOOL bBusy;
     VARIANT varName, varIndex, var;
     BSTR bstr;

     OleInitialize (NULL);
     CLSIDFromProgID (OLESTR("InternetExplorer.Application"), &clsid);
     CoCreateInstance (clsid, NULL, CLSCTX_SERVER, IID_IUnknown, (LPVOID *) &punk);
     punk->QueryInterface (IID_IWebBrowser2, (LPVOID *) &pWB);
     punk->Release();
     pWB->put_Visible (TRUE);
     BSTR bstrVal = SysAllocString (L"www.axter.com");
     var.vt = VT_I4;
     var.lVal = 0;
     pWB->Navigate (bstrVal, &var, &var, &var, &var);
     SysFreeString (bstrVal);
     do
     {
       Sleep (500);
       pWB->get_Busy (&bBusy);
     }
     while (bBusy);
     pWB->get_Document (&pdisp);
     if (pdisp == NULL)
     {//Report error here
          return 0;
     }

     pWB->Release();
     pdisp->QueryInterface (IID_IHTMLDocument2, (LPVOID *) &pHTML);
     pdisp->Release();
     pHTML->get_all (&pElement);
     long NumItems = 0;
     pElement->get_length(&NumItems);
     if (!NumItems)
     {//Report error here
          return 0;
     }
     std::vector<std::string> ListOfTagNames;
     std::vector<std::string> ListOfInnerHTML;
     std::vector<std::string> ListOfOuterHTML;
     for (int item_number_index = 0;item_number_index < NumItems;item_number_index++)
     {
          varName.vt = VT_I4;
          //varName.bstrVal = SysAllocString (L"A Valid Name");//Only use this if you know the name of the object
          varName.lVal = item_number_index;//Get item via index number (zero based number)
          varIndex.vt = VT_I4;
          varIndex.lVal = 1;
          IDispatch *pdisp2 = NULL;
          if (pElement->item (varName, varIndex, &pdisp2) != S_OK)
          {//Report error here
               return 0;
          }
          if (pdisp2 == NULL)
          {//Report error here
               return 0;
          }
          //SysFreeString (varName.bstrVal);//Only use this if used above
          IHTMLElement *pItem = NULL;
          pdisp2->QueryInterface (IID_IHTMLElement, (LPVOID *) &pItem);
          pdisp2->Release();
          if (pItem == NULL)
          {//Report error here
               return 0;
          }
          CString TempVariable;
     

          pItem->get_tagName(&bstr);
          TempVariable = bstr;
          std::string szTagName = (LPCTSTR)TempVariable;
          ListOfTagNames.push_back(szTagName);

          pItem->get_innerHTML(&bstr);
          TempVariable = bstr;
          std::string szInnerHTML = (LPCTSTR)TempVariable;
          ListOfInnerHTML.push_back(szInnerHTML);

          pItem->get_outerHTML(&bstr);
          TempVariable = bstr;
          std::string szOuterHTML = (LPCTSTR)TempVariable;
          ListOfOuterHTML.push_back(szOuterHTML);

          bstr = SysAllocString (L"Hello from C++!");
          pItem->put_innerText (bstr);
          SysFreeString (bstr);
          pItem->Release();
     }
     OleUninitialize ();
     return 1;
}

0
 
LVL 30

Accepted Solution

by:
Axter earned 50 total points
Comment Utility
The above posted code is a working example of the code you posted.

I modified a few items.
I deleted all the unused variables.
I modified the following line:
BSTR bstrVal = SysAllocString (L"www.axter.com");
I made it point to an actual web page.  Previously it was pointing to a local file on your hard drive.  If this file did not exist, the rest of the code does not work.

I commented out the following line:
varName.bstrVal = SysAllocString (L"mytitle");

You can only use that line if you know the name of the tag element that you're trying to get.
I added the following line:
varName.vt = VT_I4;
varName.lVal = item_number_index;

By changing the varName to a number, you can make the query get the element by number instead of by name.
If you don't know the tag name, then you should query for the element via index number.  The number is a zero based number.

I added a loop to the code so that it pulls all the elements on the given page, and adds the elements properties to the following variables:
std::vector<std::string> ListOfTagNames;
std::vector<std::string> ListOfInnerHTML;
std::vector<std::string> ListOfOuterHTML;

After exiting the loop, the above variables should contain all the properties of all the elements that were found in the select web page.

By the way, I beleave the following code only works if you're view a local page on your hard drive.
Since the code I posted is not viewing a local page, the code will not be able to modify it.
bstr = SysAllocString (L"Hello from C++!");
pItem->put_innerText (bstr);
SysFreeString (bstr);


I beleave the function of the code is to modify the text inside a specfic tag.
So if you tried to retrieve the following "TITLE" tag:
"<TITLE>Axter Inc. ***Quality Software***</TITLE>"

The code should change it to the following:
"<TITLE>Hello from C++!</TITLE>"

That is, it should change it if it were pointing to a page that it could modify. (Local Hard drive file)
0
 
LVL 30

Expert Comment

by:Axter
Comment Utility
To get additional information on any IDD_??? item, just remove the IDD_ and put the rest of the text in the VC help index box.  It should list information on the item.

Example:
pdisp->QueryInterface (IID_IHTMLDocument2, (LPVOID *) &pHTML);
The above code uses IID_IHTMLDocument2.
If you want to get information on what the QueryInterface() function will return using IID_IHTMLDocument2, you can look in the VC++ help index for "IHTMLDocument2".
It'll list all the methods available for the object.

You can also get more information on the object by search the VC++ include file directory for the IDD_????

To do that, you can use the following method.

1.  Click EDIT on the main menu of Visual C++ IDE
2.  Select "FIND-IN-FILES"
3.  In the "Find What" field, enter "IID_IHTMLDocument2" (with out the quotes)
4.  Change the "In Folder" field to point to the VC++ directory.
Example: "C:\Program Files\Microsoft Visual Studio\VC98"
5.  Select the "Look In Subfolders" field so that it is set.
6.  Make sure the "In Files/File Types" field is set to the following:
 "*.c;*.cpp;*.cxx;*.tli;*.h;*.tlh;*.inl;*.rc"
7.  Click the find button.

That should list all the VC++ source code for the object.  Which will give you some insigt as to how it works.

Good luck, and let me know if you have any questions.
0
 
LVL 1

Author Comment

by:andla
Comment Utility
Hi!

I have tested your new code.
Let se if i got this right.

pElement->get_length(&NumItems);

This is the number of tags found in the webpage.
If this is the case then i don't know how it is count.
If i count my self i get more than seven.
I could figure out this myself but appreciate your help.

Nice homepage :-)
I saw that you used AolPress to create it. I like this editor to bad they don't do any upgrades.

Thanks for your help.

Cheers
Andla.
0
 
LVL 30

Expert Comment

by:Axter
Comment Utility
>>I saw that you used AolPress to create it. I like this
>>editor to bad they don't do any upgrades.
Yes, I like it too.  I try using other editors, but I always end up going back to AolPress.

>>This is the number of tags found in the webpage.
That's right.

>>If i count my self i get more than seven.
It's counting the tags in the FRAME page.  Did you view the frame page?

The frame page only has seven.
I'll try posting the seven tags on my next comment, but I don't know if it'll show up, because EE some times has problems displaying tags in the comment block.
0
 
LVL 30

Expert Comment

by:Axter
Comment Utility
I'm wrong, and you're right.  It does have more then seven tags.

HTML
HEAD
TITLE
!--
FRAMESET COLS
FRAME SRC=
FRAME SRC=

NOFRAMES
BODY
P

The last three tags were not counted (NOFRAMES, BODY, P).

I believe the last three tags were not counted because they're only used for a No-Frame browser.
0
 
LVL 1

Author Comment

by:andla
Comment Utility
Ok Axter you have been very helpful.

BTW about the Aolpress i discovered that if you copy an image on the screen 'Ctrl+C' and paste it in AolPress 'Ctrl+V' it will automatically paste the bitmap image in AolPress and convert it to jpeg and you don't even have to name them. If you create a tutorial with screen shots you can do this in notime. I use irfanview to take screen shots every second and save it to a folder.

Cheers
Andla
0

Featured Post

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now