IWebBrowser2::get_Document - HILFE!



  • Hallo,
    ich will in ein Browserfenster direkt HTML Code reinladen, was ich mit IHTMLDocument2::write() ja machen kann.
    Aber um ein IHTMLDocument2-Objekt zu kriegen muss ich das ja von meinem IWebBrowser2-Objekt mir holen. Das geht aber irgendwie nicht. Ich mach das so:

    LPDISPATCH lpDispatch;
    IHTMLDocument2	*htmlDoc2;
    
    // m_pWebBrowser2 ist ein funktionierendes IWebBrowser2-Objekt
    // das gibt S_OK zurück:
    m_pWebBrowser2->get_Document(&lpDispatch)
    // aber hier stürzt es ab:
    lpDispatch->QueryInterface(IID_IHTMLDocument2, (void**)&htmlDoc2)
    

    wie gesagt, ich erhalte keinen Fehler, sondern mein Programm stürzt ab.
    Wenn ich das im Debug-Modus laufen lass krieg ich diese Meldung:
    Unhandled exception in ole.exe: 0xC0000005: Access Violation.

    Aber wo ist hier eine Zugriffsverletzung? 😕

    Vielen Dank für Hilfe,
    Black Shadow



  • ok ich weiß nun dass get_Document zwar S_OK zurückliefert, aber lpDispatch ist danach weiterhin 0.
    😕
    Weiß einer Rat?

    Danke



  • Ist im WebBrowser denn ne Seite geladen? Zumindest \1:blank oder so?



  • geeky schrieb:

    Ist im WebBrowser denn ne Seite geladen? Zumindest \1:blank oder so?

    Danke für den Hinweis, daran könnte es gelegen haben, zumindest klappts jetzt :).
    Ich hab bei der OLE-Initialisierung auch was geändert, vielleicht war auch da der Fehler.

    MfG



  • Hallo

    Hat jemand Ahnung wie ich Kontrolle über eine bestehende IE Instanz erlangen kann um beispielsweise auf eine andere Seite zu navigieren?
    Habe bei MS ein altes Beispiel für den IE4 gefunden. Das klappt allerdings alles nicht mehr bei IE7.
    Wäre für Beispiele dankbar!



  • Du musst zuerst eine Seite "laden", bevor ein Document verfügbar ist!

    So geht es (this ist CHtmlView oder abgeleitet davon; geht natürlich auch *ohne* CHtmlView!):

    this->Navigate2(_T("\1:blank"),NULL,NULL); 
      IDispatch *pDisp = this->GetHtmlDocument();
      if (pDisp != NULL)
      {
        CComPtr<IHTMLDocument2> doc;
        pDisp->QueryInterface(IID_IHTMLDocument2, (void**) &doc);
    
        HRESULT hresult = S_OK;
          VARIANT *param;
          SAFEARRAY *sfArray;
          BSTR bstr = SysAllocString(OLESTR("Written by IHTMLDocument2::write()."));
    
          // Creates a new one-dimensional array
          sfArray = SafeArrayCreateVector(VT_VARIANT, 0, 1);
    
          if (sfArray == NULL || doc == NULL) {
          goto cleanup;
          }
    
        hresult = SafeArrayAccessData(sfArray,(LPVOID*) & param);
          param->vt = VT_BSTR;
          param->bstrVal = bstr;
          hresult = SafeArrayUnaccessData(sfArray);
          hresult = doc->write(sfArray);
    
      cleanup:
          SysFreeString(bstr);
          if (sfArray != NULL) {
              SafeArrayDestroy(sfArray);
          }
          pDisp->Release();
      }
    


  • Danke Jochen, so in der Art klappts bei mir jetzt auch :).
    Mein Code:

    bool CWebBrowser::HTML(const char *psz)
    {
    	LPDISPATCH		lpDispatch = 0;
    	IHTMLDocument2	*htmlDoc2 = 0;
    
    	if(m_pWebBrowser2->get_Document(&lpDispatch) != S_OK)
    	{
    		MessageBox(m_hwnd, "HTML Write: get_Document()", "Fehler", 0);
    		return false;
    	}
    	if(!lpDispatch)
    	{
    		MessageBox(m_hwnd, "HTML Write: get_Document() return value", "Fehler", 0);
    		return false;
    	}
    
    	if(lpDispatch->QueryInterface(IID_IHTMLDocument2, (void**)&htmlDoc2) != S_OK)
    	{
    		MessageBox(m_hwnd, "HTML Write: QueryInterface() Dispatch", "Fehler", 0);
    		htmlDoc2->Release();
    		return false;
    	}
    	if(!htmlDoc2)
    	{
    		MessageBox(m_hwnd, "HTML Write: QueryInterface() Dispatch return value", "Fehler", 0);
    		htmlDoc2->Release();
    		return false;
    	}
    
    	SAFEARRAY       *sfArray;
    	VARIANT         *pVar;
    	BSTR             bstr_html_txt;
    	OLECHAR			*pszOle;
    
    	bool bRet = true;
    
    	SAFEARRAYBOUND ArrayBound = {1, 0};
    
    	sfArray = SafeArrayCreate(VT_VARIANT, 1, &ArrayBound);
    	if(sfArray)
    	{
    		if(SafeArrayAccessData(sfArray, (void**)&pVar) == S_OK)
    		{
    			pVar->vt = VT_BSTR;
    
    			int iStrLen = lstrlen(psz);
    			pszOle = (OLECHAR*)malloc(sizeof(OLECHAR) * (iStrLen + 1));
    			MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, psz, -1,
    					pszOle, iStrLen);
    			pszOle[iStrLen] = 0;
    
    			bstr_html_txt = SysAllocString(pszOle);
    			pVar->bstrVal = bstr_html_txt;
    
    			if(pVar->bstrVal)
    			{
    				htmlDoc2->write(sfArray);
    				content.append(psz);
    			}
    			else
    			{
    				MessageBox(m_hwnd, "pVar Initialisierung", "Fehler", MB_ICONERROR);
    				bRet = false;
    			}
    		}
    		else
    		{
    			MessageBox(m_hwnd, "SafeArrayAccessData()", "Fehler", MB_ICONERROR);
    			bRet = false;
    		}
    	}
    	else
    	{
    		MessageBox(m_hwnd, "sfArray Create", "Fehler", MB_ICONERROR);
    		bRet = false;
    	}
    
    	SysFreeString(bstr_html_txt);
    	SafeArrayDestroyData(sfArray);
    	SafeArrayDestroy(sfArray);
    	htmlDoc2->Release();
    	lpDispatch->Release();
    	m_pWebBrowser2->Refresh();
    	free(pszOle);
    
    	return bRet;
    }
    

    was ich mich frage - ist das mit dem Release richtig? weil dein code released net so viel.
    Außerdem: Ist die Umwandlung in einen OleString, dann in einen SysString notwendig? gehts nicht von char* in einen SysString?

    Und warum liefert m_pWebBrowser2->get_Document S_OK zurück, auch wenn kein \1:blank dokument geladen ist und pDispatch 0 dann ist?

    @ender: kriegst du irgendwo ne fehlermeldung? gibt auch mal link

    MfG



  • Bzgl. OleStr: Man macht das halt bei statischen Texten so... ist aber historisch bedingt und Du könntest anstelle von OLESTR() auch L verwenden.
    Bzgl. Release: Ich habe teilweise auch CComPtr verwendet, der macht automatisch ein release...
    AFAIK muss man vorher irgendwas geladen haben, damit es funktioniert.


Log in to reply