Skip to content

Instantly share code, notes, and snippets.

@trevorlinton
Created April 1, 2015 04:14
Show Gist options
  • Save trevorlinton/7abac1c5f044be153833 to your computer and use it in GitHub Desktop.
Save trevorlinton/7abac1c5f044be153833 to your computer and use it in GitHub Desktop.
Hacking on IWebBrowser and DirectX
#include <stdint.h>
#include <stdio.h>
#include <string>
#include <vcclr.h>
#include <windows.h>
#include <mmsystem.h>
#include <msclr/marshal.h>
#include <msclr/marshal_cppstd.h>
#include <d3d9.h>
//#include <dispex.h>
#include <dxgi.h>
#include <exdisp.h> // contains IWebBrowser2
#include <mshtml.h> // needed for IHTMLDocument2
//#import "C:\Windows\System32\mshtml.tlb" // needed for COM interops on MSHTML.
#include <mshtmlc.h>
#using <System.dll>
#using <System.Core.dll>
// using namespace MSHTML;
using namespace std;
using namespace Microsoft::Win32;
using namespace System;
using namespace System::Windows;
using namespace System::Windows::Controls;
using namespace System::Windows::Interop;
using namespace System::Windows::Media;
using namespace System::Windows::Media::Imaging;
using namespace System::Runtime::InteropServices;
using namespace System::Reflection;
// "http://ie.microsoft.com/testdrive/Performance/FishIETank/"
#define DEFAULT_URL "https://www.google.com"
#pragma comment(linker, "/SUBSYSTEM:CONSOLE")
#define TIMER_MILLISECONDS 17
// #define FRAME_RATE_ENABLED
/*
//[System::Diagnostics::CodeAnalysis::SuppressMessage("Microsoft.StyleCop.CSharp.DocumentationRules", "SA1600:ElementsMustBeDocumented", Justification = "Interop Code")]
//[System::Diagnostics::CodeAnalysis::SuppressMessage("Microsoft.StyleCop.CSharp.DocumentationRules", "SA1601:PartialElementsMustBeDocumented", Justification = "Interop Code")]
//static public class UnsafeNativeMethods
//{
//public:
//static const Guid^ DocHostCommandHandlerCgid = gcnew Guid(0xf38bc242, 0xb950, 0x11d1, 0x89, 0x18, 0x00, 0xc0, 0x4f, 0xc2, 0xc8, 0x36);
//static const String^ WebBrowserClsid = "8856f961-340a-11d0-a96b-00c04fd705a2";
[returnvalue: MarshalAs(UnmanagedType::Interface)]
[DllImport("ole32.dll", ExactSpelling = true, PreserveSig = false)]
static System::Object^ CoCreateInstance([In] Guid% clsid, [MarshalAs(UnmanagedType::Interface)] System::Object^ punkOuter, int context, [In] Guid% iid);
[System::Diagnostics::CodeAnalysis::SuppressMessage("Microsoft.StyleCop.CSharp.DocumentationRules", "SA1600:ElementsMustBeDocumented", Justification = "Interop Code")]
[GuidAttribute("34A715A0-6587-11D0-924A-0020AFC7AC4D")]
[ComImport]
[InterfaceType(ComInterfaceType::InterfaceIsIDispatch)]
[TypeLibType(TypeLibTypeFlags::FHidden)]
[System::Diagnostics::CodeAnalysis::SuppressMessage("Microsoft.StyleCop.CSharp.NamingRules", "SA1302:InterfaceNamesMustBeginWithI", Justification = "Interop Code")]
public interface DWebBrowserEvents2
{
[DispId(102)]
void StatusTextChange([In] string text);
[DispId(108)]
void ProgressChange([In] int progress, [In] int progressMax);
[DispId(105)]
void CommandStateChange([In] long command, [In] bool enable);
[DispId(106)]
void DownloadBegin();
[DispId(104)]
void DownloadComplete();
[DispId(113)]
void TitleChange([In] string text);
[DispId(112)]
void PropertyChange([In] string szProperty);
[DispId(250)]
void BeforeNavigate2([In, MarshalAs(UnmanagedType::IDispatch)] Object^ pDisp, [In] Object^% URL, [In] Object^% flags, [In] Object^% targetFrameName, [In] Object^% postData, [In] Object^% headers, [In, Out] bool% cancel);
////[DispId(251)]
////void NewWindow2([In, Out, MarshalAs(UnmanagedType.IDispatch)] ref object pDisp, [In, Out] ref bool cancel);
[DispId(252)]
void NavigateComplete2([In, MarshalAs(UnmanagedType::IDispatch)] Object^ pDisp, [In] Object^% URL);
[DispId(259)]
void DocumentComplete([In, MarshalAs(UnmanagedType::IDispatch)] Object^ pDisp, [In] Object^% URL);
[DispId(253)]
void OnQuit();
[DispId(254)]
void OnVisible([In] bool visible);
[DispId(255)]
void OnToolBar([In] bool toolBar);
[DispId(256)]
void OnMenuBar([In] bool menuBar);
[DispId(257)]
void OnStatusBar([In] bool statusBar);
[DispId(258)]
void OnFullScreen([In] bool fullScreen);
[DispId(260)]
void OnTheaterMode([In] bool theaterMode);
[DispId(262)]
void WindowSetResizable([In] bool resizable);
[DispId(264)]
void WindowSetLeft([In] int left);
[DispId(265)]
void WindowSetTop([In] int top);
[DispId(266)]
void WindowSetWidth([In] int width);
[DispId(267)]
void WindowSetHeight([In] int height);
[DispId(263)]
void WindowClosing([In] bool isChildWindow, [In, Out] bool% cancel);
[DispId(268)]
////void ClientToHostWindow([In, Out] ref long cx, [In, Out] ref long cy);
void ClientToHostWindow([In, Out] int% cx, [In, Out] int% cy);
[DispId(269)]
void SetSecureLockIcon([In] int secureLockIcon);
[DispId(270)]
void FileDownload(bool load, [In, Out] bool% cancel);
[DispId(271)]
void NavigateError([In, MarshalAs(UnmanagedType::IDispatch)] Object^ pDisp, [In] Object^% URL, [In] Object^% frame, [In] Object^% statusCode, [In, Out] bool% cancel);
[DispId(225)]
void PrintTemplateInstantiation([In, MarshalAs(UnmanagedType::IDispatch)] Object^ pDisp);
[DispId(226)]
void PrintTemplateTeardown([In, MarshalAs(UnmanagedType::IDispatch)] Object^ pDisp);
[DispId(227)]
void UpdatePageStatus([In, MarshalAs(UnmanagedType::IDispatch)] Object^ pDisp, [In] Object^% nPage, [In] Object^% fDone);
[DispId(272)]
void PrivacyImpactedStateChange([In] bool bImpacted);
[DispId(273)]
void NewWindow3([In, Out, MarshalAs(UnmanagedType::IDispatch)] Object^% ppDisp, [In, Out] bool% Cancel, [In] unsigned int dwFlags, [In, MarshalAs(UnmanagedType::BStr)] String^ bstrUrlContext, [In, MarshalAs(UnmanagedType::BStr)] String^ bstrUrl);
};
//};
*/
struct D3DData {
LPDIRECT3DVERTEXBUFFER9 vertex;
IDirect3DDevice9Ex* d3ddev;
IDirect3D9Ex* d3d9;
IDirect3DSurface9* dest;
};
struct OLEData {
IUnknown* iUnknown;
IOleControlSite* controlSite;
IViewObject* viewObj;
IAdviseSink* sinkObj;
IOleObject* oleObj;
IWebBrowser2* webBrowser;
};
namespace TintInterop {
[ComImport, ComVisible(true)]
[Guid("00000118-0000-0000-C000-000000000046")]
[InterfaceType(ComInterfaceType::InterfaceIsIUnknown)]
public interface class IOleClientSite
{
// [return:MarshalAs(System::Runtime::InteropServices::UnmanagedType::I4)]
[PreserveSig]
int SaveObject();
// [return:MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int GetMoniker(
[In, MarshalAs(UnmanagedType::U4)] unsigned int dwAssign,
[In, MarshalAs(UnmanagedType::U4)] unsigned int dwWhichMoniker,
[Out, MarshalAs(UnmanagedType::Interface)] IMoniker *ppmk);
// [return:MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int GetContainer(
[Out, MarshalAs(UnmanagedType::Interface)] IOleContainer *ppContainer);
// [return:MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int ShowObject();
// [return:MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int OnShowWindow([In, MarshalAs(UnmanagedType::Bool)] bool fShow);
// [return:MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int RequestNewObjectLayout();
};
}
public ref class WebBrowserEx : System::Runtime::InteropServices::ComTypes::IAdviseSink, MSHTML::ISurfacePresenter, MSHTML::IViewObjectPresentSite, TintInterop::IOleClientSite {
public:
// IOleClientSite
virtual int SaveObject() {
Console::WriteLine("SaveObject!");
return S_OK;
}
virtual int GetMoniker(unsigned int dwAssign, unsigned int dwWhichMoniker, IMoniker *ppmk) {
Console::WriteLine("GetMoniker!");
return S_OK;
}
virtual int GetContainer(IOleContainer *ppContainer) {
Console::WriteLine("GetContainer!");
return S_OK;
}
virtual int ShowObject() {
Console::WriteLine("ShowObject!");
return S_OK;
}
virtual int OnShowWindow(bool fShow) {
Console::WriteLine("ShowWindow!");
return S_OK;
}
virtual int RequestNewObjectLayout() {
Console::WriteLine("NewObjectLayout!");
return S_OK;
}
// IViewObjectPresentSite
virtual void SetCompositionMode(MSHTML::_VIEW_OBJECT_COMPOSITION_MODE mode) {
Console::WriteLine("SetCompositionMode!");
}
virtual int IsHardwareComposition() {
Console::WriteLine("IsHardwareComposition!");
return 1;
}
virtual MSHTML::ISurfacePresenter^ CreateSurfacePresenter(System::Object^ pDevice,
unsigned int width, unsigned int height, unsigned int backBufferCount, MSHTML::DXGI_FORMAT format, MSHTML::_VIEW_OBJECT_ALPHA_MODE mode)
{
Console::WriteLine("CreateSurfacePresenter with: width: "+width+" height: "+height+" backbuffercount: "+backBufferCount+" and others.. ");
return nullptr;
}
// ISurfacePresenter
virtual void Present(unsigned int buffer, MSHTML::tagRECT% rect) {
Console::WriteLine("Present! with buffer: " + buffer + " and rect: " + rect);
}
virtual System::IntPtr GetBuffer(unsigned int buffer, System::Guid% guid) {
Console::WriteLine("GetBuffer! with: " + buffer + " and " + guid);
return System::IntPtr::Zero;
}
virtual int IsCurrent() {
Console::WriteLine("IsCurrent!");
return 1;
}
// IAdviseSink Methods
virtual void OnClose() {
Console::WriteLine("IAdviseSink::OnClose");
}
virtual void OnDataChange( [InAttribute] System::Runtime::InteropServices::ComTypes::FORMATETC% format, [InAttribute] System::Runtime::InteropServices::ComTypes::STGMEDIUM% stgmedium) {
Console::WriteLine("IAdviseSink::OnDataChange");
}
virtual void OnRename(System::Runtime::InteropServices::ComTypes::IMoniker^ moniker) {
Console::WriteLine("IAdviseSink::OnRename");
}
virtual void OnSave() {
Console::WriteLine("IAdviseSink::OnSave");
}
virtual void OnViewChange(int aspect, int index) {
Console::WriteLine("IAdviseSink::OnViewChange");
}
virtual void OnLinkSrcChange(System::Runtime::InteropServices::ComTypes::IMoniker^ moniker) {
Console::WriteLine("IAdviseSink2::OnLinkSrcChange");
}
virtual HRESULT OnViewStatusChange(DWORD dwViewStatus) {
Console::WriteLine("IAdviseSinkEx::OnViewStatusChange "+dwViewStatus);
return S_OK;
}
WebBrowserEx() {
oledata = new OLEData();
SetBrowserFeatureControl();
this->app = gcnew Application();
this->mWnd = gcnew Window();
this->brwsr = gcnew System::Windows::Controls::WebBrowser();
this->img = gcnew Image();
Grid^ grid = gcnew Grid();
RowDefinition^ rd = gcnew RowDefinition();
rd->Height = GridLength(1, GridUnitType::Star);
RowDefinition^ rd2 = gcnew RowDefinition();
rd2->Height = GridLength(1, GridUnitType::Star);
grid->RowDefinitions->Add(rd);
grid->RowDefinitions->Add(rd2);
grid->Children->Add(this->brwsr);
grid->SetRow(this->brwsr, 0);
/* start delete here
Canvas^ canvas = gcnew Canvas();
canvas->Children->Add(this->img);
img->SetValue(Canvas::LeftProperty,(double)1);
img->SetValue(Canvas::TopProperty,(double)1);
img->Width = 500;
img->Height = 200;
grid->Children->Add(canvas);
grid->SetRow(canvas, 1);
Button^ button = gcnew Button();
button->Width = 100;
button->Height = 30;
button->Content = "HEllo";
grid->Children->Add(button);
grid->SetRow(button, 1);
//end delete here */
grid->Children->Add(this->img);
grid->SetRow(this->img, 1);
this->mWnd->Content = grid;
this->img->Stretch = Stretch::None;
}
void Run(bool useDirectX) {
renderModeDirectX = useDirectX;
this->mWnd->SizeChanged += gcnew SizeChangedEventHandler(this, &WebBrowserEx::SizeChanged);
this->brwsr->Loaded += gcnew RoutedEventHandler(this, &WebBrowserEx::Loaded);
this->brwsr->LoadCompleted += gcnew System::Windows::Navigation::LoadCompletedEventHandler(this, &WebBrowserEx::DocumentLoaded);
this->brwsr->Navigate(DEFAULT_URL);
this->app->Run(this->mWnd);
}
#ifdef FRAME_RATE_ENABLED
System::Windows::Threading::DispatcherTimer^ frameRateTimer;
int frameRate;
#endif
void DocumentLoaded(Object^ sender, System::Windows::Navigation::NavigationEventArgs^ args) {
HRESULT hr;
/*
IHTMLDocument2* htmlDoc;
hr = this->oledata->webBrowser->get_Document((IDispatch **)&htmlDoc);
if(hr == E_NOINTERFACE) {
Console::WriteLine("Failed to get IHTMLDocument2 references N_NOINTERFACE");
} else if(hr == E_POINTER) {
Console::WriteLine("Failed to get IHTMLDocument2 references E_POINTER");
} else if (htmlDoc == NULL) {
Console::WriteLine("Failed to get IHTMLDocument2 reference NULL");
} else if(hr == S_OK) {
Console::WriteLine("Got IHTMLDocument2");
}
::IServiceProvider *isp;
hr = htmlDoc->QueryInterface(__uuidof(::IServiceProvider), (void **)&(isp));
if(hr == E_NOINTERFACE) {
Console::WriteLine("E_INTERFACE//Failed to get COM interface [IID_IServiceProvider] for underlying IOleClientSite.");
} else if (hr == E_POINTER) {
Console::WriteLine("E_POINTER//Failed to get COM interface; [IID_IServiceProvider] the interface was successful, but returned NULL, however E_POINTER wasnt returned.");
} else if(isp == NULL) {
Console::WriteLine("NULL//Failed to get COM interface; the interface was successful, but returned NULL.");
} else if (hr == S_OK) {
Console::WriteLine("Got IServiceProvider");
}
IOleClientSite* siteObj;
hr = this->oledata->oleObj->GetClientSite(&siteObj);
if(hr == E_NOINTERFACE) {
Console::WriteLine("Failed to get site references N_NOINTERFACE");
} else if(hr == E_POINTER) {
Console::WriteLine("Failed to get site references E_POINTER");
} else if (siteObj == NULL) {
Console::WriteLine("Failed to get site reference NULL");
} else if(hr == S_OK) {
Console::WriteLine("Got IOLEClientSite");
}
IOleControlSite* controlSite;
hr = siteObj->QueryInterface(__uuidof(IOleControlSite),(void **)&controlSite);
if(hr == E_NOINTERFACE) {
Console::WriteLine("Failed to get control site references N_NOINTERFACE");
} else if(hr == E_POINTER) {
Console::WriteLine("Failed to get control site references E_POINTER");
} else if (controlSite == NULL) {
Console::WriteLine("Failed to get control site reference NULL");
} else if(hr == S_OK) {
Console::WriteLine("Got IOleControlSite");
}
IDispatch* exControl;
hr = controlSite->GetExtendedControl(&exControl);
if(hr == E_NOINTERFACE) {
Console::WriteLine("Failed to get extended control; references N_NOINTERFACE");
} else if(hr == E_POINTER) {
Console::WriteLine("Failed to get extended control; references E_POINTER");
} else if (controlSite == NULL) {
Console::WriteLine("Failed to get extended control; reference NULL");
} else if(hr == S_OK) {
Console::WriteLine("Got Extended Control");
} else if(hr == E_NOTIMPL) {
Console::WriteLine("Failed to get extended control; got back E_NOTIMPL");
}
ISurfacePresenter* pDXGIDevice;
// tried viewObj, webBrowser and oleObj, htmldoc, isp (service provider), and siteObj, none.
hr = this->oledata->viewObj->QueryInterface(__uuidof(ISurfacePresenter), (void **)&pDXGIDevice);
if(hr == E_NOINTERFACE) {
Console::WriteLine("Failed to get ISurfacePresenter references N_NOINTERFACE");
} else if(hr == E_POINTER) {
Console::WriteLine("Failed to get ISurfacePresenter references E_POINTER");
} else if (pDXGIDevice == NULL) {
Console::WriteLine("Failed to get ISurfacePresenter reference NULL");
} else if(hr == S_OK) {
Console::WriteLine("Got the ISurfacePresenter");
}
hr = this->oledata->webBrowser->QueryInterface(__uuidof(ISurfacePresenter), (void **)&pDXGIDevice);
if(hr == E_NOINTERFACE) {
Console::WriteLine("Failed to get ISurfacePresenter references N_NOINTERFACE");
} else if(hr == E_POINTER) {
Console::WriteLine("Failed to get ISurfacePresenter references E_POINTER");
} else if (pDXGIDevice == NULL) {
Console::WriteLine("Failed to get ISurfacePresenter reference NULL");
} else if(hr == S_OK) {
Console::WriteLine("Got the ISurfacePresenter");
}
hr = this->oledata->oleObj->QueryInterface(__uuidof(ISurfacePresenter), (void **)&pDXGIDevice);
if(hr == E_NOINTERFACE) {
Console::WriteLine("Failed to get ISurfacePresenter references N_NOINTERFACE");
} else if(hr == E_POINTER) {
Console::WriteLine("Failed to get ISurfacePresenter references E_POINTER");
} else if (pDXGIDevice == NULL) {
Console::WriteLine("Failed to get ISurfacePresenter reference NULL");
} else if(hr == S_OK) {
Console::WriteLine("Got the ISurfacePresenter");
}
hr = htmlDoc->QueryInterface(__uuidof(ISurfacePresenter), (void **)&pDXGIDevice);
if(hr == E_NOINTERFACE) {
Console::WriteLine("Failed to get ISurfacePresenter references N_NOINTERFACE");
} else if(hr == E_POINTER) {
Console::WriteLine("Failed to get ISurfacePresenter references E_POINTER");
} else if (pDXGIDevice == NULL) {
Console::WriteLine("Failed to get ISurfacePresenter reference NULL");
} else if(hr == S_OK) {
Console::WriteLine("Got the ISurfacePresenter");
}
hr = isp->QueryInterface(__uuidof(ISurfacePresenter), (void **)&pDXGIDevice);
if(hr == E_NOINTERFACE) {
Console::WriteLine("Failed to get ISurfacePresenter references N_NOINTERFACE");
} else if(hr == E_POINTER) {
Console::WriteLine("Failed to get ISurfacePresenter references E_POINTER");
} else if (pDXGIDevice == NULL) {
Console::WriteLine("Failed to get ISurfacePresenter reference NULL");
} else if(hr == S_OK) {
Console::WriteLine("Got the ISurfacePresenter");
}
hr = siteObj->QueryInterface(__uuidof(ISurfacePresenter), (void **)&pDXGIDevice);
if(hr == E_NOINTERFACE) {
Console::WriteLine("Failed to get ISurfacePresenter references N_NOINTERFACE");
} else if(hr == E_POINTER) {
Console::WriteLine("Failed to get ISurfacePresenter references E_POINTER");
} else if (pDXGIDevice == NULL) {
Console::WriteLine("Failed to get ISurfacePresenter reference NULL");
} else if(hr == S_OK) {
Console::WriteLine("Got the ISurfacePresenter");
}
hr = controlSite->QueryInterface(__uuidof(ISurfacePresenter), (void **)&pDXGIDevice);
if(hr == E_NOINTERFACE) {
Console::WriteLine("Failed to get ISurfacePresenter references N_NOINTERFACE");
} else if(hr == E_POINTER) {
Console::WriteLine("Failed to get ISurfacePresenter references E_POINTER");
} else if (pDXGIDevice == NULL) {
Console::WriteLine("Failed to get ISurfacePresenter reference NULL");
} else if(hr == S_OK) {
Console::WriteLine("Got the ISurfacePresenter");
}
hr = this->oledata->iUnknown->QueryInterface(__uuidof(ISurfacePresenter), (void **)&pDXGIDevice);
if(hr == E_NOINTERFACE) {
Console::WriteLine("Failed to get ISurfacePresenter references N_NOINTERFACE");
} else if(hr == E_POINTER) {
Console::WriteLine("Failed to get ISurfacePresenter references E_POINTER");
} else if (pDXGIDevice == NULL) {
Console::WriteLine("Failed to get ISurfacePresenter reference NULL");
} else if(hr == S_OK) {
Console::WriteLine("Got the ISurfacePresenter");
}
IViewObjectPresentNotifySite* pDXGIDevice2;
// tried viewObj, webBrowser and oleObj, htmldoc, isp (service provider), and siteObj, none.
hr = this->oledata->viewObj->QueryInterface(__uuidof(IViewObjectPresentNotifySite), (void **)&pDXGIDevice2);
if(hr == E_NOINTERFACE) {
Console::WriteLine("Failed to get IViewObjectPresentNotifySite references N_NOINTERFACE");
} else if(hr == E_POINTER) {
Console::WriteLine("Failed to get IViewObjectPresentNotifySite references E_POINTER");
} else if (pDXGIDevice == NULL) {
Console::WriteLine("Failed to get IViewObjectPresentNotifySite reference NULL");
} else if(hr == S_OK) {
Console::WriteLine("Got the IViewObjectPresentNotifySite");
}
hr = this->oledata->webBrowser->QueryInterface(__uuidof(IViewObjectPresentNotifySite), (void **)&pDXGIDevice2);
if(hr == E_NOINTERFACE) {
Console::WriteLine("Failed to get IViewObjectPresentNotifySite references N_NOINTERFACE");
} else if(hr == E_POINTER) {
Console::WriteLine("Failed to get IViewObjectPresentNotifySite references E_POINTER");
} else if (pDXGIDevice == NULL) {
Console::WriteLine("Failed to get IViewObjectPresentNotifySite reference NULL");
} else if(hr == S_OK) {
Console::WriteLine("Got the IViewObjectPresentNotifySite");
}
hr = this->oledata->oleObj->QueryInterface(__uuidof(IViewObjectPresentNotifySite), (void **)&pDXGIDevice2);
if(hr == E_NOINTERFACE) {
Console::WriteLine("Failed to get IViewObjectPresentNotifySite references N_NOINTERFACE");
} else if(hr == E_POINTER) {
Console::WriteLine("Failed to get IViewObjectPresentNotifySite references E_POINTER");
} else if (pDXGIDevice == NULL) {
Console::WriteLine("Failed to get IViewObjectPresentNotifySite reference NULL");
} else if(hr == S_OK) {
Console::WriteLine("Got the IViewObjectPresentNotifySite");
}
hr = htmlDoc->QueryInterface(__uuidof(IViewObjectPresentNotifySite), (void **)&pDXGIDevice2);
if(hr == E_NOINTERFACE) {
Console::WriteLine("Failed to get IViewObjectPresentNotifySite references N_NOINTERFACE");
} else if(hr == E_POINTER) {
Console::WriteLine("Failed to get IViewObjectPresentNotifySite references E_POINTER");
} else if (pDXGIDevice == NULL) {
Console::WriteLine("Failed to get IViewObjectPresentNotifySite reference NULL");
} else if(hr == S_OK) {
Console::WriteLine("Got the IViewObjectPresentNotifySite");
}
hr = isp->QueryInterface(__uuidof(IViewObjectPresentNotifySite), (void **)&pDXGIDevice2);
if(hr == E_NOINTERFACE) {
Console::WriteLine("Failed to get IViewObjectPresentNotifySite references N_NOINTERFACE");
} else if(hr == E_POINTER) {
Console::WriteLine("Failed to get IViewObjectPresentNotifySite references E_POINTER");
} else if (pDXGIDevice == NULL) {
Console::WriteLine("Failed to get IViewObjectPresentNotifySite reference NULL");
} else if(hr == S_OK) {
Console::WriteLine("Got the IViewObjectPresentNotifySite");
}
hr = siteObj->QueryInterface(__uuidof(IViewObjectPresentNotifySite), (void **)&pDXGIDevice2);
if(hr == E_NOINTERFACE) {
Console::WriteLine("Failed to get IViewObjectPresentNotifySite references N_NOINTERFACE");
} else if(hr == E_POINTER) {
Console::WriteLine("Failed to get IViewObjectPresentNotifySite references E_POINTER");
} else if (pDXGIDevice == NULL) {
Console::WriteLine("Failed to get IViewObjectPresentNotifySite reference NULL");
} else if(hr == S_OK) {
Console::WriteLine("Got the IViewObjectPresentNotifySite");
}
hr = controlSite->QueryInterface(__uuidof(IViewObjectPresentNotifySite), (void **)&pDXGIDevice2);
if(hr == E_NOINTERFACE) {
Console::WriteLine("Failed to get IViewObjectPresentNotifySite references N_NOINTERFACE");
} else if(hr == E_POINTER) {
Console::WriteLine("Failed to get IViewObjectPresentNotifySite references E_POINTER");
} else if (pDXGIDevice == NULL) {
Console::WriteLine("Failed to get IViewObjectPresentNotifySite reference NULL");
} else if(hr == S_OK) {
Console::WriteLine("Got the IViewObjectPresentNotifySite");
}
hr = this->oledata->iUnknown->QueryInterface(__uuidof(IViewObjectPresentNotifySite), (void **)&pDXGIDevice2);
if(hr == E_NOINTERFACE) {
Console::WriteLine("Failed to get IViewObjectPresentNotifySite references N_NOINTERFACE");
} else if(hr == E_POINTER) {
Console::WriteLine("Failed to get IViewObjectPresentNotifySite references E_POINTER");
} else if (pDXGIDevice == NULL) {
Console::WriteLine("Failed to get IViewObjectPresentNotifySite reference NULL");
} else if(hr == S_OK) {
Console::WriteLine("Got the IViewObjectPresentNotifySite");
}
IViewObjectPresentSite* pDXGIDevice3;
// tried viewObj, webBrowser and oleObj, htmldoc, isp (service provider), and siteObj, none.
hr = this->oledata->viewObj->QueryInterface(__uuidof(IViewObjectPresentSite), (void **)&pDXGIDevice3);
if(hr == E_NOINTERFACE) {
Console::WriteLine("Failed to get IViewObjectPresentSite references N_NOINTERFACE");
} else if(hr == E_POINTER) {
Console::WriteLine("Failed to get IViewObjectPresentSite references E_POINTER");
} else if (pDXGIDevice == NULL) {
Console::WriteLine("Failed to get IViewObjectPresentSite reference NULL");
} else if(hr == S_OK) {
Console::WriteLine("Got the IViewObjectPresentSite");
}
hr = this->oledata->webBrowser->QueryInterface(__uuidof(IViewObjectPresentSite), (void **)&pDXGIDevice3);
if(hr == E_NOINTERFACE) {
Console::WriteLine("Failed to get IViewObjectPresentSite references N_NOINTERFACE");
} else if(hr == E_POINTER) {
Console::WriteLine("Failed to get IViewObjectPresentSite references E_POINTER");
} else if (pDXGIDevice == NULL) {
Console::WriteLine("Failed to get IViewObjectPresentSite reference NULL");
} else if(hr == S_OK) {
Console::WriteLine("Got the IViewObjectPresentSite");
}
hr = this->oledata->oleObj->QueryInterface(__uuidof(IViewObjectPresentSite), (void **)&pDXGIDevice3);
if(hr == E_NOINTERFACE) {
Console::WriteLine("Failed to get IViewObjectPresentSite references N_NOINTERFACE");
} else if(hr == E_POINTER) {
Console::WriteLine("Failed to get IViewObjectPresentSite references E_POINTER");
} else if (pDXGIDevice == NULL) {
Console::WriteLine("Failed to get IViewObjectPresentSite reference NULL");
} else if(hr == S_OK) {
Console::WriteLine("Got the IViewObjectPresentSite");
}
hr = htmlDoc->QueryInterface(__uuidof(IViewObjectPresentSite), (void **)&pDXGIDevice3);
if(hr == E_NOINTERFACE) {
Console::WriteLine("Failed to get IViewObjectPresentSite references N_NOINTERFACE");
} else if(hr == E_POINTER) {
Console::WriteLine("Failed to get IViewObjectPresentSite references E_POINTER");
} else if (pDXGIDevice == NULL) {
Console::WriteLine("Failed to get IViewObjectPresentSite reference NULL");
} else if(hr == S_OK) {
Console::WriteLine("Got the IViewObjectPresentSite");
}
hr = isp->QueryInterface(__uuidof(IViewObjectPresentSite), (void **)&pDXGIDevice3);
if(hr == E_NOINTERFACE) {
Console::WriteLine("Failed to get IViewObjectPresentSite references N_NOINTERFACE");
} else if(hr == E_POINTER) {
Console::WriteLine("Failed to get IViewObjectPresentSite references E_POINTER");
} else if (pDXGIDevice == NULL) {
Console::WriteLine("Failed to get IViewObjectPresentSite reference NULL");
} else if(hr == S_OK) {
Console::WriteLine("Got the IViewObjectPresentSite");
}
hr = siteObj->QueryInterface(__uuidof(IViewObjectPresentSite), (void **)&pDXGIDevice3);
if(hr == E_NOINTERFACE) {
Console::WriteLine("Failed to get IViewObjectPresentSite references N_NOINTERFACE");
} else if(hr == E_POINTER) {
Console::WriteLine("Failed to get IViewObjectPresentSite references E_POINTER");
} else if (pDXGIDevice == NULL) {
Console::WriteLine("Failed to get IViewObjectPresentSite reference NULL");
} else if(hr == S_OK) {
Console::WriteLine("Got the IViewObjectPresentSite");
}
hr = controlSite->QueryInterface(__uuidof(IViewObjectPresentSite), (void **)&pDXGIDevice3);
if(hr == E_NOINTERFACE) {
Console::WriteLine("Failed to get IViewObjectPresentSite references N_NOINTERFACE");
} else if(hr == E_POINTER) {
Console::WriteLine("Failed to get IViewObjectPresentSite references E_POINTER");
} else if (pDXGIDevice == NULL) {
Console::WriteLine("Failed to get IViewObjectPresentSite reference NULL");
} else if(hr == S_OK) {
Console::WriteLine("Got the IViewObjectPresentSite");
}
hr = this->oledata->iUnknown->QueryInterface(__uuidof(IViewObjectPresentSite), (void **)&pDXGIDevice3);
if(hr == E_NOINTERFACE) {
Console::WriteLine("Failed to get IViewObjectPresentSite references N_NOINTERFACE");
} else if(hr == E_POINTER) {
Console::WriteLine("Failed to get IViewObjectPresentSite references E_POINTER");
} else if (pDXGIDevice == NULL) {
Console::WriteLine("Failed to get IViewObjectPresentSite reference NULL");
} else if(hr == S_OK) {
Console::WriteLine("Got the IViewObjectPresentSite");
}*/
/*
IDirect3DSurface9* pDXGIDevice;
// tried viewObj, webBrowser and oleObj, htmldoc, isp (service provider), and siteObj, none.
hr = this->oledata->viewObj->QueryInterface(__uuidof(IDirect3DSurface9), (void **)&pDXGIDevice);
if(hr == E_NOINTERFACE) {
Console::WriteLine("Failed to get IDirect3D9Ex references N_NOINTERFACE");
} else if(hr == E_POINTER) {
Console::WriteLine("Failed to get IDirect3D9Ex references E_POINTER");
} else if (pDXGIDevice == NULL) {
Console::WriteLine("Failed to get IDirect3D9Ex reference NULL");
} else if(hr == S_OK) {
Console::WriteLine("Got the IDirect3D9Ex");
}
hr = this->oledata->webBrowser->QueryInterface(__uuidof(IDirect3DSurface9), (void **)&pDXGIDevice);
if(hr == E_NOINTERFACE) {
Console::WriteLine("Failed to get IDirect3D9Ex references N_NOINTERFACE");
} else if(hr == E_POINTER) {
Console::WriteLine("Failed to get IDirect3D9Ex references E_POINTER");
} else if (pDXGIDevice == NULL) {
Console::WriteLine("Failed to get IDirect3D9Ex reference NULL");
} else if(hr == S_OK) {
Console::WriteLine("Got the IDirect3D9Ex");
}
hr = this->oledata->oleObj->QueryInterface(__uuidof(IDirect3DSurface9), (void **)&pDXGIDevice);
if(hr == E_NOINTERFACE) {
Console::WriteLine("Failed to get IDirect3D9Ex references N_NOINTERFACE");
} else if(hr == E_POINTER) {
Console::WriteLine("Failed to get IDirect3D9Ex references E_POINTER");
} else if (pDXGIDevice == NULL) {
Console::WriteLine("Failed to get IDirect3D9Ex reference NULL");
} else if(hr == S_OK) {
Console::WriteLine("Got the IDirect3D9Ex");
}
hr = htmlDoc->QueryInterface(__uuidof(IDirect3DSurface9), (void **)&pDXGIDevice);
if(hr == E_NOINTERFACE) {
Console::WriteLine("Failed to get IDirect3D9Ex references N_NOINTERFACE");
} else if(hr == E_POINTER) {
Console::WriteLine("Failed to get IDirect3D9Ex references E_POINTER");
} else if (pDXGIDevice == NULL) {
Console::WriteLine("Failed to get IDirect3D9Ex reference NULL");
} else if(hr == S_OK) {
Console::WriteLine("Got the IDirect3D9Ex");
}
hr = isp->QueryInterface(__uuidof(IDirect3DSurface9), (void **)&pDXGIDevice);
if(hr == E_NOINTERFACE) {
Console::WriteLine("Failed to get IDirect3D9Ex references N_NOINTERFACE");
} else if(hr == E_POINTER) {
Console::WriteLine("Failed to get IDirect3D9Ex references E_POINTER");
} else if (pDXGIDevice == NULL) {
Console::WriteLine("Failed to get IDirect3D9Ex reference NULL");
} else if(hr == S_OK) {
Console::WriteLine("Got the IDirect3D9Ex");
}
hr = siteObj->QueryInterface(__uuidof(IDirect3DSurface9), (void **)&pDXGIDevice);
if(hr == E_NOINTERFACE) {
Console::WriteLine("Failed to get IDirect3D9Ex references N_NOINTERFACE");
} else if(hr == E_POINTER) {
Console::WriteLine("Failed to get IDirect3D9Ex references E_POINTER");
} else if (pDXGIDevice == NULL) {
Console::WriteLine("Failed to get IDirect3D9Ex reference NULL");
} else if(hr == S_OK) {
Console::WriteLine("Got the IDirect3D9Ex");
}
*/
/*
IDXGIDevice1 * pDXGIDevice;
// tried viewObj, webBrowser and oleObj, htmldoc, service provider, and siteObj, none.
hr = isp->QueryInterface(__uuidof(IDXGIDevice1), (void **)&pDXGIDevice);
if(hr == E_NOINTERFACE) {
Console::WriteLine("Failed to get IDXGIDevice1 references N_NOINTERFACE");
} else if(hr == E_POINTER) {
Console::WriteLine("Failed to get IDXGIDevice1 references E_POINTER");
} else if (pDXGIDevice == NULL) {
Console::WriteLine("Failed to get IDXGIDevice1 reference NULL");
} else if(hr == S_OK) {
Console::WriteLine("Got the IDXGIDevice1");
}
*/
/*
IViewObjectPresentSite *presentNotify;
HRESULT result = htmlDoc->QueryInterface(__uuidof(IViewObjectPresentSite), (void **)&(presentNotify));
if(result == E_NOINTERFACE) {
Console::WriteLine("E_INTERFACE//Failed to get COM interface [IViewObjectPresentNotifySite] for underlying IOleClientSite.");
} else if (result == E_POINTER) {
Console::WriteLine("E_POINTER//Failed to get COM interface; [IViewObjectPresentNotifySite] the interface was successful, but returned NULL, however E_POINTER wasnt returned.");
} else if(presentNotify == NULL) { //this->oledata->viewObj
Console::WriteLine("NULL//Failed to get IViewObjectPresentNotifySite COM interface; the interface was successful, but returned NULL.");
} else if (result == S_OK) {
Console::WriteLine("Huh, welp we got the IViewObjectPResentNotifySite ?");
}
*/
/*
::IServiceProvider *isp;
HRESULT result = siteObj->QueryInterface(__uuidof(::IServiceProvider), (void **)&(isp));
if(result == E_NOINTERFACE) {
Console::WriteLine("E_INTERFACE//Failed to get COM interface [IID_IServiceProvider] for underlying IOleClientSite.");
} else if (result == E_POINTER) {
Console::WriteLine("E_POINTER//Failed to get COM interface; [IID_IServiceProvider] the interface was successful, but returned NULL, however E_POINTER wasnt returned.");
} else if(isp == NULL) { //this->oledata->viewObj
Console::WriteLine("NULL//Failed to get COM interface; the interface was successful, but returned NULL.");
} else if (result == S_OK) {
Console::WriteLine("Everything is peachy keen for IID_IServiceProvider.");
}
*/
/*
IViewObjectPresentSite *site;
HRESULT result = siteObj->QueryInterface(IID_IViewObjectPresentSite, (void **)&(site));
if(result == E_NOINTERFACE) {
Console::WriteLine("E_INTERFACE//Failed to get COM interface [IViewObjectPresentSite] for underlying IWebBrowser2.");
} else if (result == E_POINTER) {
Console::WriteLine("E_POINTER//Failed to get COM interface; [IViewObjectPresentSite] the interface was successful, but returned NULL, however E_POINTER wasnt returned.");
} else if(site == NULL) { //this->oledata->viewObj
Console::WriteLine("NULL//Failed to get COM interface; the interface was successful, but returned NULL.");
} else if (result == S_OK) {
Console::WriteLine("Everything is peachy keen.");
}
*/
HRESULT result2 = this->oledata->viewObj->SetAdvise(DVASPECT_CONTENT, ADVF_PRIMEFIRST, this->oledata->sinkObj);
if(result2 != S_OK) {
Console::WriteLine("Listening for draw events from IE failed (2). "+result2);
}
}
void SetBrowserFeatureControlKey(String^ feature, String^ appName, int value) {
String^ featuresPath = "HKEY_CURRENT_USER\\Software\\Microsoft\\Internet Explorer\\Main\\FeatureControl\\";
String^ path = featuresPath + feature;
Microsoft::Win32::Registry::SetValue(path, appName, value, Microsoft::Win32::RegistryValueKind::DWord);
}
void SetBrowserFeatureControl() {
System::Diagnostics::Process^ process = System::Diagnostics::Process::GetCurrentProcess();
String^ pName = process->Modules[0]->FileName;
array<String^>^ path = pName->Split('\\');
String^ fileName = path[path->Length-1];
SetBrowserFeatureControlKey("FEATURE_96DPI_PIXEL", fileName, 1); // enable high-dpi support.
SetBrowserFeatureControlKey("FEATURE_BROWSER_EMULATION", fileName, 00000); // turn off compatibility mode.
SetBrowserFeatureControlKey("FEATURE_AJAX_CONNECTIONEVENTS", fileName, 1);
SetBrowserFeatureControlKey("FEATURE_ENABLE_CLIPCHILDREN_OPTIMIZATION", fileName, 1);
SetBrowserFeatureControlKey("FEATURE_GPU_RENDERING", fileName, 1); // use GPU rendering
SetBrowserFeatureControlKey("FEATURE_IVIEWOBJECTDRAW_DMLT9_WITH_GDI ", fileName, 0); // force directX
SetBrowserFeatureControlKey("FEATURE_NINPUT_LEGACYMODE", fileName, 0);
SetBrowserFeatureControlKey("FEATURE_DISABLE_NAVIGATION_SOUNDS", fileName, 1);
SetBrowserFeatureControlKey("FEATURE_SCRIPTURL_MITIGATION", fileName, 1);
SetBrowserFeatureControlKey("FEATURE_SPELLCHECKING", fileName, 0);
SetBrowserFeatureControlKey("FEATURE_STATUS_BAR_THROTTLING", fileName, 1);
SetBrowserFeatureControlKey("FEATURE_VALIDATE_NAVIGATE_URL", fileName, 1);
SetBrowserFeatureControlKey("FEATURE_WEBOC_DOCUMENT_ZOOM", fileName, 1); // allow zoom.
SetBrowserFeatureControlKey("FEATURE_WEBOC_POPUPMANAGEMENT", fileName, 0); // disallow auto-popups
SetBrowserFeatureControlKey("FEATURE_ADDON_MANAGEMENT", fileName, 0); // disallow auto-addons/plugins
SetBrowserFeatureControlKey("FEATURE_WEBSOCKET", fileName, 1);
SetBrowserFeatureControlKey("FEATURE_WINDOW_RESTRICTIONS", fileName, 0); // disallow popups
SetBrowserFeatureControlKey("FEATURE_SECURITYBAND", fileName, 0); // disallow security band (still retains security)
SetBrowserFeatureControlKey("FEATURE_LOCALMACHINE_LOCKDOWN", fileName, 1); // allow file's to integrate with IWebBrowser JS execute.
SetBrowserFeatureControlKey("FEATURE_BLOCK_LMZ_SCRIPT", fileName, 0); // disable activeX security band warnings on local scripts.
SetBrowserFeatureControlKey("FEATURE_BLOCK_LMZ_OBJECT", fileName, 0); // disable activeX security.
SetBrowserFeatureControlKey("FEATURE_RESTRICT_ACTIVEXINSTALL", fileName, 0);
SetBrowserFeatureControlKey("FEATURE_PROTOCOL_LOCKDOWN", fileName, 0);
SetBrowserFeatureControlKey("FEATURE_ZONE_ELEVATION", fileName, 0);
SetBrowserFeatureControlKey("FEATURE_SCRIPTURL_MITIGATION", fileName, 0);
}
void SizeChanged(System::Object ^sender, SizeChangedEventArgs ^args) {
Width = (int)this->brwsr->ActualWidth;
Height = (int)this->brwsr->ActualHeight;
DpiWidth = (int)this->brwsr->ActualWidth*dpiX;
DpiHeight = (int)this->brwsr->ActualHeight*dpiY;
if(this->d3dimg != nullptr)
Dimensions = gcnew Int32Rect(0, 0, this->d3dimg->PixelWidth, this->d3dimg->PixelHeight);
if(!renderModeDirectX) {
if(hBitmap != NULL) {
DeleteObject(hBitmap);
}
hBitmap = CreateCompatibleBitmap(hdcFrom, DpiWidth, DpiHeight);
if(hBitmap != NULL) {
source = gcnew WriteableBitmap(System::Windows::Interop::Imaging::CreateBitmapSourceFromHBitmap(IntPtr(hBitmap),
IntPtr::Zero,
System::Windows::Int32Rect::Empty,
BitmapSizeOptions::FromEmptyOptions()));
this->img->Source = source;
}
}
}
#ifdef FRAME_RATE_ENABLED
void PrintFrameRate(Object^ sender, EventArgs^ e) {
Console::WriteLine("FPS: "+frameRate);
frameRate = 0;
}
#endif
void Loaded(System::Object ^sender, RoutedEventArgs ^args) {
brwsrHwnd = (HWND)this->brwsr->Handle.ToPointer();
hdcFrom = GetDC(brwsrHwnd);
PresentationSource^ presSource = PresentationSource::FromVisual(this->mWnd);
dpiY = dpiX = (presSource == nullptr) ? 1.0 : presSource->CompositionTarget->TransformToDevice.M11;
DpiWidth = (int)this->brwsr->ActualWidth*dpiX;
DpiHeight = (int)this->brwsr->ActualHeight*dpiY;
Width = (int)this->brwsr->ActualWidth;
Height = (int)this->brwsr->ActualHeight;
#ifdef FRAME_RATE_ENABLED
frameRate = 0;
frameRateTimer = gcnew System::Windows::Threading::DispatcherTimer(System::Windows::Threading::DispatcherPriority::Normal);
frameRateTimer->Tick += gcnew EventHandler(this, &WebBrowserEx::PrintFrameRate);
frameRateTimer->Interval = TimeSpan(0,0,0,1,0);
frameRateTimer->Start();
#endif
if(renderModeDirectX) {
Object^ rawObject;
IntPtr marshalptr;
//rawObject = System::Windows::Controls::WebBrowser::typeid->GetProperty("ActiveXSite", BindingFlags::Instance | BindingFlags::NonPublic)->GetValue(this->brwsr, nullptr);
//if(!Marshal::IsComObject(rawObject)) {
// Console::WriteLine("The returned ActiveXSite was not a COM object.");
// abort();
//}
//marshalptr = Marshal::GetIUnknownForObject(rawObject);
//this->oledata->activeXSite = static_cast<IUnknown*>(marshalptr.ToPointer());
rawObject = System::Windows::Controls::WebBrowser::typeid->GetProperty("AxIWebBrowser2", BindingFlags::Instance | BindingFlags::NonPublic)->GetValue(this->brwsr, nullptr);
if(!Marshal::IsComObject(rawObject)) {
Console::WriteLine("The returned AxIWebBrowser2 was not a COM object.");
abort();
}
marshalptr = Marshal::GetIUnknownForObject(rawObject);
this->oledata->iUnknown = static_cast<IUnknown*>(marshalptr.ToPointer());
if(this->oledata->iUnknown->QueryInterface(__uuidof(IOleObject), (void **)&this->oledata->oleObj) != S_OK) {
Console::WriteLine("Failed to get OLE Object");
abort();
}
if(this->oledata->iUnknown->QueryInterface(__uuidof(IViewObject), (void **)&this->oledata->viewObj) != S_OK) {
Console::WriteLine("Failed to get IViewObject");
abort();
}
IntPtr thisPtrUnknown = Marshal::GetComInterfaceForObject(this, System::Runtime::InteropServices::ComTypes::IAdviseSink::typeid);
IUnknown *thisComInterop = static_cast<IUnknown *>(thisPtrUnknown.ToPointer());
if(thisComInterop->QueryInterface(__uuidof(IAdviseSink), (void **)&this->oledata->sinkObj) != S_OK) {
Console::WriteLine("Using IAdviseSink as a delegate for each document failed (1).");
abort();
}
if(this->oledata->iUnknown->QueryInterface(__uuidof(IWebBrowser2), (void **)&this->oledata->webBrowser) != S_OK) {
Console::WriteLine("Failed obtaining the IWebBrowser2 backing object.");
abort();
}
// render direct3D.
this->d3dimg = gcnew D3DImage(dpiX * 96.0, dpiY * 96.0);
this->d3dimg->IsFrontBufferAvailableChanged += gcnew DependencyPropertyChangedEventHandler(this, &WebBrowserEx::OnIsFrontBufferAvailableChanged);
InitializeD3D();
this->img->Source = this->d3dimg;
Dimensions = gcnew Int32Rect(0, 0, this->d3dimg->PixelWidth, this->d3dimg->PixelHeight);
// perhaps we try ioleclientsite.
IntPtr thisOleClientSite = Marshal::GetComInterfaceForObject(this, TintInterop::IOleClientSite::typeid);
IUnknown *thisOleInterop = static_cast<IOleClientSite *>(thisOleClientSite.ToPointer());
if (this->oledata->oleObj->SetClientSite((IOleClientSite *)thisOleInterop) != S_OK) {
Console::WriteLine("Setting IOLEClientSite failed!");
}
} else {
// GDI bitblt redirect, so slow...
hdcTo = CreateCompatibleDC(hdcFrom);
hBitmap = CreateCompatibleBitmap(hdcFrom, DpiWidth, DpiHeight);
source = gcnew WriteableBitmap(System::Windows::Interop::Imaging::CreateBitmapSourceFromHBitmap(IntPtr(hBitmap),
IntPtr::Zero,
System::Windows::Int32Rect::Empty,
BitmapSizeOptions::FromEmptyOptions()));
this->img->Source = source;
SelectObject(hdcTo, hBitmap);
System::Windows::Threading::DispatcherTimer^ timer = gcnew System::Windows::Threading::DispatcherTimer(System::Windows::Threading::DispatcherPriority::Render);
timer->Tick += gcnew EventHandler(this, &WebBrowserEx::RedirectWindowWithGDI);
timer->Interval = TimeSpan(0,0,0,0,TIMER_MILLISECONDS);
timer->Start();
}
}
void RedirectWindowWithGDI(Object^ sender, EventArgs^ e) {
if (hBitmap != NULL)
{
HGDIOBJ hLocal = SelectObject(hdcTo, hBitmap);
StretchBlt(hdcTo, 0, 0, DpiWidth, DpiHeight, hdcFrom, 0, 0, DpiWidth, DpiHeight, SRCCOPY);
//BitBlt(hdcTo, 0, 0, DpiWidth, DpiHeight, hdcFrom, 0, 0, SRCCOPY);
// use this->oledata->viewObj->draw?
SelectObject(hdcTo, hLocal);
this->source->Lock();
// TODO......
//this->source->WritePixels(Int32Rect(0, 0, Width, Height), IntPtr(hBitmap), 4*Width*Height, 1);
this->source->AddDirtyRect(Int32Rect(0,0,Width,Height));
this->source->Unlock();
#ifdef FRAME_RATE_ENABLED
frameRate++;
#endif
}
}
void OnIsFrontBufferAvailableChanged(Object^ sender, DependencyPropertyChangedEventArgs e)
{
if (this->d3dimg->IsFrontBufferAvailable) {
InitializeD3D();
} else {
DeinitializeD3D();
}
}
void OnD3DRendering(Object^ sender, EventArgs^ e)
{
if (this->d3dimg->IsFrontBufferAvailable)
{
// Try lock will begin to fail persistently, setting the timespan higher helps,
// but once it locks it seems unable to re-lock, levels tried were 2, and 22.
//this->d3dimg->TryLock(Duration(TimeSpan(22)))
this->d3dimg->Lock();
this->RenderD3D();
this->d3dimg->AddDirtyRect(*Dimensions);
this->d3dimg->Unlock();
}
}
void RenderD3D() {
// Clear is only necessary if we plan to support transparency and the copy operation combines
// the source and destination operations. Otherwise the full bitmap is just copied, and thus,
// clears the source.
//this->d3ddata->d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0, 0, 0, 0), 1.0f, 0);
if (SUCCEEDED(this->d3ddata->d3ddev->BeginScene()))
{
HDC surfaceDC;
this->d3ddata->dest->GetDC(&surfaceDC);
// A variety of drawing methods:
//BLENDFUNCTION blend = { AC_SRC_OVER, 0, 100, AC_SRC_ALPHA };
//AlphaBlend(surfaceDC, 0, 0, DpiWidth, DpiHeight, hdcFrom, 0, 0, DpiWidth, DpiHeight, blend);
//Does not draw, anything.. TransparentBlt(surfaceDC, 0, 0, DpiWidth, DpiHeight, hdcFrom, 0, 0, DpiWidth, DpiHeight, RGB(0xff,0x00,0xff));
//RECT rect = { 0, 0, DpiWidth, DpiHeight };
//OleDraw(this->oledata->iUnknown, DVASPECT_CONTENT, surfaceDC, &rect);
//StretchBlt(surfaceDC, 0, 0, DpiWidth, DpiHeight, hdcFrom, 0, 0, DpiWidth, DpiHeight, SRCCOPY);
BitBlt(surfaceDC, 0, 0, DpiWidth, DpiHeight, hdcFrom, 0, 0, SRCCOPY);
this->d3ddata->dest->ReleaseDC(surfaceDC);
this->d3ddata->d3ddev->EndScene();
#ifdef FRAME_RATE_ENABLED
frameRate++;
#endif
}
}
void DeinitializeD3D() {
// timer->Stop();
if (this->d3ddata->d3ddev != NULL) {
this->d3ddata->d3ddev->Release();
}
if (this->d3ddata->d3d9 != NULL) {
this->d3ddata->d3d9->Release();
}
if (this->d3ddata->dest != NULL) {
this->d3ddata->dest->Release();
}
this->d3ddata = NULL;
}
void InitializeD3D() {
if(this->d3dimg->IsFrontBufferAvailable) {
this->d3ddata = new D3DData();
HWND hWnd = (HWND)(gcnew WindowInteropHelper(this->mWnd))->Handle.ToPointer();
if (FAILED(Direct3DCreate9Ex(D3D_SDK_VERSION, ((IDirect3D9Ex**)&(this->d3ddata->d3d9))))) {
Console::WriteLine("Direct3DCreate9Ex failed.");
abort();
}
if(FAILED(this->d3ddata->d3d9->QueryInterface(__uuidof(IDirect3D9), reinterpret_cast<void **>(&(this->d3ddata->d3d9))))) {
Console::WriteLine("D3D9->QueryInterface failed.");
abort();
}
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = TRUE;
d3dpp.BackBufferHeight = 1;
d3dpp.BackBufferWidth = 1;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
if(FAILED(this->d3ddata->d3d9->CreateDeviceEx(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING,
&d3dpp,
NULL,
&(this->d3ddata->d3ddev))))
{
Console::WriteLine("CreateDeviceEX failed.");
abort();
}
if(FAILED(this->d3ddata->d3ddev->QueryInterface(__uuidof(IDirect3DDevice9), reinterpret_cast<void **>(&(this->d3ddata->d3ddev)))))
{
Console::WriteLine("Device->QueryInterface failed.");
abort();
}
// Create a surface that has the capability of hosting the largest
// possible view we need so we don't have to resize the surface or
// destroy and recreate it later when the user resizes. Wasteful?
// absolutely, but it works for now.
if(FAILED(this->d3ddata->d3ddev->CreateRenderTarget((UINT)(1920*dpiX),
(UINT)(1200*dpiY),
D3DFMT_A8R8G8B8,
D3DMULTISAMPLE_NONE,
0,
true,
&(this->d3ddata->dest),
NULL)))
{
Console::WriteLine("Device->CreateRenderTarget failed.");
abort();
}
this->d3ddata->d3ddev->SetRenderTarget(0, this->d3ddata->dest);
this->d3ddata->d3ddev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
this->d3ddata->d3ddev->SetRenderState(D3DRS_LIGHTING, FALSE);
this->d3dimg->Lock();
this->d3dimg->SetBackBuffer(System::Windows::Interop::D3DResourceType::IDirect3DSurface9, IntPtr(this->d3ddata->dest));
this->d3dimg->Unlock();
System::Windows::Threading::DispatcherTimer^ timer = gcnew System::Windows::Threading::DispatcherTimer(System::Windows::Threading::DispatcherPriority::Render);
timer->Tick += gcnew EventHandler(this, &WebBrowserEx::OnD3DRendering);
timer->Interval = TimeSpan(0,0,0,0,TIMER_MILLISECONDS);
timer->Start();
}
}
OLEData *oledata;
D3DData *d3ddata;
Image^ img;
Window^ mWnd;
D3DImage^ d3dimg;
Application^ app;
System::Windows::Controls::WebBrowser^ brwsr;
HWND brwsrHwnd;
HDC hdcFrom;
HDC hdcTo;
HBITMAP hBitmap;
double dpiX;
double dpiY;
int Width;
int Height;
int DpiWidth;
int DpiHeight;
Int32Rect^ Dimensions;
int CurrentFrameDpiWidth;
int CurrentFrameDpiHeight;
bool renderModeDirectX;
WriteableBitmap^ source;
};
[STAThread]
// if pragma /subsystem:windows
int WinMain (HINSTANCE inst, HINSTANCE pinst, LPSTR cmdlne, int cmdshow) {
WebBrowserEx ^app = gcnew WebBrowserEx();
app->Run(/* useDirectX */ true);
}
// if pragma /subsystem = console
void main (int argc, char **argv) {
WebBrowserEx ^app = gcnew WebBrowserEx();
app->Run(/* useDirectX */ true);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment