📄 mozembed.cpp
字号:
// !!!Note: here it returns the latest GRE directory, which should be // fixed to return the GRE directory matching the currently running // Mozilla binary. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, greParentKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS) { while(RegEnumKeyEx(hKey, loop++, greVersionKey, &greVersionKeyLen, NULL, NULL, NULL, NULL) != ERROR_NO_MORE_ITEMS) { lastVersionKey = greVersionKey; greVersionKeyLen = 256; } RegCloseKey(hKey); } if (lastVersionKey == NULL) { return PR_FALSE; } char szKey[256], greHome[_MAX_PATH+1]; strcpy(szKey, greParentKey); strcat(szKey, lastVersionKey); cb = sizeof(greHome); if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKey, 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS) { return PR_FALSE; } if (RegQueryValueEx(hKey, "GreHome", NULL, NULL, (BYTE *)greHome, &cb) != ERROR_SUCCESS) { RegCloseKey(hKey); return PR_FALSE; } RegCloseKey(hKey); strncpy(pathBuf, greHome, pathBufSize); } // end of xpcom.dll doesn't exist. return PR_TRUE;}BOOL MozEmbedApp::InitMozilla(){ nsresult rv; TCHAR greDirPath[_MAX_PATH+1] = "\0"; TCHAR xpcomFilePath[_MAX_PATH+1] = "\0"; if (!GetGREPath(greDirPath, sizeof(greDirPath))) { ReportError("GetGREPath failed: can't locate the GRE path of the \ installed Mozilla binary!"); return FALSE; } strcpy(xpcomFilePath, greDirPath); strcat(xpcomFilePath, "\\xpcom.dll"); rv = XPCOMGlueStartup(xpcomFilePath); if (NS_FAILED(rv)) { ReportError("XPCOMGlueStartup failed!"); return FALSE; } nsCOMPtr<nsILocalFile> greDir; rv = NS_NewNativeLocalFile(nsEmbedCString(T2A(greDirPath)), TRUE, getter_AddRefs(greDir)); if (NS_FAILED(rv)) { ReportError("NS_NewNativeLocalFile failed!"); return FALSE; } rv = NS_InitXPCOM2(nsnull, greDir, nsnull); if (NS_FAILED(rv)) { ReportError("NS_InitXPCOM2 failed!"); return FALSE; } rv = OverrideComponents(); if (NS_FAILED(rv)) { ReportError("OverrideComponents failed!"); return FALSE; } rv = InitializeWindowCreator(); if (NS_FAILED(rv)) { ReportError("InitializeWindowCreator failed!"); return FALSE; } rv = InitializeProfile(); if (NS_FAILED(rv)) { ReportError("InitializeProfiles failed!"); return FALSE; } return TRUE;}// When the profile switch happens, all open browser windows need to be // closed. // In order for that not to kill off the app, we just make the MFC app's // mainframe be an invisible window which doesn't get closed on profile // switchesBOOL MozEmbedApp::CreateHiddenWindow(){ CFrameWnd *hiddenWnd = new CFrameWnd; if (!hiddenWnd) return FALSE; RECT bounds = { -10010, -10010, -10000, -10000 }; hiddenWnd->Create(NULL, _T("main"), WS_DISABLED, bounds, NULL, NULL, 0, NULL); m_pMainWnd = hiddenWnd; return TRUE;}#define NS_PROMPTSERVICE_CID \ {0xa2112d6a, 0x0e28, 0x421f, {0xb4, 0x6a, 0x25, 0xc0, 0xb3, 0x8, 0xcb, 0xd0}}NS_GENERIC_FACTORY_CONSTRUCTOR(CPromptService);/* Some Gecko interfaces are implemented as components, automatically registered at application initialization. nsIPrompt is an example: the default implementation uses XUL, not native windows. Embedding apps can override the default implementation by implementing the nsIPromptService interface and registering a factory for it with the same CID and Contract ID as the default's. Note that this example implements the service in a separate DLL, replacing the default if the override DLL is present. This could also have been done in the same module, without a separate DLL. See the PowerPlant example for, well, an example.*/nsresult MozEmbedApp::OverrideComponents(){ nsresult rv = NS_OK; static const nsModuleComponentInfo components[] = { { "Prompt Service", NS_PROMPTSERVICE_CID, "@mozilla.org/embedcomp/prompt-service;1", CPromptServiceConstructor } }; InitPromptService(m_hInstance); nsCOMPtr<nsIComponentRegistrar> cr; NS_GetComponentRegistrar(getter_AddRefs(cr)); if (!cr) return NS_ERROR_FAILURE; int numComponents = sizeof(components) / sizeof(components[0]); for (int i = 0; i < numComponents; ++i) { nsCOMPtr<nsIGenericFactory> componentFactory; rv = NS_NewGenericFactory(getter_AddRefs(componentFactory), &(components[i])); if (NS_FAILED(rv)) { NS_ASSERTION(PR_FALSE, "Unable to create factory for component"); continue; } rv = cr->RegisterFactory(components[i].mCID, components[i].mDescription, components[i].mContractID, componentFactory); NS_ASSERTION(NS_SUCCEEDED(rv), "Unable to register factory for component"); } return rv;}/* InitializeWindowCreator creates and hands off an object with a callback to a window creation function. This will be used by Gecko C++ code (never JS) to create new windows when no previous window is handy to begin with. This is done in a few exceptional cases, like PSM code. Failure to set this callback will only disable the ability to create new windows under these circumstances. */nsresult MozEmbedApp::InitializeWindowCreator(){ // give an nsIWindowCreator to the WindowWatcher service nsCOMPtr<nsIWindowCreator> windowCreator(NS_STATIC_CAST(nsIWindowCreator *, this)); if (windowCreator) { nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID)); if (wwatch) { wwatch->SetWindowCreator(windowCreator); return NS_OK; } } return NS_ERROR_FAILURE;}// ---------------------------------------------------------------------------// MozEmbedApp : nsISupports// ---------------------------------------------------------------------------NS_IMPL_THREADSAFE_ISUPPORTS2(MozEmbedApp, nsIWindowCreator, nsISupportsWeakReference);// ---------------------------------------------------------------------------// MozEmbedApp : nsIWindowCreator// ---------------------------------------------------------------------------//// Note: this method seems never being called. Instead // MozEmbedApp::CreateNewBrowserFrame // is always called to create a new browser frame window.//NS_IMETHODIMP MozEmbedApp::CreateChromeWindow(nsIWebBrowserChrome *parent, PRUint32 chromeFlags, nsIWebBrowserChrome **_retval){ NS_ENSURE_ARG_POINTER(_retval); *_retval = 0; HWND hParent = 0; if (parent) { CBrowserImpl *pImpl = NS_STATIC_CAST(CBrowserImpl *, parent); PRInt32 id = pImpl->m_pBrowserFrame->GetBrowserId(); hParent = pImpl->m_pBrowserFrame->GetSafeHwnd(); if (id >= 0) { // native browser needs a yes or no confirmation from the // Java side for event CEVENT_BEFORE_NEWWINDOW. int bCmdCanceled = -1, waitCount = 0; AddTrigger(id, CEVENT_BEFORE_NEWWINDOW, &bCmdCanceled); SendSocketMessage(id, CEVENT_BEFORE_NEWWINDOW); while (bCmdCanceled < 0 && waitCount++ < MAX_WAIT) { Sleep(1); } if (bCmdCanceled == 1) { return NS_ERROR_FAILURE; } } } CBrowserFrame *pBrowserFrame = CreateNewBrowserFrame(chromeFlags, hParent); if (pBrowserFrame) { *_retval = NS_STATIC_CAST(nsIWebBrowserChrome *, pBrowserFrame->GetBrowserImpl()); NS_ADDREF(*_retval); } return NS_OK;}void MozEmbedApp::MessageReceived(const char * msg){ int instance, type; char mMsgBuf[1024]; if (mInitFailed) return; int i = sscanf(msg, "%d,%d,%s", &instance, &type, mMsgBuf); ASSERT(i >= 2); // In case that the last message string argument contains spaces, sscanf // returns before the first space. Below line returns the complete message // string. char* mMsgString = (char*)strchr(msg, ','); mMsgString++; mMsgString = (char*)strchr(mMsgString, ','); mMsgString++; switch (type) { case JEVENT_INIT: if (!InitMozilla()) { mInitFailed = TRUE; NS_ShutdownXPCOM(nsnull); XPCOMGlueShutdown(); gQuitMode = TRUE; if (m_pMainWnd) m_pMainWnd->PostMessage(WM_QUIT); } break; case JEVENT_CREATEWINDOW: { // only create new browser window when the instance does not exist if (instance < m_FrameWndArray.GetSize() && m_FrameWndArray[instance] != NULL) break; if (i != 3) break; HWND hWnd = (HWND) atoi(mMsgString); CBrowserFrame *pBrowserFrame = CreateEmbeddedBrowserFrame(hWnd); if (pBrowserFrame) { m_FrameWndArray.SetAtGrow(instance, pBrowserFrame); pBrowserFrame->SetBrowserId(instance); SendSocketMessage(instance, CEVENT_INIT_WINDOW_SUCC); } } break; case JEVENT_DESTROYWINDOW: if( m_FrameWndArray[instance] != NULL){ ((CBrowserFrame *)m_FrameWndArray[instance])->DestroyBrowserFrame(); m_FrameWndArray.SetAt(instance, NULL); } SendSocketMessage(instance, CEVENT_DISTORYWINDOW_SUCC); break; case JEVENT_SHUTDOWN: gQuitMode = TRUE; m_pMainWnd->PostMessage(WM_QUIT); break; case JEVENT_SET_BOUNDS: { ASSERT(i == 3); int x, y, w, h; i = sscanf(mMsgString, "%d,%d,%d,%d", &x, &y, &w, &h); if (i == 4) ((CBrowserFrame *)m_FrameWndArray[instance])->SetWindowPos(NULL, x, y, w, h, SWP_NOMOVE | SWP_NOZORDER); } break; case JEVENT_NAVIGATE: ASSERT(i == 3); ((CBrowserFrame *)m_FrameWndArray[instance])->m_wndBrowserView.OpenURL(mMsgString); break; case JEVENT_NAVIGATE_POST: ASSERT(i == 3); mURL = mMsgString; break; case JEVENT_NAVIGATE_POSTDATA: ASSERT(i == 3); ((CBrowserFrame *)m_FrameWndArray[instance])->m_wndBrowserView.OpenURL(mURL, mMsgString, POST_HEADER); break; case JEVENT_GOBACK: ((CBrowserFrame *)m_FrameWndArray[instance])->m_wndBrowserView.PostMessage(WM_COMMAND, ID_NAV_BACK); break; case JEVENT_GOFORWARD: ((CBrowserFrame *)m_FrameWndArray[instance])->m_wndBrowserView.PostMessage(WM_COMMAND, ID_NAV_FORWARD); break; case JEVENT_REFRESH: ((CBrowserFrame *)m_FrameWndArray[instance])->m_wndBrowserView.PostMessage(WM_COMMAND, ID_NAV_RELOAD); break; case JEVENT_STOP: ((CBrowserFrame *)m_FrameWndArray[instance])->m_wndBrowserView.PostMessage(WM_COMMAND, ID_NAV_STOP); break; case JEVENT_GETURL: { nsCAutoString uriString; nsresult ret = ((CBrowserFrame *)m_FrameWndArray[instance])->m_wndBrowserView.GetURL(uriString); if (ret == NS_OK) SendSocketMessage(instance, CEVENT_RETURN_URL, uriString.get()); else SendSocketMessage(instance, CEVENT_RETURN_URL, ""); } break; case JEVENT_FOCUSGAINED: ((CBrowserFrame *)m_FrameWndArray[instance])->m_wndBrowserView.Activate(WA_ACTIVE, 0, 0); break; case JEVENT_FOCUSLOST: //((CBrowserFrame *)m_FrameWndArray[instance])->m_wndBrowserView.Activate(WA_INACTIVE, 0, 0); break; case JEVENT_GETCONTENT: { nsIWebNavigation* mWebNav = ((CBrowserFrame *)m_FrameWndArray[instance])->m_wndBrowserView.mWebNav; char *retStr = GetContent(mWebNav); if (retStr == NULL) SendSocketMessage(instance, CEVENT_GETCONTENT, ""); else SendSocketMessage(instance, CEVENT_GETCONTENT, retStr); } break; case JEVENT_SETCONTENT: { ASSERT(i == 3); nsIWebNavigation* mWebNav = ((CBrowserFrame *)m_FrameWndArray[instance])->m_wndBrowserView.mWebNav; SetContent(mWebNav, mMsgString); } break; case JEVENT_EXECUTESCRIPT: { ASSERT(i == 3); nsIWebNavigation* mWebNav = ((CBrowserFrame *)m_FrameWndArray[instance])->m_wndBrowserView.mWebNav; char *retStr = ExecuteScript(mWebNav, mMsgString); if (retStr == NULL) SendSocketMessage(instance, CEVENT_EXECUTESCRIPT, ""); else SendSocketMessage(instance, CEVENT_EXECUTESCRIPT, retStr); } break; }}void SocketMsgHandler(const char *pMsg){ char *msg = new char[strlen(pMsg) + 1]; strcpy(msg, pMsg); ::PostMessage(AfxGetApp()->GetMainWnd()->GetSafeHwnd(), WM_SOCKET_MSG, 0, (long)msg);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -