Browse Source

initial commit

Arkady Trestman 16 years ago
parent
commit
6a17f6c388
33 changed files with 4293 additions and 0 deletions
  1. 262 0
      direct/src/plugin_activex/P3DActiveX.cpp
  2. 9 0
      direct/src/plugin_activex/P3DActiveX.def
  3. 38 0
      direct/src/plugin_activex/P3DActiveX.h
  4. 51 0
      direct/src/plugin_activex/P3DActiveX.idl
  5. 12 0
      direct/src/plugin_activex/P3DActiveX.inf
  6. 160 0
      direct/src/plugin_activex/P3DActiveX.rc
  7. 32 0
      direct/src/plugin_activex/P3DActiveX.sln
  8. 254 0
      direct/src/plugin_activex/P3DActiveX.vcproj
  9. BIN
      direct/src/plugin_activex/P3DActiveXCtrl.bmp
  10. 394 0
      direct/src/plugin_activex/P3DActiveXCtrl.cpp
  11. 94 0
      direct/src/plugin_activex/P3DActiveXCtrl.h
  12. 76 0
      direct/src/plugin_activex/P3DActiveXPropPage.cpp
  13. 42 0
      direct/src/plugin_activex/P3DActiveXPropPage.h
  14. 93 0
      direct/src/plugin_activex/P3DActiveX_i.c
  15. 316 0
      direct/src/plugin_activex/P3DActiveXidl.h
  16. 202 0
      direct/src/plugin_activex/PPBrowserObject.cpp
  17. 45 0
      direct/src/plugin_activex/PPBrowserObject.h
  18. 237 0
      direct/src/plugin_activex/PPDownloadCallback.cpp
  19. 64 0
      direct/src/plugin_activex/PPDownloadCallback.h
  20. 98 0
      direct/src/plugin_activex/PPDownloadRequest.cpp
  21. 74 0
      direct/src/plugin_activex/PPDownloadRequest.h
  22. 502 0
      direct/src/plugin_activex/PPInstance.cpp
  23. 77 0
      direct/src/plugin_activex/PPInstance.h
  24. 531 0
      direct/src/plugin_activex/PPInterface.cpp
  25. 48 0
      direct/src/plugin_activex/PPInterface.h
  26. 133 0
      direct/src/plugin_activex/PPLogger.cpp
  27. 41 0
      direct/src/plugin_activex/PPLogger.h
  28. 184 0
      direct/src/plugin_activex/PPPandaObject.cpp
  29. 70 0
      direct/src/plugin_activex/PPPandaObject.h
  30. 79 0
      direct/src/plugin_activex/ReadMe.txt
  31. 27 0
      direct/src/plugin_activex/resource.h
  32. 5 0
      direct/src/plugin_activex/stdafx.cpp
  33. 43 0
      direct/src/plugin_activex/stdafx.h

+ 262 - 0
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;
+}

+ 9 - 0
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

+ 38 - 0
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;
+

+ 51 - 0
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 <olectl.h>
+#include <idispids.h>
+
+[ 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;
+	};
+
+};

+ 12 - 0
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

+ 160 - 0
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
+

+ 32 - 0
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

+ 254 - 0
direct/src/plugin_activex/P3DActiveX.vcproj

