⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 simplebrowser.cpp

📁 MiniCA V2.0版本源码。《小型CA系统V2.1含源码》发表以来
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/////////////////////////////////////////////////////////////////////////////
// SimpleBrowser.cpp: Web browser control
/////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "comdef.h"
#include "mshtml.h"
#include "mshtmcid.h"
#include "mshtmhst.h"
#include "exdispid.h"

#include "SimpleBrowser.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define Unused(parameter) parameter					// avoid compile warnings
													// about unused parameters

/////////////////////////////////////////////////////////////////////////////
// Construction and creation
/////////////////////////////////////////////////////////////////////////////

SimpleBrowser::SimpleBrowser()
	: _Browser(NULL),
	  _BrowserDispatch(NULL)
{
}

SimpleBrowser::~SimpleBrowser()
{
    // release browser interfaces

	if (_Browser != NULL) {
		_Browser->Release();
		_Browser = NULL;
	}

	if (_BrowserDispatch != NULL) {
		_BrowserDispatch->Release();
		_BrowserDispatch = NULL;
	}
}

// Standard create

BOOL SimpleBrowser::Create(DWORD dwStyle, 
                           const RECT& rect, 
                           CWnd* pParentWnd, 
						   UINT nID)
{
    BOOL results = TRUE;

    _Browser     = NULL;

    // create this window

    CWnd *window = this;
	results = window->Create(AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW),
	                         NULL,
							 dwStyle,
							 rect,
							 pParentWnd,
							 nID);
    if (!results) return FALSE;

    // create browser control window as child of this window; 
	// this window sinks events from control

	CRect browser_window_rect(0,0,(rect.right - rect.left),(rect.bottom - rect.top));

    results = _BrowserWindow.CreateControl(CLSID_WebBrowser,
                                           NULL,
                                           (WS_VISIBLE | WS_TABSTOP),
                                           browser_window_rect,
                                           this,
                                           AFX_IDW_PANE_FIRST);
    if (!results) {
        DestroyWindow();
        return FALSE;
    }

    // get control interfaces

    LPUNKNOWN unknown = _BrowserWindow.GetControlUnknown();

    HRESULT hr = unknown->QueryInterface(IID_IWebBrowser2,(void **)&_Browser);
    if (SUCCEEDED(hr)) {
        hr = unknown->QueryInterface(IID_IDispatch,(void **)&_BrowserDispatch);
    }

    if (!SUCCEEDED(hr)) {
        _BrowserWindow.DestroyWindow();
        DestroyWindow();
        return FALSE;        
    }

	// navigate to blank page; wait for document creation

	if (_Browser != NULL) {
	
		Navigate(_T("about:blank"));

		IHTMLDocument2 *document = NULL;
		HRESULT			hr       = S_OK;

		while ((document == NULL) && (hr == S_OK)) {

			Sleep(0);

			IDispatch *document_dispatch = NULL;

			hr = _Browser->get_Document(&document_dispatch);

			// if dispatch interface available, retrieve document interface
			
			if (SUCCEEDED(hr) && (document_dispatch != NULL)) {

				// retrieve document interface
				
				hr = document_dispatch->QueryInterface(IID_IHTMLDocument2,(void **)&document);

				document_dispatch->Release();

			}
			
		}
		
		if (document != NULL) {
			document->Release();	
		}

	}

    return TRUE;
}

// Create in place of dialog control

BOOL SimpleBrowser::CreateFromControl(CWnd *pParentWnd,UINT nID)
{
	BOOL result = FALSE;

	ASSERT(pParentWnd != NULL);

	CWnd *control = pParentWnd->GetDlgItem(nID);

	if (control != NULL) {

		// get control location

		CRect		rect;

		control->GetWindowRect(&rect);
		pParentWnd->ScreenToClient(&rect);

		// destroy control, since the browser will take its place

		control->DestroyWindow();

		// create browser

		result = Create((WS_CHILD | WS_VISIBLE),
		                rect,
						pParentWnd,
						nID);

	}

	return result;
}

