Created
October 26, 2012 02:04
-
-
Save t-mat/3956532 to your computer and use it in GitHub Desktop.
Windows: ActiveXを利用して、Flashをウィンドウ内に表示する
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// flash-to-directx : Library to embed Adobe Flash movies to DirectX-based applications. | |
// https://code.google.com/p/flash-to-directx/ | |
// | |
// swfui : Adobe Flash User Interface | |
// https://code.google.com/p/swfui/ | |
// | |
// C++ and Flash: Send or get data from/to a SWF using C++ and ActiveX in Win32 | |
// http://www.codeproject.com/Articles/269829/Communicate-with-Flash-Send-or-Get-data-from-to-a | |
// | |
#include <windows.h> | |
#include <windowsx.h> | |
#include <tchar.h> | |
#include <shlwapi.h> | |
#include <vector> | |
#import "PROGID:ShockwaveFlash.ShockwaveFlash" named_guids exclude("IServiceProvider") | |
#pragma comment(lib, "shlwapi.lib") | |
#define uuidof_ptr(p) __uuidof(decltype(*p)) | |
///////////////////////////////////////////////////////////////////////////// | |
template<typename OwnerClass> | |
class CFlashSink | |
: public ShockwaveFlashObjects::_IShockwaveFlashEvents | |
{ | |
public: | |
CFlashSink() | |
: dwCookie(0) | |
, pConnectionPoint(nullptr) | |
, refCnt(0) | |
, owner(nullptr) | |
{ | |
} | |
virtual ~CFlashSink() { | |
} | |
HRESULT init( | |
OwnerClass* ownerClass | |
, ShockwaveFlashObjects::IShockwaveFlash* flashInterface | |
) { | |
owner = ownerClass; | |
HRESULT hr = NOERROR; | |
IConnectionPointContainer* cpc = nullptr; | |
hr = flashInterface->QueryInterface(uuidof_ptr(cpc) | |
, (void**)&cpc); | |
if(SUCCEEDED(hr)) { | |
hr = cpc->FindConnectionPoint( | |
__uuidof(_IShockwaveFlashEvents), &pConnectionPoint | |
); | |
if(SUCCEEDED(hr)) { | |
IDispatch* d = nullptr; | |
hr = QueryInterface(__uuidof(IDispatch), (void**) &d); | |
if(SUCCEEDED(hr)) { | |
hr = pConnectionPoint->Advise((IUnknown*)d, &dwCookie); | |
} | |
if(d) { | |
d->Release(); | |
} | |
} | |
} | |
if(cpc) { | |
cpc->Release(); | |
} | |
AddRef(); | |
return hr; | |
} | |
HRESULT cleanup() { | |
HRESULT hr = S_OK; | |
Release(); | |
if(pConnectionPoint) { | |
if(dwCookie) { | |
hr = pConnectionPoint->Unadvise(dwCookie); | |
dwCookie = 0; | |
} | |
pConnectionPoint->Release(); | |
pConnectionPoint = NULL; | |
} | |
return hr; | |
} | |
protected: | |
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject) { | |
void* p = nullptr; | |
if(IsEqualGUID(riid, IID_IUnknown)) { | |
p = (void*) this; | |
} else if(IsEqualGUID(riid, IID_IDispatch)) { | |
p = (void*) dynamic_cast<IDispatch*>(this); | |
} else if(IsEqualGUID(riid, __uuidof(_IShockwaveFlashEvents))) { | |
p = (void*) dynamic_cast<_IShockwaveFlashEvents*>(this); | |
} | |
*ppvObject = p; | |
if(p) { | |
AddRef(); | |
return S_OK; | |
} else { | |
return E_NOINTERFACE; | |
} | |
} | |
ULONG STDMETHODCALLTYPE AddRef() { | |
return ++refCnt; | |
} | |
ULONG STDMETHODCALLTYPE Release() { | |
return --refCnt; | |
} | |
// IDispatch | |
HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT*) { | |
return E_NOTIMPL; | |
} | |
HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT, LCID, ITypeInfo**) { | |
return E_NOTIMPL; | |
} | |
HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID, LPOLESTR*, UINT, LCID, DISPID*) { | |
return E_NOTIMPL; | |
} | |
HRESULT STDMETHODCALLTYPE | |
Invoke(DISPID dispIdMember, REFIID, LCID, WORD, DISPPARAMS* pDispParams | |
, VARIANT*, EXCEPINFO*, UINT* | |
) { | |
switch(dispIdMember) { | |
case 0xc5: | |
if( pDispParams->cArgs != 1 | |
|| pDispParams->rgvarg[0].vt != VT_BSTR | |
) { | |
return E_INVALIDARG; | |
} | |
return owner->invoke_FlashCall(pDispParams->rgvarg[0].bstrVal); | |
case 0x96: | |
if( pDispParams->cArgs != 2 | |
|| pDispParams->rgvarg[0].vt != VT_BSTR | |
|| pDispParams->rgvarg[1].vt != VT_BSTR | |
) { | |
return E_INVALIDARG; | |
} | |
return owner->invoke_FSCommand(pDispParams->rgvarg[1].bstrVal | |
, pDispParams->rgvarg[0].bstrVal); | |
case 0x7a6: | |
return owner->invoke_OnProgress(pDispParams->rgvarg[0].intVal); | |
case DISPID_READYSTATECHANGE: | |
return E_NOTIMPL; | |
default: | |
return E_NOTIMPL; | |
} | |
} | |
IConnectionPoint* pConnectionPoint; | |
DWORD dwCookie; | |
ULONG refCnt; | |
OwnerClass* owner; | |
}; | |
///////////////////////////////////////////////////////////////////////////// | |
template<typename OwnerClass> | |
class CControlSite | |
: public IOleInPlaceSiteWindowless | |
, public IOleClientSite | |
{ | |
public: | |
CControlSite() | |
: owner(nullptr) | |
, refCnt(0) | |
{ | |
} | |
virtual ~CControlSite() { | |
} | |
void init(OwnerClass* ownerClass) { | |
owner = ownerClass; | |
AddRef(); | |
} | |
void cleanup() { | |
Release(); | |
} | |
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID* ppvObject) { | |
void* p = nullptr; | |
if(IsEqualGUID(riid, IID_IUnknown)) { | |
p = (void*) this; | |
} else if(IsEqualGUID(riid, IID_IOleWindow)) { | |
p = dynamic_cast<IOleWindow*>(this); | |
} else if(IsEqualGUID(riid, IID_IOleInPlaceSite)) { | |
p = dynamic_cast<IOleInPlaceSite*>(this); | |
} else if(IsEqualGUID(riid, IID_IOleInPlaceSiteEx)) { | |
p = dynamic_cast<IOleInPlaceSiteEx*>(this); | |
} else if(IsEqualGUID(riid, IID_IOleInPlaceSiteWindowless)) { | |
p = dynamic_cast<IOleInPlaceSiteWindowless*>(this); | |
} else if(IsEqualGUID(riid, IID_IOleClientSite)) { | |
p = dynamic_cast<IOleClientSite*>(this); | |
} | |
if(ppvObject) { | |
*ppvObject = p; | |
} | |
if(p) { | |
AddRef(); | |
return S_OK; | |
} else { | |
return E_NOINTERFACE; | |
} | |
} | |
protected: | |
ULONG STDMETHODCALLTYPE AddRef() { | |
return ++refCnt; | |
} | |
ULONG STDMETHODCALLTYPE Release() { | |
return --refCnt; | |
} | |
HRESULT STDMETHODCALLTYPE SaveObject() { | |
return E_NOTIMPL; | |
} | |
HRESULT STDMETHODCALLTYPE GetMoniker(DWORD, DWORD, IMoniker**) { | |
return E_NOTIMPL; | |
} | |
HRESULT STDMETHODCALLTYPE GetContainer(IOleContainer** ppContainer) { | |
*ppContainer = 0; | |
return E_NOINTERFACE; | |
} | |
HRESULT STDMETHODCALLTYPE ShowObject() { | |
return S_OK; | |
} | |
HRESULT STDMETHODCALLTYPE OnShowWindow(BOOL) { | |
return E_NOTIMPL; | |
} | |
HRESULT STDMETHODCALLTYPE RequestNewObjectLayout() { | |
return E_NOTIMPL; | |
} | |
HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL) { | |
return S_OK; | |
} | |
HRESULT STDMETHODCALLTYPE GetWindow(HWND* lpHwnd) { | |
HWND h = owner->getHwnd(); | |
*lpHwnd = h; | |
if(h) { | |
return S_OK; | |
} else { | |
return E_FAIL; | |
} | |
} | |
HRESULT STDMETHODCALLTYPE CanInPlaceActivate() { | |
return S_OK; | |
} | |
HRESULT STDMETHODCALLTYPE OnInPlaceActivate() { | |
return S_OK; | |
} | |
HRESULT STDMETHODCALLTYPE OnUIActivate() { | |
return S_OK; | |
} | |
HRESULT STDMETHODCALLTYPE GetWindowContext( | |
IOleInPlaceFrame** ppFrame | |
, IOleInPlaceUIWindow** ppDoc | |
, RECT* lprcPosRect | |
, RECT* lprcClipRect | |
, OLEINPLACEFRAMEINFO* lpFrameInfo | |
) { | |
RECT r = { 0, 0, owner->getWidth(), owner->getHeight() }; | |
*ppFrame = NULL; | |
QueryInterface(__uuidof(IOleInPlaceFrame), (void**) ppFrame); | |
*ppDoc = NULL; | |
lpFrameInfo->fMDIApp = FALSE; | |
lpFrameInfo->hwndFrame = NULL; | |
lpFrameInfo->haccel = NULL; | |
lpFrameInfo->cAccelEntries = 0; | |
*lprcPosRect = r; | |
*lprcClipRect = r; | |
return S_OK; | |
} | |
HRESULT STDMETHODCALLTYPE Scroll(SIZE) { | |
return E_NOTIMPL; | |
} | |
HRESULT STDMETHODCALLTYPE OnUIDeactivate(BOOL) { | |
return S_OK; | |
} | |
HRESULT STDMETHODCALLTYPE OnInPlaceDeactivate() { | |
return S_OK; | |
} | |
HRESULT STDMETHODCALLTYPE DiscardUndoState() { | |
return E_NOTIMPL; | |
} | |
HRESULT STDMETHODCALLTYPE DeactivateAndUndo() { | |
return E_NOTIMPL; | |
} | |
HRESULT STDMETHODCALLTYPE OnPosRectChange(LPCRECT) { | |
return S_OK; | |
} | |
HRESULT STDMETHODCALLTYPE OnInPlaceActivateEx(BOOL* pfNoRedraw, DWORD) { | |
*pfNoRedraw = FALSE; | |
return S_OK; | |
} | |
HRESULT STDMETHODCALLTYPE OnInPlaceDeactivateEx(BOOL) { | |
return S_FALSE; | |
} | |
HRESULT STDMETHODCALLTYPE RequestUIActivate() { | |
return S_FALSE; | |
} | |
HRESULT STDMETHODCALLTYPE CanWindowlessActivate() { | |
return S_OK; | |
} | |
HRESULT STDMETHODCALLTYPE GetCapture() { | |
return S_FALSE; | |
} | |
HRESULT STDMETHODCALLTYPE SetCapture(BOOL) { | |
return S_FALSE; | |
} | |
HRESULT STDMETHODCALLTYPE GetFocus() { | |
return S_OK; | |
} | |
HRESULT STDMETHODCALLTYPE SetFocus(BOOL) { | |
return S_OK; | |
} | |
HRESULT STDMETHODCALLTYPE GetDC(LPCRECT, DWORD, HDC*) { | |
return S_FALSE; | |
} | |
HRESULT STDMETHODCALLTYPE ReleaseDC(HDC) { | |
return S_FALSE; | |
} | |
HRESULT STDMETHODCALLTYPE InvalidateRect(LPCRECT pRect, BOOL fErase) { | |
owner->addDirtyRect(pRect, fErase); | |
return S_OK; | |
} | |
HRESULT STDMETHODCALLTYPE InvalidateRgn(HRGN, BOOL fErase) { | |
owner->addDirtyRect(NULL, fErase); | |
return S_OK; | |
} | |
HRESULT STDMETHODCALLTYPE ScrollRect(INT, INT, LPCRECT, LPCRECT) { | |
return E_NOTIMPL; | |
} | |
HRESULT STDMETHODCALLTYPE AdjustRect(LPRECT) { | |
return S_FALSE; | |
} | |
HRESULT STDMETHODCALLTYPE OnDefWindowMessage(UINT, WPARAM, LPARAM, LRESULT*) { | |
return S_FALSE; | |
} | |
OwnerClass* owner; | |
ULONG refCnt; | |
}; | |
///////////////////////////////////////////////////////////////////////////// | |
class CFlashDXPlayer { | |
public: | |
typedef CFlashDXPlayer ThisClass; | |
CFlashDXPlayer(unsigned int width, unsigned int height, HWND hWnd = nullptr) | |
: hWnd(nullptr) | |
, width(0) | |
, height(0) | |
, pShockwaveFlash(nullptr) | |
, pOleObject(nullptr) | |
, pOleInPlaceObjectWindowless(nullptr) | |
, dirtyFlag(false) | |
, backDc(nullptr) | |
, backBitmap(nullptr) | |
, backBits(nullptr) | |
, backBpp(0) | |
{ | |
this->hWnd = hWnd; | |
this->width = width; | |
this->height = height; | |
controlSite.init(this); | |
HRESULT hr; | |
hr = CoCreateInstance(ShockwaveFlashObjects::CLSID_ShockwaveFlash | |
, NULL, CLSCTX_INPROC_SERVER, IID_IOleObject | |
, (void**)&pOleObject); | |
if(FAILED(hr)) { | |
return; | |
} | |
IOleClientSite* pcs = nullptr; | |
hr = controlSite.QueryInterface(uuidof_ptr(pcs) | |
, (void**)&pcs); | |
if(FAILED(hr)) { | |
return; | |
} | |
hr = pOleObject->SetClientSite(pcs); | |
hr = pOleObject->QueryInterface(uuidof_ptr(pShockwaveFlash) | |
, (void**)&pShockwaveFlash); | |
if(pShockwaveFlash) { | |
pShockwaveFlash->DisableLocalSecurity(); | |
pShockwaveFlash->PutEmbedMovie(FALSE); | |
pShockwaveFlash->PutAllowScriptAccess(L"always"); | |
// "opaque", "transparent" | |
pShockwaveFlash->PutWMode(_bstr_t("opaque")); | |
// L"Low", L"Medium", L"High", L"Best", L"AutoLow", L"AutoHigh" | |
pShockwaveFlash->PutQuality2(_bstr_t(L"High")); | |
pShockwaveFlash->PutBackgroundColor(0x000000); | |
pShockwaveFlash->QueryInterface(uuidof_ptr(pViewObject) | |
, (void**)&pViewObject); | |
} | |
hr = pOleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, pcs, 0, NULL, NULL); | |
pcs->Release(); | |
hr = pOleObject->QueryInterface(uuidof_ptr(pOleInPlaceObjectWindowless) | |
, (void**)&pOleInPlaceObjectWindowless); | |
flashSink.init(this, pShockwaveFlash); | |
resizePlayer(width, height); | |
} | |
virtual ~CFlashDXPlayer() { | |
if(backDc) { | |
DeleteDC(backDc); | |
DeleteObject(backBitmap); | |
} | |
if(pOleInPlaceObjectWindowless) { | |
pOleInPlaceObjectWindowless->Release(); | |
} | |
if(pViewObject) { | |
pViewObject->Release(); | |
} | |
if(pShockwaveFlash) { | |
pShockwaveFlash->Release(); | |
} | |
flashSink.cleanup(); | |
if(pOleObject) { | |
pOleObject->Close(OLECLOSE_NOSAVE); | |
pOleObject->Release(); | |
} | |
controlSite.cleanup(); | |
} | |
HWND getHwnd() const { | |
return hWnd; | |
} | |
int getWidth() const { | |
return width; | |
} | |
int getHeight() const { | |
return height; | |
} | |
HDC getBackDc() const { | |
return backDc; | |
} | |
void addDirtyRect(const RECT* pRect, BOOL) { | |
if(pRect == nullptr || !IsRectEmpty(pRect)) { | |
dirtyFlag = true; | |
} | |
} | |
void resizePlayer(unsigned int newWidth, unsigned int newHeight) { | |
IOleInPlaceObject* pip = nullptr; | |
pOleObject->QueryInterface(uuidof_ptr(pip) | |
, (void**)&pip); | |
if(pip) { | |
RECT rect = { 0, 0, newWidth, newHeight }; | |
pip->SetObjectRects(&rect, &rect); | |
pip->Release(); | |
width = newWidth; | |
height = newHeight; | |
addDirtyRect(NULL, FALSE); | |
} | |
if(backDc) { | |
DeleteDC(backDc); | |
DeleteObject(backBitmap); | |
backDc = NULL; | |
backBitmap = NULL; | |
} | |
} | |
bool isDirty() const { | |
return dirtyFlag; | |
} | |
void DrawFrame(HDC dc = nullptr) { | |
if(dirtyFlag && pShockwaveFlash && pViewObject) { | |
dirtyFlag = false; | |
int w = getWidth(); | |
int h = getHeight(); | |
if(!backDc) { | |
backDc = CreateCompatibleDC(dc); | |
BITMAPINFOHEADER bih = { 0 }; | |
bih.biSize = sizeof(BITMAPINFOHEADER); | |
bih.biBitCount = 32; | |
bih.biCompression = BI_RGB; | |
bih.biPlanes = 1; | |
bih.biWidth = w; | |
bih.biHeight = -h; | |
backBitmap = CreateDIBSection( | |
dc, (BITMAPINFO*)&bih, DIB_RGB_COLORS | |
, (void **)&backBits, 0, 0); | |
SelectObject(backDc, backBitmap); | |
backBpp = GetDeviceCaps(backDc, BITSPIXEL); | |
} | |
RECTL r = { 0, 0, w, h }; | |
memset(backBits, 0, w * h * 4); | |
pViewObject->Draw(DVASPECT_TRANSPARENT, 1, 0, 0, 0, backDc, &r, &r, 0, 0); | |
} | |
} | |
std::wstring CallFunction(const wchar_t* request) { | |
BSTR response = nullptr; | |
pShockwaveFlash->raw_CallFunction(_bstr_t(request), &response); | |
if(response) { | |
return std::wstring(response); | |
} else { | |
return std::wstring(); | |
} | |
} | |
HRESULT invoke_FlashCall(const wchar_t* request) { | |
//@TODO implement | |
OutputDebugStringW(request); | |
return E_NOTIMPL; | |
} | |
HRESULT invoke_FSCommand(const wchar_t* command, const wchar_t* args) { | |
//@TODO implement | |
OutputDebugStringW(command); | |
OutputDebugStringW(args); | |
return E_NOTIMPL; | |
} | |
HRESULT invoke_OnProgress(long percentDone) { | |
//@TODO implement | |
percentDone; | |
return S_OK; | |
} | |
ShockwaveFlashObjects::IShockwaveFlash* getFlashInterface() const { | |
return pShockwaveFlash; | |
} | |
LRESULT DefaultMessageProc(UINT uMsg, WPARAM wParam, LPARAM lParam) { | |
switch(uMsg) { | |
default: | |
{ | |
LRESULT lr; | |
pOleInPlaceObjectWindowless->OnWindowMessage(uMsg, wParam, lParam, &lr); | |
return lr; | |
} | |
break; | |
case WM_SIZE: | |
resizePlayer(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); | |
return 0; | |
} | |
} | |
protected: | |
HWND hWnd; | |
unsigned int width; | |
unsigned int height; | |
ShockwaveFlashObjects::IShockwaveFlash* pShockwaveFlash; | |
IOleObject* pOleObject; | |
IOleInPlaceObjectWindowless* pOleInPlaceObjectWindowless; | |
IViewObject* pViewObject; | |
bool dirtyFlag; | |
HDC backDc; | |
HBITMAP backBitmap; | |
BYTE* backBits; | |
int backBpp; | |
CControlSite<ThisClass> controlSite; | |
CFlashSink<ThisClass> flashSink; | |
}; | |
///////////////////////////////////////////////////////////////////////////// | |
#define APPNAME _T("SwfPlayer") | |
static CFlashDXPlayer* g_flashPlayer = NULL; | |
static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { | |
switch(uMsg) { | |
case WM_DESTROY: | |
case WM_CLOSE: | |
PostQuitMessage(0); | |
return 0; | |
case WM_PAINT: | |
if(g_flashPlayer) { | |
PAINTSTRUCT ps; | |
HDC hdc = BeginPaint(hWnd, &ps); | |
if(g_flashPlayer) { | |
if(g_flashPlayer->isDirty()) { | |
g_flashPlayer->DrawFrame(); | |
BitBlt(hdc, 0, 0 | |
, g_flashPlayer->getWidth() | |
, g_flashPlayer->getHeight() | |
, g_flashPlayer->getBackDc() | |
, 0, 0, SRCCOPY); | |
} | |
} | |
EndPaint(hWnd, &ps); | |
return 0; | |
} | |
break; | |
case WM_SIZE: | |
case WM_MOUSEMOVE: | |
case WM_LBUTTONDOWN: | |
case WM_LBUTTONUP: | |
case WM_LBUTTONDBLCLK: | |
case WM_RBUTTONDOWN: | |
case WM_RBUTTONUP: | |
case WM_RBUTTONDBLCLK: | |
case WM_MBUTTONDOWN: | |
case WM_MBUTTONUP: | |
case WM_MBUTTONDBLCLK: | |
case WM_XBUTTONDOWN: | |
case WM_XBUTTONUP: | |
case WM_XBUTTONDBLCLK: | |
case WM_MOUSEWHEEL: | |
case WM_CANCELMODE: | |
case WM_CHAR: | |
case WM_DEADCHAR: | |
case WM_HELP: | |
case WM_IME_CHAR: | |
case WM_IME_COMPOSITION: | |
case WM_IME_COMPOSITIONFULL: | |
case WM_IME_CONTROL: | |
case WM_IME_ENDCOMPOSITION: | |
case WM_IME_KEYDOWN: | |
case WM_IME_KEYUP: | |
case WM_IME_NOTIFY: | |
case WM_IME_REQUEST: | |
case WM_IME_SELECT: | |
case WM_IME_SETCONTEXT: | |
case WM_IME_STARTCOMPOSITION: | |
case WM_KEYDOWN: | |
case WM_KEYUP: | |
case WM_SYSDEADCHAR: | |
case WM_SYSKEYDOWN: | |
case WM_SYSKEYUP: | |
if(g_flashPlayer) { | |
return g_flashPlayer->DefaultMessageProc(uMsg, wParam, lParam); | |
} | |
break; | |
case WM_SETCURSOR: | |
if(g_flashPlayer) { | |
static bool restoreCursor = true; | |
if(LOWORD(lParam) != HTCLIENT) { | |
restoreCursor = true; | |
} | |
if(restoreCursor) { | |
restoreCursor = false; | |
return DefWindowProc(hWnd, uMsg, wParam, lParam); | |
} | |
return 1; | |
} | |
break; | |
default: | |
break; | |
} | |
return DefWindowProc(hWnd, uMsg, wParam, lParam); | |
} | |
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int iCmdShow) { | |
CoInitialize(NULL); | |
int width = 700; | |
int height = 350; | |
const wchar_t* movie_path = L"test.swf"; | |
wchar_t movieFullpath[MAX_PATH]; | |
_wfullpath(movieFullpath, movie_path, MAX_PATH); | |
if(!PathFileExists(movieFullpath)) { | |
return MessageBox(0, movieFullpath, L"File not exist", MB_ICONEXCLAMATION); | |
} | |
WNDCLASS wc = { 0 }; | |
wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; | |
wc.lpfnWndProc = WndProc; | |
wc.hInstance = GetModuleHandle(0); | |
wc.hIcon = LoadIcon(0, IDI_APPLICATION); | |
wc.hCursor = LoadCursor(0, IDC_ARROW); | |
wc.hbrBackground = (HBRUSH) (COLOR_WINDOW+1); | |
wc.lpszClassName = APPNAME; | |
RegisterClass(&wc); | |
RECT rc = { 0, 0, width, height }; | |
DWORD ws = WS_OVERLAPPEDWINDOW; | |
DWORD es = 0; | |
BOOL bMenu = FALSE; | |
AdjustWindowRectEx(&rc, ws, bMenu, es); | |
int w = rc.right - rc.left; | |
int h = rc.bottom - rc.top; | |
HWND hWnd = CreateWindowEx(es, wc.lpszClassName, APPNAME, ws | |
, 0, 0, w, h, NULL, NULL, wc.hInstance, NULL); | |
ShowWindow(hWnd, iCmdShow); | |
UpdateWindow(hWnd); | |
g_flashPlayer = new CFlashDXPlayer(width, height, hWnd); | |
g_flashPlayer->getFlashInterface()->put_Movie(_bstr_t(movieFullpath)); | |
g_flashPlayer->getFlashInterface()->Play(); | |
MSG msg = { 0 }; | |
for(bool bLoop = true; bLoop; ) { | |
while(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { | |
if(WM_QUIT == msg.message) { | |
bLoop = false; | |
} else { | |
TranslateMessage(&msg); | |
DispatchMessage(&msg); | |
} | |
} | |
if(g_flashPlayer->isDirty()) { | |
InvalidateRect(hWnd, 0, 0); | |
} | |
} | |
g_flashPlayer->getFlashInterface()->StopPlay(); | |
CoUninitialize(); | |
return (int) msg.wParam; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment