mirror of https://github.com/roytam1/kmeleon.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1944 lines
60 KiB
1944 lines
60 KiB
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
|
/* ***** BEGIN LICENSE BLOCK ***** |
|
* Version: Mozilla-sample-code 1.0 |
|
* |
|
* Copyright (c) 2002 Netscape Communications Corporation and |
|
* other contributors |
|
* |
|
* Permission is hereby granted, free of charge, to any person obtaining a |
|
* copy of this Mozilla sample software and associated documentation files |
|
* (the "Software"), to deal in the Software without restriction, including |
|
* without limitation the rights to use, copy, modify, merge, publish, |
|
* distribute, sublicense, and/or sell copies of the Software, and to permit |
|
* persons to whom the Software is furnished to do so, subject to the |
|
* following conditions: |
|
* |
|
* The above copyright notice and this permission notice shall be included |
|
* in all copies or substantial portions of the Software. |
|
* |
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
|
* DEALINGS IN THE SOFTWARE. |
|
* |
|
* Contributor(s): |
|
* Chak Nanga <chak@netscape.com> |
|
* Conrad Carlen <ccarlen@netscape.com> |
|
* |
|
* ***** END LICENSE BLOCK ***** */ |
|
|
|
// File Overview.... |
|
// |
|
// The typical MFC app, frame creation code |
|
// |
|
// NS_InitEmbedding() is called in InitInstance() |
|
// |
|
// NS_TermEmbedding() is called in ExitInstance() |
|
// ExitInstance() also takes care of cleaning up of |
|
// multiple browser frame windows on app exit |
|
// |
|
// NS_DoIdleEmbeddingStuff(); is called in the overridden |
|
// OnIdle() method |
|
// |
|
// Code to handle the creation of a new browser window |
|
|
|
// Next suggested file to look at : BrowserFrm.cpp |
|
|
|
// Local Includes |
|
#include "stdafx.h" |
|
#include "nsXPCOM.h" |
|
#include "nsXPCOMGlue.h" |
|
#include "MfcEmbed.h" |
|
#include "HiddenWnd.h" |
|
#include "BrowserFrm.h" |
|
#include "BrowserFrmTab.h" |
|
#include "KmFileLocProvider.h" |
|
#include "ProfileMgr.h" |
|
#include "ProfilesDlg.h" |
|
#include "BrowserImpl.h" |
|
#include "kmeleonConst.h" |
|
#include "UnknownContentTypeHandler.h" |
|
#include "MenuParser.h" |
|
#include "kmeleon_plugin.h" |
|
#include <io.h> |
|
#include <fcntl.h> |
|
|
|
#include "nsXULAppAPI.h" |
|
#include "nsXPCOMGlue.h" |
|
#include "nsIIOService.h" |
|
#include "nsIWindowWatcher.h" |
|
#include "nsIChromeRegistry.h" |
|
#include "nsIAppStartup.h" |
|
#include "nsToolkitCompsCID.h" |
|
#include "nsIObserverService.h" |
|
#include "nsICommandLineRunner.h" |
|
#include "nsDirectoryServiceDefs.h" |
|
#include "nsDirectoryServiceUtils.h" |
|
#include <locale.h> |
|
|
|
static UINT WM_POSTEVENT = RegisterWindowMessage(_T("XPCOM_PostEvent")); |
|
static UINT WM_FLASHRELAY = RegisterWindowMessage(_T("MozFlashUserRelay")); |
|
static UINT WM_NSEVENTID = RegisterWindowMessage(_T("nsAppShell:EventID")); |
|
|
|
XRE_InitEmbedding2Type XRE_InitEmbedding2 = 0; |
|
XRE_TermEmbeddingType XRE_TermEmbedding = 0; |
|
XRE_NotifyProfileType XRE_NotifyProfile = 0; |
|
XRE_LockProfileDirectoryType XRE_LockProfileDirectory = 0; |
|
XRE_AddManifestLocationType XRE_AddManifestLocation = 0; |
|
XRE_GetProcessTypeType XRE_GetProcessType = 0; |
|
XRE_AddStaticComponentType XRE_AddStaticComponent = 0; |
|
|
|
#ifdef MOZ_PROFILESHARING |
|
#include "nsIProfileSharingSetup.h" |
|
#endif |
|
|
|
#ifdef _BUILD_STATIC_BIN |
|
#include "nsStaticComponents.h" |
|
nsresult PR_CALLBACK |
|
app_getModuleInfo(nsStaticModuleInfo **info, PRUint32 *count); |
|
#endif |
|
|
|
|
|
#ifdef NS_TRACE_MALLOC |
|
#include "nsTraceMalloc.h" |
|
#endif |
|
|
|
#ifdef _DEBUG |
|
/*#include "StackWalker.h" |
|
|
|
static struct _test |
|
{ |
|
_test() { InitAllocCheck(); } |
|
~_test(){ DeInitAllocCheck(); } |
|
|
|
} _myLeakFinder;*/ |
|
#define new DEBUG_NEW |
|
#undef THIS_FILE |
|
static char THIS_FILE[] = __FILE__; |
|
#endif |
|
|
|
#define LANG_CONFIG_FILE _T("language.cfg") |
|
#define MENU_CONFIG_FILE _T("menus.cfg") |
|
#define ACCEL_CONFIG_FILE _T("accel.cfg") |
|
|
|
extern CString GetMozDirectory(char* dirName); |
|
|
|
BEGIN_MESSAGE_MAP(CMfcEmbedApp, CWinApp) |
|
//{{AFX_MSG_MAP(CMfcEmbedApp) |
|
ON_COMMAND(ID_APP_ABOUT, OnAppAbout) |
|
ON_COMMAND(ID_NEW_BROWSER, OnNewBrowser) |
|
ON_COMMAND(ID_MANAGE_PROFILES, OnManageProfiles) |
|
ON_COMMAND(ID_PREFERENCES, OnPreferences) |
|
ON_COMMAND(ID_OFFLINE, OnToggleOffline) |
|
ON_COMMAND(ID_TOGGLE_JS, OnToggleJS) |
|
ON_COMMAND(ID_APP_RESTART, OnAppRestart) |
|
ON_UPDATE_COMMAND_UI(ID_APP_RESTART, OnUpdateAppRestart) |
|
ON_UPDATE_COMMAND_UI(ID_TOGGLE_JS, OnUpdateToggleJS) |
|
ON_UPDATE_COMMAND_UI(ID_OFFLINE, OnUpdateToggleOffline) |
|
ON_UPDATE_COMMAND_UI_RANGE(WINDOW_MENU_START_ID, WINDOW_MENU_STOP_ID, OnUpdateWindows) |
|
ON_COMMAND_RANGE(WINDOW_MENU_START_ID, WINDOW_MENU_STOP_ID, OnWindowSelect) |
|
// NOTE - the ClassWizard will add and remove mapping macros here. |
|
// DO NOT EDIT what you see in these blocks of generated code! |
|
//}}AFX_MSG_MAP |
|
END_MESSAGE_MAP() |
|
|
|
#include <Iads.h> |
|
#include <activeds.h> |
|
#include <comdef.h> |
|
#include <initguid.h> |
|
#include <accctrl.h> |
|
|
|
|
|
BOOL RestartAsRestricted() |
|
{ |
|
HANDLE hProcessToken = NULL; |
|
HANDLE hRestrictedToken = NULL; |
|
PTOKEN_USER pstructUserToken = NULL; |
|
|
|
if(!OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_READ, &hProcessToken)) |
|
return FALSE; |
|
|
|
DWORD dwLen = 0; |
|
DWORD dwInertFlag; |
|
if (!GetTokenInformation(hProcessToken, TokenSandBoxInert, &dwInertFlag, sizeof(dwInertFlag), &dwLen) || dwInertFlag!=0){ |
|
CloseHandle(hProcessToken); |
|
return FALSE; |
|
} |
|
|
|
// XXX : Bad check using privilege count to be compatible with sandboxie |
|
BYTE buf[1024]; |
|
if (!GetTokenInformation(hProcessToken, TokenPrivileges, &buf, 1024, &dwLen)) |
|
{ |
|
CloseHandle(hProcessToken); |
|
return FALSE; |
|
} |
|
TOKEN_PRIVILEGES *tp = (TOKEN_PRIVILEGES*)buf; |
|
if (tp->PrivilegeCount < 2) return FALSE; |
|
|
|
if(!CreateRestrictedToken(hProcessToken, DISABLE_MAX_PRIVILEGE | SANDBOX_INERT, 0, &pstructUserToken->User, 0, NULL, 0, NULL, &hRestrictedToken ) ){ |
|
CloseHandle(hProcessToken); |
|
return FALSE; |
|
} |
|
|
|
PROCESS_INFORMATION pi = {0}; |
|
STARTUPINFO si = {0}; |
|
si.cb = sizeof(STARTUPINFO); |
|
si.dwFlags = STARTF_USESHOWWINDOW; |
|
si.wShowWindow = SW_NORMAL; |
|
|
|
HANDLE hMutexOneInstance = CreateMutex( NULL, TRUE, _T("K-Meleon Instance Mutex") ); |
|
ReleaseMutex(hMutexOneInstance); |
|
|
|
BOOL res = CreateProcessAsUser(hRestrictedToken, NULL, ::GetCommandLine(), NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi); |
|
|
|
HeapFree(GetProcessHeap(), 0, (LPVOID)pstructUserToken); |
|
pstructUserToken = NULL; |
|
CloseHandle(hRestrictedToken); |
|
CloseHandle(hProcessToken); |
|
if (!res) return FALSE; |
|
|
|
CloseHandle(pi.hProcess); |
|
CloseHandle(pi.hThread); |
|
return TRUE; |
|
} |
|
|
|
CMfcEmbedApp::CMfcEmbedApp() |
|
{ |
|
mRefCnt = 1; // Start at one - nothing is going to addref this object |
|
|
|
m_ProfileMgr = NULL; |
|
m_bSwitchingProfiles = FALSE; |
|
|
|
m_bFirstWindowCreated = FALSE; |
|
m_pMostRecentBrowserFrame = NULL; |
|
m_hResDll = NULL; |
|
m_MRUList = NULL; |
|
m_bRestart = FALSE; |
|
} |
|
|
|
CMfcEmbedApp theApp; |
|
|
|
static NS_IMETHODIMP |
|
RefreshPlugins(PRBool aReloadPages) |
|
{ |
|
return NS_OK; |
|
} |
|
|
|
nsresult CMfcEmbedApp::SetOffline(BOOL offline) |
|
{ |
|
nsresult result; |
|
nsCOMPtr<nsIIOService> io = do_GetService(NS_IOSERVICE_CONTRACTID, &result); |
|
if (NS_SUCCEEDED(result)) { |
|
result = io->SetOffline(offline); |
|
if (NS_SUCCEEDED(result)) |
|
theApp.preferences.bOffline = offline; |
|
} |
|
|
|
return result; |
|
} |
|
|
|
void CMfcEmbedApp::ShowDebugConsole() |
|
{ |
|
|
|
// Show console only in debug mode |
|
|
|
if(! AllocConsole()) |
|
return; |
|
|
|
// Redirect stdout to the console |
|
int hCrtOut = _open_osfhandle( |
|
(long) GetStdHandle(STD_OUTPUT_HANDLE), |
|
_O_TEXT); |
|
if(hCrtOut == -1) |
|
return; |
|
|
|
FILE *hfOut = _fdopen(hCrtOut, "w"); |
|
if(hfOut != NULL) |
|
{ |
|
// Setup for unbuffered I/O so the console |
|
// output shows up right away |
|
*stdout = *hfOut; |
|
setvbuf(stdout, NULL, _IONBF, 0); |
|
} |
|
|
|
// Redirect stderr to the console |
|
int hCrtErr = _open_osfhandle( |
|
(long) GetStdHandle(STD_ERROR_HANDLE), |
|
_O_TEXT); |
|
if(hCrtErr == -1) |
|
return; |
|
|
|
FILE *hfErr = _fdopen(hCrtErr, "w"); |
|
if(hfErr != NULL) |
|
{ |
|
// Setup for unbuffered I/O so the console |
|
// output shows up right away |
|
*stderr = *hfErr; |
|
setvbuf(stderr, NULL, _IONBF, 0); |
|
} |
|
} |
|
|
|
#define FIREFOX_CHROME |
|
|
|
#ifdef FIREFOX_CHROME |
|
BOOL CMfcEmbedApp::LoadLanguage() |
|
{ |
|
CString locale = preferences.GetLocaleString("general.useragent.locale", _T("")); |
|
if (locale.IsEmpty()) |
|
return FALSE; |
|
|
|
if (_tcsncmp(locale, _T("en"), 2) == 0) { |
|
if (m_hResDll) { |
|
FreeLibrary(m_hResDll); |
|
m_hResDll = NULL; |
|
} |
|
|
|
lang.Reset(); |
|
AfxSetResourceHandle(m_hInstance); |
|
#if _MSC_VER >= 1300 |
|
_AtlBaseModule.SetResourceInstance(m_hInstance); |
|
#endif |
|
return TRUE; |
|
} |
|
|
|
CString localeFolder = GetFolder(LocaleFolder) + _T("\\") + locale + _T("\\"); |
|
CString resDll = localeFolder + CString("kmeleon.dll"); |
|
|
|
HINSTANCE hInstResDll = ::LoadLibrary(resDll); |
|
if (!hInstResDll) return FALSE; |
|
|
|
// Check dll version |
|
CString version, versiondll; |
|
version.LoadString(IDS_LANG_VERSION); |
|
#if _MSC_VER >= 1300 |
|
versiondll.LoadString(hInstResDll, IDS_LANG_VERSION); |
|
#else |
|
LoadString(hInstResDll, IDS_LANG_VERSION, versiondll.GetBuffer(10), 10); |
|
versiondll.ReleaseBuffer(); |
|
#endif |
|
if (version.Compare(versiondll) != 0) { |
|
::FreeLibrary(hInstResDll); |
|
return FALSE; |
|
} |
|
|
|
CFile file; |
|
if (!file.Open(localeFolder + CString("kmeleon.kml"), CFile::modeRead, NULL)) { |
|
::FreeLibrary(hInstResDll); |
|
return FALSE; |
|
} |
|
file.Close(); |
|
|
|
CFileFind finder; |
|
CString langFile, pattern = localeFolder + CString("*.kml"); |
|
BOOL bWorking = finder.FindFile(pattern); |
|
while (bWorking) { |
|
bWorking = finder.FindNextFile(); |
|
langFile = finder.GetFilePath(); |
|
lang.Load(langFile); |
|
} |
|
|
|
AfxSetResourceHandle(hInstResDll); |
|
#if _MSC_VER >= 1300 |
|
_AtlBaseModule.SetResourceInstance(hInstResDll); |
|
#endif |
|
|
|
if (m_hResDll && m_hResDll!=hInstResDll) |
|
FreeLibrary(m_hResDll); |
|
m_hResDll = hInstResDll; |
|
|
|
return TRUE; |
|
} |
|
|
|
#else |
|
|
|
BOOL CMfcEmbedApp::LoadLanguage() |
|
{ |
|
TCHAR resDll[MAX_PATH], *extension; |
|
|
|
// Look for dll resources |
|
::GetModuleFileName(m_hInstance, resDll, MAX_PATH); |
|
extension = _tcsrchr(resDll, _T('.'));//::PathFindExtension(resDll); |
|
|
|
if ((extension + 7) - resDll > MAX_PATH) |
|
return FALSE; |
|
|
|
lstrcpy(extension, _T("loc.dll")); |
|
HINSTANCE hInstResDll = ::LoadLibrary(resDll); |
|
if (!hInstResDll) return FALSE; |
|
|
|
// Check dll version |
|
CString version, versiondll; |
|
version.LoadString(IDS_LANG_VERSION); |
|
#if _MSC_VER >= 1300 |
|
versiondll.LoadString(hInstResDll, IDS_LANG_VERSION); |
|
#else |
|
LoadString(hInstResDll, IDS_LANG_VERSION, versiondll.GetBuffer(10), 10); |
|
versiondll.ReleaseBuffer(); |
|
#endif |
|
if (version.Compare(versiondll) != 0) { |
|
::FreeLibrary(hInstResDll); |
|
return FALSE; |
|
} |
|
|
|
// Look for language file |
|
TCHAR* langFile = resDll; |
|
TCHAR* lastSlash = _tcsrchr(resDll, _T('\\')); |
|
if (!lastSlash) { |
|
::FreeLibrary(hInstResDll); |
|
ASSERT(FALSE); |
|
return FALSE; |
|
} |
|
lastSlash++; |
|
|
|
TCHAR locale[10]; |
|
::LoadString(hInstResDll, IDS_LOCALE_ID, locale, 10); |
|
|
|
lstrcpy(lastSlash, _T("kmeleon.")); |
|
lstrcat(lastSlash, locale); |
|
lstrcat(lastSlash, _T(".kml")); |
|
|
|
if (!lang.Load(langFile)) { |
|
lstrcpy(lastSlash, LANG_CONFIG_FILE); |
|
if (!lang.Load(langFile)) { |
|
::FreeLibrary(hInstResDll); |
|
return FALSE; |
|
} |
|
} |
|
|
|
AfxSetResourceHandle(hInstResDll); |
|
#if _MSC_VER >= 1300 |
|
_AtlBaseModule.SetResourceInstance(hInstResDll); |
|
#endif |
|
return TRUE; |
|
} |
|
#endif |
|
|
|
// Initialize our MFC application and also init |
|
// the Gecko embedding APIs |
|
// Note that we're also init'ng the profile switching |
|
// code here |
|
// Then, create a new BrowserFrame and load our |
|
// default homepage |
|
// |
|
|
|
|
|
|
|
BOOL CMfcEmbedApp::CheckInstance() |
|
{ |
|
HANDLE hMutexOneInstance = CreateMutex( NULL, FALSE, _T("K-Meleon Instance Mutex") ); |
|
DWORD dwWaitResult = WaitForSingleObject( hMutexOneInstance, 0); |
|
if (dwWaitResult == WAIT_OBJECT_0) |
|
return TRUE; |
|
|
|
// if another instance is already running, pass it our command line paramaters, |
|
// and ask it to open a new window |
|
// eventually, we should handle this through DDE |
|
|
|
// find the hidden window |
|
if (HWND hwndPrev = ::FindWindowEx(NULL, NULL, HIDDEN_WINDOW_CLASS, NULL) ) { |
|
|
|
if(*m_lpCmdLine) { |
|
COPYDATASTRUCT copyData; |
|
copyData.dwData = 0; |
|
copyData.cbData = (strlen(cmdline.m_sCmdLine)+1)*sizeof(char); |
|
copyData.lpData = (void *) cmdline.m_sCmdLine; |
|
SendMessage(hwndPrev, WM_COPYDATA, NULL, (LPARAM) ©Data); |
|
} |
|
else |
|
SendMessage(hwndPrev, UWM_NEWWINDOW, NULL, NULL); |
|
} |
|
return FALSE; |
|
} |
|
|
|
#define PROCESS_DEP_ENABLE 0x00000001 |
|
#define PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION 0x00000002 |
|
|
|
extern mozilla::Module kBrowserModule; |
|
extern mozilla::Module kBrowserModuleApp; |
|
|
|
BOOL CMfcEmbedApp::InitEmbedding(const char* profile) |
|
{ |
|
CString xul = GetFolder(RootFolder)+_T("\\xul.dll"); |
|
int len = WideCharToMultiByte(CP_UTF8, 0, xul, -1, NULL, 0, NULL, NULL); |
|
char* gnah = new char[len+1]; |
|
WideCharToMultiByte(CP_UTF8, 0, xul, -1, gnah, len, NULL, NULL); |
|
if (NS_FAILED(XPCOMGlueStartup(gnah))) { |
|
AfxMessageBox(IDS_START_FAILED, MB_OK | MB_ICONERROR); |
|
return FALSE; |
|
} |
|
delete [] gnah; |
|
|
|
NS_LogInit(); |
|
|
|
// load XUL functions |
|
nsDynamicFunctionLoad nsFuncs[] = { |
|
{"XRE_InitEmbedding2", (NSFuncPtr*)&XRE_InitEmbedding2}, |
|
{"XRE_TermEmbedding", (NSFuncPtr*)&XRE_TermEmbedding}, |
|
{"XRE_NotifyProfile", (NSFuncPtr*)&XRE_NotifyProfile}, |
|
{"XRE_LockProfileDirectory", (NSFuncPtr*)&XRE_LockProfileDirectory}, |
|
{"XRE_AddManifestLocation", (NSFuncPtr*)&XRE_AddManifestLocation}, |
|
{"XRE_GetProcessType", (NSFuncPtr*)&XRE_GetProcessType}, |
|
{"XRE_AddStaticComponent", (NSFuncPtr*)&XRE_AddStaticComponent}, |
|
{0, 0} |
|
}; |
|
|
|
nsresult rv = XPCOMGlueLoadXULFunctions(nsFuncs); |
|
NS_ENSURE_SUCCESS(rv, FALSE); |
|
|
|
// Set provider |
|
CString strRes; |
|
strRes.LoadString(IDS_PROFILES_FOLDER_NAME); |
|
KmFileLocProvider *provider = new KmFileLocProvider(nsDependentString(T2W(strRes.GetBuffer(0)))); |
|
if(!provider) return FALSE; |
|
|
|
// Set app directory |
|
nsCOMPtr<nsIFile> mreAppDir; |
|
rv = NS_NewLocalFile(nsDependentString(theApp.GetFolder(RootFolder)), TRUE, getter_AddRefs(mreAppDir)); |
|
NS_ASSERTION(NS_SUCCEEDED(rv), "failed to create mreAppDir file"); |
|
|
|
nsCOMPtr<nsIFile> appSubdir; |
|
rv = NS_NewLocalFile(nsDependentString(theApp.GetFolder(AppFolder)), TRUE, getter_AddRefs(appSubdir)); |
|
NS_ASSERTION(NS_SUCCEEDED(rv), "failed to create appSubdir file"); |
|
|
|
// Set Profile |
|
m_ProfileMgr = new CProfileMgr; |
|
if (!m_ProfileMgr) return FALSE; |
|
|
|
BOOL result; |
|
USES_CONVERSION; |
|
result = m_ProfileMgr->StartUp(provider, profile ? A2CT(profile) : nullptr); |
|
if (profile) delete [] profile; |
|
|
|
ASSERT(result); |
|
if (!result) return FALSE; |
|
|
|
// Init XRE |
|
rv = XRE_AddStaticComponent(&kBrowserModuleApp); |
|
NS_ENSURE_SUCCESS(rv, FALSE); |
|
|
|
rv = XRE_InitEmbedding2(mreAppDir, appSubdir, provider); |
|
NS_ENSURE_SUCCESS(rv, FALSE); |
|
|
|
rv = XRE_AddStaticComponent(&kBrowserModule); |
|
NS_ENSURE_SUCCESS(rv, FALSE); |
|
|
|
rv = InitializeWindowCreator(); |
|
if (NS_FAILED(rv)) |
|
{ |
|
ASSERT(FALSE); |
|
XRE_TermEmbedding(); |
|
return FALSE; |
|
} |
|
|
|
// Register chrome language |
|
CString localesFolder = GetFolder(LocaleFolder) + _T("\\*"); |
|
WIN32_FIND_DATA ffd; |
|
HANDLE hFind = FindFirstFile(localesFolder.GetBuffer(0), &ffd); |
|
localesFolder.Truncate(localesFolder.GetLength()-1); |
|
if (hFind != INVALID_HANDLE_VALUE) { |
|
do { |
|
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY && |
|
ffd.cFileName[0]!='.') { |
|
nsCOMPtr<nsIFile> mFile; |
|
NS_NewLocalFile(CStringToNSString(localesFolder + ffd.cFileName + _T("\\") + ffd.cFileName + _T(".manifest")), false, getter_AddRefs(mFile)); |
|
XRE_AddManifestLocation(NS_COMPONENT_LOCATION, mFile); |
|
} |
|
} while ( FindNextFile(hFind, &ffd) ); |
|
FindClose(hFind); |
|
} |
|
|
|
XRE_NotifyProfile(); |
|
|
|
nsCOMPtr<nsIAppStartup> appStartup(do_GetService(NS_APPSTARTUP_CONTRACTID)); |
|
if (appStartup) { |
|
appStartup->CreateHiddenWindow(); |
|
} |
|
|
|
NS_LogTerm(); |
|
|
|
nsCOMPtr<nsICommandLineRunner> cmdLine = do_CreateInstance("@mozilla.org/toolkit/command-line;1"); |
|
if (cmdLine) { |
|
nsCOMPtr<nsIFile> workingDir; |
|
NS_GetSpecialDirectory(NS_OS_CURRENT_WORKING_DIR, getter_AddRefs(workingDir)); |
|
int argc; |
|
LPWSTR* argv16 = CommandLineToArgvW(GetCommandLineW(), &argc); |
|
int l = 0; |
|
for (int i = 0; i < argc; i++) { |
|
l += wcslen(argv16[i]) + 1; |
|
} |
|
char *_argv = new char[l * 3]; |
|
char** argv = new char*[argc]; |
|
for (int i = 0; i < argc; i++) { |
|
argv[i] = _argv; |
|
int x = WideCharToMultiByte(CP_UTF8, 0, argv16[i], -1, _argv, l, NULL, NULL); |
|
_argv += x; |
|
l -= x; |
|
} |
|
|
|
LocalFree(argv16); |
|
cmdLine->Init(argc, argv, workingDir, nsICommandLine::STATE_INITIAL_LAUNCH); |
|
delete[] argv[0]; |
|
delete[] argv; |
|
nsCOMPtr<nsIObserverService> observer(do_GetService("@mozilla.org/observer-service;1")); |
|
if (observer) observer->NotifyObservers(cmdLine, "command-line-startup", nullptr); |
|
} |
|
return TRUE; |
|
} |
|
|
|
BOOL CMfcEmbedApp::InitInstance() |
|
{ |
|
USES_CONVERSION; |
|
cmdline.Initialize(T2A(m_lpCmdLine)); |
|
|
|
// check for prior instances |
|
m_bAlreadyRunning = FALSE; |
|
if (cmdline.GetSwitch("-new", NULL, TRUE)<0 && !CheckInstance()) { |
|
m_bAlreadyRunning = TRUE; |
|
return FALSE; |
|
} |
|
|
|
// Security |
|
#ifdef _UNICODE |
|
if (cmdline.GetSwitch("-norestrict", NULL, TRUE)<0 && RestartAsRestricted()) |
|
{ |
|
m_bAlreadyRunning = TRUE; |
|
return FALSE; |
|
} |
|
#endif |
|
|
|
#ifdef _DEBUG |
|
ShowDebugConsole(); |
|
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); |
|
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG); |
|
_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG); |
|
_CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG); |
|
#endif |
|
|
|
INITCOMMONCONTROLSEX InitCtrls; |
|
InitCtrls.dwSize = sizeof(InitCtrls); |
|
InitCtrls.dwICC = ICC_WIN95_CLASSES; |
|
InitCommonControlsEx(&InitCtrls); |
|
|
|
CWinApp::InitInstance(); |
|
AfxOleInit(); |
|
|
|
// Profile selection |
|
int len = cmdline.GetSwitch("-P", NULL, FALSE); |
|
char *profile = NULL; |
|
if (len == 0) { |
|
cmdline.GetSwitch("-P", NULL, TRUE); // remove the flag from the command line |
|
} |
|
else if (len > 0) { |
|
profile = new char[len+1]; |
|
cmdline.GetSwitch("-P", profile, TRUE); |
|
} |
|
|
|
m_hMutex = CreateMutex(NULL, FALSE, NULL); |
|
|
|
// Minimal unicode support |
|
#ifndef _UNICODE |
|
OSVERSIONINFO osinfo; |
|
osinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); |
|
GetVersionEx(&osinfo); |
|
m_bUnicode = (osinfo.dwPlatformId == VER_PLATFORM_WIN32_NT); |
|
#endif |
|
|
|
// Register the hidden window class |
|
WNDCLASS wc = { 0 }; |
|
#ifdef _UNICODE |
|
wc.lpfnWndProc = DefWindowProc; // MSLU incompatibility |
|
#else |
|
wc.lpfnWndProc = AfxWndProc; |
|
#endif |
|
wc.hInstance = AfxGetInstanceHandle(); |
|
wc.lpszClassName = HIDDEN_WINDOW_CLASS; |
|
wc.hIcon=m_hMainIcon; |
|
AfxRegisterClass( &wc ); |
|
|
|
// Register the browser window class |
|
wc.lpszClassName = BROWSER_WINDOW_CLASS; |
|
AfxRegisterClass( &wc ); |
|
|
|
//plugins.Load(GetFolder(RootFolder)+_T("\\kplugins\\jsbridge.dll")); |
|
|
|
if (!InitEmbedding(profile)) |
|
return FALSE; |
|
|
|
// These have to be done in this order! |
|
InitializeDefineMap(); |
|
InitializePrefs(); |
|
SetOffline(theApp.preferences.bOffline); |
|
|
|
LoadLanguage(); |
|
CheckProfileVersion(); |
|
m_MRUList = new CMostRecentUrls(); |
|
|
|
// Initialize plugins |
|
plugins.FindAndLoad(); |
|
plugins.SendMessage("*", "* Plugin Manager", "Init2"); |
|
skin.Init(theApp.preferences.skinsCurrent); |
|
|
|
// Retrieve the default icon |
|
CString sSkinIcon; |
|
if (skin.FindSkinFile(sSkinIcon, _T("main.ico"))) |
|
{ |
|
m_hMainIcon = (HICON)LoadImage( NULL, sSkinIcon, IMAGE_ICON, 0,0, LR_DEFAULTSIZE | LR_LOADFROMFILE ); |
|
m_hSmallIcon = (HICON)LoadImage( NULL, sSkinIcon, IMAGE_ICON, 16,16, LR_LOADFROMFILE ); |
|
} |
|
else |
|
{ |
|
m_hMainIcon = LoadIcon( IDR_MAINFRAME ); |
|
m_hSmallIcon = LoadIcon( IDR_MAINFRAME ); |
|
} |
|
|
|
#ifdef INTERNAL_SITEICONS |
|
// Create the favicon list |
|
|
|
float scale = 1; |
|
/* CString _scale = theApp.preferences.GetString("layout.css.devPixelsPerPx", _T("-1.0")); |
|
float scale = _tstof_l((LPCTSTR)_scale, _create_locale(LC_ALL, "ENU")); |
|
if (scale<=0) { |
|
HDC dc = ::GetDC(NULL); |
|
scale = GetDeviceCaps(dc, LOGPIXELSY) / 96.0; |
|
::ReleaseDC(NULL, dc); |
|
} |
|
*/ |
|
if (preferences.bSiteIcons) |
|
favicons.Create(skin.GetUserWidth(),skin.GetUserWidth(),ILC_COLOR32|ILC_MASK,25,100); |
|
#endif |
|
InitializeMenusAccels(); |
|
|
|
// the hidden window will take care of creating the first |
|
// browser window for us |
|
if(!CreateHiddenWindow()){ |
|
ASSERT(FALSE); |
|
XRE_TermEmbedding(); |
|
//NS_TermEmbedding(); |
|
return FALSE; |
|
} |
|
|
|
return TRUE; |
|
} |
|
|
|
// add new download dialogs to the internal window list so we won't exit |
|
// the app while downloads are in progress |
|
void CMfcEmbedApp::RegisterWindow(CDialog *window) { |
|
m_MiscWndLst.AddHead(window); |
|
} |
|
|
|
void CMfcEmbedApp::UnregisterWindow(CDialog *window) { |
|
POSITION pos = m_MiscWndLst.Find(window); |
|
m_MiscWndLst.RemoveAt(pos); |
|
|
|
// See comment in RemoveFrameFromList() |
|
if ((m_MiscWndLst.GetCount() == 0) && (m_FrameWndLst.GetCount() == 0)) { |
|
|
|
if (m_pMainWnd) { |
|
// if we're staying resident, create the hidden browser window |
|
if (((CHiddenWnd*) m_pMainWnd)->Persisting() == PERSIST_STATE_ENABLED) |
|
((CHiddenWnd*) m_pMainWnd)->StayResident(); |
|
|
|
// otherwise we're exiting, close the Evil Hidden Window |
|
else |
|
m_pMainWnd->DestroyWindow(); |
|
} |
|
} |
|
} |
|
|
|
CBrowserFrame* CMfcEmbedApp::CreateNewBrowserFrameWithUrl(LPCTSTR pUrl, LPCTSTR refferer, |
|
BOOL bBackground, |
|
CWnd* pParent) |
|
{ |
|
if (!pUrl) return NULL; |
|
|
|
CBrowserFrame* pFrame; |
|
const TCHAR* ext = _tcschr(pUrl, L'.'); |
|
|
|
if (ext && (_tcsstr(ext, _T(".xul")) == ext) && |
|
(_tcsncmp(pUrl, _T("chrome:"), 7) == 0)) { |
|
pFrame = CreateNewChromeDialog(pUrl, pParent); |
|
} |
|
else { |
|
pFrame = CreateNewBrowserFrame(nsIWebBrowserChrome::CHROME_ALL, bBackground, pParent); |
|
pFrame->OpenURL(pUrl, refferer, FALSE); |
|
pFrame->ShowWindow(SW_SHOW); |
|
} |
|
return pFrame; |
|
} |
|
/* |
|
CDialog* diag = new CDialog(); |
|
diag->CreateIndirect((LPCDLGTEMPLATE)tplGenericDlg, pParent); |
|
|
|
CBrowserView* view = new CBrowserView(); |
|
|
|
if (!view->CreateEx(0, NULL, NULL, WS_CHILD|WS_VISIBLE, |
|
CRect(0, 0, 0, 0), diag, AFX_IDW_PANE_FIRST, NULL)) return 0; |
|
view->OpenURL(url); |
|
diag->ShowWindow(SW_SHOW); |
|
return diag; |
|
*/ |
|
|
|
CBrowserFrame* CMfcEmbedApp::CreateNewChromeDialog(LPCTSTR url, CWnd* pParent) |
|
{ |
|
// Check if it's not already open |
|
POSITION pos = theApp.m_FrameWndLst.GetHeadPosition(); |
|
CBrowserFrame* pBrowserFrame = NULL; |
|
while( pos != NULL ) { |
|
pBrowserFrame = (CBrowserFrame *) theApp.m_FrameWndLst.GetNext(pos); |
|
if(pBrowserFrame->IsDialog() && pBrowserFrame->GetActiveView()->GetCurrentURI().Compare(url) == 0) { |
|
pBrowserFrame->ActivateFrame(); |
|
return pBrowserFrame; |
|
} |
|
} |
|
|
|
//XXXX We have to make a real Dialog! |
|
PRUint32 chromeMask = nsIWebBrowserChrome::CHROME_WINDOW_RESIZE | |
|
nsIWebBrowserChrome::CHROME_WINDOW_CLOSE | |
|
nsIWebBrowserChrome::CHROME_TITLEBAR | |
|
nsIWebBrowserChrome::CHROME_OPENAS_CHROME| |
|
nsIWebBrowserChrome::CHROME_WINDOW_MIN; |
|
|
|
CBrowserFrame* pFrame = CreateNewBrowserFrame(chromeMask, FALSE, pParent); |
|
pFrame->OpenURL(url); |
|
return pFrame; |
|
} |
|
|
|
CBrowserFrame* CMfcEmbedApp::CreateNewBrowserFrame(PRUint32 chromeMask, |
|
BOOL inBackground, |
|
CWnd* pParent) |
|
{ |
|
DWORD dwWaitResult; |
|
dwWaitResult = WaitForSingleObject( m_hMutex, 1000L); |
|
if (dwWaitResult != WAIT_OBJECT_0) { |
|
return NULL; |
|
} |
|
|
|
// Load the window title from the string resource table |
|
CString strTitle; |
|
strTitle.LoadString(IDR_MAINFRAME); |
|
|
|
BOOL isPopupOrDialog = FALSE; |
|
|
|
// XXX Chrome dialogs shouldn't have thoses. |
|
if (chromeMask & nsIWebBrowserChrome::CHROME_OPENAS_CHROME) { |
|
chromeMask &= ~nsIWebBrowserChrome::CHROME_MENUBAR |
|
&~nsIWebBrowserChrome::CHROME_TOOLBAR |
|
&~nsIWebBrowserChrome::CHROME_LOCATIONBAR |
|
&~nsIWebBrowserChrome::CHROME_STATUSBAR |
|
&~nsIWebBrowserChrome::CHROME_PERSONAL_TOOLBAR; |
|
|
|
isPopupOrDialog = TRUE; |
|
} |
|
|
|
|
|
LONG style, styleEx = 0L; |
|
|
|
if (chromeMask & nsIWebBrowserChrome::CHROME_WINDOW_POPUP) { |
|
style = WS_POPUPWINDOW | WS_CAPTION; |
|
styleEx = WS_EX_TOPMOST | WS_EX_TOOLWINDOW; |
|
} |
|
else if (chromeMask & nsIWebBrowserChrome::CHROME_OPENAS_DIALOG) { |
|
style = WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_DLGFRAME; |
|
//| DS_3DLOOK | DS_MODALFRAME; |
|
styleEx = WS_EX_DLGMODALFRAME; |
|
} |
|
else { |
|
style = WS_OVERLAPPEDWINDOW; |
|
if (pParent && (chromeMask & nsIWebBrowserChrome::CHROME_DEPENDENT)) |
|
style |= WS_POPUP; |
|
} |
|
|
|
if ( !(chromeMask & nsIWebBrowserChrome::CHROME_DEFAULT) && |
|
((chromeMask & nsIWebBrowserChrome::CHROME_ALL) != nsIWebBrowserChrome::CHROME_ALL)) { |
|
|
|
if( !(chromeMask & nsIWebBrowserChrome::CHROME_TITLEBAR) ) |
|
style &= ~WS_CAPTION; // No caption |
|
|
|
if (!theApp.preferences.bDisableResize) { |
|
if( !(chromeMask & nsIWebBrowserChrome::CHROME_WINDOW_RESIZE) ) { |
|
// Can't resize this window |
|
style &= ~WS_THICKFRAME; |
|
style &= ~WS_MAXIMIZEBOX; |
|
} |
|
} |
|
|
|
if ( !(chromeMask & nsIWebBrowserChrome::CHROME_WINDOW_CLOSE) && |
|
!(chromeMask & nsIWebBrowserChrome::CHROME_MENUBAR) ) |
|
style &= ~WS_SYSMENU; |
|
|
|
if (chromeMask & nsIWebBrowserChrome::CHROME_WINDOW_MIN) |
|
style |= WS_MINIMIZEBOX; |
|
} |
|
|
|
if ( (chromeMask & (nsIWebBrowserChrome::CHROME_OPENAS_CHROME)) || |
|
(!(chromeMask & nsIWebBrowserChrome::CHROME_DEFAULT) && |
|
!(chromeMask & nsIWebBrowserChrome::CHROME_TOOLBAR)) ) { |
|
isPopupOrDialog = TRUE; |
|
style |= WS_POPUP; // XXX |
|
} |
|
|
|
if (!isPopupOrDialog && (preferences.bMaximized || |
|
(m_pMostRecentBrowserFrame && m_pMostRecentBrowserFrame->IsZoomed())) && |
|
((chromeMask & nsIWebBrowserChrome::CHROME_WINDOW_RESIZE) || (chromeMask & nsIWebBrowserChrome::CHROME_ALL))) |
|
style |= WS_MAXIMIZE; |
|
|
|
RECT screen, winSize = {0}; |
|
SystemParametersInfo(SPI_GETWORKAREA, NULL, &screen, 0); |
|
int screenWidth = screen.right - screen.left; |
|
int screenHeight = screen.bottom - screen.top; |
|
/* |
|
if (x>0 && y>0 && cx>0 && cy>0) { |
|
winSize.left = x; |
|
winSize.top = y; |
|
winSize.right = x + cx; |
|
winSize.bottom = y + cy; |
|
AdjustWindowRectEx(&winSize, style, chromeMask & (nsIWebBrowserChrome::CHROME_MENUBAR), 0); |
|
} |
|
else {*/ |
|
|
|
|
|
// If the last active window is not a popup use cascading placement |
|
if (!(chromeMask & nsIWebBrowserChrome::CHROME_OPENAS_CHROME)) { |
|
|
|
CBrowserFrame* pCascadeWnd = NULL; |
|
if (inBackground && !m_FrameWndLst.IsEmpty()) { |
|
pCascadeWnd = (CBrowserFrame*)m_FrameWndLst.GetHead(); |
|
if (pCascadeWnd->IsPopup() || pCascadeWnd->IsDialog()) |
|
pCascadeWnd = NULL; |
|
} |
|
|
|
if (!pCascadeWnd && m_pMostRecentBrowserFrame) { |
|
pCascadeWnd = m_pMostRecentBrowserFrame; |
|
if (pCascadeWnd->IsPopup() || pCascadeWnd->IsDialog()) |
|
pCascadeWnd = NULL; |
|
} |
|
|
|
if (pCascadeWnd) |
|
{ |
|
WINDOWPLACEMENT wp; |
|
wp.length = sizeof(WINDOWPLACEMENT); |
|
pCascadeWnd->GetWindowPlacement(&wp); |
|
|
|
// if the window is not maximized, let's use use GetWindowRect, which works |
|
if (wp.showCmd == SW_SHOWNORMAL) |
|
pCascadeWnd->GetWindowRect(&wp.rcNormalPosition); |
|
|
|
int offset = GetSystemMetrics(SM_CYSIZE) + GetSystemMetrics(SM_CXBORDER); |
|
winSize.left = wp.rcNormalPosition.left + offset; |
|
winSize.top = wp.rcNormalPosition.top + offset; |
|
winSize.right = wp.rcNormalPosition.right + offset; |
|
winSize.bottom = wp.rcNormalPosition.bottom + offset; |
|
|
|
// Put the window to the top corner if we're too far in |
|
// the bottom left. |
|
if ( (screen.right - winSize.right) < offset |
|
&& (screen.bottom - winSize.bottom) < offset) |
|
{ |
|
winSize.left = screen.left; |
|
winSize.top = screen.top; |
|
winSize.right = wp.rcNormalPosition.right - wp.rcNormalPosition.left; |
|
winSize.bottom = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top; |
|
} |
|
} |
|
else { |
|
|
|
// Use default position |
|
winSize.left = screen.left + screenWidth / 20; |
|
winSize.top = screen.top + screenHeight / 20; |
|
winSize.right = winSize.left + 15*screenWidth / 20; |
|
winSize.bottom = winSize.top + 18*screenHeight/20; |
|
|
|
// Use user preference position if any |
|
if (preferences.windowXPos >= 0) |
|
winSize.left = preferences.windowXPos; |
|
if (preferences.windowYPos >=0) |
|
winSize.top = preferences.windowYPos; |
|
if (preferences.windowWidth > 0) |
|
winSize.right = winSize.left + preferences.windowWidth; |
|
if (preferences.windowHeight > 0) |
|
winSize.bottom = winSize.top + preferences.windowHeight; |
|
|
|
} |
|
} else { |
|
// XXX |
|
// this is a chrome window, let set some generic size in the hope |
|
// the xul dialog will be sized correctly (with persist properties |
|
// which are currently not working). |
|
int w = preferences.GetInt("kmeleon.display.xulwidth", 0); |
|
int h = preferences.GetInt("kmeleon.display.xulheight", 0); |
|
if (w>1) { |
|
winSize.left = (screenWidth - w) / 2 + screen.left; |
|
winSize.right = winSize.left + w; |
|
} else { |
|
winSize.left = screen.left + screenWidth / 20; |
|
winSize.right = winSize.left + 12*screenWidth / 20; |
|
} |
|
if (h>1) { |
|
winSize.top = (screenHeight - h) / 2 + screen.top; |
|
winSize.bottom = winSize.top + h; |
|
} else { |
|
winSize.top = screen.top + screenHeight / 20; |
|
winSize.bottom = winSize.top + 15*screenHeight / 20; |
|
} |
|
} |
|
|
|
// don't create windows larger than the screen |
|
if ((winSize.right - winSize.left) > screenWidth) |
|
winSize.right = screenWidth - winSize.left; |
|
if ((winSize.bottom - winSize.top) > screenHeight) |
|
winSize.bottom = screenHeight - winSize.top; |
|
|
|
// make sure the window isn't going to run off the screen |
|
if ((screen.right - winSize.right) < 0) { |
|
winSize.left = screen.right - (winSize.right - winSize.left); |
|
winSize.right = screen.right; |
|
} |
|
if ((screen.bottom - winSize.bottom) < 0) { |
|
winSize.top = screen.bottom - (winSize.bottom - winSize.top); |
|
winSize.bottom = screen.bottom; |
|
} |
|
|
|
// Now, create the browser frame |
|
CBrowserFrame* pFrame = NULL; |
|
if (isPopupOrDialog || preferences.GetBool("kmeleon.notab", FALSE)) |
|
pFrame = new CBrowserFrame(chromeMask, style); |
|
else |
|
pFrame = (CBrowserFrame*)new CBrowserFrmTab(chromeMask, style); |
|
|
|
// this backup is made as part of a bad workaround: |
|
// m_pMostRecentBrowserFrame needs to be this frame for the life of this function so that |
|
// things like plugins and the rebar sizes can access it, but |
|
// m_pMostRecentBrowserFrame should not stay set to this if this window |
|
// is hidden (usually meaning that it is created using the open link in background option) |
|
// so the backup is made, and m_pMostRecentBrowserFrame will be restored |
|
// at the end of this function |
|
CBrowserFrame* pOldRecentFrame = m_pMostRecentBrowserFrame; |
|
m_pMostRecentBrowserFrame = pFrame; |
|
if (!pOldRecentFrame) |
|
pOldRecentFrame = pFrame; |
|
|
|
CMenu *menu = theApp.menus.GetMenu(_T("Main")); |
|
|
|
if (!pFrame->CreateEx(styleEx, BROWSER_WINDOW_CLASS, strTitle, style, |
|
winSize, chromeMask & nsIWebBrowserChrome::CHROME_DEPENDENT ? pParent : NULL, |
|
(UINT)menu->GetSafeHmenu(), NULL)) |
|
{ |
|
TRACE0("Warning: failed to create CFrameWnd.\n"); |
|
ReleaseMutex(theApp.m_hMutex); |
|
m_pMostRecentBrowserFrame = pOldRecentFrame; |
|
delete pFrame; |
|
return FALSE; |
|
} |
|
|
|
pFrame->SetIcon(m_hMainIcon, true); |
|
pFrame->SetIcon(m_hSmallIcon, false); |
|
|
|
// this only needs to be called once |
|
if (!m_bFirstWindowCreated) { |
|
KmMenu* menu = menus.GetKMenu(_T("@Toolbars")); |
|
if (menu) menu->Invalidate(); |
|
#ifdef INTERNAL_SIDEBAR |
|
menu = menus.GetKMenu(_T("@Sidebars")); |
|
if (menu) menu->Invalidate(); |
|
#endif |
|
m_bFirstWindowCreated = TRUE; |
|
} |
|
|
|
if (!preferences.bHideTaskBarButtons) |
|
pFrame->ModifyStyleEx(0, WS_EX_APPWINDOW); |
|
|
|
if (preferences.GetBool("kmeleon.display.hideTitleBar", FALSE) && !isPopupOrDialog) { |
|
pFrame->ModifyStyle(WS_CAPTION, 0 , SWP_DRAWFRAME); |
|
if (pFrame->IsZoomed()) |
|
pFrame->ModifyStyle(WS_THICKFRAME, 0); |
|
} |
|
|
|
if (inBackground) { |
|
pFrame->SetWindowPos((CWnd*)theApp.m_FrameWndLst.GetHead(), |
|
0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_SHOWWINDOW); |
|
theApp.m_pMostRecentBrowserFrame = pOldRecentFrame; |
|
} else if (!isPopupOrDialog) { |
|
theApp.m_pMostRecentBrowserFrame = pOldRecentFrame; |
|
} |
|
|
|
// Add to the list of BrowserFrame windows |
|
m_FrameWndLst.AddHead(pFrame); |
|
ReleaseMutex(m_hMutex); |
|
return pFrame; |
|
} |
|
|
|
void CMfcEmbedApp::OnAppAbout() |
|
{ |
|
CBrowserFrame* pFrm = CreateNewBrowserFrame( |
|
nsIWebBrowserChrome::CHROME_WINDOW_RESIZE | |
|
nsIWebBrowserChrome::CHROME_WINDOW_CLOSE | |
|
nsIWebBrowserChrome::CHROME_TITLEBAR | |
|
nsIWebBrowserChrome::CHROME_SCROLLBARS, |
|
FALSE); |
|
|
|
if (!pFrm) return; |
|
pFrm->OpenURL(_T("about:")); |
|
pFrm->ShowWindow(SW_SHOW); |
|
} |
|
|
|
void CMfcEmbedApp::OnNewBrowser() |
|
{/* |
|
if (m_pMostRecentBrowserFrame) { |
|
((CBrowserFrmTab*)m_pMostRecentBrowserFrame)->OnNewTab(); |
|
return; |
|
}*/ |
|
|
|
m_pOpenNewBrowserFrame = m_pMostRecentBrowserFrame; |
|
BOOL urlFocus = theApp.preferences.GetBool("kmeleon.display.NewWindowHasUrlFocus", FALSE); |
|
|
|
CBrowserFrame *pBrowserFrame = CreateNewBrowserFrame(); |
|
if(pBrowserFrame) { |
|
|
|
//Load the new window start page into the browser view |
|
switch (preferences.iNewWindowOpenAs) { |
|
case PREF_NEW_WINDOW_CURRENT: |
|
if (m_pOpenNewBrowserFrame) { |
|
pBrowserFrame->OpenURL(m_pOpenNewBrowserFrame->GetActiveView()->GetCurrentURI(), NULL, urlFocus); |
|
m_pOpenNewBrowserFrame->GetActiveView()->CloneBrowser(pBrowserFrame->GetActiveView()); |
|
} |
|
break; |
|
case PREF_NEW_WINDOW_HOME: |
|
pBrowserFrame->GetActiveView()->LoadHomePage(); |
|
break; |
|
case PREF_NEW_WINDOW_BLANK: |
|
pBrowserFrame->OpenURL(_T("about:blank"), NULL, urlFocus); |
|
break; |
|
case PREF_NEW_WINDOW_URL: { |
|
CString newUrl = preferences.newWindowURL; |
|
if (newUrl.IsEmpty()) |
|
pBrowserFrame->OpenURL(_T("about:blank"), NULL, urlFocus); |
|
else |
|
pBrowserFrame->OpenURL(newUrl, NULL, urlFocus); |
|
break; |
|
} |
|
} |
|
|
|
pBrowserFrame->ShowWindow(SW_SHOW); |
|
|
|
if (theApp.preferences.bNewWindowHasUrlFocus) |
|
pBrowserFrame->m_wndUrlBar.SetFocus(); |
|
} |
|
} |
|
|
|
void CMfcEmbedApp::OnToggleOffline() |
|
{ |
|
BroadcastMessage(WM_COMMAND, ID_NAV_STOP, (LPARAM) 0); |
|
|
|
SetOffline(!theApp.preferences.bOffline); |
|
//theApp.menus.SetCheck(ID_OFFLINE, theApp.preferences.bOffline); |
|
|
|
CString status; |
|
status.LoadString( theApp.preferences.bOffline ? IDS_OFFLINE : IDS_ONLINE ); |
|
|
|
m_pMostRecentBrowserFrame->UpdateStatus(status); |
|
} |
|
|
|
void CMfcEmbedApp::OnToggleJS() |
|
{ |
|
int enable = !preferences.GetBool("javascript.enabled", 1); |
|
preferences.SetBool("javascript.enabled", enable); |
|
|
|
CBrowserFrame* pBrowserFrame = NULL; |
|
POSITION pos = m_FrameWndLst.GetHeadPosition(); |
|
int i = 0; |
|
while( pos != NULL ) { |
|
pBrowserFrame = (CBrowserFrame *) m_FrameWndLst.GetNext(pos); |
|
pBrowserFrame->AllowJS(enable); |
|
} |
|
} |
|
|
|
void CMfcEmbedApp::OnUpdateToggleJS(CCmdUI* pCmdUI) |
|
{ |
|
pCmdUI->SetCheck(!preferences.GetBool("javascript.enabled", 1)); |
|
} |
|
|
|
void CMfcEmbedApp::OnUpdateToggleOffline(CCmdUI* pCmdUI) |
|
{ |
|
pCmdUI->SetCheck(preferences.bOffline); |
|
} |
|
|
|
// This gets called anytime a BrowserFrameWindow is |
|
// closed i.e. by choosing the "close" menu item from |
|
// a window's system menu or by dbl clicking on the |
|
// system menu box |
|
// |
|
// Sends a WM_QUIT to the hidden window which results |
|
// in ExitInstance() being called and the app is |
|
// properly cleaned up and shutdown |
|
// |
|
void CMfcEmbedApp::RemoveFrameFromList(CBrowserFrame* pFrm) |
|
{ |
|
POSITION pos = m_FrameWndLst.Find(pFrm); |
|
m_FrameWndLst.RemoveAt(pos); |
|
UpdateWindowListMenu(); |
|
|
|
// Unless we are set to stay resident, |
|
// destroy the hidden window (which will post a WM_QUIT msg |
|
// since this is the main frame window) if we've |
|
// just closed the last browserframe window and |
|
// if the bCloseAppOnLastFrame is TRUE. This be FALSE |
|
// only in the case we're switching profiles |
|
// Without this the hidden window will stick around |
|
// i.e. the app will never die even after all the |
|
// visible windows are gone. |
|
if ((m_FrameWndLst.GetCount() == 0) && (m_MiscWndLst.GetCount() == 0)) { |
|
|
|
// if we're switching profiles, we don't need to do anything |
|
if (m_bSwitchingProfiles) {} |
|
|
|
else if (m_pMainWnd) { |
|
|
|
// if we're staying resident, create the hidden browser window |
|
if (((CHiddenWnd*) m_pMainWnd)->Persisting() == PERSIST_STATE_ENABLED) |
|
((CHiddenWnd*) m_pMainWnd)->StayResident(); |
|
|
|
// otherwise we're exiting, close the Evil Hidden Window |
|
else |
|
m_pMainWnd->DestroyWindow(); |
|
} |
|
} |
|
} |
|
|
|
void CMfcEmbedApp::UpdateWindowListMenu() |
|
{ |
|
KmMenu* menu = menus.GetKMenu(_T("@WindowList")); |
|
if (menu) menu->Invalidate(); |
|
} |
|
|
|
void CMfcEmbedApp::DrawWindowListMenu(HMENU menu) |
|
{ |
|
CBrowserFrame* pBrowserFrame = NULL; |
|
POSITION pos = m_FrameWndLst.GetHeadPosition(); |
|
int i = 0; |
|
while( pos != NULL ) { |
|
pBrowserFrame = (CBrowserFrame *) m_FrameWndLst.GetNext(pos); |
|
CBrowserWrapper* wrapper = pBrowserFrame->GetActiveView()->GetBrowserWrapper(); |
|
if (!wrapper) continue; |
|
|
|
CString title = wrapper->GetTitle(); |
|
if (title.IsEmpty()) |
|
title = wrapper->GetURI(); |
|
|
|
AppendMenu(menu, MF_ENABLED | MF_STRING | ((pBrowserFrame == m_pMostRecentBrowserFrame) ? MF_CHECKED : 0), WINDOW_MENU_START_ID + i++ , title); |
|
} |
|
} |
|
|
|
void CMfcEmbedApp::OnUpdateWindows(CCmdUI *pCmd) |
|
{ |
|
POSITION pos = m_FrameWndLst.FindIndex(pCmd->m_nID - WINDOW_MENU_START_ID); |
|
if (pos == NULL) return; |
|
|
|
CBrowserFrame* pBrowserFrame = (CBrowserFrame *)m_FrameWndLst.GetAt(pos); |
|
if (m_pMostRecentBrowserFrame == pBrowserFrame) |
|
pCmd->SetCheck(1); |
|
else |
|
pCmd->SetCheck(0); |
|
} |
|
|
|
void CMfcEmbedApp::OnWindowSelect(UINT id) |
|
{ |
|
POSITION pos = m_FrameWndLst.FindIndex(id - WINDOW_MENU_START_ID); |
|
if (pos == NULL) return; |
|
|
|
CBrowserFrame* pBrowserFrame = (CBrowserFrame *)m_FrameWndLst.GetAt(pos); |
|
if (pBrowserFrame) pBrowserFrame->BringWindowToTop(); |
|
} |
|
|
|
void CMfcEmbedApp::BroadcastMessage(UINT Msg, WPARAM wParam, LPARAM lParam) |
|
{ |
|
CBrowserFrame* pBrowserFrame = NULL; |
|
POSITION pos = m_FrameWndLst.GetHeadPosition(); |
|
while( pos != NULL ) { |
|
pBrowserFrame = (CBrowserFrame *) m_FrameWndLst.GetNext(pos); |
|
if(pBrowserFrame) |
|
pBrowserFrame->PostMessage(Msg, wParam, lParam); |
|
} |
|
} |
|
|
|
int CMfcEmbedApp::ExitInstance() |
|
{ |
|
// When File/Exit is chosen and if the user |
|
// has opened multiple browser windows shut all |
|
// of them down properly before exiting the app |
|
|
|
|
|
// if we're exiting because an instance was already |
|
// running, then we haven't created anything that |
|
// needs to be destroyed |
|
if (m_bAlreadyRunning) |
|
return 1; |
|
|
|
CBrowserFrame* pBrowserFrame = NULL; |
|
|
|
POSITION pos = m_MiscWndLst.GetHeadPosition(); |
|
while( pos != NULL ) |
|
{ |
|
CProgressDialog *pDlg = (CProgressDialog *) m_MiscWndLst.GetNext(pos); |
|
if (pDlg) |
|
pDlg->Cancel(); |
|
} |
|
|
|
pos = m_FrameWndLst.GetHeadPosition(); |
|
while( pos != NULL ) { |
|
pBrowserFrame = (CBrowserFrame *) m_FrameWndLst.GetNext(pos); |
|
if(pBrowserFrame) |
|
pBrowserFrame->DestroyWindow(); |
|
} |
|
m_FrameWndLst.RemoveAll(); |
|
|
|
m_pMostRecentBrowserFrame = NULL; // In case plugins are weird |
|
|
|
if (m_pMainWnd) |
|
m_pMainWnd->DestroyWindow(); |
|
|
|
// unload the plugins before we terminate embedding, |
|
// this way plugins can still call the preference functions |
|
plugins.SendMessage("*", "* Plugin Manager", "Quit"); |
|
|
|
delete m_MRUList; |
|
DestroyIcon(m_hMainIcon); |
|
DestroyIcon(m_hSmallIcon); |
|
|
|
favicons.WriteCache(); |
|
|
|
preferences.Flush(); |
|
|
|
NS_LogInit(); |
|
|
|
preferences.Release(); |
|
if (m_ProfileMgr) { |
|
m_ProfileMgr->ShutDownCurrentProfile( theApp.preferences.bGuestAccount ); |
|
delete m_ProfileMgr; |
|
} |
|
|
|
XRE_TermEmbedding(); |
|
NS_LogTerm(); |
|
|
|
// In case a plugin is a component, must be unloaded last. |
|
plugins.UnLoadAll(); |
|
if (m_hResDll) FreeLibrary(m_hResDll); |
|
|
|
AfxOleTerm(FALSE); |
|
CWinApp::ExitInstance(); |
|
|
|
if (m_bRestart) { |
|
PROCESS_INFORMATION pi = {0}; |
|
STARTUPINFO si = {0}; |
|
si.cb = sizeof(STARTUPINFO); |
|
si.dwFlags = STARTF_USESHOWWINDOW; |
|
si.wShowWindow = SW_NORMAL; |
|
::CreateProcess(NULL, ::GetCommandLine(), NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi); |
|
CloseHandle(pi.hProcess); |
|
CloseHandle(pi.hThread); |
|
} |
|
|
|
return 1; |
|
} |
|
|
|
BOOL CMfcEmbedApp::OnIdle(LONG lCount) |
|
{ |
|
CWinApp::OnIdle(lCount); |
|
|
|
//NS_DoIdleEmbeddingStuff(); |
|
/* |
|
CBrowserFrame* pBrowserFrame = NULL; |
|
POSITION pos = m_FrameWndLst.GetHeadPosition(); |
|
BOOL visible = FALSE; |
|
while( pos != NULL ) { |
|
pBrowserFrame = (CBrowserFrame *) m_FrameWndLst.GetNext(pos); |
|
visible = visible || pBrowserFrame->IsWindowVisible(); |
|
} |
|
if (!visible) { |
|
ASSERT(FALSE); |
|
pBrowserFrame->ShowWindow(SW_SHOW); |
|
}*/ |
|
|
|
return FALSE; |
|
} |
|
|
|
BOOL CMfcEmbedApp::IsIdleMessage( MSG* pMsg ) |
|
{ |
|
if (!CWinApp::IsIdleMessage( pMsg ) || |
|
pMsg->message == WM_NSEVENTID || |
|
pMsg->message == WM_FLASHRELAY || |
|
pMsg->message == WM_USER + 1 || // Flash |
|
pMsg->message == WM_USER + 12 || // Flash |
|
pMsg->message == WM_USER + 112 || // Flash |
|
pMsg->message == WM_POSTEVENT || |
|
pMsg->message == WM_TIMER) |
|
|
|
return FALSE; |
|
else |
|
return TRUE; |
|
} |
|
|
|
void CMfcEmbedApp::OnPreferences () { |
|
CreateNewChromeDialog(_T("chrome://kmprefs/content/pref.xul")); |
|
//CPreferencesDlg prefDlg; |
|
//prefDlg.DoModal(); |
|
} |
|
|
|
void CMfcEmbedApp::OnManageProfiles() |
|
{ |
|
CProfilesDlg dialog(m_ProfileMgr); |
|
dialog.DoModal(); |
|
} |
|
|
|
// 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 |
|
// switches |
|
BOOL CMfcEmbedApp::CreateHiddenWindow() |
|
{ |
|
CFrameWnd *hiddenWnd = new CHiddenWnd; |
|
if(!hiddenWnd) |
|
return FALSE; |
|
|
|
// do this before Create so the window spawned in Create will know who it's parent is |
|
m_pMainWnd = hiddenWnd; |
|
|
|
RECT bounds = { 0 }; |
|
return hiddenWnd->Create(HIDDEN_WINDOW_CLASS, _T("K-Meleon hidden window"), 0, bounds, NULL, NULL, 0, NULL); |
|
} |
|
|
|
BOOL CMfcEmbedApp::InitializePrefs(){ |
|
preferences.Load(); |
|
//preferences.Save(); |
|
|
|
return TRUE; |
|
} |
|
|
|
BOOL CMfcEmbedApp::InitializeMenusAccels(){ |
|
CString filename; |
|
CMenuParser menusParser; |
|
|
|
filename = GetFolder(DefSettingsFolder) + _T("\\") ACCEL_CONFIG_FILE; |
|
accel.Load(filename); |
|
|
|
filename = GetFolder(DefSettingsFolder) + _T("\\") MENU_CONFIG_FILE; |
|
menusParser.Load(filename); |
|
|
|
plugins.SendMessage("*", "* Plugin Manager", "Init"); |
|
plugins.SendMessage("*", "* Plugin Manager", "Setup2"); |
|
|
|
nsCOMPtr<nsIObserverService> observerService(do_GetService("@mozilla.org/observer-service;1")); |
|
observerService->NotifyObservers (nullptr, "kmeleon-init", nullptr); |
|
|
|
filename = GetFolder(UserSettingsFolder) + _T("\\") ACCEL_CONFIG_FILE; |
|
accel.Load(filename); |
|
|
|
filename = GetFolder(UserSettingsFolder) + _T("\\") MENU_CONFIG_FILE; |
|
menusParser.Load(filename); |
|
|
|
plugins.SendMessage("*", "* Plugin Manager", "Setup"); |
|
plugins.SendMessage("*", "* Plugin Manager", "UserSetup"); |
|
|
|
return TRUE; |
|
} |
|
|
|
/* 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 CMfcEmbedApp::InitializeWindowCreator() { |
|
// give an nsIWindowCreator to the WindowWatcher service |
|
nsCOMPtr<nsIWindowCreator> windowCreator(static_cast<nsIWindowCreator *>(this)); |
|
if (windowCreator) { |
|
nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService("@mozilla.org/embedcomp/window-watcher;1")); |
|
if (wwatch) { |
|
wwatch->SetWindowCreator(windowCreator); |
|
return NS_OK; |
|
} |
|
} |
|
return NS_ERROR_FAILURE; |
|
} |
|
// --------------------------------------------------------------------------- |
|
// CMfcEmbedApp : nsISupports |
|
// --------------------------------------------------------------------------- |
|
|
|
#ifdef XPCOM_GLUE |
|
NS_IMPL_ISUPPORTS(CMfcEmbedApp, nsIObserver, nsIWindowCreator, nsISupportsWeakReference); |
|
#else |
|
NS_IMPL_THREADSAFE_ISUPPORTS(CMfcEmbedApp, nsIObserver, nsIWindowCreator, nsISupportsWeakReference); |
|
#endif |
|
|
|
// --------------------------------------------------------------------------- |
|
// CMfcEmbedApp : nsIObserver |
|
// --------------------------------------------------------------------------- |
|
|
|
// Mainly needed to support "on the fly" profile switching |
|
|
|
NS_IMETHODIMP CMfcEmbedApp::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *someData) |
|
{ |
|
nsresult rv = NS_OK; |
|
|
|
//USES_CONVERSION; |
|
|
|
//if (strcmp(aTopic, "profile-approve-change") == 0 && |
|
// (!someData || |
|
// strcmp(W2A(someData), "shutdown-cleanse") != 0 && |
|
// strcmp(W2A(someData), "shutdown-persist") != 0)) |
|
//{ |
|
// // Ask the user if they want to |
|
// int result = AfxMessageBox(IDS_PROFILE_SWITCH, MB_YESNO | MB_ICONQUESTION, 0); |
|
// if (result != IDYES) |
|
// { |
|
// nsCOMPtr<nsIProfileChangeStatus> status = do_QueryInterface(aSubject); |
|
// NS_ENSURE_TRUE(status, NS_ERROR_FAILURE); |
|
// status->VetoChange(); |
|
// } |
|
//} |
|
//else if (strcmp(aTopic, "profile-change-teardown") == 0) |
|
//{ |
|
// // Close all open windows. Alternatively, we could just call CBrowserWrapper::Stop() |
|
// // on each. Either way, we have to stop all network activity on this phase. |
|
// |
|
// POSITION pos = m_MiscWndLst.GetHeadPosition(); |
|
// while( pos != NULL ) |
|
// { |
|
// CProgressDialog *pDlg = (CProgressDialog *) m_MiscWndLst.GetNext(pos); |
|
// if (pDlg) |
|
// pDlg->Cancel(); |
|
// } |
|
// |
|
// m_bSwitchingProfiles = TRUE; |
|
// pos = m_FrameWndLst.GetHeadPosition(); |
|
// while( pos != NULL ) { |
|
// CBrowserFrame *pBrowserFrame = (CBrowserFrame *) m_FrameWndLst.GetNext(pos); |
|
// if(pBrowserFrame) |
|
// pBrowserFrame->SendMessage(WM_CLOSE); |
|
// } |
|
// m_bSwitchingProfiles = FALSE; |
|
|
|
// preferences.Flush(); |
|
//} |
|
//else if (strcmp(aTopic, "profile-after-change") == 0) |
|
//{ |
|
// // Only reinitialize everything if this is a profile switch, since this |
|
// // called at start up and we already do evenything once already |
|
// if (!wcscmp(someData, NS_LITERAL_STRING("switch").get())) { |
|
// |
|
// /* XXX Plugin that use global vars can't be unloaded/reloaded |
|
// correctly. |
|
// */ |
|
// |
|
// plugins.SendMessage("*", "* Plugin Manager", "Quit"); |
|
// plugins.UnLoadAll(); |
|
// menus.Destroy(); |
|
// InitializePrefs(); |
|
// CheckProfileVersion(); |
|
|
|
// plugins.FindAndLoad(); |
|
// plugins.SendMessage("*", "* Plugin Manager", "Init"); |
|
// InitializeMenusAccels(); |
|
// plugins.SendMessage("*", "* Plugin Manager", "Setup"); |
|
// |
|
// CBrowserFrame* browser; |
|
// browser = CreateNewBrowserFrame(); |
|
// |
|
// if (!browser) { |
|
// MessageBox(NULL, _T("Could not create browser frame"), NULL, MB_OK); |
|
// m_pMainWnd->PostMessage(WM_QUIT); |
|
// return NS_ERROR_FAILURE; |
|
// } |
|
// |
|
// browser->SetFocus(); |
|
// // browser->m_wndUrlBar.MaintainFocus(); |
|
// browser->GetActiveView()->LoadHomePage(); |
|
// } |
|
//} |
|
|
|
return rv; |
|
} |
|
|
|
// --------------------------------------------------------------------------- |
|
// CMfcEmbedApp : nsIWindowCreator |
|
// --------------------------------------------------------------------------- |
|
NS_IMETHODIMP CMfcEmbedApp::CreateChromeWindow(nsIWebBrowserChrome *parent, |
|
PRUint32 chromeFlags, |
|
nsIWebBrowserChrome **_retval) |
|
{ |
|
if (theApp.preferences.GetBool("kmeleon.general.BlockAllChromeWindows", false)) |
|
return NS_ERROR_FAILURE; |
|
|
|
NS_ENSURE_ARG_POINTER(_retval); |
|
*_retval = 0; |
|
|
|
CWnd* pParent = NULL; |
|
if (parent) { |
|
HWND w; |
|
nsCOMPtr<nsIEmbeddingSiteWindow> site(do_QueryInterface(parent)); |
|
if (site) { |
|
site->GetSiteWindow(reinterpret_cast<void **>(&w)); |
|
pParent = CWnd::FromHandle(w); |
|
} |
|
} |
|
/* |
|
if (!pParent) { |
|
// This means a popup opened when closing a window. NEVER >-] |
|
return NS_ERROR_FAILURE; |
|
}*/ |
|
|
|
//nsCOMPtr<nsIWindowCreator> browserChrome(do_QueryInterface(parent)); |
|
//return browserChrome->CreateChromeWindow(parent, chromeFlags, _retval); |
|
|
|
CBrowserFrame *pBrowserFrame = CreateNewBrowserFrame(chromeFlags, FALSE, pParent); |
|
if(pBrowserFrame) {//XXXX |
|
*_retval = static_cast<nsIWebBrowserChrome *>(pBrowserFrame->GetActiveView()->GetBrowserWrapper()->mpBrowserImpl); |
|
NS_ADDREF(*_retval); |
|
} |
|
return NS_OK; |
|
|
|
} |
|
|
|
|
|
|
|
// load the mapped values |
|
void CMfcEmbedApp::InitializeDefineMap() { |
|
|
|
#include "defineMap.cpp" |
|
|
|
} |
|
|
|
int CMfcEmbedApp::GetID(const char *strID) { |
|
int val = 0; |
|
USES_CONVERSION; |
|
defineMap.Lookup(A2CT(strID), val); |
|
return val; |
|
} |
|
|
|
CString CMfcEmbedApp::GetFolder(FolderType folder) |
|
{ |
|
// You can call me lazy. |
|
switch (folder) { |
|
case AppFolder: |
|
return GetFolder(RootFolder) + _T("\\") + _T("browser"); |
|
|
|
case RootFolder: |
|
if (m_sRootFolder.IsEmpty()) { |
|
TCHAR _path[_MAX_PATH+1]; |
|
TCHAR path[_MAX_PATH+1]; |
|
::GetModuleFileName(0, _path, _MAX_PATH); |
|
_wfullpath(path, _path, _MAX_PATH); |
|
|
|
TCHAR* lastSlash = _tcsrchr(path, _T('\\')); |
|
if (!lastSlash) return FALSE; |
|
*lastSlash = _T('\0'); |
|
m_sRootFolder = path; |
|
} |
|
return m_sRootFolder; |
|
|
|
case DefSettingsFolder: |
|
return preferences.settingsFolder; |
|
|
|
case UserSettingsFolder: |
|
return preferences.userSettingsFolder; |
|
|
|
case ProfileFolder: |
|
return preferences.profileFolder; |
|
|
|
case PluginsFolder: |
|
return preferences.pluginsFolder; |
|
|
|
case UserPluginsFolder: |
|
return preferences.userPluginsFolder; |
|
|
|
case SkinsFolder: |
|
return preferences.skinsFolder; |
|
|
|
case UserSkinsFolder: |
|
return preferences.userSkinsFolder; |
|
|
|
case ResFolder: |
|
return preferences.resFolder; |
|
|
|
case CurrentSkinFolder: |
|
return preferences.currentSkinFolder; |
|
|
|
case LocaleFolder: |
|
return GetFolder(RootFolder) + _T("\\locales"); |
|
} |
|
return _T(""); |
|
} |
|
|
|
#include "nsIMIMEService.h" |
|
#include "nsIRDFService.h" |
|
#include "nsIFileProtocolHandler.h" |
|
#include "nsIRDFContainer.h" |
|
#include "nsIRDFRemoteDataSource.h" |
|
#include "nsDirectoryServiceUtils.h" |
|
|
|
void CMfcEmbedApp::CheckProfileVersion() |
|
{ |
|
CString fileVersion = GetFolder(ProfileFolder) + _T("\\version.ini"); |
|
BOOL needClean = FALSE; |
|
|
|
CString locale; |
|
locale.LoadString(IDS_LOCALE_ID); |
|
|
|
TCHAR version[34]; |
|
_itot(KMELEON_VERSION, version, 10); |
|
|
|
int oldVersion = GetPrivateProfileInt(_T("Version"), _T("LastVersion"), 0, fileVersion); |
|
if (!oldVersion) |
|
{ |
|
needClean = TRUE; // XXX This will be done even with a new profile |
|
WritePrivateProfileString(_T("Version"), _T("LastVersion"), version, fileVersion); |
|
WritePrivateProfileString(_T("Version"), _T("LastLocale"), locale, fileVersion); |
|
} |
|
else { |
|
if (oldVersion != KMELEON_VERSION) { |
|
needClean = TRUE; |
|
WritePrivateProfileString(_T("Version"), _T("LastVersion"), version, fileVersion); |
|
} |
|
} |
|
|
|
if (needClean) { |
|
|
|
CString toDelete = GetFolder(ProfileFolder) + _T("compreg.dat"); |
|
DeleteFile(toDelete); |
|
toDelete = GetFolder(ProfileFolder) + _T("xpti.dat"); |
|
DeleteFile(toDelete); |
|
toDelete = GetMozDirectory(NS_APP_USER_PROFILE_LOCAL_50_DIR) + _T("\\") + _T("startupCache") + _T("\0\0"); |
|
TCHAR path[MAX_PATH] = {0}; |
|
_tcsncpy(path, toDelete, MAX_PATH-2); |
|
SHFILEOPSTRUCT fop = {0}; |
|
fop.wFunc = FO_DELETE | FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI; |
|
fop.pFrom = path; |
|
SHFileOperation(&fop); |
|
|
|
toDelete = GetMozDirectory(NS_APP_USER_PROFILE_LOCAL_50_DIR) + _T("\\xul.mfl"); |
|
DeleteFile(toDelete); |
|
|
|
if (oldVersion < 0x02010001) { |
|
bool b = theApp.preferences.GetBool("kmeleon.download.useDownloadDir", FALSE); |
|
theApp.preferences.SetBool("browser.download.useDownloadDir", b); |
|
theApp.preferences.Clear("kmeleon.download.useDownloadDir"); |
|
CString s = theApp.preferences.GetString("kmeleon.download.dir", _T("")); |
|
theApp.preferences.SetString("browser.download.dir", s); |
|
theApp.preferences.Clear("kmeleon.download.dir"); |
|
s = theApp.preferences.GetString("kmeleon.download.lastDir", _T("")); |
|
theApp.preferences.SetString("browser.download.lastDir", s); |
|
theApp.preferences.Clear("kmeleon.download.lastDir"); |
|
} |
|
if (oldVersion < 0x02010005) { |
|
|
|
nsCOMPtr<nsIFile> mimeFile; |
|
NS_GetSpecialDirectory("UMimTyp", getter_AddRefs(mimeFile)); |
|
if (mimeFile) { |
|
nsCOMPtr<nsIRDFService> rdfSvc = do_GetService("@mozilla.org/rdf/rdf-service;1"); |
|
if (rdfSvc) { |
|
|
|
nsCOMPtr<nsIIOService> ios = do_GetService("@mozilla.org/network/io-service;1"); |
|
if (ios) { |
|
nsCOMPtr<nsIProtocolHandler> _fh; |
|
ios->GetProtocolHandler("file", getter_AddRefs(_fh)); |
|
nsCOMPtr<nsIFileProtocolHandler> fh = do_QueryInterface(_fh); |
|
if (fh) { |
|
nsCString uri; |
|
fh->GetURLSpecFromFile(mimeFile, uri); |
|
nsCOMPtr<nsIRDFDataSource> dataSource; |
|
rdfSvc->GetDataSourceBlocking(uri.get(), getter_AddRefs(dataSource)); |
|
if (dataSource) { |
|
|
|
nsCOMPtr<nsIRDFContainer> typeList = do_CreateInstance("@mozilla.org/rdf/container;1"); |
|
if (typeList) { |
|
nsCOMPtr<nsIRDFResource> resource; |
|
rdfSvc->GetResource(NS_LITERAL_CSTRING("urn:mimetypes:root"), getter_AddRefs(resource)); |
|
typeList->Init(dataSource, resource); |
|
|
|
rdfSvc->GetResource(NS_LITERAL_CSTRING("urn:mimetype:application/k-skin"), getter_AddRefs(resource)); |
|
int32_t index; |
|
typeList->IndexOf(resource, &index); |
|
if (index == -1) { |
|
|
|
typeList->AppendElement(resource); |
|
|
|
rdfSvc->GetResource(NS_LITERAL_CSTRING("urn:mimetype:application/k-skin"), getter_AddRefs(resource)); |
|
nsCOMPtr<nsIRDFResource> resource2; |
|
rdfSvc->GetResource(NS_LITERAL_CSTRING("NC:value"), getter_AddRefs(resource2)); |
|
nsCOMPtr<nsIRDFLiteral> _literal; |
|
rdfSvc->GetLiteral(L"application/k-skin", getter_AddRefs(_literal)); |
|
dataSource->Assert(resource, resource2, _literal, true); |
|
|
|
//rdfSvc->GetResource(NS_LITERAL_CSTRING("urn:mimetype:application/k-skin"), getter_AddRefs(resource)); |
|
rdfSvc->GetResource(NS_LITERAL_CSTRING("NC:fileExtensions"), getter_AddRefs(resource2)); |
|
rdfSvc->GetLiteral(L"kms", getter_AddRefs(_literal)); |
|
dataSource->Assert(resource, resource2, _literal, true); |
|
|
|
//rdfSvc->GetResource(NS_LITERAL_CSTRING("urn:mimetype:application/k-skin"), getter_AddRefs(resource)); |
|
rdfSvc->GetResource(NS_LITERAL_CSTRING("NC:description"), getter_AddRefs(resource2)); |
|
rdfSvc->GetLiteral(L"K-Meleon Skin", getter_AddRefs(_literal)); |
|
dataSource->Assert(resource, resource2, _literal, true); |
|
|
|
nsCOMPtr<nsIRDFRemoteDataSource> rds = do_QueryInterface(dataSource); |
|
if (rds) rds->Flush(); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
|
|
if (oldVersion < 0x01060002) |
|
if (theApp.preferences.GetBool(PREFERENCE_REBAR_BOTTOM, FALSE)) |
|
theApp.preferences.SetString(PREFERENCE_REBAR_POSITION, _T("bottom")); |
|
|
|
if (oldVersion < 0x01050025) { |
|
CString oldPref = theApp.preferences.GetString("kmeleon.general.homePage", _T("")); |
|
if (!oldPref.IsEmpty()) theApp.preferences.SetString("browser.startup.homepage", oldPref); |
|
} |
|
|
|
if (oldVersion < 0x01010001) { |
|
|
|
if (!theApp.preferences.skinsCurrent.IsEmpty() && |
|
theApp.preferences.skinsCurrent[theApp.preferences.skinsCurrent.GetLength() - 1] == '\\') |
|
{ |
|
theApp.preferences.skinsCurrent.GetBuffer(0); |
|
theApp.preferences.skinsCurrent.ReleaseBuffer(theApp.preferences.skinsCurrent.GetLength()-1); |
|
} |
|
|
|
CString accelFile = GetFolder(UserSettingsFolder) + _T("\\") ACCEL_CONFIG_FILE; |
|
CString menuFile = GetFolder(UserSettingsFolder) + _T("\\") MENU_CONFIG_FILE; |
|
CString macroFile = GetFolder(UserSettingsFolder) + _T("\\") _T("macros.cfg"); |
|
|
|
CFile file; |
|
if (file.Open(macroFile, CFile::modeRead, NULL)) { |
|
file.Close(); |
|
|
|
CString title,msg; |
|
title.LoadString(IDS_KMELEON_UPDATE); |
|
msg.LoadString(IDS_UPDATE_11); |
|
|
|
int choice = MessageBox(NULL, msg, title, MB_ICONQUESTION|MB_YESNO); |
|
|
|
if (choice == IDNO) { |
|
DeleteFile(menuFile); |
|
DeleteFile(accelFile); |
|
DeleteFile(macroFile); |
|
} |
|
else { |
|
CString backup = GetFolder(UserSettingsFolder) + _T("\\Backup\\"); |
|
BOOL backupSucceed = FALSE; |
|
CreateDirectory(backup, NULL); |
|
backupSucceed = MoveFile(menuFile, backup + MENU_CONFIG_FILE); |
|
backupSucceed &= MoveFile(accelFile, backup + ACCEL_CONFIG_FILE); |
|
backupSucceed &= MoveFile(macroFile, backup + _T("macros.cfg")); |
|
|
|
if (backupSucceed) |
|
AfxMessageBox(IDS_UPDATE11_SUCCESS, MB_ICONINFORMATION|MB_OK); |
|
else |
|
AfxMessageBox(IDS_UPDATE11_FAIL, MB_ICONEXCLAMATION|MB_OK); |
|
|
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
int CMfcEmbedApp::Run() |
|
{ |
|
if (m_pMainWnd == NULL && AfxOleGetUserCtrl()) |
|
{ |
|
// Not launched /Embedding or /Automation, but has no main window! |
|
TRACE(traceAppMsg, 0, "Warning: m_pMainWnd is NULL in CWinApp::Run - quitting application.\n"); |
|
AfxPostQuitMessage(0); |
|
} |
|
|
|
ASSERT_VALID(this); |
|
_AFX_THREAD_STATE* pState = AfxGetThreadState(); |
|
|
|
// for tracking the idle time state |
|
BOOL bIdle = TRUE; |
|
LONG lIdleCount = 0; |
|
|
|
// acquire and dispatch messages until a WM_QUIT message is received. |
|
for (;;) |
|
{ |
|
// phase1: check to see if we can do idle work |
|
while (bIdle && |
|
!::PeekMessage(&(pState->m_msgCur), NULL, NULL, NULL, PM_NOREMOVE)) |
|
{ |
|
// call OnIdle while in bIdle state |
|
if (!OnIdle(lIdleCount++)) |
|
bIdle = FALSE; // assume "no idle" state |
|
} |
|
|
|
// phase2: pump messages while available |
|
do |
|
{ |
|
while (::PeekMessage(&(pState->m_msgCur), NULL, NULL, WM_USER, PM_NOREMOVE)) |
|
{ |
|
if (!PumpMessage2(WM_USER)) |
|
return ExitInstance(); |
|
|
|
// reset "no idle" state after pumping "normal" message |
|
//if (IsIdleMessage(&m_msgCur)) |
|
if (IsIdleMessage(&(pState->m_msgCur))) |
|
{ |
|
bIdle = TRUE; |
|
lIdleCount = 0; |
|
} |
|
|
|
} |
|
// pump message, but quit on WM_QUIT |
|
if (!PumpMessage2()) |
|
return ExitInstance(); |
|
} while (::PeekMessage(&(pState->m_msgCur), NULL, NULL, NULL, PM_NOREMOVE)); |
|
|
|
} |
|
} |
|
|
|
BOOL CMfcEmbedApp::PumpMessage2(UINT filter) |
|
{ |
|
_AFX_THREAD_STATE *pState = AfxGetThreadState(); |
|
|
|
if (!::GetMessageW(&(pState->m_msgCur), NULL, NULL, filter)) |
|
{ |
|
#ifdef _DEBUG |
|
TRACE(traceAppMsg, 1, "CWinThread::PumpMessage - Received WM_QUIT.\n"); |
|
pState->m_nDisablePumpCount++; // application must die |
|
#endif |
|
// Note: prevents calling message loop things in 'ExitInstance' |
|
// will never be decremented |
|
return FALSE; |
|
} |
|
|
|
#ifdef _DEBUG |
|
if (pState->m_nDisablePumpCount != 0) |
|
{ |
|
TRACE(traceAppMsg, 0, "Error: CWinThread::PumpMessage called when not permitted.\n"); |
|
ASSERT(FALSE); |
|
} |
|
#endif |
|
|
|
// process this message |
|
|
|
if (pState->m_msgCur.message != WM_KICKIDLE && !AfxPreTranslateMessage(&(pState->m_msgCur))) |
|
{ |
|
::TranslateMessage(&(pState->m_msgCur)); |
|
::DispatchMessage(&(pState->m_msgCur)); |
|
} |
|
return TRUE; |
|
} |
|
|
|
void CMfcEmbedApp::OnAppRestart() |
|
{ |
|
((CMfcEmbedApp*)::AfxGetApp())->SetRestart(TRUE); |
|
PostQuitMessage(0); |
|
} |