@@ -0,0 +1,254 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="P3DActiveX"
+	ProjectGUID="{74451B00-2D87-412B-9359-B5CA2C2FEC2A}"
+	Keyword="MFCActiveXProj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="Debug"
+			IntermediateDirectory="Debug"
+			ConfigurationType="2"
+			UseOfMFC="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\;..\..\.."
+				PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;_USRDLL"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+				TreatWChar_tAsBuiltInType="TRUE"
+				UsePrecompiledHeader="3"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="4"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)/P3DActiveX.ocx"
+				LinkIncremental="2"
+				AdditionalLibraryDirectories="C:\DISNEY\wintools\built\lib;&quot;C:\DISNEY\wintools\built\lib&quot;"
+				ModuleDefinitionFile=".\P3DActiveX.def"
+				GenerateDebugInformation="TRUE"
+				SubSystem="2"
+				ImportLibrary="$(OutDir)/P3DActiveX.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"
+				PreprocessorDefinitions="_DEBUG"
+				MkTypLibCompatible="FALSE"
+				TypeLibraryName="$(IntDir)/$(ProjectName).tlb"
+				HeaderFileName="$(ProjectName)idl.h"/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				Description="Performing registration"
+				CommandLine="regsvr32 /s /c &quot;$(TargetPath)&quot;"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="_DEBUG"
+				Culture="1033"
+				AdditionalIncludeDirectories="$(IntDir)"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="Release"
+			IntermediateDirectory="Release"
+			ConfigurationType="2"
+			UseOfMFC="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\;..\..\.."
+				PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;_USRDLL"
+				RuntimeLibrary="0"
+				TreatWChar_tAsBuiltInType="TRUE"
+				UsePrecompiledHeader="3"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)/P3DActiveX.ocx"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="C:\DISNEY\wintools\built\lib;&quot;C:\DISNEY\wintools\built\lib&quot;"
+				ModuleDefinitionFile=".\P3DActiveX.def"
+				GenerateDebugInformation="TRUE"
+				SubSystem="2"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				ImportLibrary="$(OutDir)/P3DActiveX.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"
+				PreprocessorDefinitions="NDEBUG"
+				MkTypLibCompatible="FALSE"
+				TypeLibraryName="$(IntDir)/$(ProjectName).tlb"
+				HeaderFileName="$(ProjectName)idl.h"/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				Description="Performing registration"
+				CommandLine="regsvr32 /s /c &quot;$(TargetPath)&quot;"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"
+				AdditionalIncludeDirectories="$(IntDir)"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+			<File
+				RelativePath=".\P3DActiveX.cpp">
+			</File>
+			<File
+				RelativePath=".\P3DActiveX.idl">
+			</File>
+			<File
+				RelativePath=".\P3DActiveXCtrl.cpp">
+			</File>
+			<File
+				RelativePath=".\P3DActiveXPropPage.cpp">
+			</File>
+			<File
+				RelativePath=".\PPBrowserObject.cpp">
+			</File>
+			<File
+				RelativePath=".\PPDownloadCallback.cpp">
+			</File>
+			<File
+				RelativePath=".\PPDownloadRequest.cpp">
+			</File>
+			<File
+				RelativePath=".\PPInstance.cpp">
+			</File>
+			<File
+				RelativePath=".\PPInterface.cpp">
+			</File>
+			<File
+				RelativePath=".\PPLogger.cpp">
+			</File>
+			<File
+				RelativePath=".\PPPandaObject.cpp">
+			</File>
+			<File
+				RelativePath=".\stdafx.cpp">
+				<FileConfiguration
+					Name="Debug|Win32">
+					<Tool
+						Name="VCCLCompilerTool"
+						UsePrecompiledHeader="1"/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Win32">
+					<Tool
+						Name="VCCLCompilerTool"
+						UsePrecompiledHeader="1"/>
+				</FileConfiguration>
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+			<File
+				RelativePath=".\P3DActiveX.h">
+			</File>
+			<File
+				RelativePath=".\P3DActiveXCtrl.h">
+			</File>
+			<File
+				RelativePath=".\P3DActiveXPropPage.h">
+			</File>
+			<File
+				RelativePath=".\PPBrowserObject.h">
+			</File>
+			<File
+				RelativePath=".\PPDownloadCallback.h">
+			</File>
+			<File
+				RelativePath=".\PPDownloadRequest.h">
+			</File>
+			<File
+				RelativePath=".\PPInstance.h">
+			</File>
+			<File
+				RelativePath=".\PPInterface.h">
+			</File>
+			<File
+				RelativePath=".\PPLogger.h">
+			</File>
+			<File
+				RelativePath=".\PPPandaObject.h">
+			</File>
+			<File
+				RelativePath=".\Resource.h">
+			</File>
+			<File
+				RelativePath=".\stdafx.h">
+			</File>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+			<File
+				RelativePath=".\P3DActiveX.rc">
+			</File>
+			<File
+				RelativePath=".\P3DActiveXCtrl.bmp">
+			</File>
+		</Filter>
+		<File
+			RelativePath=".\ReadMe.txt">
+		</File>
+	</Files>
+	<Globals>
+		<Global
+			Name="RESOURCE_FILE"
+			Value="P3DActiveX.rc"/>
+	</Globals>
+</VisualStudioProject>

BIN
direct/src/plugin_activex/P3DActiveXCtrl.bmp


+ 394 - 0
direct/src/plugin_activex/P3DActiveXCtrl.cpp

@@ -0,0 +1,394 @@
+// P3DActiveXCtrl.cpp : Implementation of the CP3DActiveXCtrl ActiveX Control class.
+
+// Filename: P3DActiveXCtrl.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 "P3DActiveXCtrl.h"
+#include "P3DActiveXPropPage.h"
+#include "PPBrowserObject.h"
+#include ".\p3dactivexctrl.h"
+
+#include "Mshtml.h"
+#include "atlconv.h"
+
+#include <strstream>
+
+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<CPropbagPropExchange*>( 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();
+}

+ 94 - 0
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 <vector>
+
+// 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 <PARAM NAME="name" VALUE="value">
+    std::vector< std::pair < CString, CString > > m_parameters; 
+
+protected:
+    HRESULT ExchangeProperties( CPropExchange* pPropBag );
+
+    LRESULT OnPandaNotification(WPARAM wParam, LPARAM lParam);
+
+    PPandaObject* m_pPandaObject;
+
+    CComPtr<IOleClientSite> m_spClientSite;
+
+    void OnmainChanged(void);
+};
+

