From 6a17f6c388fb12e55ebfa947eda29077e3d2ebfc Mon Sep 17 00:00:00 2001 From: Arkady Trestman Date: Tue, 15 Sep 2009 00:21:13 +0000 Subject: [PATCH] initial commit --- direct/src/plugin_activex/P3DActiveX.cpp | 262 +++++++++ direct/src/plugin_activex/P3DActiveX.def | 9 + direct/src/plugin_activex/P3DActiveX.h | 38 ++ direct/src/plugin_activex/P3DActiveX.idl | 51 ++ direct/src/plugin_activex/P3DActiveX.inf | 12 + direct/src/plugin_activex/P3DActiveX.rc | 160 ++++++ direct/src/plugin_activex/P3DActiveX.sln | 32 ++ direct/src/plugin_activex/P3DActiveX.vcproj | 254 +++++++++ direct/src/plugin_activex/P3DActiveXCtrl.bmp | Bin 0 -> 238 bytes direct/src/plugin_activex/P3DActiveXCtrl.cpp | 394 +++++++++++++ direct/src/plugin_activex/P3DActiveXCtrl.h | 94 ++++ .../src/plugin_activex/P3DActiveXPropPage.cpp | 76 +++ .../src/plugin_activex/P3DActiveXPropPage.h | 42 ++ direct/src/plugin_activex/P3DActiveX_i.c | 93 +++ direct/src/plugin_activex/P3DActiveXidl.h | 316 +++++++++++ direct/src/plugin_activex/PPBrowserObject.cpp | 202 +++++++ direct/src/plugin_activex/PPBrowserObject.h | 45 ++ .../src/plugin_activex/PPDownloadCallback.cpp | 237 ++++++++ .../src/plugin_activex/PPDownloadCallback.h | 64 +++ .../src/plugin_activex/PPDownloadRequest.cpp | 98 ++++ direct/src/plugin_activex/PPDownloadRequest.h | 74 +++ direct/src/plugin_activex/PPInstance.cpp | 502 +++++++++++++++++ direct/src/plugin_activex/PPInstance.h | 77 +++ direct/src/plugin_activex/PPInterface.cpp | 531 ++++++++++++++++++ direct/src/plugin_activex/PPInterface.h | 48 ++ direct/src/plugin_activex/PPLogger.cpp | 133 +++++ direct/src/plugin_activex/PPLogger.h | 41 ++ direct/src/plugin_activex/PPPandaObject.cpp | 184 ++++++ direct/src/plugin_activex/PPPandaObject.h | 70 +++ direct/src/plugin_activex/ReadMe.txt | 79 +++ direct/src/plugin_activex/resource.h | 27 + direct/src/plugin_activex/stdafx.cpp | 5 + direct/src/plugin_activex/stdafx.h | 43 ++ 33 files changed, 4293 insertions(+) create mode 100644 direct/src/plugin_activex/P3DActiveX.cpp create mode 100644 direct/src/plugin_activex/P3DActiveX.def create mode 100644 direct/src/plugin_activex/P3DActiveX.h create mode 100644 direct/src/plugin_activex/P3DActiveX.idl create mode 100644 direct/src/plugin_activex/P3DActiveX.inf create mode 100644 direct/src/plugin_activex/P3DActiveX.rc create mode 100644 direct/src/plugin_activex/P3DActiveX.sln create mode 100644 direct/src/plugin_activex/P3DActiveX.vcproj create mode 100644 direct/src/plugin_activex/P3DActiveXCtrl.bmp create mode 100644 direct/src/plugin_activex/P3DActiveXCtrl.cpp create mode 100644 direct/src/plugin_activex/P3DActiveXCtrl.h create mode 100644 direct/src/plugin_activex/P3DActiveXPropPage.cpp create mode 100644 direct/src/plugin_activex/P3DActiveXPropPage.h create mode 100644 direct/src/plugin_activex/P3DActiveX_i.c create mode 100644 direct/src/plugin_activex/P3DActiveXidl.h create mode 100644 direct/src/plugin_activex/PPBrowserObject.cpp create mode 100644 direct/src/plugin_activex/PPBrowserObject.h create mode 100644 direct/src/plugin_activex/PPDownloadCallback.cpp create mode 100644 direct/src/plugin_activex/PPDownloadCallback.h create mode 100644 direct/src/plugin_activex/PPDownloadRequest.cpp create mode 100644 direct/src/plugin_activex/PPDownloadRequest.h create mode 100644 direct/src/plugin_activex/PPInstance.cpp create mode 100644 direct/src/plugin_activex/PPInstance.h create mode 100644 direct/src/plugin_activex/PPInterface.cpp create mode 100644 direct/src/plugin_activex/PPInterface.h create mode 100644 direct/src/plugin_activex/PPLogger.cpp create mode 100644 direct/src/plugin_activex/PPLogger.h create mode 100644 direct/src/plugin_activex/PPPandaObject.cpp create mode 100644 direct/src/plugin_activex/PPPandaObject.h create mode 100644 direct/src/plugin_activex/ReadMe.txt create mode 100644 direct/src/plugin_activex/resource.h create mode 100644 direct/src/plugin_activex/stdafx.cpp create mode 100644 direct/src/plugin_activex/stdafx.h diff --git a/direct/src/plugin_activex/P3DActiveX.cpp b/direct/src/plugin_activex/P3DActiveX.cpp new file mode 100644 index 0000000000..2aacf25027 --- /dev/null +++ b/direct/src/plugin_activex/P3DActiveX.cpp @@ -0,0 +1,262 @@ +// P3DActiveX.cpp : Implementation of CP3DActiveXApp and DLL registration. + +// Filename: P3DActiveX.cpp +// Created by: atrestman (14Sept09) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "P3DActiveX.h" + +#include "comcat.h" +#include "strsafe.h" +#include "objsafe.h" + + +#ifdef _DEBUG +#define new DEBUG_NEW +#endif + + +CP3DActiveXApp NEAR theApp; + +const GUID CDECL BASED_CODE _tlid = + { 0x22A8FC5F, 0xBC33, 0x479A, { 0x83, 0x17, 0x2B, 0xC8, 0x16, 0xB8, 0xAB, 0x8A } }; +const WORD _wVerMajor = 1; +const WORD _wVerMinor = 0; + +// CLSID_SafeItem - Necessary for safe ActiveX control + +// Id taken from IMPLEMENT_OLECREATE_EX function in xxxCtrl.cpp + + +const CATID CLSID_SafeItem = +{ 0x924b4927, 0xd3ba, 0x41ea, 0x9f, 0x7e, 0x8a, 0x89, 0x19, 0x4a, 0xb3, 0xac }; + +// HRESULT CreateComponentCategory - Used to register ActiveX control as safe + + +HRESULT CreateComponentCategory(CATID catid, WCHAR *catDescription) +{ + ICatRegister *pcr = NULL ; + HRESULT hr = S_OK ; + + hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, + NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr); + if (FAILED(hr)) + return hr; + + // Make sure the HKCR\Component Categories\{..catid...} + + // key is registered. + + CATEGORYINFO catinfo; + catinfo.catid = catid; + catinfo.lcid = 0x0409 ; // english + + size_t len; + // Make sure the provided description is not too long. + + // Only copy the first 127 characters if it is. + + // The second parameter of StringCchLength is the maximum + + // number of characters that may be read into catDescription. + + // There must be room for a NULL-terminator. The third parameter + + // contains the number of characters excluding the NULL-terminator. + + hr = StringCchLengthW(catDescription, STRSAFE_MAX_CCH, &len); + if (SUCCEEDED(hr)) + { + if (len>127) + { + len = 127; + } + } + else + { + // TODO: Write an error handler; + + } + // The second parameter of StringCchCopy is 128 because you need + + // room for a NULL-terminator. + + hr = StringCchCopyW(catinfo.szDescription, len + 1, catDescription); + // Make sure the description is null terminated. + + catinfo.szDescription[len + 1] = '\0'; + + hr = pcr->RegisterCategories(1, &catinfo); + pcr->Release(); + + return hr; +} + +// HRESULT RegisterCLSIDInCategory - + +// Register your component categories information + + +HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid) +{ +// Register your component categories information. + + ICatRegister *pcr = NULL ; + HRESULT hr = S_OK ; + hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, + NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr); + if (SUCCEEDED(hr)) + { + // Register this category as being "implemented" by the class. + + CATID rgcatid[1] ; + rgcatid[0] = catid; + hr = pcr->RegisterClassImplCategories(clsid, 1, rgcatid); + } + + if (pcr != NULL) + pcr->Release(); + + return hr; +} + +// HRESULT UnRegisterCLSIDInCategory - Remove entries from the registry + + +HRESULT UnRegisterCLSIDInCategory(REFCLSID clsid, CATID catid) +{ + ICatRegister *pcr = NULL ; + HRESULT hr = S_OK ; + + hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, + NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr); + if (SUCCEEDED(hr)) + { + // Unregister this category as being "implemented" by the class. + + CATID rgcatid[1] ; + rgcatid[0] = catid; + hr = pcr->UnRegisterClassImplCategories(clsid, 1, rgcatid); + } + + if (pcr != NULL) + pcr->Release(); + + return hr; +} + + +// CP3DActiveXApp::InitInstance - DLL initialization + +BOOL CP3DActiveXApp::InitInstance() +{ + BOOL bInit = COleControlModule::InitInstance(); + + if (bInit) + { + // TODO: Add your own module initialization code here. + } + + return bInit; +} + + + +// CP3DActiveXApp::ExitInstance - DLL termination + +int CP3DActiveXApp::ExitInstance() +{ + // TODO: Add your own module termination code here. + + return COleControlModule::ExitInstance(); +} + + + +// DllRegisterServer - Adds entries to the system registry + +STDAPI DllRegisterServer(void) +{ + HRESULT hr; // HResult used by Safety Functions + + + AFX_MANAGE_STATE(_afxModuleAddrThis); + + if (!AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid)) + return ResultFromScode(SELFREG_E_TYPELIB); + + if (!COleObjectFactoryEx::UpdateRegistryAll(TRUE)) + return ResultFromScode(SELFREG_E_CLASS); + + // Mark the control as safe for initializing. + + + hr = CreateComponentCategory(CATID_SafeForInitializing, + L"Controls safely initializable from persistent data!"); + if (FAILED(hr)) + return hr; + + hr = RegisterCLSIDInCategory(CLSID_SafeItem, + CATID_SafeForInitializing); + if (FAILED(hr)) + return hr; + + // Mark the control as safe for scripting. + + + hr = CreateComponentCategory(CATID_SafeForScripting, + L"Controls safely scriptable!"); + if (FAILED(hr)) + return hr; + + hr = RegisterCLSIDInCategory(CLSID_SafeItem, + CATID_SafeForScripting); + if (FAILED(hr)) + return hr; + + return NOERROR; +} + + + +// DllUnregisterServer - Removes entries from the system registry + +STDAPI DllUnregisterServer(void) +{ + HRESULT hr; // HResult used by Safety Functions + + + AFX_MANAGE_STATE(_afxModuleAddrThis); + + // Remove entries from the registry. + + hr = UnRegisterCLSIDInCategory(CLSID_SafeItem, + CATID_SafeForInitializing); + if (FAILED(hr)) + return hr; + + hr = UnRegisterCLSIDInCategory(CLSID_SafeItem, + CATID_SafeForScripting); + if (FAILED(hr)) + return hr; + + if (!AfxOleUnregisterTypeLib(_tlid, _wVerMajor, _wVerMinor)) + return ResultFromScode(SELFREG_E_TYPELIB); + + if (!COleObjectFactoryEx::UpdateRegistryAll(FALSE)) + return ResultFromScode(SELFREG_E_CLASS); + + return NOERROR; +} diff --git a/direct/src/plugin_activex/P3DActiveX.def b/direct/src/plugin_activex/P3DActiveX.def new file mode 100644 index 0000000000..e8ca82f83a --- /dev/null +++ b/direct/src/plugin_activex/P3DActiveX.def @@ -0,0 +1,9 @@ +; P3DActiveX.def : Declares the module parameters. + +LIBRARY "P3DActiveX.OCX" + +EXPORTS + DllCanUnloadNow PRIVATE + DllGetClassObject PRIVATE + DllRegisterServer PRIVATE + DllUnregisterServer PRIVATE diff --git a/direct/src/plugin_activex/P3DActiveX.h b/direct/src/plugin_activex/P3DActiveX.h new file mode 100644 index 0000000000..2a680d53e0 --- /dev/null +++ b/direct/src/plugin_activex/P3DActiveX.h @@ -0,0 +1,38 @@ +#pragma once + +// P3DActiveX.h : main header file for P3DActiveX.DLL + +// Filename: P3DActiveX.h +// Created by: atrestman (14Sept09) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#if !defined( __AFXCTL_H__ ) +#error include 'afxctl.h' before including this file +#endif + +#include "resource.h" // main symbols + + +// CP3DActiveXApp : See P3DActiveX.cpp for implementation. + +class CP3DActiveXApp : public COleControlModule +{ +public: + BOOL InitInstance(); + int ExitInstance(); +}; + +extern const GUID CDECL _tlid; +extern const WORD _wVerMajor; +extern const WORD _wVerMinor; + diff --git a/direct/src/plugin_activex/P3DActiveX.idl b/direct/src/plugin_activex/P3DActiveX.idl new file mode 100644 index 0000000000..4406b55abe --- /dev/null +++ b/direct/src/plugin_activex/P3DActiveX.idl @@ -0,0 +1,51 @@ +// P3DActiveX.idl : type library source for ActiveX Control project. + +// This file will be processed by the MIDL compiler tool to +// produce the type library (P3DActiveX.tlb) that will become a resource in +// P3DActiveX.ocx. + +#include +#include + +[ uuid(22A8FC5F-BC33-479A-8317-2BC816B8AB8A), version(1.0), + helpfile("P3DActiveX.hlp"), + helpstring("P3DActiveX ActiveX Control module"), + control ] +library P3DActiveXLib +{ + importlib(STDOLE_TLB); + + // Primary dispatch interface for CP3DActiveXCtrl + + [ uuid(76904D54-0CC5-4DBB-B022-F48B1E95183B), + helpstring("Dispatch interface for P3DActiveX Control")] + dispinterface _DP3DActiveX + { + properties: + [id(1), helpstring("property main")] IDispatch*main; + methods: + }; + + // Event dispatch interface for CP3DActiveXCtrl + + [ uuid(1B2413ED-51C8-495E-B917-983C459B8FC7), + helpstring("Event interface for P3DActiveX Control") ] + dispinterface _DP3DActiveXEvents + { + properties: + // Event interface has no properties + + methods: + }; + + // Class information for CP3DActiveXCtrl + + [ uuid(924B4927-D3BA-41EA-9F7E-8A89194AB3AC), + helpstring("P3DActiveX Control"), control ] + coclass P3DActiveX + { + [default] dispinterface _DP3DActiveX; + [default, source] dispinterface _DP3DActiveXEvents; + }; + +}; diff --git a/direct/src/plugin_activex/P3DActiveX.inf b/direct/src/plugin_activex/P3DActiveX.inf new file mode 100644 index 0000000000..cffb1d3f41 --- /dev/null +++ b/direct/src/plugin_activex/P3DActiveX.inf @@ -0,0 +1,12 @@ +[Add.Code] +P3DActiveX.ocx=P3DActiveX.ocx +P3DActiveX.inf=P3DActiveX.inf + +[P3DActiveX.ocx] +file=thiscab +clsid={924B4927-D3BA-41EA-9F7E-8A89194AB3AC} +RegisterServer=yes +FileVersion=1,0,0,0 + +[P3DActiveX.inf] +file=thiscab \ No newline at end of file diff --git a/direct/src/plugin_activex/P3DActiveX.rc b/direct/src/plugin_activex/P3DActiveX.rc new file mode 100644 index 0000000000..5fda0e1288 --- /dev/null +++ b/direct/src/plugin_activex/P3DActiveX.rc @@ -0,0 +1,160 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "1 TYPELIB ""P3DActiveX.tlb""\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,1 + PRODUCTVERSION 1,0,0,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904e4" + BEGIN + VALUE "CompanyName", "Disney" + VALUE "FileDescription", "P3D ActiveX " + VALUE "FileVersion", "1.0.0.1" + VALUE "InternalName", "P3DActiveX.ocx" + VALUE "LegalCopyright", "Disney (c). All rights reserved." + VALUE "OLESelfRegister", "\0" + VALUE "OriginalFilename", "P3DActiveX.ocx" + VALUE "ProductName", "Disney P3D" + VALUE "ProductVersion", "1.0.0.1" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDB_P3DACTIVEX BITMAP "P3DActiveXCtrl.bmp" + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_PROPPAGE_P3DACTIVEX DIALOG 0, 0, 250, 62 +STYLE DS_SETFONT | WS_CHILD +FONT 8, "MS Sans Serif" +BEGIN + LTEXT "TODO: Place controls to manipulate properties of P3DActiveX Control on this dialog.", + IDC_STATIC,7,25,229,16 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_PROPPAGE_P3DACTIVEX, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 243 + TOPMARGIN, 7 + BOTTOMMARGIN, 55 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDS_P3DACTIVEX "P3DActiveX Control" + IDS_P3DACTIVEX_PPG "P3DActiveX Property Page" +END + +STRINGTABLE +BEGIN + IDS_P3DACTIVEX_PPG_CAPTION "General" +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// +1 TYPELIB "P3DActiveX.tlb" + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/direct/src/plugin_activex/P3DActiveX.sln b/direct/src/plugin_activex/P3DActiveX.sln new file mode 100644 index 0000000000..888984fe2e --- /dev/null +++ b/direct/src/plugin_activex/P3DActiveX.sln @@ -0,0 +1,32 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "P3DActiveX", "P3DActiveX.vcproj", "{74451B00-2D87-412B-9359-B5CA2C2FEC2A}" + ProjectSection(ProjectDependencies) = postProject + {1278896B-1978-40CC-B1A0-2D6A7450A32C} = {1278896B-1978-40CC-B1A0-2D6A7450A32C} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tinyxml", "..\..\..\wintools\sdk\tinyxml\tinyxml_lib_mfc_static.vcproj", "{1278896B-1978-40CC-B1A0-2D6A7450A32C}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectDependencies) = postSolution + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {74451B00-2D87-412B-9359-B5CA2C2FEC2A}.Debug.ActiveCfg = Debug|Win32 + {74451B00-2D87-412B-9359-B5CA2C2FEC2A}.Debug.Build.0 = Debug|Win32 + {74451B00-2D87-412B-9359-B5CA2C2FEC2A}.Release.ActiveCfg = Release|Win32 + {74451B00-2D87-412B-9359-B5CA2C2FEC2A}.Release.Build.0 = Release|Win32 + {1278896B-1978-40CC-B1A0-2D6A7450A32C}.Debug.ActiveCfg = Debug|Win32 + {1278896B-1978-40CC-B1A0-2D6A7450A32C}.Debug.Build.0 = Debug|Win32 + {1278896B-1978-40CC-B1A0-2D6A7450A32C}.Release.ActiveCfg = Release|Win32 + {1278896B-1978-40CC-B1A0-2D6A7450A32C}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/direct/src/plugin_activex/P3DActiveX.vcproj b/direct/src/plugin_activex/P3DActiveX.vcproj new file mode 100644 index 0000000000..169f5d7a54 --- /dev/null +++ b/direct/src/plugin_activex/P3DActiveX.vcproj @@ -0,0 +1,254 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/direct/src/plugin_activex/P3DActiveXCtrl.bmp b/direct/src/plugin_activex/P3DActiveXCtrl.bmp new file mode 100644 index 0000000000000000000000000000000000000000..3ffeb056fd30dd555c96a153a12070f902dbf036 GIT binary patch literal 238 zcmaisyA6Oa3`7r!9>!n}dP+;41W~3r$zx?ARtT3*3BvZfvmM3zaihm6+r%msF=3Vh zSJO91fC?#fld2U7IcGhTRw$)*LRnXm_z7Cj7-n?i@Cei37EzbgErz$5boPJFuk#OT CFi + +class CPropbagPropExchange : public CPropExchange +{ +public: + CPropbagPropExchange(LPPROPERTYBAG pPropBag, LPERRORLOG pErrorLog, + BOOL bLoading, BOOL bSaveAllProperties=FALSE); + ~CPropbagPropExchange(); + +// Operations + virtual BOOL ExchangeProp(LPCTSTR pszPropName, VARTYPE vtProp, + void* pvProp, const void* pvDefault = NULL); + virtual BOOL ExchangeBlobProp(LPCTSTR pszPropName, HGLOBAL* phBlob, + HGLOBAL hBlobDefault = NULL); + virtual BOOL ExchangeFontProp(LPCTSTR pszPropName, CFontHolder& font, + const FONTDESC* pFontDesc, LPFONTDISP pFontDispAmbient); + virtual BOOL ExchangePersistentProp(LPCTSTR pszPropName, + LPUNKNOWN* ppUnk, REFIID iid, LPUNKNOWN pUnkDefault); + +// Implementation + LPPROPERTYBAG m_pPropBag; + LPERRORLOG m_pErrorLog; + BOOL m_bSaveAllProperties; +}; + +#ifdef _DEBUG +#define new DEBUG_NEW +#endif + + +IMPLEMENT_DYNCREATE(CP3DActiveXCtrl, COleControl) + + + +// Message map + +BEGIN_MESSAGE_MAP(CP3DActiveXCtrl, COleControl) + ON_MESSAGE(OCM_COMMAND, OnOcmCommand) + ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties) + ON_WM_CREATE() + ON_MESSAGE(WM_PANDA_NOTIFICATION, OnPandaNotification) +END_MESSAGE_MAP() + + + +// Dispatch map + +BEGIN_DISPATCH_MAP(CP3DActiveXCtrl, COleControl) + DISP_PROPERTY_NOTIFY_ID(CP3DActiveXCtrl, "main", dispidmain, m_pPandaObject, OnmainChanged, VT_DISPATCH) +END_DISPATCH_MAP() + + + +// Event map + +BEGIN_EVENT_MAP(CP3DActiveXCtrl, COleControl) +END_EVENT_MAP() + + + +// Property pages + +// TODO: Add more property pages as needed. Remember to increase the count! +BEGIN_PROPPAGEIDS(CP3DActiveXCtrl, 1) + PROPPAGEID(CP3DActiveXPropPage::guid) +END_PROPPAGEIDS(CP3DActiveXCtrl) + + + +// Initialize class factory and guid + +IMPLEMENT_OLECREATE_EX(CP3DActiveXCtrl, "P3DACTIVEX.P3DActiveXCtrl.1", + 0x924b4927, 0xd3ba, 0x41ea, 0x9f, 0x7e, 0x8a, 0x89, 0x19, 0x4a, 0xb3, 0xac) + + + +// Type library ID and version + +IMPLEMENT_OLETYPELIB(CP3DActiveXCtrl, _tlid, _wVerMajor, _wVerMinor) + + + +// Interface IDs + +const IID BASED_CODE IID_DP3DActiveX = + { 0x76904D54, 0xCC5, 0x4DBB, { 0xB0, 0x22, 0xF4, 0x8B, 0x1E, 0x95, 0x18, 0x3B } }; +const IID BASED_CODE IID_DP3DActiveXEvents = + { 0x1B2413ED, 0x51C8, 0x495E, { 0xB9, 0x17, 0x98, 0x3C, 0x45, 0x9B, 0x8F, 0xC7 } }; + + + +// Control type information + +static const DWORD BASED_CODE _dwP3DActiveXOleMisc = + OLEMISC_ACTIVATEWHENVISIBLE | + OLEMISC_SETCLIENTSITEFIRST | + OLEMISC_INSIDEOUT | + OLEMISC_CANTLINKINSIDE | + OLEMISC_RECOMPOSEONRESIZE; + +IMPLEMENT_OLECTLTYPE(CP3DActiveXCtrl, IDS_P3DACTIVEX, _dwP3DActiveXOleMisc) + + + +// CP3DActiveXCtrl::CP3DActiveXCtrlFactory::UpdateRegistry - +// Adds or removes system registry entries for CP3DActiveXCtrl + +BOOL CP3DActiveXCtrl::CP3DActiveXCtrlFactory::UpdateRegistry(BOOL bRegister) +{ + // TODO: Verify that your control follows apartment-model threading rules. + // Refer to MFC TechNote 64 for more information. + // If your control does not conform to the apartment-model rules, then + // you must modify the code below, changing the 6th parameter from + // afxRegApartmentThreading to 0. + + if (bRegister) + return AfxOleRegisterControlClass( + AfxGetInstanceHandle(), + m_clsid, + m_lpszProgID, + IDS_P3DACTIVEX, + IDB_P3DACTIVEX, + afxRegApartmentThreading, + _dwP3DActiveXOleMisc, + _tlid, + _wVerMajor, + _wVerMinor); + else + return AfxOleUnregisterClass(m_clsid, m_lpszProgID); +} + + + +// CP3DActiveXCtrl::CP3DActiveXCtrl - Constructor + +CP3DActiveXCtrl::CP3DActiveXCtrl() : m_pPandaObject( NULL ), m_instance( *this ) +{ + InitializeIIDs(&IID_DP3DActiveX, &IID_DP3DActiveXEvents); + // TODO: Initialize your control's instance data here. + +} + +// CP3DActiveXCtrl::~CP3DActiveXCtrl - Destructor + +CP3DActiveXCtrl::~CP3DActiveXCtrl() +{ + // TODO: Cleanup your control's instance data here. + if ( m_pPandaObject ) + { + delete m_pPandaObject; + } +} + + + +// CP3DActiveXCtrl::OnDraw - Drawing function + +void CP3DActiveXCtrl::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid) +{ + if (!pdc) + return; + + CBrush brBackGnd(TranslateColor(AmbientBackColor())); + pdc->FillRect(rcBounds, &brBackGnd); + + DoSuperclassPaint(pdc, rcBounds); +} + + + +// CP3DActiveXCtrl::DoPropExchange - Persistence support + +void CP3DActiveXCtrl::DoPropExchange(CPropExchange* pPX) +{ + ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor)); + COleControl::DoPropExchange(pPX); + + // TODO: Call PX_ functions for each persistent custom property. + + ExchangeProperties( pPX ); +} + + + +// CP3DActiveXCtrl::GetControlFlags - +// Flags to customize MFC's implementation of ActiveX controls. +// +DWORD CP3DActiveXCtrl::GetControlFlags() +{ + DWORD dwFlags = COleControl::GetControlFlags(); + + + // The control will not be redrawn when making the transition + // between the active and inactivate state. + dwFlags |= noFlickerActivate; + return dwFlags; +} + + + +// CP3DActiveXCtrl::OnResetState - Reset control to default state + +void CP3DActiveXCtrl::OnResetState() +{ + COleControl::OnResetState(); // Resets defaults found in DoPropExchange + + // TODO: Reset any other control state here. +} + + + +// CP3DActiveXCtrl::PreCreateWindow - Modify parameters for CreateWindowEx + +BOOL CP3DActiveXCtrl::PreCreateWindow(CREATESTRUCT& cs) +{ + cs.lpszClass = _T("STATIC"); + return COleControl::PreCreateWindow(cs); +} + + + +// CP3DActiveXCtrl::IsSubclassedControl - This is a subclassed control + +BOOL CP3DActiveXCtrl::IsSubclassedControl() +{ + return TRUE; +} + + + +// CP3DActiveXCtrl::OnOcmCommand - Handle command messages + +LRESULT CP3DActiveXCtrl::OnOcmCommand(WPARAM wParam, LPARAM lParam) +{ +#ifdef _WIN32 + WORD wNotifyCode = HIWORD(wParam); +#else + WORD wNotifyCode = HIWORD(lParam); +#endif + + // TODO: Switch on wNotifyCode here. + + return 0; +} + +// CP3DActiveXCtrl message handlers + +int CP3DActiveXCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + if (COleControl::OnCreate(lpCreateStruct) == -1) + return -1; + + // TODO: Add your specialized creation code here + + int error(0); + m_spClientSite = GetClientSite(); + if ( !m_spClientSite ) + { + return ( error = -1 ); + } + std::string p3dDllFilename, p3dFilename; + error = m_instance.DownloadP3DComponents( p3dDllFilename, p3dFilename ); + if ( !error && !( p3dDllFilename.empty() ) ) + { + error = m_instance.LoadPlugin( p3dDllFilename ); + if ( !error ) + { + m_pPandaObject = new PPandaObject( this, NULL ); + m_instance.Start( p3dFilename ); + } + } + return 0; +} + +LRESULT CP3DActiveXCtrl::OnPandaNotification(WPARAM wParam, LPARAM lParam) +{ + PPInstance::HandleRequestLoop(); + + return 0; +} + +HRESULT CP3DActiveXCtrl::ExchangeProperties(CPropExchange* pPX) +{ + USES_CONVERSION; + HRESULT hr = E_FAIL; + + if ( !pPX ) + { + return hr; + } + CPropbagPropExchange* pPropExchange = dynamic_cast( pPX ); + if ( !pPropExchange || !pPropExchange->m_pPropBag ) + { + return hr; + } + + // get the property bag version 2 + IPropertyBag2 * pPropBag2; + hr = pPropExchange->m_pPropBag->QueryInterface( IID_IPropertyBag2, (void**)&pPropBag2); + if (! SUCCEEDED (hr)) { + return hr; + } + + // get the number of parameters + unsigned long aNum; + hr = pPropBag2->CountProperties (& aNum); + ATLASSERT (hr >= 0); + if (! SUCCEEDED (hr)) { + return hr; + } + if (aNum == 0) return S_OK; + + // allocate the parameters names + PROPBAG2 * aPropNames = new PROPBAG2[aNum]; + unsigned long aReaded; + + // get the param names + hr = pPropBag2->GetPropertyInfo (0, aNum, aPropNames, & aReaded); + ATLASSERT (hr >= 0); + if (! SUCCEEDED (hr)) { + delete[] aPropNames; + return hr; + } + // allocate the variants and result array + CComVariant * aVal = new CComVariant[aNum]; + HRESULT * hvs = new HRESULT[aNum]; + hr = pPropBag2->Read (aNum, aPropNames, NULL, aVal, hvs); + ATLASSERT (hr >= 0); + if (! SUCCEEDED (hr)) { + delete[] hvs; + delete[] aVal; + delete[] aPropNames; + return hr; + } + + // get the params ; put them in the ParamList + for (unsigned long ind = 0; ind < aNum; ind++) { + std::pair< CString, CString> p( CString( aPropNames[ind].pstrName ), CString( aVal[ind] ) ); + m_parameters.push_back( p ); +// do_what_you_want_with (OLE2T (aPropNames[ind].pstrName), +// aVal[ind]); + } + // delete the unused arrays + delete[] hvs; + delete[] aVal; + delete[] aPropNames; + + return hr; +} + +P3D_object* CP3DActiveXCtrl::GetP3DObject( ) +{ + return m_instance.m_p3dObject; +} + +IOleClientSite* CP3DActiveXCtrl::GetClientSte( ) +{ + return GetClientSite(); +} + +void CP3DActiveXCtrl::OnmainChanged(void) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + + // TODO: Add your property handler code here + + SetModifiedFlag(); +} diff --git a/direct/src/plugin_activex/P3DActiveXCtrl.h b/direct/src/plugin_activex/P3DActiveXCtrl.h new file mode 100644 index 0000000000..56ca08436c --- /dev/null +++ b/direct/src/plugin_activex/P3DActiveXCtrl.h @@ -0,0 +1,94 @@ +// Filename: P3DActiveXCtrl.h +// Created by: atrestman (14Sept09) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#pragma once + +// P3DActiveXCtrl.h : Declaration of the CP3DActiveXCtrl ActiveX Control class. +#include "PPInstance.h" +#include "PPPandaObject.h" +#include "PPInterface.h" +#include "Mshtml.h" + +#include + +// CP3DActiveXCtrl : See P3DActiveXCtrl.cpp for implementation. + +class CP3DActiveXCtrl : public COleControl, + public PPInterface +{ + DECLARE_DYNCREATE(CP3DActiveXCtrl) + +// Constructor +public: + CP3DActiveXCtrl(); + +// Overrides +public: + virtual void OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid); + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + virtual void DoPropExchange(CPropExchange* pPX); + virtual void OnResetState(); + virtual DWORD GetControlFlags(); + + int BeginDownload(CString& url); + + PPInstance m_instance; + +// Implementation +protected: + ~CP3DActiveXCtrl(); + + DECLARE_OLECREATE_EX(CP3DActiveXCtrl) // Class factory and guid + DECLARE_OLETYPELIB(CP3DActiveXCtrl) // GetTypeInfo + DECLARE_PROPPAGEIDS(CP3DActiveXCtrl) // Property page IDs + DECLARE_OLECTLTYPE(CP3DActiveXCtrl) // Type name and misc status + + // Subclassed control support + BOOL IsSubclassedControl(); + LRESULT OnOcmCommand(WPARAM wParam, LPARAM lParam); + +// Message maps + DECLARE_MESSAGE_MAP() + +// Dispatch maps + DECLARE_DISPATCH_MAP() + +// Event maps + DECLARE_EVENT_MAP() + +// Dispatch and event IDs +public: + enum { + dispidmain = 1 + }; + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + + virtual P3D_object* GetP3DObject( ); + virtual IOleClientSite* GetClientSte(); + + // ActiveX properties + std::vector< std::pair < CString, CString > > m_parameters; + +protected: + HRESULT ExchangeProperties( CPropExchange* pPropBag ); + + LRESULT OnPandaNotification(WPARAM wParam, LPARAM lParam); + + PPandaObject* m_pPandaObject; + + CComPtr m_spClientSite; + + void OnmainChanged(void); +}; + diff --git a/direct/src/plugin_activex/P3DActiveXPropPage.cpp b/direct/src/plugin_activex/P3DActiveXPropPage.cpp new file mode 100644 index 0000000000..fdbb902cb5 --- /dev/null +++ b/direct/src/plugin_activex/P3DActiveXPropPage.cpp @@ -0,0 +1,76 @@ +// P3DActiveXPropPage.cpp : Implementation of the CP3DActiveXPropPage property page class. + +// Filename: P3DActiveXPropPage.cpp +// Created by: atrestman (14Sept09) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "P3DActiveX.h" +#include "P3DActiveXPropPage.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#endif + + +IMPLEMENT_DYNCREATE(CP3DActiveXPropPage, COlePropertyPage) + + + +// Message map + +BEGIN_MESSAGE_MAP(CP3DActiveXPropPage, COlePropertyPage) +END_MESSAGE_MAP() + + + +// Initialize class factory and guid + +IMPLEMENT_OLECREATE_EX(CP3DActiveXPropPage, "P3DACTIVEX.P3DActiveXPropPage.1", + 0xd0111370, 0xe705, 0x485e, 0x96, 0xfd, 0xa2, 0xef, 0xb1, 0x71, 0x26, 0x9a) + + + +// CP3DActiveXPropPage::CP3DActiveXPropPageFactory::UpdateRegistry - +// Adds or removes system registry entries for CP3DActiveXPropPage + +BOOL CP3DActiveXPropPage::CP3DActiveXPropPageFactory::UpdateRegistry(BOOL bRegister) +{ + if (bRegister) + return AfxOleRegisterPropertyPageClass(AfxGetInstanceHandle(), + m_clsid, IDS_P3DACTIVEX_PPG); + else + return AfxOleUnregisterClass(m_clsid, NULL); +} + + + +// CP3DActiveXPropPage::CP3DActiveXPropPage - Constructor + +CP3DActiveXPropPage::CP3DActiveXPropPage() : + COlePropertyPage(IDD, IDS_P3DACTIVEX_PPG_CAPTION) +{ +} + + + +// CP3DActiveXPropPage::DoDataExchange - Moves data between page and properties + +void CP3DActiveXPropPage::DoDataExchange(CDataExchange* pDX) +{ + DDP_PostProcessing(pDX); +} + + + +// CP3DActiveXPropPage message handlers diff --git a/direct/src/plugin_activex/P3DActiveXPropPage.h b/direct/src/plugin_activex/P3DActiveXPropPage.h new file mode 100644 index 0000000000..1f458a4ad0 --- /dev/null +++ b/direct/src/plugin_activex/P3DActiveXPropPage.h @@ -0,0 +1,42 @@ +// Filename: P3DActiveXPropPage.h +// Created by: atrestman (14Sept09) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#pragma once + +// P3DActiveXPropPage.h : Declaration of the CP3DActiveXPropPage property page class. +#include "PPPandaObject.h" + +// CP3DActiveXPropPage : See P3DActiveXPropPage.cpp for implementation. + +class CP3DActiveXPropPage : public COlePropertyPage +{ + DECLARE_DYNCREATE(CP3DActiveXPropPage) + DECLARE_OLECREATE_EX(CP3DActiveXPropPage) + +// Constructor +public: + CP3DActiveXPropPage(); + +// Dialog Data + enum { IDD = IDD_PROPPAGE_P3DACTIVEX }; + +// Implementation +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + +// Message maps +protected: + DECLARE_MESSAGE_MAP() +}; + diff --git a/direct/src/plugin_activex/P3DActiveX_i.c b/direct/src/plugin_activex/P3DActiveX_i.c new file mode 100644 index 0000000000..ffaa13a4db --- /dev/null +++ b/direct/src/plugin_activex/P3DActiveX_i.c @@ -0,0 +1,93 @@ + + +/* this ALWAYS GENERATED file contains the IIDs and CLSIDs */ + +/* link this file in with the server and any clients */ + + + /* File created by MIDL compiler version 6.00.0361 */ +/* at Mon Sep 14 17:17:04 2009 + */ +/* Compiler settings for .\P3DActiveX.idl: + Oicf, W1, Zp8, env=Win32 (32b run) + protocol : dce , ms_ext, c_ext, robust + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +//@@MIDL_FILE_HEADING( ) + +#if !defined(_M_IA64) && !defined(_M_AMD64) + + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + + +#ifdef __cplusplus +extern "C"{ +#endif + + +#include +#include + +#ifdef _MIDL_USE_GUIDDEF_ + +#ifndef INITGUID +#define INITGUID +#include +#undef INITGUID +#else +#include +#endif + +#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ + DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) + +#else // !_MIDL_USE_GUIDDEF_ + +#ifndef __IID_DEFINED__ +#define __IID_DEFINED__ + +typedef struct _IID +{ + unsigned long x; + unsigned short s1; + unsigned short s2; + unsigned char c[8]; +} IID; + +#endif // __IID_DEFINED__ + +#ifndef CLSID_DEFINED +#define CLSID_DEFINED +typedef IID CLSID; +#endif // CLSID_DEFINED + +#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ + const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} + +#endif !_MIDL_USE_GUIDDEF_ + +MIDL_DEFINE_GUID(IID, LIBID_P3DActiveXLib,0x22A8FC5F,0xBC33,0x479A,0x83,0x17,0x2B,0xC8,0x16,0xB8,0xAB,0x8A); + + +MIDL_DEFINE_GUID(IID, DIID__DP3DActiveX,0x76904D54,0x0CC5,0x4DBB,0xB0,0x22,0xF4,0x8B,0x1E,0x95,0x18,0x3B); + + +MIDL_DEFINE_GUID(IID, DIID__DP3DActiveXEvents,0x1B2413ED,0x51C8,0x495E,0xB9,0x17,0x98,0x3C,0x45,0x9B,0x8F,0xC7); + + +MIDL_DEFINE_GUID(CLSID, CLSID_P3DActiveX,0x924B4927,0xD3BA,0x41EA,0x9F,0x7E,0x8A,0x89,0x19,0x4A,0xB3,0xAC); + +#undef MIDL_DEFINE_GUID + +#ifdef __cplusplus +} +#endif + + + +#endif /* !defined(_M_IA64) && !defined(_M_AMD64)*/ + diff --git a/direct/src/plugin_activex/P3DActiveXidl.h b/direct/src/plugin_activex/P3DActiveXidl.h new file mode 100644 index 0000000000..e6100373a0 --- /dev/null +++ b/direct/src/plugin_activex/P3DActiveXidl.h @@ -0,0 +1,316 @@ + + +/* this ALWAYS GENERATED file contains the definitions for the interfaces */ + + + /* File created by MIDL compiler version 6.00.0361 */ +/* at Mon Sep 14 17:17:04 2009 + */ +/* Compiler settings for .\P3DActiveX.idl: + Oicf, W1, Zp8, env=Win32 (32b run) + protocol : dce , ms_ext, c_ext, robust + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +//@@MIDL_FILE_HEADING( ) + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCNDR_H_VERSION__ +#define __REQUIRED_RPCNDR_H_VERSION__ 475 +#endif + +#include "rpc.h" +#include "rpcndr.h" + +#ifndef __RPCNDR_H_VERSION__ +#error this stub requires an updated version of +#endif // __RPCNDR_H_VERSION__ + + +#ifndef __P3DActiveXidl_h__ +#define __P3DActiveXidl_h__ + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +/* Forward Declarations */ + +#ifndef ___DP3DActiveX_FWD_DEFINED__ +#define ___DP3DActiveX_FWD_DEFINED__ +typedef interface _DP3DActiveX _DP3DActiveX; +#endif /* ___DP3DActiveX_FWD_DEFINED__ */ + + +#ifndef ___DP3DActiveXEvents_FWD_DEFINED__ +#define ___DP3DActiveXEvents_FWD_DEFINED__ +typedef interface _DP3DActiveXEvents _DP3DActiveXEvents; +#endif /* ___DP3DActiveXEvents_FWD_DEFINED__ */ + + +#ifndef __P3DActiveX_FWD_DEFINED__ +#define __P3DActiveX_FWD_DEFINED__ + +#ifdef __cplusplus +typedef class P3DActiveX P3DActiveX; +#else +typedef struct P3DActiveX P3DActiveX; +#endif /* __cplusplus */ + +#endif /* __P3DActiveX_FWD_DEFINED__ */ + + +#ifdef __cplusplus +extern "C"{ +#endif + +void * __RPC_USER MIDL_user_allocate(size_t); +void __RPC_USER MIDL_user_free( void * ); + + +#ifndef __P3DActiveXLib_LIBRARY_DEFINED__ +#define __P3DActiveXLib_LIBRARY_DEFINED__ + +/* library P3DActiveXLib */ +/* [control][helpstring][helpfile][version][uuid] */ + + +EXTERN_C const IID LIBID_P3DActiveXLib; + +#ifndef ___DP3DActiveX_DISPINTERFACE_DEFINED__ +#define ___DP3DActiveX_DISPINTERFACE_DEFINED__ + +/* dispinterface _DP3DActiveX */ +/* [helpstring][uuid] */ + + +EXTERN_C const IID DIID__DP3DActiveX; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("76904D54-0CC5-4DBB-B022-F48B1E95183B") + _DP3DActiveX : public IDispatch + { + }; + +#else /* C style interface */ + + typedef struct _DP3DActiveXVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + _DP3DActiveX * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + _DP3DActiveX * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + _DP3DActiveX * This); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + _DP3DActiveX * This, + /* [out] */ UINT *pctinfo); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + _DP3DActiveX * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + _DP3DActiveX * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + _DP3DActiveX * This, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ WORD wFlags, + /* [out][in] */ DISPPARAMS *pDispParams, + /* [out] */ VARIANT *pVarResult, + /* [out] */ EXCEPINFO *pExcepInfo, + /* [out] */ UINT *puArgErr); + + END_INTERFACE + } _DP3DActiveXVtbl; + + interface _DP3DActiveX + { + CONST_VTBL struct _DP3DActiveXVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define _DP3DActiveX_QueryInterface(This,riid,ppvObject) \ + (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) + +#define _DP3DActiveX_AddRef(This) \ + (This)->lpVtbl -> AddRef(This) + +#define _DP3DActiveX_Release(This) \ + (This)->lpVtbl -> Release(This) + + +#define _DP3DActiveX_GetTypeInfoCount(This,pctinfo) \ + (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) + +#define _DP3DActiveX_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) + +#define _DP3DActiveX_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) + +#define _DP3DActiveX_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + +#endif /* ___DP3DActiveX_DISPINTERFACE_DEFINED__ */ + + +#ifndef ___DP3DActiveXEvents_DISPINTERFACE_DEFINED__ +#define ___DP3DActiveXEvents_DISPINTERFACE_DEFINED__ + +/* dispinterface _DP3DActiveXEvents */ +/* [helpstring][uuid] */ + + +EXTERN_C const IID DIID__DP3DActiveXEvents; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("1B2413ED-51C8-495E-B917-983C459B8FC7") + _DP3DActiveXEvents : public IDispatch + { + }; + +#else /* C style interface */ + + typedef struct _DP3DActiveXEventsVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + _DP3DActiveXEvents * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + _DP3DActiveXEvents * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + _DP3DActiveXEvents * This); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + _DP3DActiveXEvents * This, + /* [out] */ UINT *pctinfo); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + _DP3DActiveXEvents * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + _DP3DActiveXEvents * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + _DP3DActiveXEvents * This, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ WORD wFlags, + /* [out][in] */ DISPPARAMS *pDispParams, + /* [out] */ VARIANT *pVarResult, + /* [out] */ EXCEPINFO *pExcepInfo, + /* [out] */ UINT *puArgErr); + + END_INTERFACE + } _DP3DActiveXEventsVtbl; + + interface _DP3DActiveXEvents + { + CONST_VTBL struct _DP3DActiveXEventsVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define _DP3DActiveXEvents_QueryInterface(This,riid,ppvObject) \ + (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) + +#define _DP3DActiveXEvents_AddRef(This) \ + (This)->lpVtbl -> AddRef(This) + +#define _DP3DActiveXEvents_Release(This) \ + (This)->lpVtbl -> Release(This) + + +#define _DP3DActiveXEvents_GetTypeInfoCount(This,pctinfo) \ + (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) + +#define _DP3DActiveXEvents_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) + +#define _DP3DActiveXEvents_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) + +#define _DP3DActiveXEvents_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + +#endif /* ___DP3DActiveXEvents_DISPINTERFACE_DEFINED__ */ + + +EXTERN_C const CLSID CLSID_P3DActiveX; + +#ifdef __cplusplus + +class DECLSPEC_UUID("924B4927-D3BA-41EA-9F7E-8A89194AB3AC") +P3DActiveX; +#endif +#endif /* __P3DActiveXLib_LIBRARY_DEFINED__ */ + +/* Additional Prototypes for ALL interfaces */ + +/* end of Additional Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/direct/src/plugin_activex/PPBrowserObject.cpp b/direct/src/plugin_activex/PPBrowserObject.cpp new file mode 100644 index 0000000000..f6efe04849 --- /dev/null +++ b/direct/src/plugin_activex/PPBrowserObject.cpp @@ -0,0 +1,202 @@ +// Filename: PPBrowserObject.cpp +// Created by: atrestman (14Sept09) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#include "stdafx.h" + +#include "PPBrowserObject.h" +#include "PPInstance.h" +#include "P3DActiveXCtrl.h" + +#include + +// The following functions are C-style wrappers around the above +// PPBrowserObject methods; they are defined to allow us to create the +// C-style P3D_class_definition method table to store in the +// P3D_object structure. +static void object_finish(P3D_object *object) +{ + delete ((PPBrowserObject *)object); +} + +static int object_get_repr(P3D_object *object, char *buffer, int buffer_length) +{ + return ((const PPBrowserObject *)object)->get_repr(buffer, buffer_length); +} + +static P3D_object* object_get_property(P3D_object *object, const char *property) +{ + return ((const PPBrowserObject *)object)->get_property(property); +} + +static bool object_set_property(P3D_object* object, const char* property, + P3D_object *value) +{ + return ((PPBrowserObject *)object)->set_property(property, value); +} + +static P3D_object* object_call(P3D_object* object, const char* method_name, + bool needs_response, + P3D_object *params[], int num_params) +{ + if (method_name == NULL) + { + method_name = ""; + } + P3D_object *response = ((const PPBrowserObject *)object)->call(method_name, params, num_params); + if (!needs_response) + { + // No response was expected. Throw away the response we received, + // so we can be consistent with defined semantics. + P3D_OBJECT_XDECREF(response); + response = NULL; + } + return response; +} + +static P3D_object* object_eval( P3D_object *object, const char *expression ) +{ + return ( ( const PPBrowserObject* )object )->eval( expression ); +} + +P3D_class_definition* PPBrowserObject::_browser_object_class; + +PPBrowserObject::PPBrowserObject( PPInterface* interfac, IDispatch* pDispatch ) : + m_interface( interfac ), m_pDispatch( pDispatch ) +{ + _class = get_class_definition( ); + _ref_count = 1; +} + +PPBrowserObject::PPBrowserObject( const PPBrowserObject& copy ) : + m_interface( copy.m_interface ), m_pDispatch( copy.m_pDispatch ) +{ + _class = get_class_definition( ); + _ref_count = 1; +} + +PPBrowserObject::~PPBrowserObject( ) +{ + assert( _ref_count == 0 ); +} + +P3D_object* PPBrowserObject::get_property( const std::string &property ) const +{ + assert( m_interface ); + + COleVariant varResult; + CComPtr pDispatch( m_pDispatch ); + HRESULT hr = m_interface->HasProperty( pDispatch, CString( property.c_str() ) ); + if( FAILED( hr ) ) + { + return NULL; + } + + hr = m_interface->GetProperty( pDispatch, CString( property.c_str() ), varResult ); + if ( FAILED( hr ) ) + { + return NULL; + } + + return m_interface->variant_to_p3dobj( &varResult ); +} + +bool PPBrowserObject::set_property( const std::string& property, P3D_object* value ) +{ + assert( m_interface ); + + CComPtr pDispatch( m_pDispatch ); + COleVariant varValue, varResult; + m_interface->p3dobj_to_variant( &varValue, value); + + HRESULT hr = m_interface->SetProperty( pDispatch, CString( property.c_str() ), varValue, varResult ); + if ( SUCCEEDED( hr ) ) + { + return true; + } + return false; +} + +P3D_object* PPBrowserObject::call( const std::string &method_name, P3D_object* params[], int num_params ) const +{ + assert( m_interface ); + + COleVariant* varParams = new COleVariant[ num_params ]; + COleVariant varResult; + + // First, convert all of the parameters. + for ( int i = 0; i < num_params; ++i ) + { + m_interface->p3dobj_to_variant( &varParams[i], params[i] ); + } + + CComPtr pDispatch( m_pDispatch ); + HRESULT hr = m_interface->CallMethod( pDispatch, CString( method_name.c_str() ), varResult, num_params, varParams ); + + delete [] varParams; + if ( FAILED( hr ) ) + { + return NULL; } + + return m_interface->variant_to_p3dobj( &varResult ); +} + +P3D_object* PPBrowserObject::eval( const std::string &expression ) const +{ + assert( m_interface ); + + COleVariant varResult; + CComPtr pDispatch( m_pDispatch ); + + CString evalExpression( expression.c_str() ); + HRESULT hr = m_interface->EvalExpression( pDispatch, evalExpression , varResult ); + if ( FAILED( hr ) ) + { + return NULL; + } + + return m_interface->variant_to_p3dobj( &varResult ); +} + +int PPBrowserObject::get_repr( char* buffer, int buffer_length ) const +{ + assert( m_interface ); + + VARIANT var; + var.vt = VT_DISPATCH; + var.pdispVal = m_pDispatch; + + COleVariant varDispatch( var ); + + CString result( m_interface->get_repr( varDispatch ) ); + strncpy( buffer, result, buffer_length ); + return (int)result.GetLength(); +} + +P3D_class_definition* PPBrowserObject::get_class_definition() +{ + if ( _browser_object_class == NULL ) + { + // Create a default class_definition object, and fill in the + // appropriate pointers. + _browser_object_class = P3D_make_class_definition(); + _browser_object_class->_finish = &object_finish; + + _browser_object_class->_get_repr = &object_get_repr; + _browser_object_class->_get_property = &object_get_property; + _browser_object_class->_set_property = &object_set_property; + _browser_object_class->_call = &object_call; + _browser_object_class->_eval = &object_eval; + } + return _browser_object_class; +} diff --git a/direct/src/plugin_activex/PPBrowserObject.h b/direct/src/plugin_activex/PPBrowserObject.h new file mode 100644 index 0000000000..634daf39ac --- /dev/null +++ b/direct/src/plugin_activex/PPBrowserObject.h @@ -0,0 +1,45 @@ +// Filename: PPBrowserObject.h +// Created by: atrestman (14Sept09) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#pragma once + +#include "plugin/p3d_plugin.h" +#include + +class PPInterface; + +class PPBrowserObject : public P3D_object +{ +public: + PPBrowserObject( PPInterface* interfac, IDispatch* pDisp ); + PPBrowserObject( const PPBrowserObject& copy ); + ~PPBrowserObject( ); + + int get_repr( char* buffer, int buffer_length ) const; + P3D_object* get_property( const std::string &property ) const; + bool set_property( const std::string& property, P3D_object* value ); + + P3D_object* call( const std::string &method_name, + P3D_object* params[], int num_params ) const; + P3D_object* eval( const std::string &expression ) const; + +protected: + PPBrowserObject( ); + static P3D_class_definition* get_class_definition( ); + + PPInterface* m_interface; + static P3D_class_definition* _browser_object_class; + + CComPtr m_pDispatch; +}; diff --git a/direct/src/plugin_activex/PPDownloadCallback.cpp b/direct/src/plugin_activex/PPDownloadCallback.cpp new file mode 100644 index 0000000000..d1e1ce758e --- /dev/null +++ b/direct/src/plugin_activex/PPDownloadCallback.cpp @@ -0,0 +1,237 @@ +// Filename: PPDownloadCallback.cpp +// Created by: atrestman (14Sept09) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "PPDownloadCallback.h" +#include "PPInstance.h" + + +PPDownloadCallback::PPDownloadCallback( PPDownloadCallbackSync& downloadSync ) + : m_downloadSync( downloadSync ), m_dwTotalRead( 0 ), m_ulObjRefCount( 1 ) +{ +} + +STDMETHODIMP PPDownloadCallback::QueryInterface(REFIID riid, void **ppvObject) +{ + TRACE(_T("IUnknown::QueryInterface\n")); + + *ppvObject = NULL; + + // IUnknown + if (::IsEqualIID(riid, __uuidof(IUnknown))) + { + TRACE(_T("IUnknown::QueryInterface(IUnknown)\n")); + + *ppvObject = this; + } + // IBindStatusCallback + else if (::IsEqualIID(riid, __uuidof(IBindStatusCallback))) + { + TRACE(_T("IUnknown::QueryInterface(IBindStatusCallback)\n")); + + *ppvObject = static_cast(this); + } + + if (*ppvObject) + { + (*reinterpret_cast(ppvObject))->AddRef(); + + return S_OK; + } + + return E_NOINTERFACE; +} + +STDMETHODIMP_(ULONG) PPDownloadCallback::AddRef() +{ + TRACE(_T("IUnknown::AddRef\n")); + + return ++m_ulObjRefCount; +} + +STDMETHODIMP_(ULONG) PPDownloadCallback::Release() +{ + TRACE(_T("IUnknown::Release\n")); + + return --m_ulObjRefCount; +} + +STDMETHODIMP PPDownloadCallback::OnStartBinding(DWORD, IBinding *) +{ + TRACE(_T("IBindStatusCallback::OnStartBinding\n")); + + m_downloadSync.Begin(); + + return S_OK; +} + +STDMETHODIMP PPDownloadCallback::GetPriority(LONG *) +{ + TRACE(_T("IBindStatusCallback::GetPriority\n")); + + return E_NOTIMPL; +} + +STDMETHODIMP PPDownloadCallback::OnLowResource(DWORD) +{ + TRACE(_T("IBindStatusCallback::OnLowResource\n")); + + return S_OK; +} + +STDMETHODIMP PPDownloadCallback::OnProgress(ULONG ulProgress, + ULONG ulProgressMax, + ULONG ulStatusCode, + LPCWSTR szStatusText) +{ +#ifdef _DEBUG + static const LPCTSTR plpszStatus[] = + { + _T("BINDSTATUS_FINDINGRESOURCE"), // 1 + _T("BINDSTATUS_CONNECTING"), + _T("BINDSTATUS_REDIRECTING"), + _T("BINDSTATUS_BEGINDOWNLOADDATA"), + _T("BINDSTATUS_DOWNLOADINGDATA"), + _T("BINDSTATUS_ENDDOWNLOADDATA"), + _T("BINDSTATUS_BEGINDOWNLOADCOMPONENTS"), + _T("BINDSTATUS_INSTALLINGCOMPONENTS"), + _T("BINDSTATUS_ENDDOWNLOADCOMPONENTS"), + _T("BINDSTATUS_USINGCACHEDCOPY"), + _T("BINDSTATUS_SENDINGREQUEST"), + _T("BINDSTATUS_CLASSIDAVAILABLE"), + _T("BINDSTATUS_MIMETYPEAVAILABLE"), + _T("BINDSTATUS_CACHEFILENAMEAVAILABLE"), + _T("BINDSTATUS_BEGINSYNCOPERATION"), + _T("BINDSTATUS_ENDSYNCOPERATION"), + _T("BINDSTATUS_BEGINUPLOADDATA"), + _T("BINDSTATUS_UPLOADINGDATA"), + _T("BINDSTATUS_ENDUPLOADINGDATA"), + _T("BINDSTATUS_PROTOCOLCLASSID"), + _T("BINDSTATUS_ENCODING"), + _T("BINDSTATUS_VERFIEDMIMETYPEAVAILABLE"), + _T("BINDSTATUS_CLASSINSTALLLOCATION"), + _T("BINDSTATUS_DECODING"), + _T("BINDSTATUS_LOADINGMIMEHANDLER"), + _T("BINDSTATUS_CONTENTDISPOSITIONATTACH"), + _T("BINDSTATUS_FILTERREPORTMIMETYPE"), + _T("BINDSTATUS_CLSIDCANINSTANTIATE"), + _T("BINDSTATUS_IUNKNOWNAVAILABLE"), + _T("BINDSTATUS_DIRECTBIND"), + _T("BINDSTATUS_RAWMIMETYPE"), + _T("BINDSTATUS_PROXYDETECTING"), + _T("BINDSTATUS_ACCEPTRANGES"), + _T("???") // unknown + }; +#endif + + TRACE(_T("IBindStatusCallback::OnProgress\n")); + + TRACE(_T("ulProgress: %lu, ulProgressMax: %lu\n"), + ulProgress, ulProgressMax); + + TRACE(_T("ulStatusCode: %lu "), ulStatusCode); + + if (ulStatusCode < UF_BINDSTATUS_FIRST || + ulStatusCode > UF_BINDSTATUS_LAST) + { + ulStatusCode = UF_BINDSTATUS_LAST + 1; + } + + m_downloadSync.ProgressNotify( ulProgress, ulProgressMax ); + +#ifdef _DEBUG + TRACE(_T("(%s), szStatusText: %ls\n"), + plpszStatus[ulStatusCode - UF_BINDSTATUS_FIRST], + szStatusText); +#endif + + return S_OK; +} + +STDMETHODIMP PPDownloadCallback::OnStopBinding(HRESULT, LPCWSTR) +{ + TRACE(_T("IBindStatusCallback::OnStopBinding\n")); + + m_downloadSync.End( ); + + return S_OK; +} + +STDMETHODIMP PPDownloadCallback::GetBindInfo(DWORD *, BINDINFO *) +{ + TRACE(_T("IBindStatusCallback::GetBindInfo\n")); + + return S_OK; +} + +STDMETHODIMP PPDownloadCallback::OnDataAvailable(DWORD grfBSCF, DWORD dwSize, + FORMATETC *, STGMEDIUM *pstgmed) +{ + TRACE(_T("IBindStatusCallback::OnDataAvailable\n")); + + HRESULT hr = S_OK; + + // Get the Stream passed + if (BSCF_FIRSTDATANOTIFICATION & grfBSCF) + { + if (!m_spStream && pstgmed->tymed == TYMED_ISTREAM) + { + m_spStream = pstgmed->pstm; + } + } + + DWORD dwRead = dwSize - m_dwTotalRead; // Minimum amount available that hasn't been read + DWORD dwActuallyRead = 0; // Placeholder for amount read during this pull + + // If there is some data to be read then go ahead and read them + if (m_spStream) + { + if (dwRead > 0) + { + BYTE* pBytes = NULL; + ATLTRY(pBytes = new BYTE[dwRead + 1]); + if (pBytes == NULL) + return E_OUTOFMEMORY; + hr = m_spStream->Read(pBytes, dwRead, &dwActuallyRead); + if (SUCCEEDED(hr)) + { + pBytes[dwActuallyRead] = 0; + if (dwActuallyRead>0) + { + bool ret = m_downloadSync.DataNotify( dwSize, (const void*)pBytes, dwActuallyRead ); + if (!ret) + { + hr = E_ABORT; + } + + m_dwTotalRead += dwActuallyRead; + } + } + delete[] pBytes; + } + } + + if (BSCF_LASTDATANOTIFICATION & grfBSCF) + { + m_spStream.Release(); + } + return hr; +} + +STDMETHODIMP PPDownloadCallback::OnObjectAvailable(REFIID, IUnknown *) +{ + TRACE(_T("IBindStatusCallback::OnObjectAvailable\n")); + + return S_OK; +} diff --git a/direct/src/plugin_activex/PPDownloadCallback.h b/direct/src/plugin_activex/PPDownloadCallback.h new file mode 100644 index 0000000000..adbe9890c6 --- /dev/null +++ b/direct/src/plugin_activex/PPDownloadCallback.h @@ -0,0 +1,64 @@ +// Filename: PPDownloadCallback.h +// Created by: atrestman (14Sept09) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#pragma once + +enum +{ + UF_BINDSTATUS_FIRST = BINDSTATUS_FINDINGRESOURCE, + UF_BINDSTATUS_LAST = BINDSTATUS_ACCEPTRANGES +}; + +class PPDownloadCallbackSync +{ +public: + virtual bool Begin( ) = 0; + virtual bool DataNotify( size_t expectedDataSize, const void* data, size_t dataSize ) = 0; + virtual void ProgressNotify( size_t progress, size_t maxProgress ) = 0; + virtual bool End( ) = 0; +}; + +class PPDownloadCallback : public IBindStatusCallback +{ +public: + PPDownloadCallback( PPDownloadCallbackSync& downloadSync ); + + // IUnknown methods + STDMETHOD(QueryInterface)(REFIID riid, void **ppvObject); + STDMETHOD_(ULONG, AddRef)(); + STDMETHOD_(ULONG, Release)(); + + // IBindStatusCallback methods + STDMETHOD(OnStartBinding)(DWORD, IBinding *); + STDMETHOD(GetPriority)(LONG *); + STDMETHOD(OnLowResource)(DWORD); + STDMETHOD(OnProgress)(ULONG ulProgress, + ULONG ulProgressMax, + ULONG ulStatusCode, + LPCWSTR szStatusText); + STDMETHOD(OnStopBinding)(HRESULT, LPCWSTR); + STDMETHOD(GetBindInfo)(DWORD *, BINDINFO *); + STDMETHOD(OnDataAvailable)(DWORD, DWORD, FORMATETC *, STGMEDIUM *); + STDMETHOD(OnObjectAvailable)(REFIID, IUnknown *); + +protected: + ULONG m_ulObjRefCount; + CComPtr m_spStream; + +private: + PPDownloadCallbackSync& m_downloadSync; + + DWORD m_dwTotalRead; + +}; diff --git a/direct/src/plugin_activex/PPDownloadRequest.cpp b/direct/src/plugin_activex/PPDownloadRequest.cpp new file mode 100644 index 0000000000..652c213a6e --- /dev/null +++ b/direct/src/plugin_activex/PPDownloadRequest.cpp @@ -0,0 +1,98 @@ +// Filename: PPDownloadRequest.cpp +// Created by: atrestman (14Sept09) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#include "stdafx.h" + +#include "PPDownloadRequest.h" +#include "PPInstance.h" + +bool PPDownloadRequest::Begin( ) +{ + return true; +} + +bool PPDownloadRequest::DataNotify( size_t expectedDataSize, const void* data, size_t dataSize ) +{ + bool ret = false; + if ( m_instance.m_eventStop.m_hObject != NULL ) + { + if ( ::WaitForSingleObject( m_instance.m_eventStop.m_hObject, 0 ) == WAIT_OBJECT_0 ) + { + return ret; // canceled by the user + } + } + switch ( this->m_requestType ) + { + case ( RequestType::P3DObject ): + { + if ( m_p3dRequest ) + { + ret = P3D_instance_feed_url_stream( m_p3dRequest->_instance, + m_p3dRequest->_request._get_url._unique_id, + P3D_RC_in_progress, + 0, + expectedDataSize, + data, + dataSize ); + } + } + break; + case ( RequestType::File ): + { + if ( m_hFile == INVALID_HANDLE_VALUE ) + { + m_hFile = ::CreateFile( m_fileName.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); + if ( m_hFile == INVALID_HANDLE_VALUE ) + { + return ret; + } + } + DWORD numberOfBytesWritten = 0; + if ( ::WriteFile( m_hFile, data, dataSize, &numberOfBytesWritten, NULL ) == TRUE ) + { + ret = true; + } + } + break; + case ( RequestType::Data ): + { + if ( m_data ) + { + std::string bits( static_cast< const char* >( data ), dataSize ); + *m_data << bits; + ret = true; + } + } + break; + } + return ret; +} + +void PPDownloadRequest::ProgressNotify( size_t progress, size_t maxProgress ) +{ + if ( ::IsWindow( m_instance.m_parentWnd ) ) + { + SendMessage( m_instance.m_parentWnd, WM_PROGRESS, (WPARAM)(progress * 100.0 / maxProgress), 0 ); + } +} + +bool PPDownloadRequest::End( ) +{ + if ( m_hFile != INVALID_HANDLE_VALUE ) + { + ::CloseHandle( m_hFile ); + m_hFile = INVALID_HANDLE_VALUE; + } + return true; +} diff --git a/direct/src/plugin_activex/PPDownloadRequest.h b/direct/src/plugin_activex/PPDownloadRequest.h new file mode 100644 index 0000000000..b35828f052 --- /dev/null +++ b/direct/src/plugin_activex/PPDownloadRequest.h @@ -0,0 +1,74 @@ +// Filename: PPDownloadRequest.h +// Created by: atrestman (14Sept09) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#pragma once + +#include +#include + +#include "PPDownloadCallback.h" +#include "PPInstance.h" + +class PPDownloadRequest : public PPDownloadCallbackSync +{ +public: + enum RequestType + { + File, + Data, + P3DObject + }; + + PPDownloadRequest( PPInstance& instance, P3D_request* p3dRequest ) : + m_instance( instance ), m_p3dRequest( p3dRequest ), m_data( NULL ), + m_requestType( RequestType::P3DObject ), m_hFile( INVALID_HANDLE_VALUE ) + { + } + + PPDownloadRequest( PPInstance& instance, const std::string& fileName ) : + m_instance( instance ), m_p3dRequest( NULL ), m_fileName( fileName ), + m_data( NULL ), m_requestType( RequestType::File ), m_hFile( INVALID_HANDLE_VALUE ) + { + } + + PPDownloadRequest( PPInstance& instance, std::strstream* data ) : + m_instance( instance ), m_p3dRequest ( NULL ), m_data( data ), + m_requestType( RequestType::Data ), m_hFile( INVALID_HANDLE_VALUE ) + { + } + + virtual ~PPDownloadRequest( ) + { + End(); + } + + // PPDownloadCallbackSync interface + virtual bool Begin( ); + virtual bool DataNotify( size_t expectedDataSize, const void* data, size_t size ); + virtual void ProgressNotify( size_t progress, size_t maxProgress ); + virtual bool End( ); + + PPInstance& m_instance; + RequestType m_requestType; + +protected: + P3D_request* m_p3dRequest; + std::string m_fileName; + std::strstream* m_data; + + HANDLE m_hFile; + +private: + PPDownloadRequest(); +}; diff --git a/direct/src/plugin_activex/PPInstance.cpp b/direct/src/plugin_activex/PPInstance.cpp new file mode 100644 index 0000000000..a043cf8b85 --- /dev/null +++ b/direct/src/plugin_activex/PPInstance.cpp @@ -0,0 +1,502 @@ +// Filename: PPInstance.cpp +// Created by: atrestman (14Sept09) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#include "stdafx.h" + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "resource.h" +#include "PPInstance.h" +#include "P3DActiveXCtrl.h" +#include "PPBrowserObject.h" +#include "PPDownloadRequest.h" + +#include "wintools/sdk/tinyxml/tinyxml.h" + +#define P3D_CONTENTS_FILENAME "contents.xml" + +#define P3D_BASE_URL "http://www.ddrose.com/~drose/p3d_7/" +//#define P3D_BASE_URL "file:///C:/p3dstage/" + +#define P3D_FILE_BASE_URL "http://www.ddrose.com/~drose/plugin/" +//#define P3D_FILE_BASE_URL "file:///C:/temp/" + +#define P3D_DEFAULT_PLUGIN_FILENAME "p3d_plugin.dll" + +P3D_initialize_func *P3D_initialize; +P3D_new_instance_func *P3D_new_instance; +P3D_instance_start_func *P3D_instance_start; +P3D_instance_finish_func *P3D_instance_finish; +P3D_instance_setup_window_func *P3D_instance_setup_window; +P3D_instance_get_request_func *P3D_instance_get_request; +P3D_check_request_func *P3D_check_request; +P3D_request_finish_func *P3D_request_finish; +P3D_instance_feed_url_stream_func *P3D_instance_feed_url_stream; + +P3D_instance_set_browser_script_object_func *P3D_instance_set_browser_script_object; +P3D_instance_get_panda_script_object_func *P3D_instance_get_panda_script_object; +P3D_make_class_definition_func *P3D_make_class_definition; + +P3D_new_undefined_object_func *P3D_new_undefined_object; +P3D_new_none_object_func *P3D_new_none_object; +P3D_new_bool_object_func *P3D_new_bool_object; +P3D_new_int_object_func *P3D_new_int_object; +P3D_new_float_object_func *P3D_new_float_object; +P3D_new_string_object_func *P3D_new_string_object; + + +void P3D_NofificationSync(P3D_instance *instance) +{ + static bool handleRequestOnUIThread = true; + if ( instance ) + { + CP3DActiveXCtrl* parent = static_cast(instance->_user_data); + if ( parent ) + { + if ( ::IsWindow( parent->m_hWnd ) ) + { + ::PostMessage( parent->m_hWnd, WM_PANDA_NOTIFICATION, 0, 0 ); + } + else + { + nout << "Can handle P3D_Notification on UI thread. Controls window is invalid\n"; + } + } + else + { + nout << "Can handle P3D_Notification on UI thread. Instance's user data is not a Control\n"; + } + } +} + +PPInstance::PPInstance( CP3DActiveXCtrl& parentCtrl ) : + m_parentCtrl( parentCtrl ), m_p3dInstance( NULL ), m_p3dObject( NULL ), m_hP3DPluginDll( NULL ), m_handleRequestOnUIThread( true ) +{ + TCHAR tempFolderName[ MAX_PATH ]; + DWORD pathLength = ::GetTempPath( MAX_PATH, tempFolderName ); + + m_logger.Open( std::string( tempFolderName ), std::string( P3D_DEFAULT_PLUGIN_LOG_FILENAME ) ); +} + +PPInstance::~PPInstance( ) +{ + if ( m_p3dObject ) + { + P3D_OBJECT_DECREF( m_p3dObject ); + } + if ( m_p3dInstance ) + { + P3D_instance_finish( m_p3dInstance ); + m_p3dInstance = NULL; + } + UnloadPlugin(); +} + +int PPInstance::DownloadFile( const std::string& from, const std::string& to ) +{ + int error( 0 ); + PPDownloadRequest p3dContentsDownloadRequest( *this, to ); + PPDownloadCallback dcForContents( p3dContentsDownloadRequest ); + + nout << "Downloading " << from << " into " << to << "\n"; + HRESULT hr = ::URLOpenStream( m_parentCtrl.GetControllingUnknown(), from.c_str(), 0, &dcForContents ); + if ( FAILED( hr ) ) + { + error = 1; + nout << "Error downloading " << from << " :" << hr << "\n"; + } + return error; +} + +int PPInstance::ReadContents( const std::string& contentsFilename, std::string& p3dDllFilename ) +{ + int error(1); + + TiXmlDocument doc( contentsFilename.c_str( ) ); + if ( doc.LoadFile( ) ) + { + TiXmlElement *xcontents = doc.FirstChildElement( "contents" ); + if ( xcontents != NULL ) + { + TiXmlElement *xpackage = xcontents->FirstChildElement( "package" ); + while ( xpackage != NULL ) + { + const char *name = xpackage->Attribute( "name" ); + if ( name != NULL && strcmp( name, "coreapi" ) == 0 ) + { + const char *platform = xpackage->Attribute( "platform" ); + if ( platform != NULL && !strcmp(platform, "win32") ) + { + p3dDllFilename += xpackage->Attribute( "filename" ); + error = 0; + break; + } + } + xpackage = xpackage->NextSiblingElement( "package" ); + } + } + } + return error; +} + +int PPInstance::DownloadP3DComponents( std::string& p3dDllFilename, std::string& p3dFilename ) +{ + int error(0); + + TCHAR tempFolderName[ MAX_PATH ]; + DWORD pathLength = ::GetTempPath( MAX_PATH, tempFolderName ); + + std::string localContentsFileName( tempFolderName, pathLength ); + localContentsFileName += P3D_CONTENTS_FILENAME; + + std::string remoteContentsFilename( P3D_BASE_URL ); + remoteContentsFilename += P3D_CONTENTS_FILENAME; + + error = DownloadFile( remoteContentsFilename, localContentsFileName ); + if ( !error ) + { + std::string p3dRemoteModuleFileName( P3D_BASE_URL ); + error = ReadContents( localContentsFileName, p3dRemoteModuleFileName ); + if ( !error ) + { + std::string p3dLocalModuleFileName( tempFolderName, pathLength ); + p3dLocalModuleFileName += P3D_DEFAULT_PLUGIN_FILENAME; + + // Check for existance + if ( ::GetFileAttributes( p3dLocalModuleFileName.c_str( ) ) == INVALID_FILE_ATTRIBUTES ) + { + error = DownloadFile( p3dRemoteModuleFileName, p3dLocalModuleFileName ); + } + if ( !error ) + { + p3dDllFilename = p3dLocalModuleFileName; + + std::string p3dLocalFilename( tempFolderName ); + p3dLocalFilename += GetP3DFilename( ); + + std::string p3dRemoteFilename( P3D_FILE_BASE_URL ); + p3dRemoteFilename += GetP3DFilename( ); + + // Check for existance + if ( ::GetFileAttributes( p3dLocalFilename.c_str( ) ) == INVALID_FILE_ATTRIBUTES ) + { + error = DownloadFile( p3dRemoteFilename, p3dLocalFilename ); + } + p3dFilename = p3dLocalFilename; + } + } + } + return error; +} + +int PPInstance::LoadPlugin( const std::string& dllFilename ) +{ + int error(0); + std::string filename( dllFilename ); + + if ( filename.empty() ) + { + // Look for the plugin along the path. + filename = P3D_DEFAULT_PLUGIN_FILENAME; + filename += ".dll"; + } + + nout << "Loading " << filename << "\n"; + m_hP3DPluginDll = LoadLibrary( filename.c_str() ); + if ( m_hP3DPluginDll == NULL ) + { + // Couldn't load the DLL. + nout << "Error loading " << filename << " :" << GetLastError() << "\n"; + return false; + } + + char buffer[MAX_PATH]; + if ( GetModuleFileName( m_hP3DPluginDll, buffer, MAX_PATH ) != 0 ) + { + if ( GetLastError() != 0 ) + { + filename = buffer; + } + } + + // Now get all of the function pointers. + P3D_initialize = (P3D_initialize_func *)GetProcAddress(m_hP3DPluginDll, "P3D_initialize"); + P3D_new_instance = (P3D_new_instance_func *)GetProcAddress(m_hP3DPluginDll, "P3D_new_instance"); + P3D_instance_start = (P3D_instance_start_func *)GetProcAddress(m_hP3DPluginDll, "P3D_instance_start"); + P3D_instance_finish = (P3D_instance_finish_func *)GetProcAddress(m_hP3DPluginDll, "P3D_instance_finish"); + P3D_instance_setup_window = (P3D_instance_setup_window_func *)GetProcAddress(m_hP3DPluginDll, "P3D_instance_setup_window"); + P3D_instance_get_request = (P3D_instance_get_request_func *)GetProcAddress(m_hP3DPluginDll, "P3D_instance_get_request"); + P3D_check_request = (P3D_check_request_func *)GetProcAddress(m_hP3DPluginDll, "P3D_check_request"); + P3D_request_finish = (P3D_request_finish_func *)GetProcAddress(m_hP3DPluginDll, "P3D_request_finish"); + P3D_instance_feed_url_stream = (P3D_instance_feed_url_stream_func *)GetProcAddress(m_hP3DPluginDll, "P3D_instance_feed_url_stream"); + + P3D_instance_set_browser_script_object = (P3D_instance_set_browser_script_object_func *)GetProcAddress(m_hP3DPluginDll, "P3D_instance_set_browser_script_object"); + P3D_instance_get_panda_script_object = (P3D_instance_get_panda_script_object_func *)GetProcAddress(m_hP3DPluginDll, "P3D_instance_get_panda_script_object"); + P3D_make_class_definition = (P3D_make_class_definition_func *)GetProcAddress(m_hP3DPluginDll, "P3D_make_class_definition"); + + P3D_new_undefined_object = (P3D_new_undefined_object_func *)GetProcAddress(m_hP3DPluginDll, "P3D_new_undefined_object"); + P3D_new_none_object = (P3D_new_none_object_func *)GetProcAddress(m_hP3DPluginDll, "P3D_new_none_object"); + P3D_new_bool_object = (P3D_new_bool_object_func *)GetProcAddress(m_hP3DPluginDll, "P3D_new_bool_object"); + P3D_new_int_object = (P3D_new_int_object_func *)GetProcAddress(m_hP3DPluginDll, "P3D_new_int_object"); + P3D_new_float_object = (P3D_new_float_object_func *)GetProcAddress(m_hP3DPluginDll, "P3D_new_float_object"); + P3D_new_string_object = (P3D_new_string_object_func *)GetProcAddress(m_hP3DPluginDll, "P3D_new_string_object"); + + // Ensure that all of the function pointers have been found. + if (P3D_initialize == NULL || + P3D_new_instance == NULL || + P3D_instance_finish == NULL || + P3D_instance_get_request == NULL || + P3D_check_request == NULL || + P3D_request_finish == NULL || + P3D_instance_get_panda_script_object == NULL || + P3D_instance_set_browser_script_object == NULL || + P3D_instance_feed_url_stream == NULL || + P3D_make_class_definition == NULL || + P3D_new_none_object == NULL || + P3D_new_bool_object == NULL || + P3D_new_int_object == NULL || + P3D_new_float_object == NULL || + P3D_new_string_object == NULL ) + { + return ( error = 1 ); + } + + // Successfully loaded. + nout << "Initializing P3D P3D_API_VERSION=" << P3D_API_VERSION << "\n"; + if ( !P3D_initialize( P3D_API_VERSION, "", "", true, "", "", "", false ) ) + { + // Oops, failure to initialize. + nout << "Error initializing P3D: " << GetLastError() << "\n"; + return ( error = 1 ); + } + + return error ; +} + +int PPInstance::UnloadPlugin() +{ + int error( 0 ); + + if ( m_hP3DPluginDll ) + { + nout << "Unloading P3D dll \n"; + if ( !::FreeLibrary( m_hP3DPluginDll ) ) + { + nout << "Error unloading P3D dll :" << GetLastError << "\n"; + error = 1; + } + else + { + m_hP3DPluginDll = NULL; + } + } + return error; +} + +int PPInstance::Start( const std::string& p3dFilename ) +{ + m_eventStop.ResetEvent(); + + P3D_window_handle parent_window; + parent_window._hwnd = m_parentCtrl.m_hWnd; + + RECT rect; + GetClientRect( m_parentCtrl.m_hWnd, &rect ); + + P3D_token* p3dTokens = new P3D_token[ m_parentCtrl.m_parameters.size() ]; + for ( UINT i = 0; i < m_parentCtrl.m_parameters.size(); i++ ) + { + std::pair< CString, CString > keyAndValue = m_parentCtrl.m_parameters[ i ]; + p3dTokens[i]._keyword = strdup( m_parentCtrl.m_parameters[ i ].first ); + p3dTokens[i]._value = strdup( m_parentCtrl.m_parameters[ i ].second ); + } + nout << "Creating new P3D instance object \n"; + m_p3dInstance = P3D_new_instance( &P3D_NofificationSync, p3dTokens, m_parentCtrl.m_parameters.size(), 0, NULL, (void*)&m_parentCtrl ); + + for ( UINT j = 0; j < m_parentCtrl.m_parameters.size(); j++ ) + { + delete [] p3dTokens[j]._keyword; + delete [] p3dTokens[j]._value; + } + delete [] p3dTokens; + + if ( !m_p3dInstance ) + { + nout << "Error creating P3D instance: " << GetLastError() << "\n"; + return 0; + } + CComPtr pDispatch; + PPBrowserObject *pobj = new PPBrowserObject( &m_parentCtrl, pDispatch ); + P3D_instance_set_browser_script_object( m_p3dInstance, pobj ); + + m_p3dObject = P3D_instance_get_panda_script_object( m_p3dInstance ); + P3D_OBJECT_INCREF( m_p3dObject ); + + P3D_instance_setup_window( m_p3dInstance, P3D_WT_embedded, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, parent_window ); + + nout << "Starting new P3D instance " << p3dFilename << "\n"; + if ( !P3D_instance_start( m_p3dInstance, true, p3dFilename.c_str() ) ) + { + nout << "Error starting P3D instance: " << GetLastError() << "\n"; + } + + return 1; +} + +CString PPInstance::GetP3DFilename( ) +{ + CString p3dFilename; + for ( UINT i = 0; i < m_parentCtrl.m_parameters.size(); i++ ) + { + std::pair< CString, CString > keyAndValue = m_parentCtrl.m_parameters[ i ]; + if ( keyAndValue.first == "src" ) + { + p3dFilename = keyAndValue.second; + } + } + return p3dFilename; +} + +void PPInstance::HandleRequestLoop() +{ + P3D_instance *p3d_inst = P3D_check_request(false); + while ( p3d_inst != NULL ) + { + P3D_request *request = P3D_instance_get_request(p3d_inst); + if ( request != NULL ) + { + CP3DActiveXCtrl* parent = ( CP3DActiveXCtrl* )(p3d_inst->_user_data); + if ( parent ) + { + parent->m_instance.HandleRequest( request ); + } + else + { + nout << "Error handling P3D request. Instance's user data is not a Control \n"; + } + } + p3d_inst = P3D_check_request( false ); + } +} + +void PPInstance::HandleRequestGetUrl( void* data ) +{ + P3D_request *request = static_cast( data ); + if ( !request ) + { + return; + } + int unique_id = request->_request._get_url._unique_id; + const std::string &url = request->_request._get_url._url; + CP3DActiveXCtrl* parent = static_cast ( request->_instance->_user_data ); + + if ( !parent ) + { + return; + } + + nout << "Handling P3D_RT_get_url request from " << url << "\n"; + PPDownloadRequest p3dObjectDownloadRequest( parent->m_instance, request ); + PPDownloadCallback bsc( p3dObjectDownloadRequest ); + HRESULT hr = ::URLOpenStream( parent->GetControllingUnknown(), url.c_str(), 0, &bsc ); + if ( FAILED( hr ) ) + { + nout << "Error handling P3D_RT_get_url request" << " :" << hr << "\n"; + return; + } + //inet_InternetSession inet(parent->m_pythonEmbed.m_threadData.m_parent); + //std::string outdata; + //if ( !inet.getURLMemory( url, outdata, request ) ) + //{ + // handled = false; + //} + + P3D_instance_feed_url_stream( + request->_instance, + request->_request._get_url._unique_id, + P3D_RC_done, + 0, + 0, + (const void*)NULL, + 0 + ); + P3D_request_finish( request, true ); +} + +void PPInstance::HandleRequest( P3D_request *request ) +{ + if ( !request ) + { + return; + } + bool handled = false; + + switch ( request->_request_type ) + { + case P3D_RT_stop: + { + P3D_instance_finish( request->_instance ); + handled = true; + break; + } + case P3D_RT_get_url: + { + if ( !m_handleRequestOnUIThread ) + { + _beginthread( HandleRequestGetUrl, 0, request ); + } + else + { + HandleRequestGetUrl( request ); + } + handled = true; + + return; + } + case P3D_RT_notify: + { + CString notification = request->_request._notify._message; + if ( notification == "ondownloadbegin" ) + { + m_handleRequestOnUIThread = false; + } + else if ( notification == "ondownloadcomplete" ) + { + m_handleRequestOnUIThread = true; + } + handled = true; + break; + } + default: + { + // Some request types are not handled. + break; + } + }; + P3D_request_finish( request, handled ); +} + + + diff --git a/direct/src/plugin_activex/PPInstance.h b/direct/src/plugin_activex/PPInstance.h new file mode 100644 index 0000000000..176090c5cd --- /dev/null +++ b/direct/src/plugin_activex/PPInstance.h @@ -0,0 +1,77 @@ +// Filename: PPInstance.h +// Created by: atrestman (14Sept09) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#pragma once + +#include +#include +#include "afxmt.h" + +#include "plugin/p3d_plugin.h" +#include "PPDownloadCallback.h" +#include "PPLogger.h" + +#define WM_PY_LAUNCHED (WM_USER + 1) +#define WM_PROGRESS (WM_USER + 2) +#define WM_PANDA_NOTIFICATION (WM_USER + 3) + +class CP3DActiveXCtrl; + +extern P3D_instance_feed_url_stream_func *P3D_instance_feed_url_stream; +extern P3D_make_class_definition_func *P3D_make_class_definition; +extern P3D_new_undefined_object_func *P3D_new_undefined_object; +extern P3D_new_none_object_func *P3D_new_none_object; +extern P3D_new_bool_object_func *P3D_new_bool_object; +extern P3D_new_int_object_func *P3D_new_int_object; +extern P3D_new_float_object_func *P3D_new_float_object; +extern P3D_new_string_object_func *P3D_new_string_object; + +class PPInstance +{ +public: + PPInstance( CP3DActiveXCtrl& parentCtrl ); + virtual ~PPInstance( ); + + int DownloadP3DComponents( std::string& p3dDllFilename, std::string& p3dFileName ); + + int LoadPlugin( const std::string& dllFilename ); + int UnloadPlugin( void ); + + int Start( const std::string& p3dFileName ); + + static void HandleRequestLoop(); + + HWND m_parentWnd; + CEvent m_eventStop; + P3D_object* m_p3dObject; + +protected: + PPInstance( ); + PPInstance( const PPInstance& ); + + int DownloadFile( const std::string& from, const std::string& to ); + int ReadContents( const std::string& contentsFilename, std::string& p3dDllFilename ); + + CString GetP3DFilename( ); + void HandleRequest( P3D_request *request ); + static void HandleRequestGetUrl( void *data ); + + P3D_instance* m_p3dInstance; + CP3DActiveXCtrl& m_parentCtrl; + PPLogger m_logger; + + HMODULE m_hP3DPluginDll; + + bool m_handleRequestOnUIThread; +}; diff --git a/direct/src/plugin_activex/PPInterface.cpp b/direct/src/plugin_activex/PPInterface.cpp new file mode 100644 index 0000000000..56e3c9c148 --- /dev/null +++ b/direct/src/plugin_activex/PPInterface.cpp @@ -0,0 +1,531 @@ +// Filename: PPInterface.cpp +// Created by: atrestman (14Sept09) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#include "stdafx.h" + +#include "PPInterface.h" +#include "PPPandaObject.h" +#include "PPBrowserObject.h" +#include "PPInstance.h" +#include "P3DActiveXCtrl.h" + +#include +#include "Mshtml.h" + +PPInterface::PPInterface( ) +{ +} + +PPInterface::~PPInterface( ) +{ +} + + +HRESULT PPInterface::GetIdOfName( IDispatch* pDisp, CString& ptName, DISPID* dispID ) +{ + if( !pDisp ) + { + return E_FAIL; + } + OLECHAR* pElementName = ptName.AllocSysString(); + + HRESULT hr = pDisp->GetIDsOfNames(IID_NULL, &pElementName, 1, LOCALE_USER_DEFAULT, dispID); + SysFreeString( pElementName ); + + return hr; +} + +HRESULT PPInterface::Invoke(int nType, IDispatch* pDisp, CString& ptName, VARIANT* pvResult, int cArgs, VARIANT* params) +{ + if( !pDisp ) + { + return E_FAIL; + } + + DISPPARAMS dp = { NULL, NULL, 0, 0 }; + DISPID dispidNamed = DISPID_PROPERTYPUT; + DISPID dispID; + + HRESULT hr = GetIdOfName( pDisp, ptName, &dispID ); + if ( FAILED( hr ) ) + { + return hr; + } + + // Allocate memory for arguments... + VARIANT *pArgs = new VARIANT[ cArgs + 1 ]; + + // Reversing the arguments!!! + // NOTE: http://msdn.microsoft.com/en-us/library/cc237569(PROT.10).aspx + // pDispParams: MUST point to a DISPPARAMS structure that defines the arguments passed to the method. + // Arguments MUST be stored in pDispParams->rgvarg in reverse order, so that the first argument is + // the one with the highest index in the array. Byref arguments MUST be marked in this array + // as VT_EMPTY entries, and stored in rgVarRef instead. + + for( int i = 0; i < cArgs; i++ ) + { + pArgs[i] = params[ cArgs - 1 - i ]; + } + + // Build DISPPARAMS + dp.cArgs = cArgs; + dp.rgvarg = pArgs; + + // Handle special-case for property-puts! + if( nType & DISPATCH_PROPERTYPUT ) + { + dp.cNamedArgs = 1; + dp.rgdispidNamedArgs = &dispidNamed; + } + + // Make the call! + hr = pDisp->Invoke( dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT, + nType, &dp, pvResult, NULL, NULL ); + + delete [] pArgs; + + return hr; +} + +HRESULT PPInterface::GetHtmlDocDispatch( CComPtr& pDispScript ) +{ + HRESULT hr = S_OK; + + CComPtr pOleClientSite = GetClientSte( ); + ASSERT( pOleClientSite ); + + CComPtr pOleContainer; + hr = pOleClientSite->GetContainer(& pOleContainer ); + ASSERT( SUCCEEDED( hr ) && pOleContainer ); + + CComPtr pHtmlDoc; + hr = pOleContainer->QueryInterface( IID_IHTMLDocument, ( void** )&pHtmlDoc ); + ASSERT( SUCCEEDED( hr ) && pHtmlDoc ); + + // Get the script object (this returns the script object, NOT the script + // element(s) that the get_scripts method does). + hr = pHtmlDoc->get_Script( &pDispScript ); + ASSERT( SUCCEEDED( hr ) && pDispScript ); + + CComPtr pTypeInfo; + hr = pDispScript->GetTypeInfo( 0, 0, &pTypeInfo ); + + return hr; +} + +HRESULT PPInterface::HasProperty( CComPtr& pDispatch, CString& name ) +{ + HRESULT hr = S_OK; + if ( pDispatch == NULL ) + { + hr = GetHtmlDocDispatch( pDispatch ); + } + + DISPID dispID; + if ( SUCCEEDED( hr ) ) + { + hr = GetIdOfName( pDispatch, name, &dispID ); + } + return hr; +} + +HRESULT PPInterface::CallMethod( CComPtr& pDispatch, CString& name, COleVariant& varResult, int numParams, COleVariant* params ) +{ + HRESULT hr = S_OK; + if ( pDispatch == NULL ) + { + hr = GetHtmlDocDispatch( pDispatch ); + } + if ( SUCCEEDED( hr ) ) + { + hr = Invoke( DISPATCH_METHOD, pDispatch, name, &varResult, numParams, params ); + } + return hr; +} + +HRESULT PPInterface::GetProperty( CComPtr& pDispatch, CString& name, COleVariant& varResult ) +{ + HRESULT hr = S_OK; + if ( pDispatch == NULL ) + { + hr = GetHtmlDocDispatch( pDispatch ); + } + if ( SUCCEEDED( hr ) ) + { + hr = Invoke( DISPATCH_PROPERTYGET, pDispatch, name, &varResult, 0, NULL ); + } + return hr; +} + +HRESULT PPInterface::SetProperty( CComPtr& pDispatch, CString& name, COleVariant& varValue, COleVariant& varResult ) +{ + HRESULT hr = S_OK; + if ( pDispatch == NULL ) + { + hr = GetHtmlDocDispatch( pDispatch ); + } + if ( SUCCEEDED( hr ) ) + { + hr = Invoke( DISPATCH_PROPERTYPUT, pDispatch, name, &varResult, 1, &varValue ); + } + return hr; +} + +HRESULT PPInterface::EvalExpression( CComPtr& pDispatch, CString& expression, COleVariant& varResult ) +{ + HRESULT hr = S_OK; + if ( pDispatch == NULL ) + { + hr = GetHtmlDocDispatch( pDispatch ); + } + if ( SUCCEEDED( hr ) ) + { + COleVariant param( expression ); + hr = Invoke( DISPATCH_METHOD, pDispatch, CString("eval"), &varResult, 1, ¶m ); + } + return hr; +} + +HRESULT PPInterface::P3DHasMethod( P3D_object* p3dObject, CString& name, bool& result ) +{ + if ( !p3dObject ) + { + p3dObject = GetP3DObject( ); + if ( !p3dObject ) + { + return E_FAIL; + } + } + result = P3D_OBJECT_HAS_METHOD( p3dObject, name ); + return S_OK; +} + +HRESULT PPInterface::P3DCallMethod( P3D_object* p3dObject, CString& name, DISPPARAMS FAR* pdispparams, VARIANT FAR* varResult ) +{ + if ( !p3dObject ) + { + p3dObject = GetP3DObject( ); + if ( !p3dObject ) + { + return E_FAIL; + } + } + P3D_object** params = new P3D_object*[pdispparams->cArgs]; + for ( UINT i = 0; i < pdispparams->cArgs; i++ ) + { + // Reversing the arguments!!! + // http://msdn.microsoft.com/en-us/library/cc237569(PROT.10).aspx + // pDispParams: MUST point to a DISPPARAMS structure that defines the arguments passed to the method. + // Arguments MUST be stored in pDispParams->rgvarg in reverse order, so that the first argument is + // the one with the highest index in the array. Byref arguments MUST be marked in this array + // as VT_EMPTY entries, and stored in rgVarRef instead. + + COleVariant vaArg( pdispparams->rgvarg[pdispparams->cArgs - 1 - i] ); + params[i] = variant_to_p3dobj( &vaArg ); + } + bool needResult( false ); + if ( varResult ) + { + needResult = true; + } + P3D_object* p3dObjectResult = P3D_OBJECT_CALL( p3dObject, name, needResult, params, pdispparams->cArgs ); + if ( p3dObjectResult ) + { + p3dobj_to_variant( varResult, p3dObjectResult ); + P3D_OBJECT_DECREF( p3dObjectResult ); + } + delete [] params; + + return S_OK; +} + +HRESULT PPInterface::P3DGetProperty( P3D_object* p3dObject, CString& name, VARIANT FAR* varResult ) +{ + if ( !p3dObject ) + { + p3dObject = GetP3DObject( ); + if ( !p3dObject ) + { + return E_FAIL; + } + } + P3D_object* p3dObjectResult = P3D_OBJECT_GET_PROPERTY( p3dObject, name ); + if ( p3dObjectResult ) + { + p3dobj_to_variant( varResult, p3dObjectResult ); + P3D_OBJECT_DECREF( p3dObjectResult ); + } + return S_OK; +} + +HRESULT PPInterface::P3DSetProperty( P3D_object* p3dObject, CString& name, DISPPARAMS FAR* pdispparams, bool& result ) +{ + if ( !p3dObject ) + { + p3dObject = GetP3DObject( ); + if ( !p3dObject ) + { + return E_FAIL; + } + } + COleVariant vaArg( pdispparams->rgvarg ); + P3D_object* param = variant_to_p3dobj( &vaArg ); + result = P3D_OBJECT_SET_PROPERTY( p3dObject, name, param ); + + delete param; + return S_OK; +} + +void PPInterface::p3dobj_to_variant(VARIANT* result, P3D_object* object) +{ + if ( !result ) + { + return; + } + switch ( P3D_OBJECT_GET_TYPE( object ) ) + { + case P3D_OT_undefined: + { + result->vt = VT_EMPTY; + break; + } + case P3D_OT_none: + { + result->vt = VT_EMPTY; + break; + } + case P3D_OT_bool: + { + result->vt = VT_BOOL; + result->bVal = P3D_OBJECT_GET_BOOL( object ); + break; + } + case P3D_OT_int: + { + result->vt = VT_I4; + result->lVal = P3D_OBJECT_GET_INT( object ); + break; + } + case P3D_OT_float: + { + result->vt = VT_R4; + result->fltVal = P3D_OBJECT_GET_FLOAT( object ); + break; + } + case P3D_OT_string: + { + int size = P3D_OBJECT_GET_STRING(object, NULL, 0); + char *buffer = new char[ size ]; + P3D_OBJECT_GET_STRING(object, buffer, size); + CString tmp( buffer, size ); + result->vt = VT_BSTR; + result->bstrVal = tmp.AllocSysString(); + + delete [] buffer; + break; + } + case P3D_OT_object: + { + PPBrowserObject *ppBrowserObject = (PPBrowserObject *)object; + PPandaObject* ppPandaObject = new PPandaObject( this, ppBrowserObject ); + result->vt = VT_DISPATCH; + result->pdispVal = ppPandaObject; + break; + } + default: + { + result->vt = VT_EMPTY; + break; + } + } +} + +P3D_object* PPInterface::variant_to_p3dobj(COleVariant* variant) +{ + if ( !variant ) + { + return P3D_new_none_object(); + } + switch( variant->vt ) + { + case VT_VOID: + { + return P3D_new_undefined_object(); + break; + } + case VT_EMPTY: + { + // return P3D_new_none_object(); + // A.T. Panda really expect undefined object here + return P3D_new_undefined_object(); + break; + } + case VT_BOOL: + { + return P3D_new_bool_object( variant->bVal ); + break; + } + case VT_I2: + { + return P3D_new_int_object( variant->iVal ); + break; + } + case VT_I4: + { + return P3D_new_int_object( variant->lVal ); + break; + } + case VT_I8: + { + return P3D_new_int_object( variant->llVal ); + break; + } + case VT_R4: + { + return P3D_new_float_object( variant->fltVal ); + break; + } + case VT_R8: + { + return P3D_new_float_object( variant->dblVal ); + break; + } + case VT_BSTR: + { + CString str( *variant ); + return P3D_new_string_object( str.GetBuffer(), str.GetLength() ); + break; + } + case VT_DISPATCH: + { + CComPtr pDispObject( variant->pdispVal ); + CComPtr pTypeInfo; + HRESULT hr = pDispObject->GetTypeInfo( 0, 0, &pTypeInfo ); + if ( SUCCEEDED( hr ) && pTypeInfo ) + { + TYPEATTR* pTypeAttr; + hr = pTypeInfo->GetTypeAttr( &pTypeAttr ); + + pTypeInfo->ReleaseTypeAttr( pTypeAttr ); + } + return new PPBrowserObject( this, variant->pdispVal ); + break; + } + default: + { + return P3D_new_undefined_object(); + break; + } + } +} + +CString PPInterface::get_repr(COleVariant& variant) +{ + std::strstream repr; + repr << "IDispatch"; + switch( variant.vt ) + { + case VT_VOID: + { + repr << ":VT_VOID"; + break; + } + case VT_EMPTY: + { + repr << ":VT_EMPTY"; + break; + } + case VT_BOOL: + { + repr << ":VT_BOOL:" << variant.bVal; + break; + } + case VT_I2: + { + repr << ":VT_I2:" << variant.iVal; + break; + } + case VT_I4: + { + repr << ":VT_I4:" << variant.lVal; + break; + } + case VT_I8: + { + repr << ":VT_I8:" << variant.llVal; + break; + } + case VT_R4: + { + repr << ":VT_R4:" << variant.fltVal; + break; + } + case VT_R8: + { + repr << ":VT_R8:" << variant.dblVal; + break; + } + case VT_BSTR: + { + CString str( variant ); + repr << ":VT_BSTR:" << str; + break; + } + case VT_DISPATCH: + { + if ( variant.pdispVal ) + { + CComPtr pDispObject( variant.pdispVal ); + CComPtr pTypeInfo; + HRESULT hr = pDispObject->GetTypeInfo( 0, 0, &pTypeInfo ); + if ( SUCCEEDED( hr ) && pTypeInfo ) + { + TYPEATTR* pTypeAttr; + hr = pTypeInfo->GetTypeAttr( &pTypeAttr ); + if ( pTypeAttr ) + { + OLECHAR szGuid[40] = { 0 }; + int nCount = ::StringFromGUID2( pTypeAttr->guid, szGuid, sizeof( szGuid ) ); + CString guid( szGuid, nCount ); + + repr << ":VT_DISPATCH:GUID:" << guid; + pTypeInfo->ReleaseTypeAttr( pTypeAttr ); + } + else + { + repr << ":VT_DISPATCH:" << variant.pdispVal; + } + } + else + { + repr << ":VT_DISPATCH:" << variant.pdispVal; + } + } + else + { + repr << ":UNKNOWN"; + } + + break; + } + default: + { + repr << ":UNKNOWN"; + break; + } + } + + return CString ( repr.str(), repr.pcount() ); +} + diff --git a/direct/src/plugin_activex/PPInterface.h b/direct/src/plugin_activex/PPInterface.h new file mode 100644 index 0000000000..f9fec57620 --- /dev/null +++ b/direct/src/plugin_activex/PPInterface.h @@ -0,0 +1,48 @@ +// Filename: PPInterface.h +// Created by: atrestman (14Sept09) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#pragma once + +#include "plugin/p3d_plugin.h" + +class PPInterface +{ +public: + PPInterface(); + virtual ~PPInterface(); + + virtual P3D_object* GetP3DObject() = 0; + virtual IOleClientSite* GetClientSte() = 0; + + HRESULT HasProperty( CComPtr& pDispatch, CString& name ); + HRESULT CallMethod( CComPtr& pDispatch, CString& name, COleVariant& varResult, int num_params, COleVariant* params ); + HRESULT GetProperty( CComPtr& pDispatch, CString& name, COleVariant& varResult ); + HRESULT SetProperty( CComPtr& pDispatch, CString& name, COleVariant& varValue, COleVariant& varResult ); + HRESULT EvalExpression( CComPtr& pDispatch, CString& expression, COleVariant& varResult ); + + HRESULT P3DHasMethod( P3D_object* p3dObject, CString& name, bool& result ); + HRESULT P3DCallMethod( P3D_object* p3dObject, CString& name, DISPPARAMS FAR* pdispparams, VARIANT FAR* varResult ); + HRESULT P3DGetProperty( P3D_object* p3dObject, CString& name, VARIANT FAR* varResult ); + HRESULT P3DSetProperty( P3D_object* p3dObject, CString& name, DISPPARAMS FAR* pdispparams, bool& result ); + + void p3dobj_to_variant(VARIANT* result, P3D_object* object); + P3D_object* variant_to_p3dobj(COleVariant* variant); + CString get_repr(COleVariant& variant); + +private: + HRESULT GetIdOfName( IDispatch* pDisp, CString& ptName, DISPID* dispID ); + HRESULT Invoke( int nType, IDispatch* pDisp, CString& ptName, VARIANT* pvResult, int cArgs, VARIANT* params ); + HRESULT GetHtmlDocDispatch( CComPtr& pHTMLDocDispatch ); + +}; \ No newline at end of file diff --git a/direct/src/plugin_activex/PPLogger.cpp b/direct/src/plugin_activex/PPLogger.cpp new file mode 100644 index 0000000000..1ffac82331 --- /dev/null +++ b/direct/src/plugin_activex/PPLogger.cpp @@ -0,0 +1,133 @@ +// Filename: PPLogger.cpp +// Created by: atrestman (14Sept09) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#include "stdafx.h" + +#include "windows.h" +#include "PPLogger.h" + +std::ofstream PPLogger::m_logfile; +bool PPLogger::m_isOpen = false; + +PPLogger::PPLogger( ) +{ +} + +PPLogger::~PPLogger( ) +{ +} + +int PPLogger::CreateNewFolder( const std::string& dirname ) +{ + int error( 0 ); + if ( CreateDirectory( dirname.c_str( ), NULL ) != 0 ) + { + // Success! + return error; + } + // Failed. + DWORD lastError = GetLastError( ); + if ( lastError == ERROR_ALREADY_EXISTS ) + { + // Not really an error: the directory is already there. + return error; + } + if ( lastError == ERROR_PATH_NOT_FOUND ) + { + // We need to make the parent directory first. + std::string parent = dirname; + if ( !parent.empty() && CreateNewFolder( parent ) ) + { + // Parent successfully created. Try again to make the child. + if ( CreateDirectory( dirname.c_str(), NULL ) != 0) + { + // Got it! + return error; + } + m_logfile << "Couldn't create " << dirname << "\n"; + } + } + return ( error = 1 ); +} + +int PPLogger::CreateNewFile(const std::string& dirname, const std::string& filename) +{ + int error( 0 ); + std::string logfilename = dirname + filename; + HANDLE file = CreateFile( logfilename.c_str(), GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); + if ( file == INVALID_HANDLE_VALUE ) + { + // Try to make the parent directory first. + std::string parent = dirname; + if ( !parent.empty( ) && CreateNewFolder( parent ) ) + { + // Parent successfully created. Try again to make the file. + file = CreateFile( logfilename.c_str(), GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); + } + if ( file == INVALID_HANDLE_VALUE ) + { + m_logfile << "Couldn't create " << filename << "\n"; + return ( error = 1 ); + } + } + CloseHandle( file ); + return error; +} + +void PPLogger::Open( const std::string& logdir, const std::string& filename ) +{ + if ( !m_isOpen ) + { + int error = CreateNewFile( logdir, filename ); + // Note that this logfile name may not be specified at runtime. It + // must be compiled in if it is specified at all. + + std::string logBasename = filename; + +#ifdef P3D_DEFAULT_PLUGIN_LOG_FILENAME + if ( logBasename.empty( ) ) + { + logBasename = P3D_DEFAULT_PLUGIN_LOG_FILENAME; + } +#endif + if ( !logBasename.empty( ) ) + { + // Get the log directory. + std::string logDirectory = logdir; + if ( logDirectory.empty( ) ) + { + char buffer[MAX_PATH]; + if ( GetTempPath( MAX_PATH, buffer ) != 0 ) + { + logDirectory = buffer; + } + } + // Construct the full logfile pathname. + std::string logPathname = logDirectory; + logPathname += logBasename; + + m_logfile.open( logPathname.c_str( ) ); + m_logfile.setf( std::ios::unitbuf ); + } + + // If we didn't have a logfile name compiled in, we throw away log + // output by the simple expedient of never actually opening the + // ofstream. + m_isOpen = true; + } +} diff --git a/direct/src/plugin_activex/PPLogger.h b/direct/src/plugin_activex/PPLogger.h new file mode 100644 index 0000000000..0e102e4db9 --- /dev/null +++ b/direct/src/plugin_activex/PPLogger.h @@ -0,0 +1,41 @@ +// Filename: PPLogger.h +// Created by: atrestman (14Sept09) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#pragma once + +#include +#include +#include + +#define P3D_DEFAULT_PLUGIN_LOG_FILENAME "p3dActiveXlog.log" + +class PPLogger +{ +public: + PPLogger( ); + virtual ~PPLogger( ); + + void Open( const std::string& logdir, const std::string& logbasename ); + static std::ofstream& Log( ) { return m_logfile; } + +protected: + int CreateNewFile(const std::string& dirname, const std::string& filename ); + int CreateNewFolder( const std::string& dirname ); + + static bool m_isOpen; + static std::ofstream m_logfile; +}; + +#define nout PPLogger::Log( ) + diff --git a/direct/src/plugin_activex/PPPandaObject.cpp b/direct/src/plugin_activex/PPPandaObject.cpp new file mode 100644 index 0000000000..bb6d7bc98d --- /dev/null +++ b/direct/src/plugin_activex/PPPandaObject.cpp @@ -0,0 +1,184 @@ +// Filename: PPPandaObject.cpp +// Created by: atrestman (14Sept09) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "PPPandaObject.h" + +PPandaObject::PPandaObject( PPInterface* interfac, P3D_object* p3dObject ) : + m_interface( interfac), m_p3dObject( p3dObject ), m_refs( 0 ), m_ptinfo( NULL ) +{ + if ( m_p3dObject ) + { + P3D_OBJECT_INCREF( m_p3dObject ); + } + AddRef(); +} + +PPandaObject::~PPandaObject() +{ + if( m_ptinfo ) + { + m_ptinfo->Release(); + } + if ( m_p3dObject ) + { + P3D_OBJECT_DECREF( m_p3dObject ); + } +} + +// Dispatch Methods + +STDMETHODIMP_(unsigned long) PPandaObject::AddRef() +{ + return ++m_refs; +} + +STDMETHODIMP_(unsigned long) PPandaObject::Release() +{ + --m_refs; + if( m_refs <= 0 ) + { + delete this; + } + return m_refs; +} + +STDMETHODIMP PPandaObject::GetIDsOfNames( + REFIID riid, + OLECHAR FAR* FAR* rgszNames, + unsigned int cNames, + LCID lcid, + DISPID FAR* rgdispid) +{ + UNUSED(lcid); + + if(!IsEqualIID(riid, IID_NULL)) + return DISP_E_UNKNOWNINTERFACE; + + for ( UINT i = 0; i < cNames; i++ ) + { + UINT j = 0; + for ( j = 0; j < m_idsOfNames.size(); j++ ) + { + if ( m_idsOfNames[j] == rgszNames[i] ) + { + rgdispid[i] = j; + break; + } + } + if ( j >= m_idsOfNames.size() ) + { + CString name( rgszNames[i] ); + m_idsOfNames.push_back( name ); + rgdispid[i] = j; + } + } + return S_OK; +} + +STDMETHODIMP PPandaObject::GetTypeInfo(unsigned int iTInfo, LCID lcid, ITypeInfo FAR* FAR* ppTInfo) +{ + UNUSED(lcid); + + if ( ppTInfo == NULL ) + { + return E_INVALIDARG; + } + *ppTInfo = NULL; + + if( iTInfo != 0 ) + { + return DISP_E_BADINDEX; + } + if ( m_ptinfo == NULL ) + { + return E_FAIL; + } + m_ptinfo->AddRef(); // AddRef and return pointer to cached + // typeinfo for this object. + *ppTInfo = m_ptinfo; + + return NOERROR; +} + +STDMETHODIMP PPandaObject::GetTypeInfoCount(unsigned int FAR* pctinfo) +{ + // This object has a single *introduced* interface + // + *pctinfo = 1; + + return NOERROR; +} + +STDMETHODIMP PPandaObject::Invoke( + DISPID dispidMember, + REFIID riid, + LCID lcid, + unsigned short wFlags, + DISPPARAMS FAR* pdispparams, + VARIANT FAR* pvarResult, + EXCEPINFO FAR* pexcepinfo, + unsigned int FAR* puArgErr) +{ + UNUSED(lcid); + + if(!IsEqualIID(riid, IID_NULL)) + { + return DISP_E_UNKNOWNINTERFACE; + } + + CString& name( m_idsOfNames[dispidMember] ); + HRESULT hr( S_OK ); + + switch ( wFlags ) + { + case DISPATCH_METHOD: + { + bool hasMethod( false ); + hr = m_interface->P3DHasMethod( m_p3dObject, name, hasMethod ); + if ( SUCCEEDED( hr ) && hasMethod ) + { + hr = m_interface->P3DCallMethod( m_p3dObject, name, pdispparams, pvarResult ); + } + } + break; + case DISPATCH_PROPERTYGET: + { + hr = m_interface->P3DGetProperty( m_p3dObject, name, pvarResult ); + } + break; + case DISPATCH_PROPERTYPUT: + { + bool result( false ); + hr = m_interface->P3DSetProperty( m_p3dObject, name, pdispparams, result ); + } + break; + } + return hr; +} + +STDMETHODIMP PPandaObject::QueryInterface(REFIID riid, void FAR* FAR* ppv) +{ + if(!IsEqualIID(riid, IID_IUnknown)) + { + if(!IsEqualIID(riid, IID_IDispatch)) + { + *ppv = NULL; + return E_NOINTERFACE; + } + } + *ppv = this; + AddRef(); + return NOERROR; +} diff --git a/direct/src/plugin_activex/PPPandaObject.h b/direct/src/plugin_activex/PPPandaObject.h new file mode 100644 index 0000000000..8486e3c88a --- /dev/null +++ b/direct/src/plugin_activex/PPPandaObject.h @@ -0,0 +1,70 @@ +// Filename: PPPandaObject.h +// Created by: atrestman (14Sept09) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#pragma once + +#include +#include + +#include "plugin/p3d_plugin.h" +#include "PPInterface.h" + +class PPandaObject : public IDispatch +{ +public: + + // Methods + PPandaObject( PPInterface* interfac, P3D_object* p3dObject ); + virtual ~PPandaObject(); + + // IUnknown methods + STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppvObj); + STDMETHOD_(unsigned long, AddRef)(void); + STDMETHOD_(unsigned long, Release)(void); + + // IDispatch methods + STDMETHOD(GetTypeInfoCount)(unsigned int FAR* pcTypeInfo); + + STDMETHOD(GetTypeInfo)( + unsigned int iTypeInfo, + LCID lcid, + ITypeInfo FAR* FAR* ppTypeInfo); + + STDMETHOD(GetIDsOfNames)( + REFIID riid, + OLECHAR FAR* FAR* rgszNames, + unsigned int cNames, + LCID lcid, + DISPID FAR* rgdispid); + + STDMETHOD(Invoke)( + DISPID dispidMember, + REFIID riid, + LCID lcid, + unsigned short wFlags, + DISPPARAMS FAR* pdispparams, + VARIANT FAR* pvarResult, + EXCEPINFO FAR* pexcepinfo, + unsigned int FAR* puArgErr); + +private: + PPandaObject(); + + // Props - Dispatch related + unsigned long m_refs; + ITypeInfo FAR* m_ptinfo; + std::vector m_idsOfNames; + PPInterface* m_interface; + P3D_object *m_p3dObject; +}; diff --git a/direct/src/plugin_activex/ReadMe.txt b/direct/src/plugin_activex/ReadMe.txt new file mode 100644 index 0000000000..c40fee8cfc --- /dev/null +++ b/direct/src/plugin_activex/ReadMe.txt @@ -0,0 +1,79 @@ +======================================================================== + ACTIVEX CONTROL DLL : MyActiveX Project Overview +======================================================================== + +ControlWizard has created this project for your MyActiveX ActiveX Control +DLL, which contains 1 control. + +This skeleton project not only demonstrates the basics of writing an +ActiveX Control, but is also a starting point for writing the specific +features of your control. + +This file contains a summary of what you will find in each of the files +that make up your MyActiveX ActiveX Control DLL. + +P3DActiveX.vcproj + This is the main project file for VC++ projects generated using an + Application Wizard. It contains information about the version of + Visual C++ that generated the file, and information about the platforms, + configurations, and project features selected with the Application Wizard. + +P3DActiveX.h + This is the main include file for the ActiveX Control DLL. It + includes other project-specific includes such as resource.h. + +P3DActiveX.cpp + This is the main source file that contains code for DLL initialization, + termination and other bookkeeping. + +P3DActiveX.rc + This is a listing of the Microsoft Windows resources that the project + uses. This file can be directly edited with the Visual C++ resource + editor. + +P3DActiveX.def + This file contains information about the ActiveX Control DLL that + must be provided to run with Microsoft Windows. + +P3DActiveX.idl + This file contains the Object Description Language source code for the + type library of your control. + +///////////////////////////////////////////////////////////////////////////// +CP3DActiveXCtrl control: + +P3DActiveXCtrl.h + This file contains the declaration of the CP3DActiveXCtrl C++ class. + +P3DActiveXCtrl.cpp + This file contains the implementation of the CP3DActiveXCtrl C++ class. + +P3DActiveXPropPage.h + This file contains the declaration of the CP3DActiveXPropPage C++ class. + +P3DActiveXPropPage.cpp + This file contains the implementation of the CP3DActiveXPropPage C++ class. + +CP3DActiveXCtrl.bmp + This file contains a bitmap that a container will use to represent the + CP3DActiveXCtrl control when it appears on a tool palette. This bitmap + is included by the main resource file P3DActiveX.rc. + +///////////////////////////////////////////////////////////////////////////// +Other standard files: + +stdafx.h, stdafx.cpp + These files are used to build a precompiled header (PCH) file + named P3DActiveX.pch and a precompiled types (PCT) file named stdafx.obj. + +resource.h + This is the standard header file, which defines new resource IDs. + The Visual C++ resource editor reads and updates this file. + +///////////////////////////////////////////////////////////////////////////// +Other notes: + +ControlWizard uses "TODO:" to indicate parts of the source code you +should add to or customize. + +///////////////////////////////////////////////////////////////////////////// diff --git a/direct/src/plugin_activex/resource.h b/direct/src/plugin_activex/resource.h new file mode 100644 index 0000000000..cb7e075db2 --- /dev/null +++ b/direct/src/plugin_activex/resource.h @@ -0,0 +1,27 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by P3DActiveX.rc +// +#define IDS_P3DACTIVEX 1 +#define IDB_P3DACTIVEX 1 +#define IDS_P3DACTIVEX_PPG 2 +#define IDS_P3DACTIVEX_PPG_CAPTION 200 +#define IDD_PROPPAGE_P3DACTIVEX 200 +#define IDR_GIF1 201 +#define IDC_PANDALAUNCH_BUTTON 202 +#define IDC_PANDAOUT 203 +#define IDC_EDIT1 204 +#define IDC_EDIT2 205 +#define IDC_CLEAR 206 +#define IDC_PANDACONTAINER 207 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 203 +#define _APS_NEXT_COMMAND_VALUE 32768 +#define _APS_NEXT_CONTROL_VALUE 208 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/direct/src/plugin_activex/stdafx.cpp b/direct/src/plugin_activex/stdafx.cpp new file mode 100644 index 0000000000..40ffb29d93 --- /dev/null +++ b/direct/src/plugin_activex/stdafx.cpp @@ -0,0 +1,5 @@ +// stdafx.cpp : source file that includes just the standard includes +// P3DActiveX.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" diff --git a/direct/src/plugin_activex/stdafx.h b/direct/src/plugin_activex/stdafx.h new file mode 100644 index 0000000000..541e2dbab1 --- /dev/null +++ b/direct/src/plugin_activex/stdafx.h @@ -0,0 +1,43 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, +// but are changed infrequently + +#pragma once + +#ifndef VC_EXTRALEAN +#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers +#endif + +// Modify the following defines if you have to target a platform prior to the ones specified below. +// Refer to MSDN for the latest info on corresponding values for different platforms. +#ifndef WINVER // Allow use of features specific to Windows 95 and Windows NT 4 or later. +#define WINVER 0x0400 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later. +#endif + +#ifndef _WIN32_WINNT // Allow use of features specific to Windows NT 4 or later. +#define _WIN32_WINNT 0x0400 // Change this to the appropriate value to target Windows 2000 or later. +#endif + +#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later. +#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later. +#endif + +#ifndef _WIN32_IE // Allow use of features specific to IE 4.0 or later. +#define _WIN32_IE 0x0400 // Change this to the appropriate value to target IE 5.0 or later. +#endif + +#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit + +#include // MFC support for ActiveX Controls +#include // MFC extensions +#include // MFC support for Internet Explorer 4 Comon Controls +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // MFC support for Windows Common Controls +#endif // _AFX_NO_AFXCMN_SUPPORT + +// Delete the two includes below if you do not wish to use the MFC +// database classes +#include // MFC database classes +#include // MFC DAO database classes +#include +