Browser-Control nur mit WinAPI



  • Liebe Freunde,

    könnte jemand ein funktionierendes Beispiel für ein Browser-Control durch die WinAPI geben? - Ich habe im ganzen Netz gesucht und nur MFC, ATL, ... ähnliches gefunden. Aber kein natives WinAPI-Programming.

    Und am besten noch, wie man Events wie OnProgressChange trappen kann?
    Welche Version von Windows ist den mindestens erforderlich?

    Lässt sich auch der Firefox ohne Installation so einbinden (ocx irgendwo erhältlich?)

    Ich danke euch für eure Hilfe!

    MfG
    Inno



  • Tja, dann machs doch mit MFC 😃



  • das hatte ich auch mal gebraucht... ich hoffe ich hab jetzt beim kopieren alles wichtige erwischt:

    #include <atlbase.h> 
    #include <mshtml.h> 
    #include <exdisp.h>
    
    [...]
    
    IWebBrowser2		*pWeb;
    
    pWeb = NULL;
    
    CoCreateInstance(CLSID_WebBrowser, NULL, CLSCTX_INPROC_SERVER, IID_IWebBrowser2, (LPVOID*) &pWeb); 
    AtlAxAttachControl(pWeb, m_WndView,(IUnknown**)&container);
    
    HWND m_WndView = CreateWindow ("STATIC", TEXT (""),
    	WS_CHILD | WS_VISIBLE | WS_BORDER,
    	0, 100, 500, 500,
    	hParent, (HMENU) 0, Instance, NULL) ;
    
    CComVariant url;
    
    url = "http://www.c-plusplus.net/";
    pWeb->Navigate2(&url, NULL, NULL, NULL, NULL);
    
    // Am ende
    delete(pWeb);
    

    Ich hoffe das hilft dir...



  • Den Code habe ich mir mal vor längerer Zeit zusammengetippt, es könnte manches falsch oder im schlechten Stil sein :D. SaveAs speichert den aktuellen Inhalt in einer Datei (z.B. *.html), Print druckt den Inhalt aus mit der Methode HTML kannst du HTML-Text festlegen, der im Browser angezeigt wird.

    Datei CWebBrowser.cpp:

    #include <windows.h>
    #include <atlbase.h>
    
    CComModule _Module;
    
    #include <atlcom.h>
    #include <atlhost.h>
    #include <mshtml.h>
    #include <mshtmcid.h>
    #include <commctrl.h>
    #include <string>
    #include <sstream>
    #include "CWebBrowser.h"
    
    using namespace std;
    
    CWebBrowser::CWebBrowser(void)
    {
    	m_hInstance = GetModuleHandle(0);
    	m_hwnd = 0;
    }
    
    CWebBrowser::~CWebBrowser(void)
    {
    	if(m_hwnd)
    		DestroyBrowser();
    }
    
    HWND CWebBrowser::CreateBrowser(HWND hwndParent, DWORD dwStyle)
    {
    	InitCommonControls();
    	_Module.Init(0, m_hInstance);
    	AtlAxWinInit();
    
    	m_hwnd = CreateWindowEx(0, "AtlAxWin",
    				"8856F961-340A-11D0-12F6A0",
    				WS_CHILD | dwStyle, 0, 0, 400, 400, hwndParent, 
    				0, m_hInstance, 0);
    	if(!m_hwnd)
    		return 0;
    
    	IWebBrowser2 *pWB;
    	OleInitialize(0);
    	if(CoCreateInstance(CLSID_InternetExplorer, NULL, CLSCTX_SERVER, IID_IWebBrowserApp, (LPVOID *)&pWB))
    	{
    		MessageBox(hwndParent,
    			"Der Internet Explorer scheint nicht installiert zu sein.",
    			"Fehler", MB_ICONERROR);
    		DestroyBrowser();
    		return false;
    	}
    	pWB->Release();
    
    	AtlAxGetControl(m_hwnd, &m_pUnknown);
    	m_pUnknown->QueryInterface(IID_IWebBrowser2, 
    				(void**)&m_pWebBrowser2);
    
    	return m_hwnd;
    }
    
    // see http://www.codeproject.com/miscctrl/simplebrowserformfc.asp?df=100&forumid=15103&exp=0&select=1529052
    bool CWebBrowser::Print(char *pszHeader, char *pszFooter)
    {
    	HRESULT hr;
    
    	// construct two element SAFEARRAY;
    	// first element is header string,
    	// second element is footer string
    
    	OLECHAR *pszOle;
    	int iStrLen;
    
    	VARIANT header_variant;
    	VariantInit(&header_variant);
    	header_variant.vt = VT_BSTR;
    
    	if(pszHeader)
    	{
    		iStrLen = lstrlen(pszHeader);
    		pszOle = (OLECHAR*)malloc(sizeof(OLECHAR) * (iStrLen + 1));
    		MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pszHeader, -1, pszOle, iStrLen);
    		pszOle[iStrLen] = 0;
    
    		header_variant.bstrVal = SysAllocString(pszOle);
    		free(pszOle);
    	}
    	else
    		header_variant.bstrVal = SysAllocString(L"");
    
    	VARIANT     footer_variant;
    	VariantInit(&footer_variant);
    	footer_variant.vt = VT_BSTR;
    
    	if(pszFooter)
    	{
    		iStrLen = lstrlen(pszFooter);
    		pszOle = (OLECHAR*)malloc(sizeof(OLECHAR) * (iStrLen + 1));
    		MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pszFooter, -1, pszOle, iStrLen);
    		pszOle[iStrLen] = 0;
    
    		footer_variant.bstrVal = SysAllocString(pszOle);
    		free(pszOle);
    	}
    	else
    		footer_variant.bstrVal = SysAllocString(L"");
    
    	long index;
    	SAFEARRAYBOUND  parameter_array_bound[1];
    	SAFEARRAY       *parameter_array = NULL;
    
    	parameter_array_bound[0].cElements = 2;
    	parameter_array_bound[0].lLbound   = 0;
    
    	parameter_array = SafeArrayCreate(VT_VARIANT,1,
    									parameter_array_bound);
    
    	index = 0;
    	hr = SafeArrayPutElement(parameter_array, &index, &header_variant);
    
    	index = 1;
    	hr = SafeArrayPutElement(parameter_array, &index, &footer_variant);
    
    	VARIANT parameter;
    	VariantInit(&parameter);
    	parameter.vt = VT_ARRAY | VT_BYREF;
    	parameter.parray = parameter_array;
    
    	// start printing browser contents
    	hr = m_pWebBrowser2->ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_DODEFAULT, &parameter, 0);
    
    	// release SAFEARRAY. Aber nur wenn der Druckvorgang
    	// nicht erfolgreich war. Denn sonst löscht es der Browser selbst!
    	if(!SUCCEEDED(hr))
    	{
    		VariantClear(&header_variant);
    		VariantClear(&footer_variant);
    		if(parameter_array != NULL)
    		{
    			SafeArrayDestroy(parameter_array);
    		}
    		return false;
    	}
    	return true;
    }
    
    bool CWebBrowser::SaveAs(char *psz)
    {
    	IWebBrowser2 *webBrowser2 = 0;
    
    	VARIANT var;
    	OLECHAR	*pszOle;
    
    	int iStrLen = lstrlen(psz);
    	pszOle = (OLECHAR*)malloc(sizeof(OLECHAR) * (iStrLen + 1));
    	MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, psz, -1,
    			pszOle, iStrLen);
    	pszOle[iStrLen] = 0;
    
    	VariantInit(&var);
    	BSTR path = SysAllocString(pszOle);
    
    	var.bstrVal = path;
    	var.vt = VT_BSTR;
    
    	HRESULT hRes;
    	hRes = m_pWebBrowser2->ExecWB(OLECMDID_SAVEAS, OLECMDEXECOPT_DODEFAULT, &var, 0);
    
    	VariantClear(&var);
    	SysFreeString(path);
    	free(pszOle);
    
    	webBrowser2->Release();
    
    	return (hRes == S_OK);
    }
    
    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;
    }
    
    void CWebBrowser::Clear()
    {
    	HTML("");
    	content = "";
    }
    
    void CWebBrowser::NavigateTo(char *pszURL)
    {
    	OLECHAR szOleURL[MAX_PATH];
    	MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pszURL, -1,
    					szOleURL, MAX_PATH);
    
    	BSTR bstrURL = SysAllocString(szOleURL);
    
    	VariantInit(&m_var);
    	m_var.vt		= VT_BSTR;
    	m_var.bstrVal	= bstrURL;
    
    	m_pWebBrowser2->Navigate2(&m_var, 0, 0, 0, 0);
    
    	VariantClear(&m_var);
    	SysFreeString(bstrURL);
    }
    
    bool CWebBrowser::IsBusy(void)
    {
    	VARIANT_BOOL varBool;
    
    	m_pWebBrowser2->get_Busy(&varBool);
    
    	return (varBool == VARIANT_TRUE);
    }
    
    void CWebBrowser::GetCurrentURL(char *pszBuffer, int nMaxCount)
    {
    	BSTR bstrURL = SysAllocString(0);
    
    	m_pWebBrowser2->get_LocationURL(&bstrURL);
    
    	WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, bstrURL, -1, 
    						pszBuffer, nMaxCount, NULL, NULL);
    
    	SysFreeString(bstrURL);
    }
    
    bool CWebBrowser::IsBrowser(void)
    {
    	return (m_hwnd != 0);
    }
    
    void CWebBrowser::Move(int x, int y, int cx, int cy)
    {
    	MoveWindow(m_hwnd, x, y, cx, cy, true);
    }
    
    HWND CWebBrowser::GetHandle(void)
    {
    	return m_hwnd;
    }
    
    void CWebBrowser::Show(bool bShow)
    {
    	ShowWindow(m_hwnd, bShow);
    }
    
    void CWebBrowser::DestroyBrowser(void)
    {
    	if(m_pUnknown)
    		m_pUnknown->Release();
    	if(m_pWebBrowser2)
    		m_pWebBrowser2->Release();
    	DestroyWindow(m_hwnd);
    
    	OleUninitialize();
    	_Module.Term();
    	AtlAxWinTerm();
    
    	m_hwnd = 0;
    }
    

    Datei CWebBrowser.h:

    #ifndef _CWEBBROWSER_H_
    #define _CWEBBROWSER_H_
    
    #include <exdisp.h>
    #include <string>
    using namespace std;
    
    class CWebBrowser
    {
    public:
    	CWebBrowser(void);
    	~CWebBrowser(void);
    	HWND CreateBrowser(HWND, DWORD);
    	void DestroyBrowser(void);
    	void NavigateTo(char*);
    	bool IsBusy(void);
    	bool IsBrowser(void);
    	void GetCurrentURL(char*, int);
    	void Move(int, int, int, int);
    	HWND GetHandle(void);
    	void Show(bool);
    	bool HTML(const char*);
    	bool Print(char*, char*);
    	void Clear();
    	bool SaveAs(char*);
    	string content;
    
    private:
    	HINSTANCE			m_hInstance;
    	HWND				m_hwndParent;
    	HWND				m_hwnd;
    	IWebBrowser2		*m_pWebBrowser2;
    	VARIANTARG			m_var;
    	IUnknown			*m_pUnknown;
    };
    
    #endif
    


  • Wow, danke!

    Echt nett von euch!
    Schade, dass die MFC Library nicht vollständig und integriert OpenSource ist.

    🙂

    Ich danke euch vielmals!

    MfG
    Inno



  • War gerade auf der Suche nach einer solchen Klasse, insofern herzlichen Dank 🙂
    Eine Nachfrage:
    Läuft diese Klasse auch als unsichtbares Fenster?

    Falls nein, wie wäre das zu modifizieren?



  • Percy2000 schrieb:

    War gerade auf der Suche nach einer solchen Klasse, insofern herzlichen Dank 🙂
    Eine Nachfrage:
    Läuft diese Klasse auch als unsichtbares Fenster?

    Falls nein, wie wäre das zu modifizieren?

    Du musst ja bei CreateBrowser() sowieso den style übergeben. lass da einfach WS_VISIBLE weg. oder du rufst Show(false) auf. Oder Move(0, 0, 0, 0). ^^

    P.S.: möcht ihr direkt HTML-Code anzeigen, müsst ihr HTML() aufrufen. Aber: es wird der HTML-Code an den der schon da ist _angehängt_! Dies habe ich nur so gemacht weil es eine spezielle Situation so erforderte. Entweder ihr modifiziert das oder müsst, um alten HTML-Code zu überschreiben, Clear() aufrufen.



  • Nochmals, ganz 🙂 herzlichen Dank


Anmelden zum Antworten