none
Unable to cast COM object of type 'mshtml.HTMLDocumentClass' to class type 'System.Array' RRS feed

  • Question

  • Hey everyone...

    Let me first state that this issue has me completely frustrated - here's the deal...

    I have a program that uses the Microsoft HTML Object Library for HTML parsing (I'm trying to create a treeview representation of a webpage)...I use Visual Studio C++ 2008 Express, my project uses .NET 3.5, AND I've included the MSHTML library by doing the following:

    Clicking on Project -> Add Reference...
    Clicking on the COM tab
    Scrolling to "Microsoft HTML Object Library" and clicking OK.

    I've even included the following statement (although I don't need it):
    #include <mshtml.h>

    okay with that said, here's may problem, my code complies with no issue...however, at runtime, once I perform a function I get:

    An unhandled exception of type 'System.InvalidCastException' occurred in UNREAL Browser.exe

    Additional information: Unable to cast COM object of type 'mshtml.HTMLDocumentClass' to class type 'System.Array'. Instances of types that represent COM components cannot be cast to types that do not represent COM components; however they can be cast to interfaces as long as the underlying COM component supports QueryInterface calls for the IID of the interface.


    Here's the code (the line in bold is what's giving me problems):
    private: System::Void viewDOMToolStripMenuItem_Click(System::Object ^sender, System::EventArgs ^e){
    		UNREALDOMViewer ^domViewer = gcnew UNREALDOMViewer();
    		short itag;
    
    		//clear the treeview
    		domViewer->treeView1->Nodes->Clear();
    
    		//find the <html> tag
    		for (itag = 0; itag < safe_cast<Array^>((safe_cast<WebBrowser^>(tabControl1->SelectedTab->Controls[0]))->Document->DomDocument)->Length; itag++){
    			if (safe_cast<mshtml::IHTMLElement^>(safe_cast<mshtml::IHTMLElement^>((safe_cast<WebBrowser^>(tabControl1->SelectedTab->Controls[0]))->Document->DomDocument)->all)->tagName[itag] == 'HTML'){
    				break;
    			}
    		}
    
    		//if for some reason we never found an html tag, we stop parsing altogether
    		if (itag == safe_cast<Array^>((safe_cast<WebBrowser^>(tabControl1->SelectedTab->Controls[0]))->Document->DomDocument)->Length - 1){
    			return;
    		}
    
    		ParseAndDisplay(safe_cast<array<mshtml::IHTMLElement^,1>^>(safe_cast<mshtml::IHTMLElement^>((safe_cast<WebBrowser^>(tabControl1->SelectedTab->Controls[0]))->Document->DomDocument)->all)[itag]);
    	}
    
    	private: System::Void ParseAndDisplay(mshtml::IHTMLElement ^htmlObj){
    		UNREALDOMViewer ^domViewer = gcnew UNREALDOMViewer();
    		mshtml::IHTMLDOMNode2 ^nodeObj = nullptr;
    		mshtml::IHTMLElement ^childObj = nullptr;
    
    		//if there is no parentelement, add it as the root (html tag)
    		if (htmlObj->parentElement == nullptr){
    			nodeObj = safe_cast<mshtml::IHTMLDOMNode2^>(domViewer->treeView1->Nodes->Add("k" + htmlObj->sourceIndex, "<" + htmlObj->tagName + ">", 0));
    		}else{
    			nodeObj = safe_cast<mshtml::IHTMLDOMNode2^>(domViewer->treeView1->Nodes->Find("k" + htmlObj->parentElement->sourceIndex, true)[0]->Nodes->Add("k" + htmlObj->sourceIndex, "<" + htmlObj->tagName + ">", ((safe_cast<Array^>(htmlObj->children)->Length == 0) ? 3 : 2)));
    			if (safe_cast<Array^>(htmlObj->children)->Length == 0){
    				nodeObj = safe_cast<mshtml::IHTMLDOMNode2^>(domViewer->treeView1->Nodes->Find("k" + htmlObj->sourceIndex, true)[0]->Nodes->Add("k" + htmlObj->sourceIndex, htmlObj->innerText, 2));
    			}
    		}
    
    		if (safe_cast<Array^>(htmlObj->children)->Length == 0){
    			return; //no children, exit sub
    		}
    
    		//recursion loop
    		for (int index = 0; index < safe_cast<Array^>(htmlObj->children)->Length; ++index){
    			ParseAndDisplay(safe_cast<array<mshtml::IHTMLElement^,1>^>(htmlObj->children)[index]);
    		}
    
    		nodeObj = nullptr;
    		childObj = nullptr;
    	}



    Friday, January 29, 2010 2:42 PM

Answers

All replies

  • I don't quite understand what is the problem here. The error exactly explains to you that you cannot cast object of type mshtml.HTMLDocumentClass to System.Array.
    It is like trying to convert System.Int32 to System.Array, it just cannot be done.

    So what do I misunderstand?
    -Karel
    Friday, January 29, 2010 6:38 PM
    Moderator
  • any suggestions on how I can go about fixing it...

    While the error maybe self explanatory - a solution, atleast to me, is not as easy to find...
    Saturday, January 30, 2010 3:21 AM
  • I don't know what you want to achieve.
    If you want to convert a general COM object to System.Array, then it cannot be done.
    If the COM object is specific and functions as a collection of nodes or something like that, then you can iterate them and put the into a new array in a loop.

    If this doesn't help you with solution, pelase describe what exactly you want to achieve.

    -Karel
    Saturday, January 30, 2010 8:48 PM
    Moderator
  • well if that is the case, then my question is this...

    How do I loop through the IHTMLElements of a HTML DOM and find the <html> tag?
    Sunday, January 31, 2010 8:44 PM
  • That is question for mshtml.dll forum - try to use microsoft.public.inetsdk newsgroups.

    I guess (without ever trying this), you will need to use IHTMLElementCollection to iterate through HTML tags - see e.g. IHTMLDocument2::get_all. Here's an example: http://msdn.microsoft.com/en-us/library/aa703930(VS.85).aspx.

    -Karel
    Sunday, January 31, 2010 11:54 PM
    Moderator