Scarabol wrote:OMG IT WORKS!!!
If anybody is interested in it, tell me.
MfG
Scarabol
#include <windows.h>
#include <d3d9.h>
#include "SWFContainer.h"
#import "flash10e.ocx"
// globals
LPDIRECT3D9 g_pDirect3D = NULL;
LPDIRECT3DDEVICE9 g_pDirect3D_Device = NULL;
LRESULT WINAPI WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPSTR lpCmdLine,
int nShow)
{
MSG msg;
WNDCLASSEX wc = {sizeof(WNDCLASSEX), CS_VREDRAW|CS_HREDRAW|CS_OWNDC,
WndProc, 0, 0, hInstance, NULL, NULL, (HBRUSH)(COLOR_WINDOW+1),
NULL, "DX9_TUTORIAL1_CLASS", NULL};
RegisterClassEx(&wc);
HWND hMainWnd = CreateWindow("DX9_TUTORIAL1_CLASS",
"DirectX 9 Bare Bones Tutorial 1",
WS_OVERLAPPEDWINDOW, 100, 100, 300, 300,
NULL, NULL, hInstance, NULL);
g_pDirect3D = Direct3DCreate9(D3D_SDK_VERSION);
D3DPRESENT_PARAMETERS PresentParams;
memset(&PresentParams, 0, sizeof(D3DPRESENT_PARAMETERS));
PresentParams.Windowed = TRUE;
PresentParams.SwapEffect = D3DSWAPEFFECT_DISCARD;
g_pDirect3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hMainWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &PresentParams,
&g_pDirect3D_Device);
SwfContainer test(g_pDirect3D_Device, "test.swf", 400, 300);
ShowWindow(hMainWnd, nShow);
UpdateWindow(hMainWnd);
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return(0);
}
LRESULT WINAPI WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return(0);
case WM_PAINT: // <— ADD THIS BLOCK
// drawing code goes here…
ValidateRect(hwnd, NULL);
return(0);
}
return(DefWindowProc(hwnd, msg, wParam, lParam));
}
#pragma once
//#include "stdafx.h"
//things needed for flash
#include "flash.h"
//#include <atlbase.h>
//#include <atlwin.h>
#include "OCIdl.h"
//DirectX9 goodies
#include <d3d9.h>
#pragma comment(lib,"d3d9.lib")
#include <d3dx9.h>
#pragma comment(lib,"d3dx9.lib")
#include <dxerr9.h>
#pragma comment(lib,"dxerr9.lib")
#include <windows.h>
//ShatterStar thingz
//#include "wrapperutils.h"
//#include "shatterstarutils.h"
#define NOTIMPLEMENTED return E_NOTIMPL
//Our own little thread. This will push the Flash AcitveX Control
//to the least used Core on a multi-core system
DWORD WINAPI LoadSWF (LPVOID filename);
//yes, this needs to be mutexed
typedef enum FlashThreadStatus
{
eNotStarted = 0x0,
eRunning,
eWaitingToStop,
eFinished,
} FlashThreadStatus;
class SwfContainer : public _IShockwaveFlashEvents
{
public:
//hidden window that will hold the flash ActiveX Control
HWND windowless;
//interfaces to shockwave object
IShockwaveFlash *iflash;
IUnknown *unk;
IViewObject *viewobject;
//the stream interface to marshal the viewobject into the Rendering Thread
IStream *pStream;
//the RenderThread's version of the view object
IViewObject *RTviewobject;
//the ready state of the Flash Document
long state;
//handle to Flash's thread
HANDLE hThread;
//event thinga-ma-bobs
IConnectionPointContainer *m_lpConCont;
IConnectionPoint *m_lpConPoint;
//Event Advise cookie (mmmmmmm cookies)
DWORD m_dwConPointID;
//System memory texture
IDirect3DTexture9 * memtex;
//Size of ActiveX Container
int _width,_height;
//number of frames in the Flash Document
long totalframes;
//path to flash file in Unicode
unsigned short real_name[256];
//status of the flash thread
FlashThreadStatus flashThreadStatus;
SwfContainer(IDirect3DDevice9 * m_pDevice, char * Path, int Width,int Height);
~SwfContainer(void);
HRESULT GetFrame(IDirect3DDevice9 * m_pDevice, IDirect3DTexture9 * m_pOutTexture);
//DShockwaveFlashEvents
HRESULT STDMETHODCALLTYPE OnReadyStateChange (
long newState );
HRESULT STDMETHODCALLTYPE OnProgress (
long percentDone );
HRESULT STDMETHODCALLTYPE FSCommand (
BSTR command,
BSTR args );
HRESULT STDMETHODCALLTYPE FlashCall(
BSTR request);
//IDispatch proto
virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount(
/* [out] */ UINT __RPC_FAR *pctinfo);
virtual HRESULT STDMETHODCALLTYPE GetTypeInfo(
/* [in] */ UINT iTInfo,
/* [in] */ LCID lcid,
/* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(
/* [in] */ REFIID riid,
/* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
/* [in] */ UINT cNames,
/* [in] */ LCID lcid,
/* [size_is][out] */ DISPID __RPC_FAR *rgDispId);
virtual /* [local] */ HRESULT STDMETHODCALLTYPE Invoke(
/* [in] */ DISPID dispIdMember,
/* [in] */ REFIID riid,
/* [in] */ LCID lcid,
/* [in] */ WORD wFlags,
/* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
/* [out] */ VARIANT __RPC_FAR *pVarResult,
/* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
/* [out] */ UINT __RPC_FAR *puArgErr);
//IUnknown proto
int m_iRef;
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void ** ppvObject);
ULONG STDMETHODCALLTYPE AddRef();
ULONG STDMETHODCALLTYPE Release();
};
//#include "atlwin.h"
//LPAtlAxWinInit AtlAxWinInit3 = (LPAtlAxWinInit)GetProcAddress(LoadLibrary("atl"), "AtlAxWinInit");
#include "windows.h"
typedef HRESULT(WINAPI * LPAtlAxAttachControl)(IUnknown* pControl,HWND hWnd,IUnknown** ppUnkContainer);
LPAtlAxAttachControl AtlAxAttachControl = (LPAtlAxAttachControl)GetProcAddress(LoadLibrary("atl"), "AtlAxAttachControl");
#include "SwfContainer.h"
SwfContainer::SwfContainer(IDirect3DDevice9 * m_pDevice,char * Path,int Width,int Height)
{
HRESULT hr = S_OK;
_width = Width;
_height = Height;
//create the system memory texture to hold the pixel buffer
hr = m_pDevice->CreateTexture(Width, // width
Height, // height
1, // levels
D3DUSAGE_DYNAMIC, // usage
D3DFMT_X8R8G8B8, // format
D3DPOOL_SYSTEMMEM,
&memtex,
NULL);
//convert Path to WideChar
MultiByteToWideChar(CP_ACP,0,Path,-1,(LPWSTR)real_name,256);
//change threading model
DWORD dwID;
hThread = CreateThread(NULL,0,LoadSWF,(LPVOID)this,0,&dwID);
}
DWORD WINAPI LoadSWF (LPVOID data) throw()
{
SwfContainer * cont = (SwfContainer *)data;
HRESULT hr = S_OK;
CoInitialize(NULL);
//create Window and Attach Flash control
cont->windowless = CreateWindowEx(0,/*CAxWindow::GetWndClassName()*/"",0,WS_POPUP,0,0,cont->_width,cont->_height,0,0,0,0);
hr = CoCreateInstance(__uuidof(ShockwaveFlash), NULL, CLSCTX_ALL, __uuidof(IShockwaveFlash), (void **)&cont->iflash);
//set up event notifications
hr = cont->iflash->QueryInterface(IID_IConnectionPointContainer, (void**)&cont->m_lpConCont);
if (FAILED(hr))
return -1;
hr = cont->m_lpConCont->FindConnectionPoint(DIID__IShockwaveFlashEvents, &cont->m_lpConPoint);
if (FAILED(hr))
return -1;
hr = cont->m_lpConPoint->Advise((_IShockwaveFlashEvents *)cont, &cont->m_dwConPointID);
if (FAILED(hr))
return -1;
//We went through all this trouble, make the little prick give us the Alpha Channel
hr = cont->iflash->put_WMode(L"transparent");
hr = AtlAxAttachControl(cont->iflash, cont->windowless,0);
//get the view object
hr = cont->iflash->QueryInterface(__uuidof(IViewObject),(void **)&cont->viewobject);
//create stream to Marshal view object into render thread
cont->pStream = NULL;
hr = CoMarshalInterThreadInterfaceInStream(__uuidof(IViewObject), cont->viewobject, &cont->pStream);
//sanity check
cont->RTviewobject = NULL;
//we want it to always loop
hr = cont->iflash->put_Loop(true);
//load the movie
hr = cont->iflash->put_Movie((BSTR)cont->real_name);
//since these are always going to be local media, force wait until ready state is loaded
for(cont->state = -1; (!hr) && (cont->state != 4);)
{
hr = cont->iflash->get_ReadyState(&cont->state);
if(cont->state == 4)
{
//get the total frames of the SWF file
hr = cont->iflash->get_TotalFrames(&cont->totalframes);
break;
}
Sleep(0); //snooze
}
hr = cont->iflash->Play();
cont->flashThreadStatus = eRunning;
//our own little message loop. The ActiveX container needs this to run outside of the main proc thread.
MSG msg;
while (GetMessage (&msg, 0, 0, 0))
{
//TO-Do mutex this!
if(eWaitingToStop == cont->flashThreadStatus)
{
break;
}
else
{
DispatchMessage (&msg);
}
}
cont->flashThreadStatus = eFinished;
return 0;
}
SwfContainer::~SwfContainer(void)
{
//kill the memtexture
if (memtex)
delete memtex;
//release the viewobject and it's evil twin RTviewobject
if (RTviewobject)
delete RTviewobject;
if (viewobject)
delete viewobject;
//unadvise the event sink
m_lpConPoint->Unadvise(m_dwConPointID);
//stop the flash thread
flashThreadStatus = eWaitingToStop;
while(flashThreadStatus == eWaitingToStop)
{
Sleep(10);
}
CloseHandle(hThread);
if (iflash)
delete iflash;
}
//Draw the contents of the SFW hiden window onto a Render Target in the GPU (m_pOutTexture)
HRESULT SwfContainer::GetFrame(IDirect3DDevice9 * m_pDevice, IDirect3DTexture9 * m_pOutTexture)
{
HRESULT hr = S_OK;
//Don't bother if it's not fully loaded
if(state != 4) return hr;
//do we need to un-marshall our version of the view object?
if(!RTviewobject)
{
CoGetInterfaceAndReleaseStream (pStream, __uuidof(IViewObject), (void**) &RTviewobject);
}
RECT rc={0,0,0,0};
rc.right = _width;
rc.bottom = _height;
VARIANT_BOOL isplay;
long fn = -1;
iflash->IsPlaying(&isplay);
iflash->CurrentFrame(&fn);
//clear out the memtexture
D3DLOCKED_RECT d3dlr;
hr = memtex->LockRect(0,&d3dlr,0,D3DLOCK_DONOTWAIT);
_int32 * buffer = (_int32 *)d3dlr.pBits;
DWORD buffersize = _width * _height;
for(unsigned int i = 1; i < buffersize; i++)
{
buffer[i] = (_int32)0x00000000;
}
memtex->UnlockRect(0);
//draw frame onto surface of memtexture
IDirect3DSurface9 * memsurface = NULL;
memtex->GetSurfaceLevel(0,&memsurface);
//Draw contents of hidden SWF window directly onto surface of in-memory texture
HDC hdcCompatible;
hr = memsurface->GetDC(&hdcCompatible);
//Sanity check
SetMapMode(hdcCompatible,MM_TEXT);
if(!hr)
{
//draw the frame
try
{
hr = OleDraw(RTviewobject,DVASPECT_CONTENT,hdcCompatible,&rc);
}
catch(HRESULT hr1)
{
hr = hr1;
}
memsurface->ReleaseDC(hdcCompatible);
}
if (memsurface)
delete memsurface;
//upload mem-texture to render target on GPU
memtex->AddDirtyRect(NULL);
m_pDevice->UpdateTexture(memtex,m_pOutTexture);
return hr;
}
//implement these if we want event feedback from Flash Scripting
//DShockwaveFlashEvents
HRESULT STDMETHODCALLTYPE SwfContainer::OnReadyStateChange(long newState)
{
return S_OK;
}
HRESULT STDMETHODCALLTYPE SwfContainer::OnProgress(long percentDone)
{
return S_OK;
}
HRESULT STDMETHODCALLTYPE SwfContainer::FSCommand(BSTR command, BSTR args)
{
return S_OK;
}
HRESULT STDMETHODCALLTYPE SwfContainer::FlashCall(BSTR request)
{
return S_OK;
}
//IDispatch Impl
HRESULT STDMETHODCALLTYPE SwfContainer::GetTypeInfoCount(UINT __RPC_FAR *pctinfo)
{
NOTIMPLEMENTED;
}
HRESULT STDMETHODCALLTYPE SwfContainer::GetTypeInfo(
/* [in] */ UINT iTInfo,
/* [in] */ LCID lcid,
/* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo)
{
NOTIMPLEMENTED;
}
HRESULT STDMETHODCALLTYPE SwfContainer::GetIDsOfNames(
/* [in] */ REFIID riid,
/* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
/* [in] */ UINT cNames,
/* [in] */ LCID lcid,
/* [size_is][out] */ DISPID __RPC_FAR *rgDispId)
{
NOTIMPLEMENTED;
}
HRESULT STDMETHODCALLTYPE SwfContainer::Invoke(
/* [in] */ DISPID dispIdMember,
/* [in] */ REFIID riid,
/* [in] */ LCID lcid,
/* [in] */ WORD wFlags,
/* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
/* [out] */ VARIANT __RPC_FAR *pVarResult,
/* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
/* [out] */ UINT __RPC_FAR *puArgErr)
{
return S_OK;
}
//IUnknown Impl
HRESULT STDMETHODCALLTYPE SwfContainer::QueryInterface(REFIID riid, void ** ppvObject)
{
if (IsEqualGUID(riid, DIID__IShockwaveFlashEvents))
*ppvObject = (void*)dynamic_cast<_IShockwaveFlashEvents *>(this);
else
{
*ppvObject = 0;
return E_NOINTERFACE;
}
if (!(*ppvObject))
return E_NOINTERFACE; //if dynamic_cast returned 0
m_iRef++;
return S_OK;
}
ULONG STDMETHODCALLTYPE SwfContainer::AddRef()
{
m_iRef++;
return m_iRef;
}
ULONG STDMETHODCALLTYPE SwfContainer::Release()
{
m_iRef--;
return m_iRef;
}
Users browsing this forum: No registered users and 1 guest