+ 76 - 0
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

+ 42 - 0
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()
+};
+

+ 93 - 0
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 <rpc.h>
+#include <rpcndr.h>
+
+#ifdef _MIDL_USE_GUIDDEF_
+
+#ifndef INITGUID
+#define INITGUID
+#include <guiddef.h>
+#undef INITGUID
+#else
+#include <guiddef.h>
+#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)*/
+

+ 316 - 0
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 <rpcndr.h> 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 <rpcndr.h>
+#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
+
+

+ 202 - 0
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 <assert.h>
+
+// 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<IDispatch> 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<IDispatch> 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<IDispatch> 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<IDispatch> 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;
+}

+ 45 - 0
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 <string>
+
+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<IDispatch> m_pDispatch;
+};

+ 237 - 0
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<IBindStatusCallback *>(this);
+	}
+
+	if (*ppvObject)
+	{
+		(*reinterpret_cast<LPUNKNOWN *>(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;
+}

+ 64 - 0
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<IStream> m_spStream;
+
+private:
+    PPDownloadCallbackSync& m_downloadSync;
+
+    DWORD m_dwTotalRead;
+
+};

+ 98 - 0
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;
+}

+ 74 - 0
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 <string>
+#include <strstream>
+
+#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();
+};

+ 502 - 0
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 <string>
+#include <sstream>
+#include <iostream>
+#include <fstream>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <windows.h>
+#include <process.h>
+
+#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<CP3DActiveXCtrl*>(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<IDispatch> 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<P3D_request*>( 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<CP3DActiveXCtrl*> ( 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 );
+}
+
+
+

+ 77 - 0
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 <string>
+#include <math.h>
+#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;
+};

+ 531 - 0
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 <strstream>
+#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<IDispatch>& pDispScript )
+{
+    HRESULT hr = S_OK; 
+
+    CComPtr<IOleClientSite> pOleClientSite = GetClientSte( ); 
+    ASSERT( pOleClientSite ); 
+
+    CComPtr<IOleContainer> pOleContainer; 
+    hr = pOleClientSite->GetContainer(& pOleContainer ); 
+    ASSERT( SUCCEEDED( hr ) && pOleContainer ); 
+
+    CComPtr<IHTMLDocument> 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<ITypeInfo> pTypeInfo;
+    hr = pDispScript->GetTypeInfo( 0, 0, &pTypeInfo );
+
+    return hr; 
+}
+
+HRESULT PPInterface::HasProperty( CComPtr<IDispatch>& 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<IDispatch>& 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<IDispatch>& 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<IDispatch>& 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<IDispatch>& 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, &param ); 
+    }
+    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<IDispatch> pDispObject( variant->pdispVal );
+            CComPtr<ITypeInfo> 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<IDispatch> pDispObject( variant.pdispVal );
+                CComPtr<ITypeInfo> 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() );
+}
+

+ 48 - 0
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<IDispatch>& pDispatch, CString& name );
+    HRESULT CallMethod( CComPtr<IDispatch>& pDispatch, CString& name, COleVariant& varResult, int num_params, COleVariant* params  );
+    HRESULT GetProperty( CComPtr<IDispatch>& pDispatch, CString& name, COleVariant& varResult );
+    HRESULT SetProperty( CComPtr<IDispatch>& pDispatch, CString& name, COleVariant& varValue, COleVariant& varResult );
+    HRESULT EvalExpression( CComPtr<IDispatch>& 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<IDispatch>& pHTMLDocDispatch );
+
+};

+ 133 - 0
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;
+    }
+}

+ 41 - 0
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 <string>
+#include <iostream>
+#include <fstream>
+
+#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( )
+

+ 184 - 0
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;
+}

+ 70 - 0
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 <vector>
+#include <string>
+
+#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<CString> m_idsOfNames;
+    PPInterface* m_interface;
+    P3D_object *m_p3dObject;
+};

+ 79 - 0
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.
+
+/////////////////////////////////////////////////////////////////////////////

+ 27 - 0
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

+ 5 - 0
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"

+ 43 - 0
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 <afxctl.h>         // MFC support for ActiveX Controls
+#include <afxext.h>         // MFC extensions
+#include <afxdtctl.h>		// MFC support for Internet Explorer 4 Comon Controls
+#ifndef _AFX_NO_AFXCMN_SUPPORT
+#include <afxcmn.h>			// 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 <afxdb.h>			// MFC database classes
+#include <afxdao.h>			// MFC DAO database classes
+#include <afxwin.h>
+