Page 1 of 2
Irrlicht + ActiveX (Internet Explorer) = ? (project linked)
Posted: Mon Jul 02, 2007 6:45 am
by godmode2k
Answer is ******. lol
but it works fine !
// ---------------------------------------------------------------
// Project: You wanna Rendering 3D materials using Irrlicht on the Web ?
// ---------------------------------------------------------------
// Purpose: Irrlicht as ActiveX Control on the Web Browser such as Internet Explorer.
// Author : June (
godmode2k@hotmail.com | MSN)
// Date : July. 2nd. 2007, KST
// ---------------------------------------------------------------
// Note : Ready ?
// Update:
// + August 28, 2008:
// 1. You can check out full of source code relevant this thread below link.
//
http://code.google.com/p/gedk/downloads/list
// ---------------------------------------------------------------
Q: I don't know how to create an ActiveX Control with Visual C++ !!!
A: Don't worry baby. See below site.
http://www.codeguru.com/cpp/com-tech/activex/
http://www.codeproject.com/KB/COM/CompleteActiveX.aspx
[STEP #1]
Make an ActiveX Control using MS-VC++ (6.0 or whatever) where Project - > "MFC ActiveX ControlWizard" tab.
Its done ?
[STEP #2]
Adds below code.
Code: Select all
//! ~Ctl.h
// ---------------------------------------------------------------
class ~Ctrl : public COleControl
{
public:
...
// ADD [
HWND m_hWnd;
HWND m_hIrrlichtWindow;
HINSTANCE m_hInstance;
bool m_IsFirst; // set flag, at drawing first time via OnDraw(...)
void EngineTest(CWnd* cWnd);
// ]
...
};
// ---------------------------------------------------------------
Code: Select all
//! ~Ctl.cpp
// ---------------------------------------------------------------
// Global Variable
#include "stdafx.h"
#include "~.h"
#include "~Ctl.h"
#include "~Ppg.h"
//! Here !
#include <irrlicht.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
// 3D Engine Test
// -----------------------------------------------------------------------------
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
#pragma comment(lib, "Irrlicht.lib")
IrrlichtDevice *device = 0;
video::IVideoDriver* driver = 0;
IGUIEnvironment* env = 0;
scene::ISceneManager* smgr = 0;
s32 cnt = 0;
IGUIListBox* listbox = 0;
HWND g_hWnd;
// -----------------------------------------------------------------------------
...
CTest_engine_activex_vc60Ctrl::CTest_engine_activex_vc60Ctrl()
{
InitializeIIDs(&IID_DTest_engine_activex_vc60, &IID_DTest_engine_activex_vc60Events);
// TODO: Initialize your control's instance data here.
// ADD [
m_IsFirst = true;
// ]
}
void ~Ctrl::OnDraw(
CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
{
// TODO: Replace the following code with your own drawing code.
// pdc->FillRect(rcBounds, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));
// pdc->Ellipse(rcBounds);
// ADD [
if( m_IsFirst ) {
m_IsFirst = false;
EngineTest( pdc->GetWindow() );
}
// ]
//! EventReceiver
// Yes, you using your own EventReceiver class as before.
// ADD [
class MyEventReceiver : public IEventReceiver
{
public:
virtual bool OnEvent(SEvent event)
{
...
}
...
};
// ]
void ~Ctrl::EngineTest(CWnd* cWnd)
{
// ADD [
//! Set for Child Window as a Button
// -----------------------------------------
video::E_DRIVER_TYPE driverType;
driverType = video::EDT_OPENGL;
MyEventReceiver receiver;
irr::SIrrlichtCreationParameters param;
m_hWnd = cWnd->m_hWnd;
m_hInstance = AfxGetInstanceHandle();
m_hIrrlichtWindow = CreateWindow("BUTTON", "Test Engine On The ActiveX", WS_CHILD | WS_VISIBLE | BS_OWNERDRAW, 10, 200, 640, 480, m_hWnd, NULL, m_hInstance, NULL);
param.WindowId = reinterpret_cast<s32>( m_hIrrlichtWindow );
param.DriverType = driverType;
device = createDeviceEx( param );
device->setEventReceiver(&receiver);
// -----------------------------------------
// Your code
// -----------------------------------------
//! Prepare to Rendering
// -----------------------------------------
g_hWnd = m_hWnd;
::ShowWindow( m_hIrrlichtWindow , SW_SHOW );
::UpdateWindow( m_hIrrlichtWindow );
while( device->run() && driver ) {
//! "isWindowActivate()" isn't work here.
//if( device->isWindowActive() ) {
driver->beginScene(true, true, SColor(0,200,200,200));
smgr->drawAll();
env->drawAll();
driver->endScene();
//! ^___^
::UpdateWindow( m_hIrrlichtWindow );
//}
}
// ]
}
//! Mouse Event
// ClassWizard -> add Message "WM_MOUSEACTIVATE"
int ~Ctrl::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message)
{
// TODO: Add your message handler code here and/or call default
// ADD [
OnActivateInPlace( true, NULL );
// ]
return COleControl::OnMouseActivate(pDesktopWnd, nHitTest, message);
}
// ---------------------------------------------------------------
* Screenshot *
hmm...
Posted: Mon Jul 02, 2007 12:45 pm
by godmode2k
Its as an application works good.
But, as an ActiveX, its a different each other.
* Confer below Internet Explorer Version *
//! Not Work
Windows XP Professional SP1 -> SP2 -> SP1
Version: 6.0.2800.1106.xpsp2.050301-1526
Update Version:; SP1; Q824145; Q330994;
Windows XP Professional SP1 -> SP2
Version: 6.0.2900.2180.xpsp_sp2_gdr.070227-2254
Update Version:; SP2;
//! It seems to work
Windows XP Professional SP2
Version: 6.0.2900.2180.xpsp_sp2_gdr.070227-2254
Update Version:; SP2; 3283;
and you ?
Posted: Mon Jul 02, 2007 3:53 pm
by bob
I've been using Irrlicht in an Active-X and haven't had any trouble. I've tried Home/Pro/2000/Server. And several different service pack combinations.
The biggest hurdle is IE's use of threads. You may be initialized in one thread, timers may come from another, destructor in another, Javascript calls in just any ol' convenient thread, etc.. but you have to handle this in most any Active-X. I create a dedicated thread to create/update/destroy Irrlicht.
It looks as though you're only updating Irrlicht on the first draw. I'm using an MM timer. It's not optimal, but you will have to cooperate with Windows somehow.
Posted: Wed Jul 04, 2007 2:25 am
by godmode2k
Thanks bob.
I've tried using thread which AfxBeginThread API.
But its not work.
I've just use thread in ~Ctrl Constructor like a below.
Code: Select all
AfxBeginThread( (AFX_THREADPROC)EngineTest_thread, (LPVOID)this);
Windows XP Professional SP2
Version: 6.0.2900.2180.xpsp_sp2_gdr.070227-2254
Update Version:; SP2; 3283;
In above IE version, seems to pretty good work without
occur OnDraw() event which like a ScrollBar in IE when finish rendering.
Code: Select all
device->closeDevice(); device->drop();
BUT. In below IE version, occur an Access Violation.
Windows XP Professional SP1 -> SP2 -> SP1
Version: 6.0.2800.1106.xpsp2.050301-1526
Update Version:; SP1; Q824145; Q330994;
Windows XP Professional SP1 -> SP2
Version: 6.0.2900.2180.xpsp_sp2_gdr.070227-2254
Update Version:; SP2;
Works/Not are same code either.
Occur Access Violation in here.
Is cause related IE thread ?
Best Regards,
godmode2k
Posted: Thu Jul 05, 2007 1:34 pm
by bob
I'm not saying this is the best or even remotely correct way.
But this is the architecture I'm using and it's worked well for me.
As an added bonus, it is simple to also create a Mozilla/Firefox plug-in. I suppose you could use this for any Windows app, but it may force needless threading issues upon you.
Use:
- Create a
CIrrThread object in your Active-X control.
- Be sure your control forces a real window
- Call
CIrrThread::Create() with a handle to the window after it is initialized and sized.
- Call
CIrrThread::Destroy() before you're window closes ( I use
WM_DESTROY )
IrrThread.h
Code: Select all
#pragma once
class CIrrThread
{
public:
/// Default constructor
CIrrThread();
/// Destructor
~CIrrThread();
/// Releases resources
/**
\warning Call before destroying the window passed to Create() !!!
*/
void Destroy();
/// Creates the thread
/*
\param [in] hWnd - Handle to window that will contain the Irrlicht view.
*/
BOOL Create( HWND hWnd );
protected:
/// Irrlicht engine variables
struct SIrrEngine
{
/// Default constructor
SIrrEngine()
{ SetRect( &rect, 0, 0, 0, 0 );
pDevice = NULL;
pSm = NULL;
pDriver = NULL;
pCamera = NULL;
}
/// Irlicht device
irr::IrrlichtDevice *pDevice;
/// Irlicht scene manager
irr::scene::ISceneManager *pSm;
/// Irlicht video driver
irr::video::IVideoDriver *pDriver;
/// Main camera
irr::scene::ICameraSceneNode *pCamera;
/// Size of the device
RECT rect;
};
protected:
/// Pump windows messages
BOOL MsgPump( HACCEL hAccel = NULL );
/// Initialize Irrlicht engine
virtual HRESULT Init();
/// Run the thing
virtual HRESULT Work();
/// Shutdown Irrlicht engine
virtual DWORD End();
private:
/// static API Thread procedure, Just calls ThreadProc()
static DWORD WINAPI _ThreadProc( LPVOID pData );
/// Instance callback
DWORD ThreadProc();
private:
/// Handle to our thread
HANDLE m_hThread;
/// Thread id
DWORD m_dwThreadId;
/// Parent window
HWND m_hWnd;
/// Stop event
HANDLE m_hStop;
/// Irrlicht engine
SIrrEngine m_sIe;
};
IrrThread.cpp
Code: Select all
#include "stdafx.h"
#include "IrrThread.h"
#define FRAME_RATE 30
#define CIrrThread_ReleaseHandle( h ) ( ( h ) ? ( CloseHandle( h ), h = NULL ) : ( h ) )
#define CIrrThread_RW( r ) ( r.right - r.left )
#define CIrrThread_RH( r ) ( r.bottom - r.top )
CIrrThread::CIrrThread(void) :
m_hStop( CreateEvent( NULL, TRUE, FALSE, NULL ) )
{
m_hWnd = NULL;
m_hThread = NULL;
m_dwThreadId = 0;
}
CIrrThread::~CIrrThread()
{
Destroy();
CIrrThread_ReleaseHandle( m_hStop );
}
void CIrrThread::Destroy()
{
// Punt if no thread
if ( !m_hThread )
return;
// Tell the thread to stop
SetEvent( m_hStop );
// Shutdown thread
if ( WAIT_TIMEOUT == WaitForSingleObject( m_hThread, 30000 ) )
// ???
TerminateThread( m_hThread, ERROR_GEN_FAILURE );
// No more thread
m_dwThreadId = 0;
CIrrThread_ReleaseHandle( m_hThread );
// No Window
m_hWnd = NULL;
// Reset event
ResetEvent( m_hStop );
// ... Ready to call Create() ...
}
BOOL CIrrThread::Create( HWND hWnd )
{
// Lose old device
Destroy();
// Ensure valid window
if ( !hWnd || !::IsWindow( hWnd ) )
return FALSE;
// Ensure valid window size
RECT rect; GetClientRect( hWnd, &rect );
if ( 0 >= CIrrThread_RW( rect ) || 0 >= CIrrThread_RH( rect ) )
return FALSE;
// Save window handle
m_hWnd = hWnd;
// Create a thread
m_hThread = CreateThread( (LPSECURITY_ATTRIBUTES)NULL,
0,
CIrrThread::_ThreadProc,
(LPVOID)this,
0,
&m_dwThreadId );
// Did we get the thread?
if ( m_hThread == NULL )
return FALSE;
return TRUE;
}
DWORD WINAPI CIrrThread::_ThreadProc( LPVOID pData )
{
CIrrThread *pIt = (CIrrThread*)pData;
if ( !pIt ) return 0;
return pIt->ThreadProc();
}
DWORD CIrrThread::ThreadProc()
{
// Initialize
if ( ERROR_SUCCESS == Init() )
// Run
while ( MsgPump()
&& ERROR_SUCCESS == Work()
&& WAIT_TIMEOUT == WaitForSingleObject( m_hStop, 0 ) )
// Multi-media timer is a little less jittery ... see timeSetEvent()
Sleep( 1000 / FRAME_RATE );
// Shutdown
return End();
}
BOOL CIrrThread::MsgPump( HACCEL hAccel )
{
MSG msg;
// See if a message is waiting
if ( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )
{
// Get if from the queue
if( GetMessage( &msg, NULL, 0, 0 ) )
{
// Give the dialog box a chance at this message
if ( !IsDialogMessage( msg.hwnd, &msg ) )
{
// Translate the message
if ( hAccel == NULL || !TranslateAccelerator( msg.hwnd, hAccel, &msg ) )
TranslateMessage ( &msg );
// Dispatch the message
DispatchMessage ( &msg );
} // end if
} // end else
else return FALSE;
} // end if
return TRUE;
}
HRESULT CIrrThread::Init()
{
if ( !m_hWnd || !::IsWindow( m_hWnd ) )
return -1;
RECT rect;
::GetClientRect( m_hWnd, &m_sIe.rect );
// Ensure valid window size
if ( 0 >= CIrrThread_RW( m_sIe.rect ) || 0 >= CIrrThread_RH( m_sIe.rect ) )
return -2;
// Params
irr::SIrrlichtCreationParameters icp;
icp.WindowId = (irr::s32)m_hWnd;
icp.DriverType = irr::video::EDT_DIRECT3D8;
icp.AntiAlias = true;
icp.WindowSize = irr::core::dimension2di( CIrrThread_RW( m_sIe.rect ), CIrrThread_RH( m_sIe.rect ) );
// Create Irr device
if ( !( m_sIe.pDevice = irr::createDeviceEx( icp ) ) )
return -3;
// Get scene manager
if ( !( m_sIe.pSm = m_sIe.pDevice->getSceneManager() ) )
return -4;
// Get video driver
if ( !( m_sIe.pDriver = m_sIe.pDevice->getVideoDriver() ) )
return -5;
m_sIe.pDevice->setResizeAble( TRUE );
m_sIe.pDriver->setAmbientLight( irr::video::SColorf( .5f, .5f, .5f ) );
m_sIe.pDriver->setTextureCreationFlag( irr::video::ETCF_ALWAYS_32_BIT, true );
// Add camera
if ( !( m_sIe.pCamera = m_sIe.pSm->addCameraSceneNode() ) )
return -6;
// Initialize camera
m_sIe.pCamera->setPosition( irr::core::vector3df( 0, 300, 300 ) );
m_sIe.pCamera->setTarget( irr::core::vector3df( 0, 0, 0 ) );
// *** Create a simple scene
// Animate camera
irr::scene::ISceneNodeAnimator *pAnim =
m_sIe.pSm->createFlyCircleAnimator( irr::core::vector3df( 0, 200, 0 ), 300 );
m_sIe.pCamera->addAnimator( pAnim );
pAnim->drop();
// Add lights
float fRad = 500;
m_sIe.pSm->addLightSceneNode( 0, irr::core::vector3df( fRad, fRad, fRad ),
irr::video::SColor( 255, 255, 255, 255 ), fRad );
// Add cube
m_sIe.pSm->addCubeSceneNode( 100 ); //>addTestSceneNode( 50 );
return ERROR_SUCCESS;
}
HRESULT CIrrThread::Work()
{
m_sIe.pDevice->getTimer()->tick();
m_sIe.pDevice->run();
// m_sIe.pDriver->beginScene( true, true, 0 );
m_sIe.pDriver->beginScene( true, true, irr::video::SColor( 255, 50, 0, 0 ) );
m_sIe.pSm->drawAll();
m_sIe.pDriver->endScene();
return ERROR_SUCCESS;
}
DWORD CIrrThread::End()
{
// Close the engine
m_sIe.pSm = NULL;
m_sIe.pDriver = NULL;
m_sIe.pCamera = NULL;
if ( m_sIe.pDevice )
{ m_sIe.pDevice->drop();
m_sIe.pDevice = NULL;
} // end if
return ERROR_SUCCESS;
}
Thanks Bob...
Posted: Thu Jul 05, 2007 3:18 pm
by godmode2k
hmm...
I've figured out why occuring Access Violation in createDeviceEx().
It was my mistake. So, i've just delete the /WINDOWS/System32/Irrlicht.dll.
And rebuild & packing & run.
Works good for me.
So, i reply modified code here.
Code: Select all
//! ~Ctl.h
// ---------------------------------------------------------------
class ~Ctrl : public COleControl
{
public:
...
// ADD [
HWND m_hWnd;
HWND m_hIrrlichtWindow;
HINSTANCE m_hInstance;
bool m_IsFirst; // set flag, at drawing first time via OnDraw(...)
void EngineTest(CWnd* cWnd);
// ]
...
};
// ---------------------------------------------------------------
Code: Select all
//! ~Ctl.cpp
// ---------------------------------------------------------------
// Global Variable
#include "stdafx.h"
#include "~.h"
#include "~Ctl.h"
#include "~Ppg.h"
//! Here !
#include <irrlicht.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
// 3D Engine Test
// -----------------------------------------------------------------------------
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
#pragma comment(lib, "Irrlicht.lib")
video::IVideoDriver* driver = 0;
IGUIEnvironment* env = 0;
scene::ISceneManager* smgr = 0;
s32 cnt = 0;
IGUIListBox* listbox = 0;
HWND g_hWnd;
// -----------------------------------------------------------------------------
...
CTest_engine_activex_vc60Ctrl::CTest_engine_activex_vc60Ctrl()
{
InitializeIIDs(&IID_DTest_engine_activex_vc60, &IID_DTest_engine_activex_vc60Events);
// TODO: Initialize your control's instance data here.
// ADD [
m_IsFirst = true;
// ]
}
void ~Ctrl::OnDraw(
CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
{
// TODO: Replace the following code with your own drawing code.
// pdc->FillRect(rcBounds, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));
// pdc->Ellipse(rcBounds);
// ADD [
if( m_IsFirst ) {
m_IsFirst = false;
EngineTest( pdc->GetWindow() );
}
// ]
//! EventReceiver
// Yes, you using your own EventReceiver class as before.
// ADD [
class MyEventReceiver : public IEventReceiver
{
private:
bool m_isRender;
IrrlichtDevice* device;
public:
void setDevice(IrrlichtDevice* v) { device = v; }
void setRender(bool v) { m_isRender = v; }
bool getRender(void) { return m_isRender; }
virtual bool OnEvent(SEvent event)
{
if (event.EventType == EET_GUI_EVENT)
{
s32 id = event.GUIEvent.Caller->getID();
IGUIEnvironment* env = device->getGUIEnvironment();
switch(event.GUIEvent.EventType)
{
case EGET_SCROLL_BAR_CHANGED:
if (id == 104)
{
s32 pos = ((IGUIScrollBar*)event.GUIEvent.Caller)->getPos();
for (u32 i=0; i<EGDC_COUNT ; ++i)
{
SColor col = env->getSkin()->getColor((EGUI_DEFAULT_COLOR)i);
col.setAlpha(pos);
env->getSkin()->setColor((EGUI_DEFAULT_COLOR)i, col);
}
}
break;
case EGET_BUTTON_CLICKED:
if (id == 101)
{
setRender( false );
return true;
}
default:
break;
}
}
return false;
}
...
};
// ]
void ~Ctrl::EngineTest(CWnd* cWnd)
{
// ADD [
//! Set for Child Window as a Button
// -----------------------------------------
video::E_DRIVER_TYPE driverType;
driverType = video::EDT_OPENGL;
MyEventReceiver receiver;
irr::SIrrlichtCreationParameters param;
m_hWnd = cWnd->m_hWnd;
m_hInstance = AfxGetInstanceHandle();
m_hIrrlichtWindow = CreateWindow("BUTTON", "Test Engine On The ActiveX", WS_CHILD | WS_VISIBLE | BS_OWNERDRAW, 10, 200, 640, 480, m_hWnd, NULL, m_hInstance, NULL);
param.WindowId = reinterpret_cast<s32>( m_hIrrlichtWindow );
param.DriverType = driverType;
IrrlichtDevice* device = irr::createDeviceEx( param );
receiver.setDevice( device );
receiver.setRender( true );
device->setEventReceiver(&receiver);
// -----------------------------------------
// Your code
// -----------------------------------------
//! Prepare to Rendering
// -----------------------------------------
g_hWnd = m_hWnd;
::ShowWindow( m_hIrrlichtWindow , SW_SHOW );
::UpdateWindow( m_hIrrlichtWindow );
while( device->run() && driver ) {
if( !receiver.getRender() ) { break; }
//! "isWindowActivate()" isn't work here.
//if( device->isWindowActive() ) {
driver->beginScene(true, true, SColor(0,200,200,200));
smgr->drawAll();
env->drawAll();
driver->endScene();
//! ^___^
::UpdateWindow( m_hIrrlichtWindow );
//}
}
// ]
device->closeDevice();
device->drop();
}
//! Mouse Event
// ClassWizard -> add Message "WM_MOUSEACTIVATE"
int ~Ctrl::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message)
{
// TODO: Add your message handler code here and/or call default
// ADD [
OnActivateInPlace( true, NULL );
// ]
return COleControl::OnMouseActivate(pDesktopWnd, nHitTest, message);
}
// ---------------------------------------------------------------
Posted: Thu Jul 05, 2007 3:33 pm
by bob
So, i've just delete the /WINDOWS/System32/Irrlicht.dll.
I static linked to avoid the whole dll issue. Otherwise you have to figure out how to download it to the client...
Glad it's working
Posted: Fri Jul 06, 2007 1:12 am
by godmode2k
ah-ha...
thanks bob.
Posted: Thu Jul 12, 2007 11:30 pm
by Midnight
I think I'm in love.
how come asians are so gd efficiant.
this looks like it might be useful.
Posted: Fri Jul 13, 2007 7:04 am
by godmode2k
^^
Thanks Midnight.
But, i'm not a girl... ^^;
My avatar image is Korean pop singer, Jang Na-Ra.
Regards,
godmode2k.
Posted: Sun Jul 29, 2007 1:56 pm
by BlindSide
Haha Midnight you pimp
ANYWAY... this sounds very very useful if I understood right. You can create a full online gaming website using Irrlicht as long as users install a special addon that will maybe extract Irrlicht.dll to system32? Anything else thats required? Special server things etc?
Also this is Internet Explorer-only huh? Do you think there is a way to do this in firefox? (Maybe through writing a custom firefox plugin???)
I am interested in this because alot of clients these days are asking for online gaming sites, (100x more than a normal C++ application.).
Cheers
Posted: Sun Jul 29, 2007 5:29 pm
by bob
Irrlicht works perfectly in an Internet Explorer ActiveX or Mozilla/Firefox plug-in. With a little planing, you can easily create both from one project.
Static linking Irrlicht does away with the need to download the .dll to the user. And there's really no special requirements beyond basic understanding of ActiveX/COM and or Mozilla.
I could probably find the time to create a complete example, unless god is up to it?
Posted: Sun Jul 29, 2007 8:18 pm
by Midnight
so I'm in love with a pop singer then
Posted: Mon Jul 30, 2007 3:23 am
by BlindSide
bob wrote:Irrlicht works perfectly in an Internet Explorer ActiveX or Mozilla/Firefox plug-in. With a little planing, you can easily create both from one project.
Static linking Irrlicht does away with the need to download the .dll to the user. And there's really no special requirements beyond basic understanding of ActiveX/COM and or Mozilla.
I could probably find the time to create a complete example, unless god is up to it?
But static linking to every project means every game on the website would needlessly take a long time to load. Hmmm but I guess if its a single application then thats alright. It would be nice to create some sort of online mmorpg using this technology.
Posted: Mon Jul 30, 2007 2:31 pm
by bob
You only pay the penalty the first time you load the Active-X, I'm not sure that's any different than downloading an install package.
If you don't static link, the user will have to download the DLL separately and install it themselves, or you have to code another Active-X or install package to do this, since your control won't even launch without all the dependencies in place.
There are some definite benefits to the Active-X/Plug-in design as to mmorpg. You can leverage Javascript/AJAX for communications which may simplify things. Although, the latency may be unacceptable.
@Midnight - I thought it was probably the guys daughter, guess I'm getting old.