// Destruction

void SimpleBrowser::PostNcDestroy()
{
    // release browser interfaces

	if (_Browser != NULL) {
		_Browser->Release();
		_Browser = NULL;
	}

	if (_BrowserDispatch != NULL) {
		_BrowserDispatch->Release();
		_BrowserDispatch = NULL;
	}
}

/////////////////////////////////////////////////////////////////////////////
// Controls
/////////////////////////////////////////////////////////////////////////////

// Navigate to URL

void SimpleBrowser::Navigate(LPCTSTR URL)
{
	if (_Browser != NULL) {

		CString		url(URL);

		_variant_t	flags(0L,VT_I4);
		_variant_t	target_frame_name("");
		_variant_t	post_data("");
		_variant_t	headers("");

		_Browser->Navigate(url.AllocSysString(),
						   &flags,
						   &target_frame_name,
						   &post_data,
						   &headers);

	}
}

// Navigate to HTML document in resource

void SimpleBrowser::NavigateResource(int resource_ID)
{
	if (_Browser != NULL) {

		CString resource_string;

		// load HTML document from resource

		HRSRC resource_handle = FindResource(AfxGetResourceHandle(),
											 MAKEINTRESOURCE(resource_ID),
											 RT_HTML);

		if (resource_handle != NULL) {

			HGLOBAL resource = LoadResource(AfxGetResourceHandle(),
											resource_handle);

			if (resource != NULL) {

				LPVOID resource_memory = LockResource(resource);

				if (resource_memory != NULL) {

					DWORD resource_size = SizeofResource(AfxGetResourceHandle(),
														 resource_handle);

					// identify the resource document as MBCS (e.g. ANSI)
					// or UNICODE

					bool     UNICODE_document = false;

					wchar_t *UNICODE_memory   = (wchar_t *)resource_memory;
					int      UNICODE_size     = resource_size / sizeof(wchar_t);

					if (UNICODE_size >= 1) {

						// check for UNICODE byte order mark

						if (*UNICODE_memory == L'\xFEFF') {
							UNICODE_document = true;
							UNICODE_memory  += 1;
							UNICODE_size    -= 1;
						}

						// otherwise, check for UNICODE leading tag

						else if (UNICODE_size >= 5) {

							if ((UNICODE_memory[0]           == L'<') &&
							    (towupper(UNICODE_memory[1]) == L'H') &&
							    (towupper(UNICODE_memory[2]) == L'T') &&
							    (towupper(UNICODE_memory[3]) == L'M') &&
							    (towupper(UNICODE_memory[4]) == L'L')) {
								UNICODE_document = true;
							}

						}

						// Note: This logic assumes that the UNICODE resource document is 
						//       in little-endian byte order, which would be typical for 
						//       any HTML document used as a resource in a Windows application.

					}

					// convert resource document if required

#if !defined(UNICODE)

					if (UNICODE_document) {

						char *MBCS_buffer = resource_string.GetBufferSetLength(resource_size + 1);

						int MBCS_length = ::WideCharToMultiByte(CP_ACP,
						                                        0,
											                    UNICODE_memory,
											                    UNICODE_size,
											                    MBCS_buffer,
											                    resource_size + 1,
											                    NULL,
											                    NULL);

						resource_string.ReleaseBuffer(MBCS_length);

					}

					else {

						resource_string = CString((char *)resource_memory,resource_size);

					}

#else

					if (UNICODE_document) {

						resource_string = CString(UNICODE_memory,UNICODE_size);

					}

					else {

						wchar_t *UNICODE_buffer = resource_string.GetBufferSetLength(resource_size + 1);

						int UNICODE_length = ::MultiByteToWideChar(CP_ACP,
						                                           0,
											                       (const char *)resource_memory,
											                       resource_size,
											                       UNICODE_buffer,
											                       (resource_size + 1));

						resource_string.ReleaseBuffer(UNICODE_length);

					}

#endif


				}

			}

		}

		Clear();
		Write(resource_string);

	}
}

