mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
1480 lines
48 KiB
C++
1480 lines
48 KiB
C++
/* -*- 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):
|
|
* Doug Turner <dougt@netscape.com>
|
|
* Adam Lock <adamlock@netscape.com>
|
|
*
|
|
* ***** END LICENSE BLOCK ***** */
|
|
|
|
#include <stdio.h>
|
|
|
|
// OS/2 header files
|
|
#define INCL_WIN
|
|
#define INCL_DOS
|
|
#include <os2.h>
|
|
|
|
// Mozilla header files
|
|
#include "nsEmbedAPI.h"
|
|
#include "nsWeakReference.h"
|
|
#include "nsIClipboardCommands.h"
|
|
#include "nsXPIDLString.h"
|
|
#include "nsIWebBrowserPersist.h"
|
|
#include "nsIWebBrowserFocus.h"
|
|
#include "nsIWindowWatcher.h"
|
|
#include "nsIProfile.h"
|
|
#include "nsIObserverService.h"
|
|
#include "nsIObserver.h"
|
|
#include "nsIProfileChangeStatus.h"
|
|
#include "nsIURI.h"
|
|
#include "plstr.h"
|
|
#include "nsIInterfaceRequestor.h"
|
|
#include "nsCRT.h"
|
|
|
|
// Local header files
|
|
#include "os2Embed.h"
|
|
#include "WebBrowserChrome.h"
|
|
#include "WindowCreator.h"
|
|
#include "resource.h"
|
|
#include "nsStaticComponents.h"
|
|
|
|
// Printing header files
|
|
#include "nsIPrintSettings.h"
|
|
#include "nsIWebBrowserPrint.h"
|
|
|
|
#define MAX_LOADSTRING 100
|
|
|
|
|
|
#ifndef _BUILD_STATIC_BIN
|
|
nsStaticModuleInfo const *const kPStaticModules = nsnull;
|
|
PRUint32 const kStaticModuleCount = 0;
|
|
#endif
|
|
|
|
const CHAR *szWindowClass = "OS2EMBED";
|
|
|
|
// Foward declarations of functions included in this code module:
|
|
static void MyRegisterClass();
|
|
static MRESULT EXPENTRY BrowserWndProc(HWND, ULONG, MPARAM, MPARAM);
|
|
static MRESULT EXPENTRY BrowserDlgProc(HWND hwndDlg, ULONG uMsg, MPARAM wParam, MPARAM lParam);
|
|
|
|
static nsresult InitializeWindowCreator();
|
|
static nsresult OpenWebPage(const char * url);
|
|
static nsresult ResizeEmbedding(nsIWebBrowserChrome* chrome);
|
|
|
|
// Profile chooser stuff
|
|
static BOOL ChooseNewProfile(BOOL bShowForMultipleProfilesOnly, const char *szDefaultProfile);
|
|
static MRESULT EXPENTRY ChooseProfileDlgProc(HWND, ULONG, MPARAM, MPARAM);
|
|
|
|
// Global variables
|
|
static UINT gDialogCount = 0;
|
|
static BOOL gProfileSwitch = FALSE;
|
|
static HMODULE ghInstanceResources = NULL;
|
|
static char gFirstURL[1024];
|
|
|
|
// A list of URLs to populate the URL drop down list with
|
|
static const CHAR *gDefaultURLs[] =
|
|
{
|
|
("http://www.mozilla.org/"),
|
|
("http://www.netscape.com/"),
|
|
("http://browsertest.web.aol.com/tests/javascript/javascpt/index.htm"),
|
|
("http://127.0.0.1/"),
|
|
("http://www.yahoo.com/"),
|
|
("http://www.travelocity.com/"),
|
|
("http://www.disney.com/"),
|
|
("http://www.go.com/"),
|
|
("http://www.google.com/"),
|
|
("http://www.ebay.com/"),
|
|
("http://www.shockwave.com/"),
|
|
("http://www.slashdot.org/"),
|
|
("http://www.quicken.com/"),
|
|
("http://www.hotmail.com/"),
|
|
("http://www.cnn.com/"),
|
|
("http://www.javasoft.com/")
|
|
};
|
|
|
|
class ProfileChangeObserver : public nsIObserver,
|
|
public nsSupportsWeakReference
|
|
|
|
{
|
|
public:
|
|
ProfileChangeObserver();
|
|
|
|
NS_DECL_ISUPPORTS
|
|
NS_DECL_NSIOBSERVER
|
|
};
|
|
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
printf("You are embedded, man!\n\n");
|
|
|
|
// Sophisticated command-line parsing in action
|
|
char *szFirstURL = "http://www.mozilla.org/projects/embedding";
|
|
char *szDefaultProfile = nsnull;
|
|
int argn;
|
|
for (argn = 1; argn < argc; argn++)
|
|
{
|
|
if (stricmp("-P", argv[argn]) == 0)
|
|
{
|
|
if (argn + 1 < argc)
|
|
{
|
|
szDefaultProfile = argv[++argn];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
szFirstURL = argv[argn];
|
|
}
|
|
}
|
|
strncpy(gFirstURL, szFirstURL, sizeof(gFirstURL) - 1);
|
|
|
|
// Initialize global strings
|
|
CHAR szTitle[MAX_LOADSTRING];
|
|
WinLoadString((HAB)0, ghInstanceResources, IDS_APP_TITLE, MAX_LOADSTRING, szTitle);
|
|
MyRegisterClass();
|
|
|
|
// Init Embedding APIs
|
|
NS_InitEmbedding(nsnull, nsnull, kPStaticModules, kStaticModuleCount);
|
|
|
|
// Choose the new profile
|
|
if (!ChooseNewProfile(TRUE, szDefaultProfile))
|
|
{
|
|
NS_TermEmbedding();
|
|
return 1;
|
|
}
|
|
MPARAM rv;
|
|
{
|
|
// Now register an observer to watch for profile changes
|
|
nsCOMPtr<nsIObserverService> observerService(do_GetService("@mozilla.org/observer-service;1"));
|
|
|
|
ProfileChangeObserver *observer = new ProfileChangeObserver;
|
|
observer->AddRef();
|
|
observerService->AddObserver(static_cast<nsIObserver *>(observer), "profile-approve-change", PR_TRUE);
|
|
observerService->AddObserver(static_cast<nsIObserver *>(observer), "profile-change-teardown", PR_TRUE);
|
|
observerService->AddObserver(static_cast<nsIObserver *>(observer), "profile-after-change", PR_TRUE);
|
|
|
|
InitializeWindowCreator();
|
|
|
|
// Open the initial browser window
|
|
OpenWebPage(gFirstURL);
|
|
|
|
// Main message loop.
|
|
// NOTE: We use a fake event and a timeout in order to process idle stuff for
|
|
// Mozilla every 1/10th of a second.
|
|
PRBool runCondition = PR_TRUE;
|
|
|
|
rv = (MPARAM)RunEventLoop(runCondition);
|
|
|
|
observer->Release();
|
|
}
|
|
// Close down Embedding APIs
|
|
NS_TermEmbedding();
|
|
|
|
return (int)rv;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// ProfileChangeObserver
|
|
//-----------------------------------------------------------------------------
|
|
|
|
NS_IMPL_THREADSAFE_ISUPPORTS2(ProfileChangeObserver, nsIObserver, nsISupportsWeakReference)
|
|
|
|
ProfileChangeObserver::ProfileChangeObserver()
|
|
{
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// CMfcEmbedApp : nsIObserver
|
|
// ---------------------------------------------------------------------------
|
|
|
|
NS_IMETHODIMP ProfileChangeObserver::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *someData)
|
|
{
|
|
nsresult rv = NS_OK;
|
|
|
|
if (nsCRT::strcmp(aTopic, "profile-approve-change") == 0)
|
|
{
|
|
// The profile is about to change!
|
|
|
|
// Ask the user if they want to
|
|
int result = ::WinMessageBox(HWND_DESKTOP, NULL, "Do you want to close all windows in order to switch the profile?", "Confirm", 101, MB_YESNO | MB_ICONQUESTION);
|
|
if (result != MBID_YES)
|
|
{
|
|
nsCOMPtr<nsIProfileChangeStatus> status = do_QueryInterface(aSubject);
|
|
NS_ENSURE_TRUE(status, NS_ERROR_FAILURE);
|
|
status->VetoChange();
|
|
}
|
|
}
|
|
else if (nsCRT::strcmp(aTopic, "profile-change-teardown") == 0)
|
|
{
|
|
// The profile is changing!
|
|
|
|
// Prevent WM_QUIT by incrementing the dialog count
|
|
gDialogCount++;
|
|
}
|
|
else if (nsCRT::strcmp(aTopic, "profile-after-change") == 0)
|
|
{
|
|
// Decrease the dialog count so WM_QUIT can once more happen
|
|
gDialogCount--;
|
|
if (gDialogCount == 0)
|
|
{
|
|
// All the dialogs have been torn down so open new page
|
|
OpenWebPage(gFirstURL);
|
|
}
|
|
else
|
|
{
|
|
// The profile has changed, but dialogs are still being
|
|
// torn down. Set this flag so when the last one goes
|
|
// it can finish the switch.
|
|
gProfileSwitch = TRUE;
|
|
}
|
|
}
|
|
|
|
return rv;
|
|
}
|
|
|
|
/* InitializeWindowCreator creates and hands off an object with a callback
|
|
to a window creation function. This is how all new windows are opened,
|
|
except any created directly by the embedding app. */
|
|
nsresult InitializeWindowCreator()
|
|
{
|
|
// create an nsWindowCreator and give it to the WindowWatcher service
|
|
WindowCreator *creatorCallback = new WindowCreator();
|
|
if (creatorCallback)
|
|
{
|
|
nsCOMPtr<nsIWindowCreator> windowCreator(static_cast<nsIWindowCreator *>(creatorCallback));
|
|
if (windowCreator)
|
|
{
|
|
nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
|
|
if (wwatch)
|
|
{
|
|
wwatch->SetWindowCreator(windowCreator);
|
|
return NS_OK;
|
|
}
|
|
}
|
|
}
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
//
|
|
// FUNCTION: OpenWebPage()
|
|
//
|
|
// PURPOSE: Opens a new browser dialog and starts it loading to the
|
|
// specified url.
|
|
//
|
|
nsresult OpenWebPage(const char *url)
|
|
{
|
|
nsresult rv;
|
|
|
|
// Create the chrome object. Note that it leaves this function
|
|
// with an extra reference so that it can released correctly during
|
|
// destruction (via Win32UI::Destroy)
|
|
|
|
nsCOMPtr<nsIWebBrowserChrome> chrome;
|
|
rv = CreateBrowserWindow(nsIWebBrowserChrome::CHROME_ALL,
|
|
nsnull, getter_AddRefs(chrome));
|
|
if (NS_SUCCEEDED(rv))
|
|
{
|
|
// Start loading a page
|
|
nsCOMPtr<nsIWebBrowser> newBrowser;
|
|
chrome->GetWebBrowser(getter_AddRefs(newBrowser));
|
|
nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(newBrowser));
|
|
return webNav->LoadURI(NS_ConvertASCIItoUTF16(url).get(),
|
|
nsIWebNavigation::LOAD_FLAGS_NONE,
|
|
nsnull,
|
|
nsnull,
|
|
nsnull);
|
|
}
|
|
|
|
return rv;
|
|
}
|
|
|
|
//
|
|
// FUNCTION: GetBrowserFromChrome()
|
|
//
|
|
// PURPOSE: Returns the HWND for the webbrowser container associated
|
|
// with the specified chrome.
|
|
//
|
|
HWND GetBrowserFromChrome(nsIWebBrowserChrome *aChrome)
|
|
{
|
|
if (!aChrome)
|
|
{
|
|
return NULL;
|
|
}
|
|
nsCOMPtr<nsIEmbeddingSiteWindow> baseWindow = do_QueryInterface(aChrome);
|
|
HWND hwnd = NULL;
|
|
baseWindow->GetSiteWindow((void **) & hwnd);
|
|
return hwnd;
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: GetBrowserDlgFromChrome()
|
|
//
|
|
// PURPOSE: Returns the HWND for the browser dialog associated with
|
|
// the specified chrome.
|
|
//
|
|
HWND GetBrowserDlgFromChrome(nsIWebBrowserChrome *aChrome)
|
|
{
|
|
return WinQueryWindow(GetBrowserFromChrome(aChrome), QW_PARENT);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: SaveWebPage()
|
|
//
|
|
// PURPOSE: Saves the contents of the web page to a file
|
|
//
|
|
void SaveWebPage(HWND hDlg, nsIWebBrowser *aWebBrowser)
|
|
{
|
|
// Use the browser window title as the initial file name
|
|
nsCOMPtr<nsIBaseWindow> webBrowserAsWin = do_QueryInterface(aWebBrowser);
|
|
nsXPIDLString windowTitle;
|
|
webBrowserAsWin->GetTitle(getter_Copies(windowTitle));
|
|
nsCString fileName; fileName.AssignWithConversion(windowTitle);
|
|
|
|
// Sanitize the title of all illegal characters
|
|
fileName.CompressWhitespace(); // Remove whitespace from the ends
|
|
fileName.StripChars("\\*|:\"><?"); // Strip illegal characters
|
|
fileName.ReplaceChar('.', L'_'); // Dots become underscores
|
|
fileName.ReplaceChar('/', L'-'); // Forward slashes become hyphens
|
|
fileName.ReplaceChar(' ', L'_'); // Spaces become underscores
|
|
|
|
// Initialize the file save as information structure
|
|
FILEDLG saveFileNameInfo;
|
|
memset(&saveFileNameInfo, 0, sizeof(saveFileNameInfo));
|
|
saveFileNameInfo.cbSize = sizeof(saveFileNameInfo);
|
|
PL_strncpyz(saveFileNameInfo.szFullFile, fileName.get(), CCHMAXPATH);
|
|
strcat(saveFileNameInfo.szFullFile, ".html");
|
|
|
|
PSZ *apszTypeList = (PSZ *)malloc(3 * sizeof(PSZ) + 1);
|
|
apszTypeList[0] = "Web Page, HTML Only (*.htm;*.html)";
|
|
apszTypeList[1] = "Web Page, Complete (*.htm;*.html)";
|
|
apszTypeList[2] = "Text File (*.txt)";
|
|
apszTypeList[3] = 0;
|
|
saveFileNameInfo.papszITypeList = (PAPSZ)apszTypeList;
|
|
saveFileNameInfo.pszTitle = NULL;
|
|
saveFileNameInfo.fl = FDS_SAVEAS_DIALOG | FDS_CENTER | FDS_ENABLEFILELB;
|
|
saveFileNameInfo.pszIType = apszTypeList[0];
|
|
|
|
WinFileDlg(HWND_DESKTOP, hDlg, &saveFileNameInfo);
|
|
if (saveFileNameInfo.lReturn == DID_OK)
|
|
{
|
|
char *pszDataPath = NULL;
|
|
static char szDataFile[_MAX_PATH];
|
|
char szDataPath[_MAX_PATH];
|
|
char drive[_MAX_DRIVE];
|
|
char dir[_MAX_DIR];
|
|
char fname[_MAX_FNAME];
|
|
char ext[_MAX_EXT];
|
|
|
|
_splitpath(saveFileNameInfo.szFullFile, drive, dir, fname, ext);
|
|
//add the extension to the filename if there is no extension already
|
|
if (strcmp(ext, "") == 0) {
|
|
if ((saveFileNameInfo.sEAType == 2) && (stricmp(ext, ".txt") != 0)) {
|
|
strcat(saveFileNameInfo.szFullFile, ".txt");
|
|
strcpy(ext, ".txt");
|
|
} else
|
|
if ((stricmp(ext, ".html") != 0) && (stricmp(ext, ".htm") != 0)) {
|
|
strcat(saveFileNameInfo.szFullFile, ".html");
|
|
strcpy(ext, ".html");
|
|
}
|
|
}
|
|
|
|
// Does the user want to save the complete document including
|
|
// all frames, images, scripts, stylesheets etc. ?
|
|
if (saveFileNameInfo.sEAType == 1) //apszTypeList[1] means save everything
|
|
{
|
|
sprintf(szDataFile, "%s_files", fname);
|
|
_makepath(szDataPath, drive, dir, szDataFile, "");
|
|
|
|
pszDataPath = szDataPath;
|
|
}
|
|
|
|
// Save away
|
|
nsCOMPtr<nsIWebBrowserPersist> persist(do_QueryInterface(aWebBrowser));
|
|
|
|
nsCOMPtr<nsILocalFile> file;
|
|
NS_NewNativeLocalFile(nsDependentCString(saveFileNameInfo.szFullFile), TRUE, getter_AddRefs(file));
|
|
|
|
nsCOMPtr<nsILocalFile> dataPath;
|
|
if (pszDataPath)
|
|
{
|
|
NS_NewNativeLocalFile(nsDependentCString(pszDataPath), TRUE, getter_AddRefs(dataPath));
|
|
}
|
|
|
|
persist->SaveDocument(nsnull, file, dataPath, nsnull, 0, 0);
|
|
}
|
|
if (saveFileNameInfo.papszFQFilename)
|
|
WinFreeFileDlgList(saveFileNameInfo.papszFQFilename);
|
|
for (int i = 0; i < 3; i++)
|
|
free(saveFileNameInfo.papszITypeList[i]);
|
|
free(saveFileNameInfo.papszITypeList);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: ResizeEmbedding()
|
|
//
|
|
// PURPOSE: Resizes the webbrowser window to fit its container.
|
|
//
|
|
nsresult ResizeEmbedding(nsIWebBrowserChrome* chrome)
|
|
{
|
|
if (!chrome)
|
|
return NS_ERROR_FAILURE;
|
|
|
|
nsCOMPtr<nsIEmbeddingSiteWindow> embeddingSite = do_QueryInterface(chrome);
|
|
HWND hWnd;
|
|
embeddingSite->GetSiteWindow((void **) & hWnd);
|
|
|
|
if (!hWnd)
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
RECTL rect;
|
|
WinQueryWindowRect(hWnd, &rect);
|
|
|
|
// Make sure the browser is visible and sized
|
|
nsCOMPtr<nsIWebBrowser> webBrowser;
|
|
chrome->GetWebBrowser(getter_AddRefs(webBrowser));
|
|
nsCOMPtr<nsIBaseWindow> webBrowserAsWin = do_QueryInterface(webBrowser);
|
|
if (webBrowserAsWin)
|
|
{
|
|
webBrowserAsWin->SetPositionAndSize(rect.xLeft,
|
|
rect.yBottom,
|
|
rect.xRight - rect.xLeft,
|
|
rect.yTop - rect.yBottom,
|
|
PR_TRUE);
|
|
webBrowserAsWin->SetVisibility(PR_TRUE);
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: MyRegisterClass()
|
|
//
|
|
// PURPOSE: Registers the window class.
|
|
//
|
|
// COMMENTS:
|
|
//
|
|
//
|
|
void MyRegisterClass()
|
|
{
|
|
WinRegisterClass((HAB)0, szWindowClass, BrowserWndProc, CS_SIZEREDRAW, sizeof(ULONG));
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: UpdateUI()
|
|
//
|
|
// PURPOSE: Refreshes the buttons and menu items in the browser dialog
|
|
//
|
|
void UpdateUI(nsIWebBrowserChrome *aChrome)
|
|
{
|
|
HWND hwndDlg = GetBrowserDlgFromChrome(aChrome);
|
|
nsCOMPtr<nsIWebBrowser> webBrowser;
|
|
nsCOMPtr<nsIWebNavigation> webNavigation;
|
|
aChrome->GetWebBrowser(getter_AddRefs(webBrowser));
|
|
webNavigation = do_QueryInterface(webBrowser);
|
|
|
|
PRBool canGoBack = PR_FALSE;
|
|
PRBool canGoForward = PR_FALSE;
|
|
if (webNavigation)
|
|
{
|
|
webNavigation->GetCanGoBack(&canGoBack);
|
|
webNavigation->GetCanGoForward(&canGoForward);
|
|
}
|
|
|
|
PRBool canCutSelection = PR_FALSE;
|
|
PRBool canCopySelection = PR_FALSE;
|
|
PRBool canPaste = PR_FALSE;
|
|
|
|
nsCOMPtr<nsIClipboardCommands> clipCmds = do_GetInterface(webBrowser);
|
|
if (clipCmds)
|
|
{
|
|
clipCmds->CanCutSelection(&canCutSelection);
|
|
clipCmds->CanCopySelection(&canCopySelection);
|
|
clipCmds->CanPaste(&canPaste);
|
|
}
|
|
|
|
HWND hmenu = WinWindowFromID(hwndDlg, FID_MENU);
|
|
if (hmenu)
|
|
{
|
|
MENUITEM goMenu, editMenu;
|
|
WinSendMsg(hmenu, MM_QUERYITEM, MPFROM2SHORT(MOZ_Go, TRUE), (MPARAM)&goMenu);
|
|
WinEnableMenuItem(goMenu.hwndSubMenu, MOZ_GoBack, canGoBack);
|
|
WinEnableMenuItem(goMenu.hwndSubMenu, MOZ_GoForward, canGoForward);
|
|
|
|
WinSendMsg(hmenu, MM_QUERYITEM, MPFROM2SHORT(MOZ_Edit, TRUE), (MPARAM)&editMenu);
|
|
WinEnableMenuItem(editMenu.hwndSubMenu, MOZ_Cut, canCutSelection);
|
|
WinEnableMenuItem(editMenu.hwndSubMenu, MOZ_Copy, canCopySelection);
|
|
WinEnableMenuItem(editMenu.hwndSubMenu, MOZ_Paste, canPaste);
|
|
}
|
|
|
|
HWND button;
|
|
button = WinWindowFromID(hwndDlg, IDC_BACK);
|
|
if (button)
|
|
WinEnableWindow(button, canGoBack);
|
|
button = WinWindowFromID(hwndDlg, IDC_FORWARD);
|
|
if (button)
|
|
WinEnableWindow(button, canGoForward);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: BrowserDlgProc()
|
|
//
|
|
// PURPOSE: Browser dialog windows message handler.
|
|
//
|
|
// COMMENTS:
|
|
//
|
|
// The code for handling buttons and menu actions is here.
|
|
//
|
|
MRESULT EXPENTRY BrowserDlgProc(HWND hwndDlg, ULONG uMsg, MPARAM wParam, MPARAM lParam)
|
|
{
|
|
if (uMsg == WM_COMMAND && SHORT1FROMMP(wParam) == MOZ_SwitchProfile)
|
|
{
|
|
ChooseNewProfile(FALSE, NULL);
|
|
return (MRESULT)FALSE;
|
|
}
|
|
|
|
// Get the browser and other pointers since they are used a lot below
|
|
HWND hwndBrowser = WinWindowFromID(hwndDlg, IDC_BROWSER);
|
|
nsIWebBrowserChrome *chrome = nsnull ;
|
|
if (hwndBrowser)
|
|
{
|
|
chrome = (nsIWebBrowserChrome *) WinQueryWindowULong(hwndBrowser, QWL_USER);
|
|
}
|
|
nsCOMPtr<nsIWebBrowser> webBrowser;
|
|
nsCOMPtr<nsIWebNavigation> webNavigation;
|
|
nsCOMPtr<nsIWebBrowserPrint> webBrowserPrint;
|
|
if (chrome)
|
|
{
|
|
chrome->GetWebBrowser(getter_AddRefs(webBrowser));
|
|
webNavigation = do_QueryInterface(webBrowser);
|
|
webBrowserPrint = do_GetInterface(webBrowser);
|
|
}
|
|
|
|
// Test the message
|
|
switch (uMsg)
|
|
{
|
|
case WM_INITDLG:
|
|
return (MRESULT)TRUE;
|
|
|
|
case WM_INITMENU:
|
|
UpdateUI(chrome);
|
|
return (MRESULT)TRUE;
|
|
|
|
case WM_SYSCOMMAND:
|
|
if (SHORT1FROMMP(wParam) == SC_CLOSE)
|
|
{
|
|
WebBrowserChromeUI::Destroy(chrome);
|
|
return (MRESULT)TRUE;
|
|
}
|
|
break;
|
|
|
|
case WM_DESTROY:
|
|
return (MRESULT)TRUE;
|
|
|
|
case WM_COMMAND:
|
|
if (!webBrowser)
|
|
{
|
|
return (MRESULT)TRUE;
|
|
}
|
|
|
|
// Test which command was selected
|
|
switch (SHORT1FROMMP(wParam))
|
|
{
|
|
case IDC_ADDRESS:
|
|
if (SHORT1FROMMP(wParam) == CBN_EFCHANGE || SHORT1FROMMP(wParam) == CBN_LBSELECT)
|
|
{
|
|
// User has changed the address field so enable the Go button
|
|
WinEnableWindow(WinWindowFromID(hwndDlg, IDC_GO), TRUE);
|
|
}
|
|
break;
|
|
|
|
case IDC_GO:
|
|
{
|
|
char szURL[2048];
|
|
memset(szURL, 0, sizeof(szURL));
|
|
WinQueryDlgItemText(hwndDlg, IDC_ADDRESS, sizeof(szURL) / sizeof(szURL[0]) - 1, szURL);
|
|
webNavigation->LoadURI(
|
|
NS_ConvertASCIItoUTF16(szURL).get(),
|
|
nsIWebNavigation::LOAD_FLAGS_NONE,
|
|
nsnull,
|
|
nsnull,
|
|
nsnull);
|
|
}
|
|
break;
|
|
|
|
case IDC_STOP:
|
|
webNavigation->Stop(nsIWebNavigation::STOP_ALL);
|
|
UpdateUI(chrome);
|
|
break;
|
|
|
|
case IDC_RELOAD:
|
|
webNavigation->Reload(nsIWebNavigation::LOAD_FLAGS_NONE);
|
|
break;
|
|
|
|
case IDM_EXIT:
|
|
WinPostMsg(hwndDlg, WM_SYSCOMMAND, MPFROMSHORT(SC_CLOSE), 0);
|
|
break;
|
|
|
|
// File menu commands
|
|
|
|
case MOZ_NewBrowser:
|
|
OpenWebPage(gFirstURL);
|
|
break;
|
|
|
|
case MOZ_Save:
|
|
SaveWebPage(hwndDlg, webBrowser);
|
|
break;
|
|
|
|
case MOZ_Print:
|
|
{
|
|
// NOTE: Embedding code shouldn't need to get the docshell or
|
|
// contentviewer AT ALL. This code below will break one
|
|
// day but will have to do until the embedding API has
|
|
// a cleaner way to do the same thing.
|
|
if (webBrowserPrint)
|
|
{
|
|
nsCOMPtr<nsIPrintSettings> printSettings;
|
|
webBrowserPrint->GetGlobalPrintSettings(getter_AddRefs(printSettings));
|
|
NS_ASSERTION(printSettings, "You can't PrintPreview without a PrintSettings!");
|
|
if (printSettings)
|
|
{
|
|
printSettings->SetPrintSilent(PR_TRUE);
|
|
webBrowserPrint->Print(printSettings, (nsIWebProgressListener*)nsnull);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
// Edit menu commands
|
|
|
|
case MOZ_Cut:
|
|
{
|
|
nsCOMPtr<nsIClipboardCommands> clipCmds = do_GetInterface(webBrowser);
|
|
clipCmds->CutSelection();
|
|
}
|
|
break;
|
|
|
|
case MOZ_Copy:
|
|
{
|
|
nsCOMPtr<nsIClipboardCommands> clipCmds = do_GetInterface(webBrowser);
|
|
clipCmds->CopySelection();
|
|
}
|
|
break;
|
|
|
|
case MOZ_Paste:
|
|
{
|
|
nsCOMPtr<nsIClipboardCommands> clipCmds = do_GetInterface(webBrowser);
|
|
clipCmds->Paste();
|
|
}
|
|
break;
|
|
|
|
case MOZ_SelectAll:
|
|
{
|
|
nsCOMPtr<nsIClipboardCommands> clipCmds = do_GetInterface(webBrowser);
|
|
clipCmds->SelectAll();
|
|
}
|
|
break;
|
|
|
|
case MOZ_SelectNone:
|
|
{
|
|
nsCOMPtr<nsIClipboardCommands> clipCmds = do_GetInterface(webBrowser);
|
|
clipCmds->SelectNone();
|
|
}
|
|
break;
|
|
|
|
// Go menu commands
|
|
case IDC_BACK:
|
|
case MOZ_GoBack:
|
|
webNavigation->GoBack();
|
|
UpdateUI(chrome);
|
|
break;
|
|
|
|
case IDC_FORWARD:
|
|
case MOZ_GoForward:
|
|
webNavigation->GoForward();
|
|
UpdateUI(chrome);
|
|
break;
|
|
|
|
// Help menu commands
|
|
case MOZ_About:
|
|
{
|
|
char szAboutTitle[MAX_LOADSTRING];
|
|
char szAbout[MAX_LOADSTRING];
|
|
WinLoadString((HAB)0, ghInstanceResources, IDS_ABOUT_TITLE, MAX_LOADSTRING, szAboutTitle);
|
|
WinLoadString((HAB)0, ghInstanceResources, IDS_ABOUT, MAX_LOADSTRING, szAbout);
|
|
WinMessageBox(HWND_DESKTOP, NULL, szAbout, szAboutTitle, 0, MB_OK | MB_APPLMODAL);
|
|
}
|
|
break;
|
|
}
|
|
|
|
return (MRESULT)TRUE;
|
|
|
|
case WM_ACTIVATE:
|
|
{
|
|
nsCOMPtr<nsIWebBrowserFocus> focus(do_GetInterface(webBrowser));
|
|
if(focus)
|
|
{
|
|
switch (SHORT1FROMMP(wParam))
|
|
{
|
|
case TRUE: //WA_ACTIVE:
|
|
focus->Activate();
|
|
break;
|
|
case FALSE: //WA_INACTIVE:
|
|
focus->Deactivate();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WM_ADJUSTWINDOWPOS:
|
|
{
|
|
PSWP swp = (PSWP)wParam;
|
|
if (swp->fl & (SWP_SIZE)) {
|
|
UINT newDlgWidth = swp->cx;
|
|
UINT newDlgHeight = swp->cy;
|
|
|
|
// TODO Reposition the control bar - for the moment it's fixed size
|
|
// Reposition all buttons, combobox, status, progress bar, and browser
|
|
// Status bar gets any space that the fixed size progress bar doesn't use.
|
|
// Address combobox gets any space not used by buttons and 'Address:'
|
|
int progressWidth, statusWidth, addressWidth, goWidth, forwardWidth, reloadWidth, stopWidth, backWidth, staticWidth;
|
|
int statusHeight, backHeight, buttonHeight, addressHeight, comboboxHeight;
|
|
|
|
HWND hwndStatus = WinWindowFromID(hwndDlg, IDC_STATUS);
|
|
if (hwndStatus) {
|
|
RECTL rcStatus;
|
|
WinQueryWindowRect(hwndStatus, &rcStatus);
|
|
statusHeight = rcStatus.yTop - rcStatus.yBottom;
|
|
} else
|
|
statusHeight = 0;
|
|
|
|
HWND hwndProgress = WinWindowFromID(hwndDlg, IDC_PROGRESS);
|
|
if (hwndProgress) {
|
|
RECTL rcProgress;
|
|
WinQueryWindowRect(hwndProgress, &rcProgress);
|
|
progressWidth = rcProgress.xRight - rcProgress.xLeft;
|
|
} else
|
|
progressWidth = 0;
|
|
statusWidth = newDlgWidth - progressWidth;
|
|
|
|
HWND hwndBack = WinWindowFromID(hwndDlg, IDC_BACK);
|
|
if (hwndBack) {
|
|
RECTL rcBack;
|
|
WinQueryWindowRect(hwndBack, &rcBack);
|
|
backHeight = rcBack.yTop - rcBack.yBottom;
|
|
backWidth = rcBack.xRight - rcBack.xLeft;
|
|
} else {
|
|
backHeight = 0;
|
|
backWidth = 0;
|
|
}
|
|
buttonHeight = newDlgHeight - backHeight - 50;//24;
|
|
|
|
HWND hwndForward = WinWindowFromID(hwndDlg, IDC_FORWARD);
|
|
if (hwndForward) {
|
|
RECTL rcForward;
|
|
WinQueryWindowRect(hwndForward, &rcForward);
|
|
forwardWidth = rcForward.xRight - rcForward.xLeft;
|
|
} else
|
|
forwardWidth = 0;
|
|
|
|
HWND hwndReload = WinWindowFromID(hwndDlg, IDC_RELOAD);
|
|
if (hwndReload) {
|
|
RECTL rcReload;
|
|
WinQueryWindowRect(hwndReload, &rcReload);
|
|
reloadWidth = rcReload.xRight - rcReload.xLeft;
|
|
} else
|
|
reloadWidth = 0;
|
|
|
|
HWND hwndStop = WinWindowFromID(hwndDlg, IDC_STOP);
|
|
if (hwndStop) {
|
|
RECTL rcStop;
|
|
WinQueryWindowRect(hwndStop, &rcStop);
|
|
stopWidth = rcStop.xRight - rcStop.xLeft;
|
|
} else
|
|
stopWidth = 0;
|
|
|
|
HWND hwndStatic = WinWindowFromID(hwndDlg, IDC_ADDRESSLABEL);
|
|
if (hwndStatic) {
|
|
RECTL rcStatic;
|
|
WinQueryWindowRect(hwndStatic, &rcStatic);
|
|
staticWidth = rcStatic.xRight - rcStatic.xLeft;
|
|
} else
|
|
staticWidth = 0;
|
|
|
|
HWND hwndGo = WinWindowFromID(hwndDlg, IDC_GO);
|
|
if (hwndGo) {
|
|
RECTL rcGo;
|
|
WinQueryWindowRect(hwndGo, &rcGo);
|
|
goWidth = rcGo.xRight - rcGo.xLeft;
|
|
} else
|
|
goWidth = 0;
|
|
|
|
HWND hwndAddress = WinWindowFromID(hwndDlg, IDC_ADDRESS);
|
|
if (hwndAddress) {
|
|
RECTL rcAddress;
|
|
WinQueryWindowRect(hwndAddress, &rcAddress);
|
|
addressHeight = rcAddress.yTop - rcAddress.yBottom;
|
|
comboboxHeight = buttonHeight + backHeight - addressHeight;
|
|
} else {
|
|
addressHeight = 0;
|
|
comboboxHeight = 0;
|
|
}
|
|
addressWidth = newDlgWidth - goWidth - backWidth - forwardWidth - reloadWidth - stopWidth - staticWidth - 15;
|
|
|
|
if (hwndStatus)
|
|
WinSetWindowPos(hwndStatus,
|
|
HWND_TOP,
|
|
0, 0,
|
|
statusWidth,
|
|
statusHeight,
|
|
SWP_MOVE | SWP_SIZE | SWP_SHOW);
|
|
if (hwndProgress)
|
|
WinSetWindowPos(hwndProgress,
|
|
HWND_TOP,
|
|
statusWidth, 0,
|
|
0, 0,
|
|
SWP_MOVE | SWP_SHOW);
|
|
if (hwndBack)
|
|
WinSetWindowPos(hwndBack,
|
|
HWND_TOP,
|
|
2, buttonHeight,
|
|
0, 0,
|
|
SWP_MOVE | SWP_SHOW);
|
|
if (hwndForward)
|
|
WinSetWindowPos(hwndForward,
|
|
HWND_TOP,
|
|
2 + backWidth, buttonHeight,
|
|
0, 0,
|
|
SWP_MOVE | SWP_SHOW);
|
|
if (hwndReload)
|
|
WinSetWindowPos(hwndReload,
|
|
HWND_TOP,
|
|
4 + backWidth + forwardWidth, buttonHeight,
|
|
0, 0,
|
|
SWP_MOVE | SWP_SHOW);
|
|
if (hwndStop)
|
|
WinSetWindowPos(hwndStop,
|
|
HWND_TOP,
|
|
5 + backWidth + forwardWidth + reloadWidth, buttonHeight,
|
|
0, 0,
|
|
SWP_MOVE | SWP_SHOW);
|
|
if (hwndStatic)
|
|
WinSetWindowPos(hwndStatic,
|
|
HWND_TOP,
|
|
9 + backWidth + forwardWidth + reloadWidth + stopWidth, buttonHeight + 3,
|
|
0, 0,
|
|
SWP_MOVE | SWP_SHOW);
|
|
if (hwndAddress)
|
|
WinSetWindowPos(hwndAddress,
|
|
HWND_TOP,
|
|
12 + backWidth + forwardWidth + reloadWidth + stopWidth + staticWidth, comboboxHeight,
|
|
addressWidth, addressHeight,
|
|
SWP_MOVE | SWP_SIZE | SWP_SHOW);
|
|
if (hwndGo)
|
|
WinSetWindowPos(hwndGo,
|
|
HWND_TOP,
|
|
13 + backWidth + forwardWidth + reloadWidth + stopWidth + staticWidth + addressWidth, buttonHeight,
|
|
0, 0,
|
|
SWP_MOVE | SWP_SHOW);
|
|
|
|
// Resize the browser area (assuming the browser is
|
|
// sandwiched between the control bar and status area)
|
|
WinSetWindowPos(hwndBrowser,
|
|
HWND_TOP,
|
|
2, statusHeight,
|
|
newDlgWidth - 4,
|
|
newDlgHeight - backHeight - statusHeight - 52,
|
|
SWP_MOVE | SWP_SIZE | SWP_SHOW);
|
|
}
|
|
}
|
|
return (MRESULT)TRUE;
|
|
}
|
|
return WinDefDlgProc(hwndDlg, uMsg, wParam, lParam);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: BrowserWndProc(HWND, unsigned, WORD, LONG)
|
|
//
|
|
// PURPOSE: Processes messages for the browser container window.
|
|
//
|
|
MRESULT EXPENTRY BrowserWndProc(HWND hWnd, ULONG message, MPARAM wParam, MPARAM lParam)
|
|
{
|
|
nsIWebBrowserChrome *chrome = (nsIWebBrowserChrome *) WinQueryWindowULong(hWnd, QWL_USER);
|
|
switch (message)
|
|
{
|
|
case WM_SIZE:
|
|
// Resize the embedded browser
|
|
ResizeEmbedding(chrome);
|
|
return (MRESULT)0;
|
|
case WM_ERASEBACKGROUND:
|
|
// Reduce flicker by not painting the non-visible background
|
|
return (MRESULT)1;
|
|
}
|
|
return WinDefWindowProc(hWnd, message, wParam, lParam);
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// Profile chooser dialog
|
|
|
|
|
|
//
|
|
// FUNCTION: ChooseNewProfile()
|
|
//
|
|
// PURPOSE: Allows the user to select a new profile from a list.
|
|
// The bShowForMultipleProfilesOnly argument specifies whether the
|
|
// function should automatically select the first profile and return
|
|
// without displaying a dialog box if there is only one profile to
|
|
// select.
|
|
//
|
|
BOOL ChooseNewProfile(BOOL bShowForMultipleProfilesOnly, const char *szDefaultProfile)
|
|
{
|
|
nsresult rv;
|
|
nsCOMPtr<nsIProfile> profileService =
|
|
do_GetService(NS_PROFILE_CONTRACTID, &rv);
|
|
if (NS_FAILED(rv))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if (szDefaultProfile)
|
|
{
|
|
// Make a new default profile
|
|
nsAutoString newProfileName; newProfileName.AssignWithConversion(szDefaultProfile);
|
|
rv = profileService->CreateNewProfile(newProfileName.get(), nsnull, nsnull, PR_FALSE);
|
|
if (NS_FAILED(rv)) return FALSE;
|
|
rv = profileService->SetCurrentProfile(newProfileName.get());
|
|
if (NS_FAILED(rv)) return FALSE;
|
|
return TRUE;
|
|
}
|
|
|
|
PRInt32 profileCount = 0;
|
|
rv = profileService->GetProfileCount(&profileCount);
|
|
if (profileCount == 0)
|
|
{
|
|
// Make a new default profile
|
|
NS_NAMED_LITERAL_STRING(newProfileName, "os2Embed");
|
|
rv = profileService->CreateNewProfile(newProfileName.get(), nsnull, nsnull, PR_FALSE);
|
|
if (NS_FAILED(rv)) return FALSE;
|
|
rv = profileService->SetCurrentProfile(newProfileName.get());
|
|
if (NS_FAILED(rv)) return FALSE;
|
|
return TRUE;
|
|
}
|
|
else if (profileCount == 1 && bShowForMultipleProfilesOnly)
|
|
{
|
|
// GetCurrentProfile returns the profile which was last used but is not nescesarily
|
|
// active. Call SetCurrentProfile to make it installed and active.
|
|
|
|
nsXPIDLString currProfileName;
|
|
rv = profileService->GetCurrentProfile(getter_Copies(currProfileName));
|
|
if (NS_FAILED(rv)) return FALSE;
|
|
rv = profileService->SetCurrentProfile(currProfileName);
|
|
if (NS_FAILED(rv)) return FALSE;
|
|
return TRUE;
|
|
}
|
|
|
|
INT nResult;
|
|
nResult = WinDlgBox(HWND_DESKTOP, HWND_DESKTOP, (PFNWP)ChooseProfileDlgProc, NULL, IDD_CHOOSEPROFILE, (PVOID)ghInstanceResources);
|
|
return (nResult == DID_OK) ? TRUE : FALSE;
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: ChooseProfileDlgProc(HWND, unsigned, WORD, LONG)
|
|
//
|
|
// PURPOSE: Dialog handler procedure for the open uri dialog.
|
|
//
|
|
MRESULT EXPENTRY ChooseProfileDlgProc(HWND hDlg, ULONG message, MPARAM wParam, MPARAM lParam)
|
|
{
|
|
nsresult rv;
|
|
switch (message)
|
|
{
|
|
case WM_INITDLG:
|
|
{
|
|
WinSetActiveWindow(HWND_DESKTOP, hDlg);
|
|
HWND hwndProfileList = WinWindowFromID(hDlg, IDC_PROFILELIST);
|
|
|
|
nsCOMPtr<nsIProfile> profileService =
|
|
do_GetService(NS_PROFILE_CONTRACTID, &rv);
|
|
|
|
// Get the list of profile names and add them to the list box
|
|
PRUint32 listLen = 0;
|
|
PRUnichar **profileList = nsnull;
|
|
rv = profileService->GetProfileList(&listLen, &profileList);
|
|
for (PRUint32 index = 0; index < listLen; index++)
|
|
{
|
|
#ifdef UNICODE
|
|
WinSendMsg(hwndProfileList, LM_INSERTITEM, (MPARAM)LIT_END, (MPARAM) profileList[index]);
|
|
#else
|
|
nsCAutoString profile; profile.AssignWithConversion(profileList[index]);
|
|
WinSendMsg(hwndProfileList, LM_INSERTITEM, (MPARAM)LIT_END, (MPARAM) profile.get());
|
|
#endif
|
|
}
|
|
|
|
// Select the current profile (if there is one)
|
|
|
|
// Get the current profile
|
|
#ifdef UNICODE
|
|
nsXPIDLString currProfile;
|
|
profileService->GetCurrentProfile(getter_Copies(currProfile));
|
|
#else
|
|
nsXPIDLString currProfileUnicode;
|
|
profileService->GetCurrentProfile(getter_Copies(currProfileUnicode));
|
|
nsCAutoString currProfile; currProfile.AssignWithConversion(currProfileUnicode);
|
|
#endif
|
|
|
|
// Now find and select it
|
|
LONG currentProfileIndex = LIT_ERROR;
|
|
currentProfileIndex = (LONG)WinSendMsg(hwndProfileList, LM_SEARCHSTRING, MPFROM2SHORT(LSS_CASESENSITIVE, LIT_FIRST), (MPARAM) currProfile.get());
|
|
if (currentProfileIndex != LIT_ERROR)
|
|
{
|
|
WinSendMsg(hwndProfileList, LM_SELECTITEM, (MPARAM)currentProfileIndex, (MPARAM)TRUE);
|
|
}
|
|
|
|
return (MRESULT)TRUE;
|
|
}
|
|
case WM_COMMAND:
|
|
if (SHORT1FROMMP(wParam) == DID_OK)
|
|
{
|
|
HWND hwndProfileList = WinWindowFromID(hDlg, IDC_PROFILELIST);
|
|
|
|
// Get the selected profile from the list box and make it current
|
|
LONG currentProfileIndex = (LONG)WinSendMsg(hwndProfileList, LM_QUERYSELECTION, (MPARAM)LIT_FIRST, (MPARAM)0);
|
|
if (currentProfileIndex != LIT_ERROR)
|
|
{
|
|
nsCOMPtr<nsIProfile> profileService =
|
|
do_GetService(NS_PROFILE_CONTRACTID, &rv);
|
|
// Convert TCHAR name to unicode and make it current
|
|
INT profileNameLen = (INT)WinSendMsg(hwndProfileList, LM_QUERYITEMTEXTLENGTH, (MPARAM)currentProfileIndex, 0);
|
|
char *profileName = new char[profileNameLen + 1];
|
|
WinSendMsg(hwndProfileList, LM_QUERYITEMTEXT, MPFROM2SHORT(currentProfileIndex, profileNameLen + 1) ,(MPARAM)profileName);
|
|
nsAutoString newProfile; newProfile.AssignWithConversion(profileName);
|
|
rv = profileService->SetCurrentProfile(newProfile.get());
|
|
}
|
|
WinDismissDlg(hDlg, DID_OK);
|
|
}
|
|
else if (SHORT1FROMMP(wParam) == DID_CANCEL)
|
|
{
|
|
WinDismissDlg(hDlg, SHORT1FROMMP(wParam));
|
|
}
|
|
return (MRESULT)TRUE;
|
|
}
|
|
|
|
return WinDefDlgProc(hDlg, message, wParam, lParam);
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// WebBrowserChromeUI
|
|
|
|
//
|
|
// FUNCTION: CreateNativeWindow()
|
|
//
|
|
// PURPOSE: Creates a new browser dialog.
|
|
//
|
|
// COMMENTS:
|
|
//
|
|
// This function loads the browser dialog from a resource template
|
|
// and returns the HWND for the webbrowser container dialog item
|
|
// to the caller.
|
|
//
|
|
nativeWindow WebBrowserChromeUI::CreateNativeWindow(nsIWebBrowserChrome* chrome)
|
|
{
|
|
// Load the browser dialog from resource
|
|
HWND hwndDialog;
|
|
PRUint32 chromeFlags;
|
|
|
|
chrome->GetChromeFlags(&chromeFlags);
|
|
if ((chromeFlags & nsIWebBrowserChrome::CHROME_ALL) == nsIWebBrowserChrome::CHROME_ALL)
|
|
hwndDialog = WinLoadDlg(HWND_DESKTOP, HWND_DESKTOP, BrowserDlgProc, ghInstanceResources, IDD_BROWSER, NULL);
|
|
else
|
|
hwndDialog = WinLoadDlg(HWND_DESKTOP, HWND_DESKTOP, BrowserDlgProc, ghInstanceResources, IDD_BROWSER_NC, NULL);
|
|
if (!hwndDialog)
|
|
return NULL;
|
|
|
|
// Stick a menu onto it
|
|
if (chromeFlags & nsIWebBrowserChrome::CHROME_MENUBAR) {
|
|
HWND hmenuDlg = WinLoadMenu(hwndDialog, 0, IDC_OS2EMBED);
|
|
WinSendMsg(hwndDialog, WM_UPDATEFRAME, MPFROMLONG(FCF_MENU), 0);
|
|
} else
|
|
WinSendMsg(hwndDialog, WM_UPDATEFRAME, 0, 0);
|
|
|
|
// Add some interesting URLs to the address drop down
|
|
HWND hwndAddress = WinWindowFromID(hwndDialog, IDC_ADDRESS);
|
|
if (hwndAddress) {
|
|
for (int i = 0; i < sizeof(gDefaultURLs) / sizeof(gDefaultURLs[0]); i++)
|
|
{
|
|
WinSendMsg(hwndAddress, LM_INSERTITEM, (MPARAM)LIT_SORTASCENDING, (MPARAM)gDefaultURLs[i]);
|
|
}
|
|
}
|
|
|
|
// Fetch the browser window handle
|
|
HWND hwndBrowser = WinWindowFromID(hwndDialog, IDC_BROWSER);
|
|
WinSetWindowULong(hwndBrowser, QWL_USER, (ULONG)chrome); // save the browser LONG_PTR.
|
|
WinSetWindowULong(hwndBrowser, QWL_STYLE, WinQueryWindowULong(hwndBrowser, QWL_STYLE) | WS_CLIPCHILDREN);
|
|
|
|
// Activate the window
|
|
WinPostMsg(hwndDialog, WM_ACTIVATE, MPFROMSHORT(TRUE), (MPARAM)0);
|
|
|
|
gDialogCount++;
|
|
|
|
return (void *)hwndBrowser;
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: Destroy()
|
|
//
|
|
// PURPOSE: Destroy the window specified by the chrome
|
|
//
|
|
void WebBrowserChromeUI::Destroy(nsIWebBrowserChrome* chrome)
|
|
{
|
|
nsCOMPtr<nsIWebBrowser> webBrowser;
|
|
nsCOMPtr<nsIWebNavigation> webNavigation;
|
|
|
|
chrome->GetWebBrowser(getter_AddRefs(webBrowser));
|
|
webNavigation = do_QueryInterface(webBrowser);
|
|
if (webNavigation)
|
|
webNavigation->Stop(nsIWebNavigation::STOP_ALL);
|
|
|
|
chrome->ExitModalEventLoop(NS_OK);
|
|
|
|
HWND hwndDlg = GetBrowserDlgFromChrome(chrome);
|
|
if (hwndDlg == NULL)
|
|
return;
|
|
|
|
// Explicitly destroy the embedded browser and then the chrome
|
|
|
|
// First the browser
|
|
nsCOMPtr<nsIWebBrowser> browser = nsnull;
|
|
chrome->GetWebBrowser(getter_AddRefs(browser));
|
|
nsCOMPtr<nsIBaseWindow> browserAsWin = do_QueryInterface(browser);
|
|
if (browserAsWin)
|
|
browserAsWin->Destroy();
|
|
|
|
// Now the chrome
|
|
chrome->SetWebBrowser(nsnull);
|
|
NS_RELEASE(chrome);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: Called as the final act of a chrome object during its destructor
|
|
//
|
|
void WebBrowserChromeUI::Destroyed(nsIWebBrowserChrome* chrome)
|
|
{
|
|
HWND hwndDlg = GetBrowserDlgFromChrome(chrome);
|
|
if (hwndDlg == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Clear the window user data
|
|
HWND hwndBrowser = WinWindowFromID(hwndDlg, IDC_BROWSER);
|
|
WinSetWindowULong(hwndBrowser, QWL_USER, nsnull);
|
|
WinDestroyWindow(hwndBrowser);
|
|
WinDestroyWindow(hwndDlg);
|
|
|
|
--gDialogCount;
|
|
if (gDialogCount == 0)
|
|
{
|
|
if (gProfileSwitch)
|
|
{
|
|
gProfileSwitch = FALSE;
|
|
OpenWebPage(gFirstURL);
|
|
}
|
|
else
|
|
{
|
|
// Quit when there are no more browser objects
|
|
WinPostQueueMsg(0, WM_QUIT, 0, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: Set the input focus onto the browser window
|
|
//
|
|
void WebBrowserChromeUI::SetFocus(nsIWebBrowserChrome *chrome)
|
|
{
|
|
HWND hwndDlg = GetBrowserDlgFromChrome(chrome);
|
|
if (hwndDlg == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
HWND hwndBrowser = WinWindowFromID(hwndDlg, IDC_BROWSER);
|
|
::WinSetFocus(HWND_DESKTOP, hwndBrowser);
|
|
}
|
|
|
|
//
|
|
// FUNCTION: UpdateStatusBarText()
|
|
//
|
|
// PURPOSE: Set the status bar text.
|
|
//
|
|
void WebBrowserChromeUI::UpdateStatusBarText(nsIWebBrowserChrome *aChrome, const PRUnichar* aStatusText)
|
|
{
|
|
HWND hwndDlg = GetBrowserDlgFromChrome(aChrome);
|
|
nsCString status;
|
|
if (aStatusText)
|
|
status.AssignWithConversion(aStatusText);
|
|
WinSetDlgItemText(hwndDlg, IDC_STATUS, status.get());
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: UpdateCurrentURI()
|
|
//
|
|
// PURPOSE: Updates the URL address field
|
|
//
|
|
void WebBrowserChromeUI::UpdateCurrentURI(nsIWebBrowserChrome *aChrome)
|
|
{
|
|
nsCOMPtr<nsIWebBrowser> webBrowser;
|
|
nsCOMPtr<nsIWebNavigation> webNavigation;
|
|
aChrome->GetWebBrowser(getter_AddRefs(webBrowser));
|
|
webNavigation = do_QueryInterface(webBrowser);
|
|
|
|
nsCOMPtr<nsIURI> currentURI;
|
|
webNavigation->GetCurrentURI(getter_AddRefs(currentURI));
|
|
if (currentURI)
|
|
{
|
|
nsCAutoString uriString;
|
|
currentURI->GetAsciiSpec(uriString);
|
|
HWND hwndDlg = GetBrowserDlgFromChrome(aChrome);
|
|
WinSetDlgItemText(hwndDlg, IDC_ADDRESS, uriString.get());
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: UpdateBusyState()
|
|
//
|
|
// PURPOSE: Refreshes the stop/go buttons in the browser dialog
|
|
//
|
|
void WebBrowserChromeUI::UpdateBusyState(nsIWebBrowserChrome *aChrome, PRBool aBusy)
|
|
{
|
|
HWND hwndDlg = GetBrowserDlgFromChrome(aChrome);
|
|
HWND button;
|
|
button = WinWindowFromID(hwndDlg, IDC_STOP);
|
|
if (button)
|
|
WinEnableWindow(button, aBusy);
|
|
button = WinWindowFromID(hwndDlg, IDC_GO);
|
|
if (button)
|
|
WinEnableWindow(button, !aBusy);
|
|
UpdateUI(aChrome);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: UpdateProgress()
|
|
//
|
|
// PURPOSE: Refreshes the progress bar in the browser dialog
|
|
//
|
|
void WebBrowserChromeUI::UpdateProgress(nsIWebBrowserChrome *aChrome, PRInt32 aCurrent, PRInt32 aMax)
|
|
{
|
|
HWND hwndDlg = GetBrowserDlgFromChrome(aChrome);
|
|
HWND hwndProgress = WinWindowFromID(hwndDlg, IDC_PROGRESS);
|
|
if (aCurrent < 0)
|
|
{
|
|
aCurrent = 0;
|
|
}
|
|
if (aCurrent > aMax)
|
|
{
|
|
aMax = aCurrent + 20; // What to do?
|
|
}
|
|
if (hwndProgress)
|
|
{
|
|
ULONG value = (double)aCurrent/(double)aMax*(double)100;
|
|
WinSendMsg(hwndProgress, SLM_SETSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), (MPARAM)(value == 100? value-1: value));
|
|
}
|
|
}
|
|
|
|
//
|
|
// FUNCTION: ShowContextMenu()
|
|
//
|
|
// PURPOSE: Display a context menu for the given node
|
|
//
|
|
void WebBrowserChromeUI::ShowContextMenu(nsIWebBrowserChrome *aChrome, PRUint32 aContextFlags, nsIDOMEvent *aEvent, nsIDOMNode *aNode)
|
|
{
|
|
// TODO code to test context flags and display a popup menu should go here
|
|
}
|
|
|
|
//
|
|
// FUNCTION: ShowTooltip()
|
|
//
|
|
// PURPOSE: Show a tooltip
|
|
//
|
|
void WebBrowserChromeUI::ShowTooltip(nsIWebBrowserChrome *aChrome, PRInt32 aXCoords, PRInt32 aYCoords, const PRUnichar *aTipText)
|
|
{
|
|
// TODO code to show a tooltip should go here
|
|
}
|
|
|
|
//
|
|
// FUNCTION: HideTooltip()
|
|
//
|
|
// PURPOSE: Hide the tooltip
|
|
//
|
|
void WebBrowserChromeUI::HideTooltip(nsIWebBrowserChrome *aChrome)
|
|
{
|
|
// TODO code to hide a tooltip should go here
|
|
}
|
|
|
|
void WebBrowserChromeUI::ShowWindow(nsIWebBrowserChrome *aChrome, PRBool aShow)
|
|
{
|
|
HWND win = GetBrowserDlgFromChrome(aChrome);
|
|
::WinShowWindow(win, aShow);
|
|
}
|
|
|
|
void WebBrowserChromeUI::SizeTo(nsIWebBrowserChrome *aChrome, PRInt32 aWidth, PRInt32 aHeight)
|
|
{
|
|
HWND hchrome = GetBrowserDlgFromChrome(aChrome);
|
|
HWND hbrowser = GetBrowserFromChrome(aChrome);
|
|
RECTL chromeRect, browserRect;
|
|
|
|
::WinQueryWindowRect(hchrome, &chromeRect);
|
|
::WinQueryWindowRect(hbrowser, &browserRect);
|
|
|
|
PRInt32 decoration_x = (browserRect.xLeft - chromeRect.xLeft) +
|
|
(chromeRect.xRight - browserRect.xRight);
|
|
PRInt32 decoration_y = (chromeRect.yTop - browserRect.yTop) +
|
|
(browserRect.yBottom - chromeRect.yBottom);
|
|
|
|
::WinSetWindowPos(hchrome, HWND_TOP, WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN)/2 - (aWidth+decoration_x)/2,
|
|
WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN)/2 - (aHeight+decoration_y)/2,
|
|
aWidth+decoration_x, aHeight+decoration_y, SWP_SIZE | SWP_MOVE | SWP_SHOW);
|
|
}
|
|
|
|
//
|
|
// FUNCTION: GetResourceStringByID()
|
|
//
|
|
// PURPOSE: Get the resource string for the ID
|
|
//
|
|
void WebBrowserChromeUI::GetResourceStringById(PRInt32 aID, char ** aReturn)
|
|
{
|
|
char resBuf[MAX_LOADSTRING];
|
|
int retval = WinLoadString((HAB)0, ghInstanceResources, aID, sizeof(resBuf), (PSZ)resBuf );
|
|
if (retval != 0)
|
|
{
|
|
int resLen = strlen(resBuf);
|
|
*aReturn = (char *)calloc(resLen+1, sizeof(char *));
|
|
if (!*aReturn) return;
|
|
PL_strncpy(*aReturn, (char *) resBuf, resLen);
|
|
}
|
|
return;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
nsresult CreateBrowserWindow(PRUint32 aChromeFlags,
|
|
nsIWebBrowserChrome *aParent,
|
|
nsIWebBrowserChrome **aNewWindow)
|
|
{
|
|
WebBrowserChrome * chrome = new WebBrowserChrome();
|
|
if (!chrome)
|
|
return NS_ERROR_FAILURE;
|
|
|
|
// the interface to return and one addref, which we assume will be
|
|
// immediately released
|
|
CallQueryInterface(static_cast<nsIWebBrowserChrome*>(chrome), aNewWindow);
|
|
// now an extra addref; the window owns itself (to be released by
|
|
// WebBrowserChromeUI::Destroy)
|
|
NS_ADDREF(*aNewWindow);
|
|
|
|
chrome->SetChromeFlags(aChromeFlags);
|
|
chrome->SetParent(aParent);
|
|
|
|
// Insert the browser
|
|
nsCOMPtr<nsIWebBrowser> newBrowser;
|
|
chrome->CreateBrowser(-1, -1, -1, -1, getter_AddRefs(newBrowser));
|
|
if (!newBrowser)
|
|
return NS_ERROR_FAILURE;
|
|
|
|
// Place it where we want it.
|
|
ResizeEmbedding(static_cast<nsIWebBrowserChrome*>(chrome));
|
|
|
|
// Subscribe new window to profile changes so it can kill itself when one happens
|
|
nsCOMPtr<nsIObserverService> observerService(do_GetService("@mozilla.org/observer-service;1"));
|
|
if (observerService)
|
|
observerService->AddObserver(static_cast<nsIObserver *>(chrome),
|
|
"profile-change-teardown", PR_TRUE);
|
|
|
|
// if opened as chrome, it'll be made visible after the chrome has loaded.
|
|
// otherwise, go ahead and show it now.
|
|
if (!(aChromeFlags & nsIWebBrowserChrome::CHROME_OPENAS_CHROME))
|
|
WebBrowserChromeUI::ShowWindow(*aNewWindow, PR_TRUE);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
void EnableChromeWindow(nsIWebBrowserChrome *aWindow,
|
|
PRBool aEnabled)
|
|
{
|
|
HWND hwnd = GetBrowserDlgFromChrome(aWindow);
|
|
::WinEnableWindow(hwnd, aEnabled ? TRUE : FALSE);
|
|
}
|
|
|
|
PRUint32 RunEventLoop(PRBool &aRunCondition)
|
|
{
|
|
QMSG msg;
|
|
HEV hFakeEvent = 0;
|
|
::DosCreateEventSem(NULL, &hFakeEvent, 0L, FALSE);
|
|
|
|
while (aRunCondition ) {
|
|
// Process pending messages
|
|
while (::WinPeekMsg((HAB)0, &msg, NULL, 0, 0, PM_NOREMOVE)) {
|
|
if (!::WinGetMsg((HAB)0, &msg, NULL, 0, 0)) {
|
|
// WM_QUIT
|
|
aRunCondition = PR_FALSE;
|
|
break;
|
|
}
|
|
|
|
PRBool wasHandled = PR_FALSE;
|
|
::NS_HandleEmbeddingEvent(msg, wasHandled);
|
|
if (wasHandled)
|
|
continue;
|
|
|
|
::WinDispatchMsg((HAB)0, &msg);
|
|
}
|
|
|
|
// Do idle stuff
|
|
::DosWaitEventSem(hFakeEvent, 100);
|
|
}
|
|
::DosCloseEventSem(hFakeEvent);
|
|
return LONGFROMMP(msg.mp1);
|
|
}
|