#include "StdAfx.h" #include "NPApplication.h" #include "FirefoxPlugin.h" #include "NPViewport.h" #include static WNDPROC lpOldProc = NULL; NPApplication::NPApplication(NPP pNPInstance, uint16 mode, int16 argc, char* argn[], char* argv[]) { m_pNPInstance = pNPInstance; m_bInitialized = FALSE; m_bFailed = FALSE; m_pNPInstance = pNPInstance; m_Window = NULL; m_pNPStream = NULL; m_hWnd = NULL; m_pCtrlWnd = NULL; m_PluginInterface = NULL; m_Viewport = NULL; memset(m_BaseUrl,0,1024); m_hStreamSystem = m_hGameInterface = NULL; m_Loading = TRUE; } NPApplication::~NPApplication(void) { Destroy(); } void NPApplication::Destroy() { AFX_MANAGE_STATE(AfxGetStaticModuleState()); //// kill the console //LockConsole(); //if( m_console ) { // SafeDelete(m_console); //} //UnlockConsole(); if (m_Viewport) { delete m_Viewport; m_Viewport = NULL; } m_pCtrlWnd->UnsubclassWindow(); ::SetWindowLong(m_hWnd, GWL_WNDPROC, (long) lpOldProc); m_hWnd = NULL; delete m_pCtrlWnd; m_pCtrlWnd = NULL; if (m_PluginInterface) { delete m_PluginInterface; m_PluginInterface = NULL; } //// stop the app //if (m_app) // m_app->Finish(); m_bInitialized = FALSE; if (m_hGameInterface) { CloseHandle(m_hGameInterface); m_hGameInterface = NULL; } if (m_hStreamSystem) { CloseHandle(m_hStreamSystem); m_hStreamSystem = NULL; } } NPBool NPApplication::Initialize(NPWindow* pNPWindow) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); if(pNPWindow == NULL) return FALSE; m_hWnd = (HWND)pNPWindow->window; if(m_hWnd == NULL) return FALSE; // subclass window so we can intercept window messages and // do our drawing to it lpOldProc = (WNDPROC)::SetWindowLong(m_hWnd, GWL_WNDPROC, (long)PluginWinProc); //lpOldProc = SubclassWindow(m_hWnd, (WNDPROC)PluginWinProc); // associate window with our nsPluginInstance object so we can access // it in the window procedure SetWindowLong(m_hWnd, GWL_USERDATA, (LONG)this); // 我们可以通过WIN32 来直接操作,但是这样不太方便, 目前实现中我们总是会在INET 处理中启用MFC 相关处理的. // 所以干脆就用MFC来简化了, // TODO 如果需要优化的话, 我们可以考虑用WIN32. m_pCtrlWnd = new CNPCtrlWnd; m_pCtrlWnd->SubclassWindow(m_hWnd); m_PluginInterface = new FirefoxPlugin(this); if (m_PluginInterface == NULL) { return FALSE; } // 获取安装目录 HKEY hWebClientKey = NULL; DWORD Type; DWORD Size; BOOL Success = FALSE; if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, "SOFTWARE\\SunyouGame\\WebClient", 0, KEY_READ, &hWebClientKey) == ERROR_SUCCESS) { // 安全起见, 先确保目录字符数. if (RegQueryValueEx(hWebClientKey, "InstallPath", NULL, &Type, NULL, &Size) == ERROR_SUCCESS && Size < MAX_PATH) { if (RegQueryValueEx(hWebClientKey, "InstallPath", NULL, &Type, (BYTE*)m_InstallPath, &Size) == ERROR_SUCCESS) { Success = TRUE; } } RegCloseKey(hWebClientKey); } if (!Success) { MessageBox(m_hWnd,"未正确安装Sunyou Web Client 插件.","Sunyou Web Client", MB_OK); return FALSE; } // 创建游戏逻辑接口 char ModulePath[MAX_PATH]; sprintf(ModulePath,"%s\\%s",m_InstallPath,"SceneApp.dll"); m_hGameInterface = LoadLibrary(ModulePath); if (m_hGameInterface == NULL) { return FALSE; } CreateGameInterfaceFunc CreateFunc = (CreateGameInterfaceFunc)GetProcAddress(m_hGameInterface,"CreateGameInterface"); if (CreateFunc == NULL) { return FALSE; } m_iGame = CreateFunc(AfxGetInstanceHandle()); //m_iGame = CreateGameInterface(AfxGetInstanceHandle()); if (!m_iGame) { return FALSE; } // 创建Stream SYSTEM sprintf(ModulePath,"%s\\%s",m_InstallPath,"LWStream.dll"); m_hStreamSystem = LoadLibrary(ModulePath); if (m_hStreamSystem == NULL) { return FALSE; } CreateSteamSystemFunc CreateStreamFunc = (CreateSteamSystemFunc)GetProcAddress(m_hStreamSystem,"CreateStreamSystem"); if (CreateStreamFunc == NULL) { return FALSE; } m_StreamSystem = CreateStreamFunc(); if (m_StreamSystem == NULL) { return FALSE; } /*m_StreamClient = new LWStreamClient(this); if (m_StreamClient == NULL) { return FALSE; }*/ //m_StreamSystem->SetClient(m_StreamClient); if (!m_StreamSystem->Intialise()) { return FALSE; } // 创建视口 RECT rect; m_pCtrlWnd->GetClientRect(&rect); m_Viewport = new NPViewport(this); ASSERT(m_Viewport); if (!m_Viewport->Create(NULL, "WViewport", WS_CHILD | WS_VISIBLE, rect, m_pCtrlWnd, 2)) { return FALSE; } // 初始化逻辑接口 if (!InitClientApp()) { return FALSE; } // m_app->Init(); // if (m_src) // m_app->SetURL(m_src->GetBuf()); // m_app->SceneInit(); // m_app->Start(); SetTimer(m_hWnd,0xE0F,40,NULL); m_bInitialized = TRUE; return TRUE; } BOOL NPApplication::InitClientApp() { // 务必确保客户端程序对象和视口有效. if (m_iGame == NULL || m_Viewport == NULL) { return FALSE; } ASSERT(m_PluginInterface); m_PluginInterface->ComputeBaseUrl(m_BaseUrl,1024); m_StreamSystem->SetBaseUrl(m_BaseUrl); m_iGame->InitializeForCtrl(m_Viewport->m_hWnd,m_StreamSystem); return TRUE; } void NPApplication::UpdateClientApp() { m_MainCS.Lock(); if (m_iGame) { m_Loading = m_iGame->IsLoadingScene(); if (m_Loading) { m_iGame->GetSceneLoadingSink()->OnRender(); }else { m_iGame->Update(); } } m_MainCS.Unlock(); if (m_StreamSystem) { m_StreamSystem->Stream(); } } void NPApplication::OnSize(INT Width, INT Height) { /*if( !pApp->Paused() && pApp->GetDevice() ) { CAnmWorld *pWorld = pApp->GetWorld(); assert(pWorld); if( pWorld ) { try { pWorld->Lock(); pApp->GetDevice()->HandleSize(width, height); pWorld->Unlock(); } catch (CAnmError &err) { pWorld->Unlock(); ::MessageBox( NULL, err.GetText(), "Flux - Fatal Error", MB_OK|MB_ICONEXCLAMATION ); } } */ if (m_Viewport) { m_Viewport->SetWindowPos(NULL, 0, 0, Width, Height, 0); } } void NPApplication::OnLBDown(INT X, INT Y) { } void NPApplication::OnLBUp(INT X, INT Y) { } void NPApplication::OnMBDown(INT X, INT Y) { } void NPApplication::OnMBUp(INT X, INT Y) { } void NPApplication::OnRBDown(INT X, INT Y) { } void NPApplication::OnRBUp(INT X, INT Y) { } void NPApplication::OnMouseMove(INT X, INT Y) { } void NPApplication::OnMouseWheel(INT ZDelta) { } void NPApplication::OnKey(WORD Key) { } void NPApplication::OnChar(WORD Char) { } void NPApplication::OnSetFocus() { } void NPApplication::OnTimer(UINT nIDEvent) { if (nIDEvent == 0xE0F) { UpdateClientApp(); } } LRESULT CALLBACK NPApplication::PluginWinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { NPApplication* App = (NPApplication*)GetWindowLong(hWnd, GWL_USERDATA); ASSERT(App); //if (plugin->AppCreateFailed()) //return DefWindowProc(hWnd, msg, wParam, lParam); //cAnimaApp *pApp = plugin->GetApp(); WORD xPos, yPos, width, height; bool doDefault = true; switch (msg) { //case WM_SETCURSOR: // break; case WM_PAINT: { //PAINTSTRUCT ps; //HDC hdc = BeginPaint(hWnd, &ps); //RECT rc; //GetClientRect(hWnd, &rc); ////FrameRect(hdc, &rc, GetStockBrush(BLACK_BRUSH)); //DrawText(hdc, "Sunyou Web client Firefox plugin", -1, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER); //EndPaint(hWnd, &ps); /*if (pApp && !pApp->Paused() && pApp->GetDevice()) { CAnmWorld *pWorld = pApp->GetWorld(); if (pWorld) { try { pWorld->Lock(); if (pApp->PausedForResize()) pApp->GetDevice()->Flip(); pWorld->Unlock(); } catch (CAnmError &err) { pWorld->Unlock(); ::MessageBox( NULL, err.GetText(), "Flux - Fatal Error", MB_OK|MB_ICONEXCLAMATION ); } } }*/ } break; case WM_SIZE: { width = LOWORD(lParam); height = HIWORD(lParam); App->OnSize(width, height); } break; case WM_LBUTTONDOWN: { SetFocus(hWnd); xPos = LOWORD(lParam); yPos = HIWORD(lParam); App->OnLBDown(xPos, yPos); doDefault = false; } break; case WM_LBUTTONUP: { xPos = LOWORD(lParam); yPos = HIWORD(lParam); App->OnLBUp(xPos, yPos); doDefault = false; } break; case WM_MBUTTONDOWN: { SetFocus(hWnd); xPos = LOWORD(lParam); yPos = HIWORD(lParam); App->OnMBDown(xPos, yPos); doDefault = false; } break; case WM_MBUTTONUP: { xPos = LOWORD(lParam); yPos = HIWORD(lParam); App->OnMBUp(xPos, yPos); doDefault = false; } break; case WM_RBUTTONDOWN : { SetFocus(hWnd); xPos = LOWORD(lParam); yPos = HIWORD(lParam); App->OnRBDown(xPos, yPos); doDefault = false; } break; case WM_RBUTTONUP: { xPos = LOWORD(lParam); yPos = HIWORD(lParam); App->OnRBUp(xPos, yPos); doDefault = false; } break; case WM_MOUSEMOVE: { xPos = LOWORD(lParam); yPos = HIWORD(lParam); App->OnMouseMove(xPos, yPos); } break; case WM_MOUSEWHEEL : { WORD zDelta = HIWORD(wParam); WORD nFlags = LOWORD(wParam); float zdelt = (float) zDelta / WHEEL_DELTA; bool shiftKey = false; if (nFlags & MK_SHIFT) shiftKey = true; bool ctrlKey = false; if (nFlags & MK_CONTROL) ctrlKey = true; //App->HandleWheel(zdelt, shiftKey, ctrlKey); App->OnMouseWheel(zdelt); } break; case WM_SETFOCUS : App->OnSetFocus(); break; case WM_KEYDOWN : App->OnKey(wParam); break; case WM_CHAR : App->OnChar(wParam); break; case WM_TIMER : App->OnTimer( wParam ); break; default: return DefWindowProc(hWnd, msg, wParam, lParam); break; } if (doDefault) return (*lpOldProc)(hWnd, msg, wParam, lParam); else return 0L; }