// Append string to current document

void SimpleBrowser::Write(LPCTSTR string)
{
	if (_Browser != NULL) {

		// get document interface

		IHTMLDocument2 *document = GetDocument();
		
		if (document != NULL) {

			// construct text to be written to browser as SAFEARRAY

			SAFEARRAY *safe_array = SafeArrayCreateVector(VT_VARIANT,0,1);
			
			VARIANT	*variant;
			
			SafeArrayAccessData(safe_array,(LPVOID *)&variant);
			
			variant->vt      = VT_BSTR;
			variant->bstrVal = CString(string).AllocSysString();
			
			SafeArrayUnaccessData(safe_array);

			// write SAFEARRAY to browser document

			document->write(safe_array);
			
			document->Release();
			document = NULL;

		}

	}
}

void SimpleBrowser::Clear()
{
	if (_Browser != NULL) {

		// if document interface available, close/re-open document to clear display

		IHTMLDocument2	*document	= GetDocument();
		HRESULT			hr			= S_OK;
		
		if (document != NULL) {

			// close and re-open document to empty contents

			document->close();
			
			VARIANT		open_name;
			VARIANT		open_features;
			VARIANT		open_replace;
			IDispatch	*open_window	= NULL;

			::VariantInit(&open_name);

			open_name.vt      = VT_BSTR;
			open_name.bstrVal = ::SysAllocString(L"_self");

			::VariantInit(&open_features);
			::VariantInit(&open_replace);
			
			hr = document->open(::SysAllocString(L"text/html"),
			                    open_name,
			                    open_features,
			                    open_replace,
			                    &open_window);

			if (hr == S_OK) {
				Refresh();
			}

			if (open_window != NULL) {
				open_window->Release();
			}

		}

		// otherwise, navigate to about:blank and wait for document ready

		else {

			Navigate(_T("about:blank"));

			IHTMLDocument2 *document = NULL;
			HRESULT			hr       = S_OK;

			while ((document == NULL) && (hr == S_OK)) {

				Sleep(0);

				IDispatch *document_dispatch = NULL;

				hr = _Browser->get_Document(&document_dispatch);

				// if dispatch interface available, retrieve document interface
				
				if (SUCCEEDED(hr) && (document_dispatch != NULL)) {

					// retrieve document interface
					
					hr = document_dispatch->QueryInterface(IID_IHTMLDocument2,(void **)&document);

					document_dispatch->Release();

				}
				
			}
			
			if (document != NULL) {
				document->Release();	
			}

		}
		
	}
}

// Navigation operations

void SimpleBrowser::GoBack()
{
	if (_Browser != NULL) {
		_Browser->GoBack();
	}
}

void SimpleBrowser::GoForward()
{
	if (_Browser != NULL) {
		_Browser->GoForward();
	}
}

void SimpleBrowser::GoHome()
{
	if (_Browser != NULL) {
		_Browser->GoHome();
	}
}

void SimpleBrowser::Refresh()
{
	if (_Browser != NULL) {
		_Browser->Refresh();
	}
}

void SimpleBrowser::Stop()
{
	if (_Browser != NULL) {
		_Browser->Stop();
	}
}

// Print contents

void SimpleBrowser::Print(LPCTSTR header,LPCTSTR footer)
{
	if (_Browser != NULL) {

		// construct two element SAFEARRAY;
		// first element is header string, second element is footer string

		HRESULT hr;

		VARIANT		header_variant;
		VariantInit(&header_variant);
		V_VT(&header_variant)   = VT_BSTR;
		V_BSTR(&header_variant) = CString(header).AllocSysString();

		VARIANT		footer_variant;
		VariantInit(&footer_variant);
		V_VT(&footer_variant)   = VT_BSTR;
		V_BSTR(&footer_variant) = CString(footer).AllocSysString();

		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);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -