Back to index

lightning-sunbird  0.9+nobinonly
os2Embed.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: Mozilla-sample-code 1.0
00004  *
00005  * Copyright (c) 2002 Netscape Communications Corporation and
00006  * other contributors
00007  *
00008  * Permission is hereby granted, free of charge, to any person obtaining a
00009  * copy of this Mozilla sample software and associated documentation files
00010  * (the "Software"), to deal in the Software without restriction, including
00011  * without limitation the rights to use, copy, modify, merge, publish,
00012  * distribute, sublicense, and/or sell copies of the Software, and to permit
00013  * persons to whom the Software is furnished to do so, subject to the
00014  * following conditions:
00015  *
00016  * The above copyright notice and this permission notice shall be included
00017  * in all copies or substantial portions of the Software.
00018  *
00019  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00020  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00021  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
00022  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00023  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00024  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
00025  * DEALINGS IN THE SOFTWARE.
00026  *
00027  * Contributor(s):
00028  *   Doug Turner <dougt@netscape.com>
00029  *   Adam Lock <adamlock@netscape.com>
00030  *
00031  * ***** END LICENSE BLOCK ***** */
00032 
00033 #include <stdio.h>
00034 
00035 // OS/2 header files
00036 #define INCL_WIN
00037 #define INCL_DOS
00038 #include <os2.h>
00039 
00040 // Mozilla header files
00041 #include "nsEmbedAPI.h"
00042 #include "nsWeakReference.h"
00043 #include "nsIClipboardCommands.h"
00044 #include "nsXPIDLString.h"
00045 #include "nsIWebBrowserPersist.h"
00046 #include "nsIWebBrowserFocus.h"
00047 #include "nsIWindowWatcher.h"
00048 #include "nsIProfile.h"
00049 #include "nsIObserverService.h"
00050 #include "nsIObserver.h"
00051 #include "nsIProfileChangeStatus.h"
00052 #include "nsIURI.h"
00053 #include "plstr.h"
00054 #include "nsIInterfaceRequestor.h"
00055 #include "nsCRT.h"
00056 
00057 // Local header files
00058 #include "os2Embed.h"
00059 #include "WebBrowserChrome.h"
00060 #include "WindowCreator.h"
00061 #include "resource.h"
00062 #include "nsStaticComponents.h"
00063 
00064 // Printing header files
00065 #include "nsIPrintSettings.h"
00066 #include "nsIWebBrowserPrint.h"
00067 
00068 #define MAX_LOADSTRING 100
00069 
00070 
00071 #ifndef _BUILD_STATIC_BIN
00072 nsStaticModuleInfo const *const kPStaticModules = nsnull;
00073 PRUint32 const kStaticModuleCount = 0;
00074 #endif
00075 
00076 const CHAR *szWindowClass = "OS2EMBED";
00077 
00078 // Foward declarations of functions included in this code module:
00079 static void             MyRegisterClass();
00080 static MRESULT EXPENTRY BrowserWndProc(HWND, ULONG, MPARAM, MPARAM);
00081 static MRESULT EXPENTRY BrowserDlgProc(HWND hwndDlg, ULONG uMsg, MPARAM wParam, MPARAM lParam);
00082 
00083 static nsresult InitializeWindowCreator();
00084 static nsresult OpenWebPage(const char * url);
00085 static nsresult ResizeEmbedding(nsIWebBrowserChrome* chrome);
00086 
00087 // Profile chooser stuff
00088 static BOOL ChooseNewProfile(BOOL bShowForMultipleProfilesOnly, const char *szDefaultProfile);
00089 static MRESULT EXPENTRY ChooseProfileDlgProc(HWND, ULONG, MPARAM, MPARAM);
00090 
00091 // Global variables
00092 static UINT gDialogCount = 0;
00093 static BOOL gProfileSwitch = FALSE;
00094 static HMODULE ghInstanceResources = NULL;
00095 static char gFirstURL[1024];
00096 
00097 // A list of URLs to populate the URL drop down list with
00098 static const CHAR *gDefaultURLs[] = 
00099 {
00100     ("http://www.mozilla.org/"),
00101     ("http://www.netscape.com/"),
00102     ("http://browsertest.web.aol.com/tests/javascript/javascpt/index.htm"),
00103     ("http://127.0.0.1/"),
00104     ("http://www.yahoo.com/"),
00105     ("http://www.travelocity.com/"),
00106     ("http://www.disney.com/"),
00107     ("http://www.go.com/"),
00108     ("http://www.google.com/"),
00109     ("http://www.ebay.com/"),
00110     ("http://www.shockwave.com/"),
00111     ("http://www.slashdot.org/"),
00112     ("http://www.quicken.com/"),
00113     ("http://www.hotmail.com/"),
00114     ("http://www.cnn.com/"),
00115     ("http://www.javasoft.com/")
00116 };
00117 
00118 class ProfileChangeObserver : public nsIObserver,
00119                               public nsSupportsWeakReference
00120 
00121 {
00122 public:
00123         ProfileChangeObserver();
00124 
00125     NS_DECL_ISUPPORTS
00126     NS_DECL_NSIOBSERVER
00127 };
00128 
00129 
00130 int main(int argc, char *argv[])
00131 {
00132     printf("You are embedded, man!\n\n");
00133 
00134     // Sophisticated command-line parsing in action
00135     char *szFirstURL = "http://www.mozilla.org/projects/embedding";
00136     char *szDefaultProfile = nsnull;
00137     int argn;
00138     for (argn = 1; argn < argc; argn++)
00139     {
00140         if (stricmp("-P", argv[argn]) == 0)
00141         {
00142             if (argn + 1 < argc)
00143             {
00144                 szDefaultProfile = argv[++argn];
00145             }
00146         }
00147         else
00148         {
00149             szFirstURL = argv[argn];
00150         }
00151     }
00152     strncpy(gFirstURL, szFirstURL, sizeof(gFirstURL) - 1);
00153 
00154     // Initialize global strings
00155     CHAR szTitle[MAX_LOADSTRING];
00156     WinLoadString((HAB)0, ghInstanceResources, IDS_APP_TITLE, MAX_LOADSTRING, szTitle);
00157     MyRegisterClass();
00158 
00159     // Init Embedding APIs
00160     NS_InitEmbedding(nsnull, nsnull, kPStaticModules, kStaticModuleCount);
00161 
00162     // Choose the new profile
00163     if (!ChooseNewProfile(TRUE, szDefaultProfile))
00164     {
00165         NS_TermEmbedding();
00166         return 1;
00167     }
00168     MPARAM rv;
00169     {    
00170        // Now register an observer to watch for profile changes
00171         nsCOMPtr<nsIObserverService> observerService(do_GetService("@mozilla.org/observer-service;1"));
00172 
00173         ProfileChangeObserver *observer = new ProfileChangeObserver;
00174         observer->AddRef();
00175         observerService->AddObserver(NS_STATIC_CAST(nsIObserver *, observer), "profile-approve-change", PR_TRUE);
00176         observerService->AddObserver(NS_STATIC_CAST(nsIObserver *, observer), "profile-change-teardown", PR_TRUE);
00177         observerService->AddObserver(NS_STATIC_CAST(nsIObserver *, observer), "profile-after-change", PR_TRUE);
00178 
00179         InitializeWindowCreator();
00180 
00181         // Open the initial browser window
00182         OpenWebPage(gFirstURL);
00183 
00184         // Main message loop.
00185         // NOTE: We use a fake event and a timeout in order to process idle stuff for
00186         //       Mozilla every 1/10th of a second.
00187         PRBool runCondition = PR_TRUE;
00188 
00189         rv = (MPARAM)RunEventLoop(runCondition);
00190 
00191         observer->Release();
00192     }
00193     // Close down Embedding APIs
00194     NS_TermEmbedding();
00195 
00196     return (int)rv;
00197 }
00198 
00199 //-----------------------------------------------------------------------------
00200 // ProfileChangeObserver
00201 //-----------------------------------------------------------------------------
00202 
00203 NS_IMPL_THREADSAFE_ISUPPORTS2(ProfileChangeObserver, nsIObserver, nsISupportsWeakReference)
00204 
00205 ProfileChangeObserver::ProfileChangeObserver()
00206 {
00207 }
00208 
00209 // ---------------------------------------------------------------------------
00210 //  CMfcEmbedApp : nsIObserver
00211 // ---------------------------------------------------------------------------
00212 
00213 NS_IMETHODIMP ProfileChangeObserver::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *someData)
00214 {
00215     nsresult rv = NS_OK;
00216 
00217     if (nsCRT::strcmp(aTopic, "profile-approve-change") == 0)
00218     {
00219               // The profile is about to change!
00220 
00221         // Ask the user if they want to
00222         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);
00223         if (result != MBID_YES)
00224         {
00225             nsCOMPtr<nsIProfileChangeStatus> status = do_QueryInterface(aSubject);
00226             NS_ENSURE_TRUE(status, NS_ERROR_FAILURE);
00227             status->VetoChange();
00228         }
00229     }
00230     else if (nsCRT::strcmp(aTopic, "profile-change-teardown") == 0)
00231     {
00232               // The profile is changing!
00233 
00234               // Prevent WM_QUIT by incrementing the dialog count
00235               gDialogCount++;
00236     }
00237     else if (nsCRT::strcmp(aTopic, "profile-after-change") == 0)
00238     {
00239               // Decrease the dialog count so WM_QUIT can once more happen
00240               gDialogCount--;
00241         if (gDialogCount == 0)
00242         {
00243             // All the dialogs have been torn down so open new page
00244             OpenWebPage(gFirstURL);
00245         }
00246         else
00247         {
00248                   // The profile has changed, but dialogs are still being
00249             // torn down. Set this flag so when the last one goes
00250             // it can finish the switch.
00251             gProfileSwitch = TRUE;
00252         }
00253     }
00254 
00255     return rv;
00256 }
00257 
00258 /* InitializeWindowCreator creates and hands off an object with a callback
00259    to a window creation function. This is how all new windows are opened,
00260    except any created directly by the embedding app. */
00261 nsresult InitializeWindowCreator()
00262 {
00263     // create an nsWindowCreator and give it to the WindowWatcher service
00264     WindowCreator *creatorCallback = new WindowCreator();
00265     if (creatorCallback)
00266     {
00267         nsCOMPtr<nsIWindowCreator> windowCreator(NS_STATIC_CAST(nsIWindowCreator *, creatorCallback));
00268         if (windowCreator)
00269         {
00270             nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
00271             if (wwatch)
00272             {
00273                 wwatch->SetWindowCreator(windowCreator);
00274                 return NS_OK;
00275             }
00276         }
00277     }
00278     return NS_ERROR_FAILURE;
00279 }
00280 
00281 //-----------------------------------------------------------------------------
00282 
00283 //
00284 //  FUNCTION: OpenWebPage()
00285 //
00286 //  PURPOSE: Opens a new browser dialog and starts it loading to the
00287 //           specified url.
00288 //
00289 nsresult OpenWebPage(const char *url)
00290 {
00291     nsresult  rv;
00292 
00293     // Create the chrome object. Note that it leaves this function
00294     // with an extra reference so that it can released correctly during
00295     // destruction (via Win32UI::Destroy)
00296 
00297     nsCOMPtr<nsIWebBrowserChrome> chrome;
00298     rv = CreateBrowserWindow(nsIWebBrowserChrome::CHROME_ALL,
00299            nsnull, getter_AddRefs(chrome));
00300     if (NS_SUCCEEDED(rv))
00301     {
00302         // Start loading a page
00303         nsCOMPtr<nsIWebBrowser> newBrowser;
00304         chrome->GetWebBrowser(getter_AddRefs(newBrowser));
00305         nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(newBrowser));
00306         return webNav->LoadURI(NS_ConvertASCIItoUCS2(url).get(),
00307                                nsIWebNavigation::LOAD_FLAGS_NONE,
00308                                nsnull,
00309                                nsnull,
00310                                nsnull);
00311     }
00312 
00313     return rv;
00314 }   
00315 
00316 //
00317 //  FUNCTION: GetBrowserFromChrome()
00318 //
00319 //  PURPOSE: Returns the HWND for the webbrowser container associated
00320 //           with the specified chrome.
00321 //
00322 HWND GetBrowserFromChrome(nsIWebBrowserChrome *aChrome)
00323 {
00324     if (!aChrome)
00325     {
00326         return NULL;
00327     }
00328     nsCOMPtr<nsIEmbeddingSiteWindow> baseWindow = do_QueryInterface(aChrome);
00329     HWND hwnd = NULL;
00330     baseWindow->GetSiteWindow((void **) & hwnd);
00331     return hwnd;
00332 }
00333 
00334 
00335 //
00336 //  FUNCTION: GetBrowserDlgFromChrome()
00337 //
00338 //  PURPOSE: Returns the HWND for the browser dialog associated with
00339 //           the specified chrome.
00340 //
00341 HWND GetBrowserDlgFromChrome(nsIWebBrowserChrome *aChrome)
00342 {
00343     return WinQueryWindow(GetBrowserFromChrome(aChrome), QW_PARENT);
00344 }
00345 
00346 
00347 //
00348 //  FUNCTION: SaveWebPage()
00349 //
00350 //  PURPOSE: Saves the contents of the web page to a file
00351 //
00352 void SaveWebPage(HWND hDlg, nsIWebBrowser *aWebBrowser)
00353 {
00354     // Use the browser window title as the initial file name
00355     nsCOMPtr<nsIBaseWindow> webBrowserAsWin = do_QueryInterface(aWebBrowser);
00356     nsXPIDLString windowTitle;
00357     webBrowserAsWin->GetTitle(getter_Copies(windowTitle));
00358     nsCString fileName; fileName.AssignWithConversion(windowTitle);
00359 
00360        // Sanitize the title of all illegal characters
00361     fileName.CompressWhitespace();     // Remove whitespace from the ends
00362     fileName.StripChars("\\*|:\"><?"); // Strip illegal characters
00363     fileName.ReplaceChar('.', L'_');   // Dots become underscores
00364     fileName.ReplaceChar('/', L'-');   // Forward slashes become hyphens
00365     fileName.ReplaceChar(' ', L'_');   // Spaces become underscores
00366 
00367     // Initialize the file save as information structure
00368     FILEDLG saveFileNameInfo;
00369     memset(&saveFileNameInfo, 0, sizeof(saveFileNameInfo));
00370     saveFileNameInfo.cbSize = sizeof(saveFileNameInfo);
00371     PL_strncpyz(saveFileNameInfo.szFullFile, fileName.get(), CCHMAXPATH);
00372     strcat(saveFileNameInfo.szFullFile, ".html");
00373 
00374     PSZ *apszTypeList = (PSZ *)malloc(3 * sizeof(PSZ) + 1);
00375     apszTypeList[0] = "Web Page, HTML Only (*.htm;*.html)";
00376     apszTypeList[1] = "Web Page, Complete (*.htm;*.html)";
00377     apszTypeList[2] = "Text File (*.txt)";
00378     apszTypeList[3] = 0;
00379     saveFileNameInfo.papszITypeList = (PAPSZ)apszTypeList; 
00380     saveFileNameInfo.pszTitle = NULL; 
00381     saveFileNameInfo.fl = FDS_SAVEAS_DIALOG | FDS_CENTER | FDS_ENABLEFILELB; 
00382     saveFileNameInfo.pszIType = apszTypeList[0];
00383 
00384     WinFileDlg(HWND_DESKTOP, hDlg, &saveFileNameInfo);
00385     if (saveFileNameInfo.lReturn == DID_OK)  
00386     {
00387         char *pszDataPath = NULL;
00388         static char szDataFile[_MAX_PATH];
00389         char szDataPath[_MAX_PATH];
00390         char drive[_MAX_DRIVE];
00391         char dir[_MAX_DIR];
00392         char fname[_MAX_FNAME];
00393         char ext[_MAX_EXT];
00394 
00395         _splitpath(saveFileNameInfo.szFullFile, drive, dir, fname, ext);
00396         //add the extension to the filename if there is no extension already
00397         if (strcmp(ext, "") == 0) {
00398           if ((saveFileNameInfo.sEAType == 2) && (stricmp(ext, ".txt") != 0)) {
00399             strcat(saveFileNameInfo.szFullFile, ".txt");
00400             strcpy(ext, ".txt");
00401           } else 
00402             if ((stricmp(ext, ".html") != 0) && (stricmp(ext, ".htm") != 0)) {
00403               strcat(saveFileNameInfo.szFullFile, ".html");
00404               strcpy(ext, ".html");
00405           }
00406         }
00407 
00408         // Does the user want to save the complete document including
00409         // all frames, images, scripts, stylesheets etc. ?
00410         if (saveFileNameInfo.sEAType == 1) //apszTypeList[1] means save everything
00411         {
00412             sprintf(szDataFile, "%s_files", fname);
00413             _makepath(szDataPath, drive, dir, szDataFile, "");
00414 
00415             pszDataPath = szDataPath;
00416        }
00417 
00418         // Save away
00419         nsCOMPtr<nsIWebBrowserPersist> persist(do_QueryInterface(aWebBrowser));
00420 
00421         nsCOMPtr<nsILocalFile> file;
00422         NS_NewNativeLocalFile(nsDependentCString(saveFileNameInfo.szFullFile), TRUE, getter_AddRefs(file));
00423 
00424         nsCOMPtr<nsILocalFile> dataPath;
00425         if (pszDataPath)
00426         {
00427             NS_NewNativeLocalFile(nsDependentCString(pszDataPath), TRUE, getter_AddRefs(dataPath));
00428         }
00429 
00430         persist->SaveDocument(nsnull, file, dataPath, nsnull, 0, 0);
00431     }
00432     if (saveFileNameInfo.papszFQFilename) 
00433        WinFreeFileDlgList(saveFileNameInfo.papszFQFilename);
00434     for (int i = 0; i < 3; i++)
00435        free(saveFileNameInfo.papszITypeList[i]);
00436     free(saveFileNameInfo.papszITypeList);
00437 }
00438 
00439 
00440 //
00441 //  FUNCTION: ResizeEmbedding()
00442 //
00443 //  PURPOSE: Resizes the webbrowser window to fit its container.
00444 //
00445 nsresult ResizeEmbedding(nsIWebBrowserChrome* chrome)
00446 {
00447     if (!chrome)
00448         return NS_ERROR_FAILURE;
00449     
00450     nsCOMPtr<nsIEmbeddingSiteWindow> embeddingSite = do_QueryInterface(chrome);
00451     HWND hWnd;
00452        embeddingSite->GetSiteWindow((void **) & hWnd);
00453     
00454     if (!hWnd)
00455         return NS_ERROR_NULL_POINTER;
00456     
00457     RECTL rect;
00458     WinQueryWindowRect(hWnd, &rect);
00459     
00460     // Make sure the browser is visible and sized
00461     nsCOMPtr<nsIWebBrowser> webBrowser;
00462     chrome->GetWebBrowser(getter_AddRefs(webBrowser));
00463     nsCOMPtr<nsIBaseWindow> webBrowserAsWin = do_QueryInterface(webBrowser);
00464     if (webBrowserAsWin)
00465     {
00466         webBrowserAsWin->SetPositionAndSize(rect.xLeft, 
00467                                             rect.yBottom, 
00468                                             rect.xRight - rect.xLeft,
00469                                             rect.yTop - rect.yBottom,
00470                                             PR_TRUE);
00471         webBrowserAsWin->SetVisibility(PR_TRUE);
00472        }
00473 
00474     return NS_OK;
00475 }
00476 
00477 
00478 //
00479 //  FUNCTION: MyRegisterClass()
00480 //
00481 //  PURPOSE: Registers the window class.
00482 //
00483 //  COMMENTS:
00484 //
00485 //
00486 void MyRegisterClass()
00487 {
00488     WinRegisterClass((HAB)0, szWindowClass, BrowserWndProc, CS_SIZEREDRAW, sizeof(ULONG));
00489 }
00490 
00491 
00492 //
00493 //  FUNCTION: UpdateUI()
00494 //
00495 //  PURPOSE: Refreshes the buttons and menu items in the browser dialog
00496 //
00497 void UpdateUI(nsIWebBrowserChrome *aChrome)
00498 {
00499     HWND hwndDlg = GetBrowserDlgFromChrome(aChrome);
00500     nsCOMPtr<nsIWebBrowser> webBrowser;
00501     nsCOMPtr<nsIWebNavigation> webNavigation;
00502     aChrome->GetWebBrowser(getter_AddRefs(webBrowser));
00503     webNavigation = do_QueryInterface(webBrowser);
00504 
00505     PRBool canGoBack = PR_FALSE;
00506     PRBool canGoForward = PR_FALSE;
00507     if (webNavigation)
00508     {
00509         webNavigation->GetCanGoBack(&canGoBack);
00510         webNavigation->GetCanGoForward(&canGoForward);
00511     }
00512 
00513     PRBool canCutSelection = PR_FALSE;
00514     PRBool canCopySelection = PR_FALSE;
00515     PRBool canPaste = PR_FALSE;
00516 
00517     nsCOMPtr<nsIClipboardCommands> clipCmds = do_GetInterface(webBrowser);
00518     if (clipCmds)
00519     {
00520         clipCmds->CanCutSelection(&canCutSelection);
00521         clipCmds->CanCopySelection(&canCopySelection);
00522         clipCmds->CanPaste(&canPaste);
00523     }
00524 
00525     HWND hmenu = WinWindowFromID(hwndDlg, FID_MENU);
00526     if (hmenu)
00527     {
00528         MENUITEM goMenu, editMenu;
00529         WinSendMsg(hmenu, MM_QUERYITEM, MPFROM2SHORT(MOZ_Go, TRUE), (MPARAM)&goMenu);
00530         WinEnableMenuItem(goMenu.hwndSubMenu, MOZ_GoBack, canGoBack);
00531         WinEnableMenuItem(goMenu.hwndSubMenu, MOZ_GoForward, canGoForward);
00532 
00533         WinSendMsg(hmenu, MM_QUERYITEM, MPFROM2SHORT(MOZ_Edit, TRUE), (MPARAM)&editMenu);
00534         WinEnableMenuItem(editMenu.hwndSubMenu, MOZ_Cut, canCutSelection);
00535         WinEnableMenuItem(editMenu.hwndSubMenu, MOZ_Copy, canCopySelection);
00536         WinEnableMenuItem(editMenu.hwndSubMenu, MOZ_Paste, canPaste);
00537     }
00538 
00539     HWND button;
00540     button = WinWindowFromID(hwndDlg, IDC_BACK);
00541     if (button)
00542       WinEnableWindow(button, canGoBack);
00543     button = WinWindowFromID(hwndDlg, IDC_FORWARD);
00544     if (button)
00545       WinEnableWindow(button, canGoForward);
00546 }
00547 
00548 
00549 //
00550 //  FUNCTION: BrowserDlgProc()
00551 //
00552 //  PURPOSE: Browser dialog windows message handler.
00553 //
00554 //  COMMENTS:
00555 //
00556 //    The code for handling buttons and menu actions is here.
00557 //
00558 MRESULT EXPENTRY BrowserDlgProc(HWND hwndDlg, ULONG uMsg, MPARAM wParam, MPARAM lParam)
00559 {
00560     if (uMsg == WM_COMMAND && SHORT1FROMMP(wParam) == MOZ_SwitchProfile)
00561     {
00562        ChooseNewProfile(FALSE, NULL);
00563        return (MRESULT)FALSE;
00564     }
00565 
00566     // Get the browser and other pointers since they are used a lot below
00567     HWND hwndBrowser = WinWindowFromID(hwndDlg, IDC_BROWSER);
00568     nsIWebBrowserChrome *chrome = nsnull ;
00569     if (hwndBrowser)
00570     {
00571         chrome = (nsIWebBrowserChrome *) WinQueryWindowULong(hwndBrowser, QWL_USER);
00572     }
00573     nsCOMPtr<nsIWebBrowser> webBrowser;
00574     nsCOMPtr<nsIWebNavigation> webNavigation;
00575     nsCOMPtr<nsIWebBrowserPrint> webBrowserPrint;
00576     if (chrome)
00577     {
00578         chrome->GetWebBrowser(getter_AddRefs(webBrowser));
00579         webNavigation = do_QueryInterface(webBrowser);
00580         webBrowserPrint = do_GetInterface(webBrowser);
00581     }
00582 
00583     // Test the message
00584     switch (uMsg)
00585     {
00586     case WM_INITDLG:
00587         return (MRESULT)TRUE;
00588 
00589     case WM_INITMENU:
00590         UpdateUI(chrome);
00591         return (MRESULT)TRUE;
00592 
00593     case WM_SYSCOMMAND:
00594         if (SHORT1FROMMP(wParam) == SC_CLOSE)
00595         {
00596             WebBrowserChromeUI::Destroy(chrome);
00597             return (MRESULT)TRUE;
00598         }
00599         break;
00600 
00601     case WM_DESTROY:
00602            return (MRESULT)TRUE;
00603 
00604     case WM_COMMAND:
00605         if (!webBrowser)
00606         {
00607             return (MRESULT)TRUE;
00608         }
00609 
00610         // Test which command was selected
00611         switch (SHORT1FROMMP(wParam))
00612               {
00613         case IDC_ADDRESS:
00614             if (SHORT1FROMMP(wParam) == CBN_EFCHANGE || SHORT1FROMMP(wParam) == CBN_LBSELECT)
00615             {
00616                 // User has changed the address field so enable the Go button
00617                 WinEnableWindow(WinWindowFromID(hwndDlg, IDC_GO), TRUE);
00618             }
00619             break;
00620 
00621         case IDC_GO:
00622             {
00623                 char szURL[2048];
00624                 memset(szURL, 0, sizeof(szURL));
00625                 WinQueryDlgItemText(hwndDlg, IDC_ADDRESS, sizeof(szURL) / sizeof(szURL[0]) - 1, szURL);
00626                 webNavigation->LoadURI(
00627                     NS_ConvertASCIItoUCS2(szURL).get(),
00628                     nsIWebNavigation::LOAD_FLAGS_NONE,
00629                     nsnull,
00630                     nsnull,
00631                     nsnull);
00632             }
00633             break;
00634 
00635         case IDC_STOP:
00636             webNavigation->Stop(nsIWebNavigation::STOP_ALL);
00637             UpdateUI(chrome);
00638             break;
00639 
00640         case IDC_RELOAD:
00641             webNavigation->Reload(nsIWebNavigation::LOAD_FLAGS_NONE);
00642             break;
00643 
00644         case IDM_EXIT:
00645             WinPostMsg(hwndDlg, WM_SYSCOMMAND, MPFROMSHORT(SC_CLOSE), 0);
00646             break;
00647 
00648         // File menu commands
00649 
00650         case MOZ_NewBrowser:
00651             OpenWebPage(gFirstURL);
00652             break;
00653 
00654         case MOZ_Save:
00655             SaveWebPage(hwndDlg, webBrowser);
00656             break;
00657 
00658         case MOZ_Print:
00659             {
00660                 // NOTE: Embedding code shouldn't need to get the docshell or
00661                 //       contentviewer AT ALL. This code below will break one
00662                 //       day but will have to do until the embedding API has
00663                 //       a cleaner way to do the same thing.
00664               if (webBrowserPrint)
00665               {
00666                   nsCOMPtr<nsIPrintSettings> printSettings;
00667                   webBrowserPrint->GetGlobalPrintSettings(getter_AddRefs(printSettings));
00668                   NS_ASSERTION(printSettings, "You can't PrintPreview without a PrintSettings!");
00669                   if (printSettings) 
00670                   {
00671                       printSettings->SetPrintSilent(PR_TRUE);
00672                       webBrowserPrint->Print(printSettings, (nsIWebProgressListener*)nsnull);
00673                   }
00674               }
00675             }
00676             break;
00677 
00678         // Edit menu commands
00679 
00680         case MOZ_Cut:
00681             {
00682                 nsCOMPtr<nsIClipboardCommands> clipCmds = do_GetInterface(webBrowser);
00683                 clipCmds->CutSelection();
00684             }
00685             break;
00686 
00687         case MOZ_Copy:
00688             {
00689                 nsCOMPtr<nsIClipboardCommands> clipCmds = do_GetInterface(webBrowser);
00690                 clipCmds->CopySelection();
00691             }
00692             break;
00693 
00694         case MOZ_Paste:
00695             {
00696                 nsCOMPtr<nsIClipboardCommands> clipCmds = do_GetInterface(webBrowser);
00697                 clipCmds->Paste();
00698             }
00699             break;
00700 
00701         case MOZ_SelectAll:
00702             {
00703                 nsCOMPtr<nsIClipboardCommands> clipCmds = do_GetInterface(webBrowser);
00704                 clipCmds->SelectAll();
00705             }
00706             break;
00707 
00708         case MOZ_SelectNone:
00709             {
00710                 nsCOMPtr<nsIClipboardCommands> clipCmds = do_GetInterface(webBrowser);
00711                 clipCmds->SelectNone();
00712             }
00713             break;
00714 
00715         // Go menu commands
00716         case IDC_BACK:
00717         case MOZ_GoBack:
00718             webNavigation->GoBack();
00719             UpdateUI(chrome);
00720             break;
00721 
00722         case IDC_FORWARD:
00723         case MOZ_GoForward:
00724             webNavigation->GoForward();
00725             UpdateUI(chrome);
00726             break;
00727 
00728         // Help menu commands
00729         case MOZ_About:
00730             {
00731                 char szAboutTitle[MAX_LOADSTRING];
00732                 char szAbout[MAX_LOADSTRING];
00733                 WinLoadString((HAB)0, ghInstanceResources, IDS_ABOUT_TITLE, MAX_LOADSTRING, szAboutTitle);
00734                 WinLoadString((HAB)0, ghInstanceResources, IDS_ABOUT, MAX_LOADSTRING, szAbout);
00735                 WinMessageBox(HWND_DESKTOP, NULL, szAbout, szAboutTitle, 0, MB_OK | MB_APPLMODAL);
00736             }
00737             break;
00738               }
00739 
00740            return (MRESULT)TRUE;
00741 
00742     case WM_ACTIVATE:
00743         {
00744             nsCOMPtr<nsIWebBrowserFocus> focus(do_GetInterface(webBrowser));
00745             if(focus)
00746             {
00747                 switch (SHORT1FROMMP(wParam))
00748                 {
00749                 case TRUE: //WA_ACTIVE:
00750                     focus->Activate();
00751                     break;
00752                 case FALSE: //WA_INACTIVE:
00753                     focus->Deactivate();
00754                     break;
00755                 default:
00756                     break;
00757                 }
00758             }
00759         }
00760         break;
00761 
00762     case WM_ADJUSTWINDOWPOS: 
00763         {
00764             PSWP swp = (PSWP)wParam;
00765             if (swp->fl & (SWP_SIZE)) {
00766                UINT newDlgWidth = swp->cx;
00767                UINT newDlgHeight = swp->cy;
00768 
00769                // TODO Reposition the control bar - for the moment it's fixed size
00770                // Reposition all buttons, combobox, status, progress bar, and browser
00771                // Status bar gets any space that the fixed size progress bar doesn't use.
00772                // Address combobox gets any space not used by buttons and 'Address:'
00773                int progressWidth, statusWidth, addressWidth, goWidth, forwardWidth, reloadWidth, stopWidth, backWidth, staticWidth;
00774                int statusHeight, backHeight, buttonHeight, addressHeight, comboboxHeight;
00775 
00776                HWND hwndStatus = WinWindowFromID(hwndDlg, IDC_STATUS);
00777                if (hwndStatus) {
00778                  RECTL rcStatus;
00779                  WinQueryWindowRect(hwndStatus, &rcStatus);
00780                  statusHeight = rcStatus.yTop - rcStatus.yBottom;
00781                } else
00782                  statusHeight = 0;
00783    
00784                HWND hwndProgress = WinWindowFromID(hwndDlg, IDC_PROGRESS);
00785                if (hwndProgress) {
00786                  RECTL rcProgress;
00787                  WinQueryWindowRect(hwndProgress, &rcProgress);
00788                  progressWidth = rcProgress.xRight - rcProgress.xLeft;
00789                } else
00790                  progressWidth = 0;
00791                statusWidth = newDlgWidth - progressWidth;
00792    
00793                HWND hwndBack = WinWindowFromID(hwndDlg, IDC_BACK);
00794                if (hwndBack) {
00795                  RECTL rcBack;
00796                  WinQueryWindowRect(hwndBack, &rcBack);
00797                  backHeight = rcBack.yTop - rcBack.yBottom;
00798                  backWidth = rcBack.xRight - rcBack.xLeft;
00799                } else {
00800                  backHeight = 0;
00801                  backWidth = 0;
00802                }
00803                buttonHeight = newDlgHeight - backHeight - 50;//24;
00804 
00805                HWND hwndForward = WinWindowFromID(hwndDlg, IDC_FORWARD);
00806                if (hwndForward) {
00807                  RECTL rcForward;
00808                  WinQueryWindowRect(hwndForward, &rcForward);
00809                  forwardWidth = rcForward.xRight - rcForward.xLeft;
00810                } else
00811                  forwardWidth = 0;
00812 
00813                HWND hwndReload = WinWindowFromID(hwndDlg, IDC_RELOAD);
00814                if (hwndReload) {
00815                  RECTL rcReload;
00816                  WinQueryWindowRect(hwndReload, &rcReload);
00817                  reloadWidth = rcReload.xRight - rcReload.xLeft;
00818                } else
00819                  reloadWidth = 0;
00820 
00821                HWND hwndStop = WinWindowFromID(hwndDlg, IDC_STOP);
00822                if (hwndStop) {
00823                  RECTL rcStop;
00824                  WinQueryWindowRect(hwndStop, &rcStop);
00825                  stopWidth = rcStop.xRight - rcStop.xLeft;
00826                } else
00827                  stopWidth = 0;
00828 
00829                HWND hwndStatic = WinWindowFromID(hwndDlg, IDC_ADDRESSLABEL);
00830                if (hwndStatic) {
00831                  RECTL rcStatic;
00832                  WinQueryWindowRect(hwndStatic, &rcStatic);
00833                  staticWidth = rcStatic.xRight - rcStatic.xLeft;
00834                } else
00835                  staticWidth = 0;
00836 
00837                HWND hwndGo = WinWindowFromID(hwndDlg, IDC_GO);
00838                if (hwndGo) {
00839                  RECTL rcGo;
00840                  WinQueryWindowRect(hwndGo, &rcGo);
00841                  goWidth = rcGo.xRight - rcGo.xLeft;
00842                } else
00843                  goWidth = 0;
00844 
00845                HWND hwndAddress = WinWindowFromID(hwndDlg, IDC_ADDRESS);
00846                if (hwndAddress) {
00847                  RECTL rcAddress;
00848                  WinQueryWindowRect(hwndAddress, &rcAddress);
00849                  addressHeight = rcAddress.yTop - rcAddress.yBottom;
00850                  comboboxHeight = buttonHeight + backHeight - addressHeight;
00851                } else {
00852                  addressHeight = 0;
00853                  comboboxHeight = 0;
00854                }
00855                addressWidth = newDlgWidth - goWidth - backWidth - forwardWidth - reloadWidth - stopWidth - staticWidth - 15;
00856 
00857                if (hwndStatus)
00858                  WinSetWindowPos(hwndStatus,
00859                                  HWND_TOP,
00860                                  0, 0, 
00861                                  statusWidth,
00862                                  statusHeight,
00863                                  SWP_MOVE | SWP_SIZE | SWP_SHOW);
00864                if (hwndProgress)
00865                  WinSetWindowPos(hwndProgress,
00866                                  HWND_TOP,
00867                                  statusWidth, 0, 
00868                                  0, 0,
00869                                  SWP_MOVE | SWP_SHOW);
00870                if (hwndBack)
00871                  WinSetWindowPos(hwndBack,
00872                                  HWND_TOP,
00873                                  2, buttonHeight,
00874                                  0, 0,
00875                                  SWP_MOVE | SWP_SHOW);
00876                if (hwndForward)
00877                  WinSetWindowPos(hwndForward,
00878                                  HWND_TOP,
00879                                  2 + backWidth, buttonHeight, 
00880                                  0, 0,
00881                                  SWP_MOVE | SWP_SHOW);
00882                if (hwndReload)
00883                  WinSetWindowPos(hwndReload,
00884                                  HWND_TOP,
00885                                  4 + backWidth + forwardWidth, buttonHeight,
00886                                  0, 0,
00887                                  SWP_MOVE | SWP_SHOW);
00888                if (hwndStop)
00889                  WinSetWindowPos(hwndStop,
00890                                  HWND_TOP,
00891                                  5 + backWidth + forwardWidth + reloadWidth, buttonHeight, 
00892                                  0, 0,
00893                                  SWP_MOVE | SWP_SHOW);
00894                if (hwndStatic)
00895                  WinSetWindowPos(hwndStatic,
00896                                  HWND_TOP,
00897                                  9 + backWidth + forwardWidth + reloadWidth + stopWidth, buttonHeight + 3,
00898                                  0, 0,
00899                                  SWP_MOVE | SWP_SHOW);
00900                if (hwndAddress)
00901                  WinSetWindowPos(hwndAddress,
00902                                  HWND_TOP,
00903                                  12 + backWidth + forwardWidth + reloadWidth + stopWidth + staticWidth, comboboxHeight,
00904                                  addressWidth, addressHeight,
00905                                  SWP_MOVE | SWP_SIZE | SWP_SHOW);
00906                if (hwndGo)
00907                  WinSetWindowPos(hwndGo,
00908                                  HWND_TOP,
00909                                  13 + backWidth + forwardWidth + reloadWidth + stopWidth + staticWidth + addressWidth, buttonHeight,
00910                                  0, 0,
00911                                  SWP_MOVE | SWP_SHOW);
00912 
00913                // Resize the browser area (assuming the browser is
00914                // sandwiched between the control bar and status area)
00915                WinSetWindowPos(hwndBrowser,
00916                                HWND_TOP,
00917                                2, statusHeight,
00918                                newDlgWidth - 4,
00919                                newDlgHeight - backHeight - statusHeight - 52,
00920                                SWP_MOVE | SWP_SIZE | SWP_SHOW);
00921             }
00922         }
00923         return (MRESULT)TRUE;
00924     }
00925     return WinDefDlgProc(hwndDlg, uMsg, wParam, lParam);
00926 }
00927 
00928 
00929 //
00930 //  FUNCTION: BrowserWndProc(HWND, unsigned, WORD, LONG)
00931 //
00932 //  PURPOSE:  Processes messages for the browser container window.
00933 //
00934 MRESULT EXPENTRY BrowserWndProc(HWND hWnd, ULONG message, MPARAM wParam, MPARAM lParam)
00935 {
00936     nsIWebBrowserChrome *chrome = (nsIWebBrowserChrome *) WinQueryWindowULong(hWnd, QWL_USER);
00937        switch (message) 
00938        {
00939     case WM_SIZE:
00940         // Resize the embedded browser
00941         ResizeEmbedding(chrome);
00942         return (MRESULT)0;
00943     case WM_ERASEBACKGROUND:
00944         // Reduce flicker by not painting the non-visible background
00945         return (MRESULT)1;
00946     }
00947     return WinDefWindowProc(hWnd, message, wParam, lParam);
00948 }
00949 
00950 
00952 // Profile chooser dialog
00953 
00954 
00955 //
00956 //  FUNCTION: ChooseNewProfile()
00957 //
00958 //  PURPOSE: Allows the user to select a new profile from a list.
00959 //           The bShowForMultipleProfilesOnly argument specifies whether the
00960 //           function should automatically select the first profile and return
00961 //           without displaying a dialog box if there is only one profile to
00962 //           select.
00963 //
00964 BOOL ChooseNewProfile(BOOL bShowForMultipleProfilesOnly, const char *szDefaultProfile)
00965 {
00966     nsresult rv;
00967     nsCOMPtr<nsIProfile> profileService = 
00968              do_GetService(NS_PROFILE_CONTRACTID, &rv);
00969     if (NS_FAILED(rv))
00970     {
00971         return FALSE;
00972     }
00973 
00974     if (szDefaultProfile)
00975     {
00976         // Make a new default profile
00977         nsAutoString newProfileName; newProfileName.AssignWithConversion(szDefaultProfile);
00978         rv = profileService->CreateNewProfile(newProfileName.get(), nsnull, nsnull, PR_FALSE);
00979         if (NS_FAILED(rv)) return FALSE;
00980         rv = profileService->SetCurrentProfile(newProfileName.get());
00981         if (NS_FAILED(rv)) return FALSE;
00982         return TRUE;
00983     }
00984 
00985     PRInt32 profileCount = 0;
00986     rv = profileService->GetProfileCount(&profileCount);
00987     if (profileCount == 0)
00988     {
00989         // Make a new default profile
00990         NS_NAMED_LITERAL_STRING(newProfileName, "os2Embed");
00991         rv = profileService->CreateNewProfile(newProfileName.get(), nsnull, nsnull, PR_FALSE);
00992         if (NS_FAILED(rv)) return FALSE;
00993         rv = profileService->SetCurrentProfile(newProfileName.get());
00994         if (NS_FAILED(rv)) return FALSE;
00995         return TRUE;
00996     }
00997     else if (profileCount == 1 && bShowForMultipleProfilesOnly)
00998     {
00999         // GetCurrentProfile returns the profile which was last used but is not nescesarily
01000         // active. Call SetCurrentProfile to make it installed and active.
01001         
01002         nsXPIDLString   currProfileName;
01003         rv = profileService->GetCurrentProfile(getter_Copies(currProfileName));
01004         if (NS_FAILED(rv)) return FALSE;
01005         rv = profileService->SetCurrentProfile(currProfileName);
01006         if (NS_FAILED(rv)) return FALSE;
01007         return TRUE;
01008     }
01009 
01010     INT nResult;
01011     nResult = WinDlgBox(HWND_DESKTOP, HWND_DESKTOP, (PFNWP)ChooseProfileDlgProc, NULL, IDD_CHOOSEPROFILE, (PVOID)ghInstanceResources);
01012     return (nResult == DID_OK) ? TRUE : FALSE;
01013 }
01014 
01015 
01016 //
01017 //  FUNCTION: ChooseProfileDlgProc(HWND, unsigned, WORD, LONG)
01018 //
01019 //  PURPOSE:  Dialog handler procedure for the open uri dialog.
01020 //
01021 MRESULT EXPENTRY ChooseProfileDlgProc(HWND hDlg, ULONG message, MPARAM wParam, MPARAM lParam)
01022 {
01023     nsresult rv;
01024        switch (message)
01025        {
01026        case WM_INITDLG:
01027         {
01028             WinSetActiveWindow(HWND_DESKTOP, hDlg);
01029             HWND hwndProfileList = WinWindowFromID(hDlg, IDC_PROFILELIST);
01030 
01031             nsCOMPtr<nsIProfile> profileService = 
01032                      do_GetService(NS_PROFILE_CONTRACTID, &rv);
01033 
01034             // Get the list of profile names and add them to the list box
01035             PRUint32 listLen = 0;
01036             PRUnichar **profileList = nsnull;
01037             rv = profileService->GetProfileList(&listLen, &profileList);
01038             for (PRUint32 index = 0; index < listLen; index++)
01039             {
01040 #ifdef UNICODE
01041                 WinSendMsg(hwndProfileList, LM_INSERTITEM, (MPARAM)LIT_END, (MPARAM) profileList[index]);
01042 #else
01043                 nsCAutoString profile; profile.AssignWithConversion(profileList[index]);
01044                 WinSendMsg(hwndProfileList, LM_INSERTITEM, (MPARAM)LIT_END, (MPARAM) profile.get());
01045 #endif
01046             }
01047 
01048             // Select the current profile (if there is one)
01049 
01050             // Get the current profile
01051 #ifdef UNICODE
01052             nsXPIDLString currProfile;
01053             profileService->GetCurrentProfile(getter_Copies(currProfile));
01054 #else
01055             nsXPIDLString currProfileUnicode;
01056             profileService->GetCurrentProfile(getter_Copies(currProfileUnicode));
01057             nsCAutoString currProfile; currProfile.AssignWithConversion(currProfileUnicode);
01058 #endif
01059 
01060             // Now find and select it
01061             LONG currentProfileIndex = LIT_ERROR;
01062             currentProfileIndex = (LONG)WinSendMsg(hwndProfileList, LM_SEARCHSTRING, MPFROM2SHORT(LSS_CASESENSITIVE, LIT_FIRST), (MPARAM) currProfile.get());
01063             if (currentProfileIndex != LIT_ERROR)
01064             {
01065                 WinSendMsg(hwndProfileList, LM_SELECTITEM, (MPARAM)currentProfileIndex, (MPARAM)TRUE);
01066             }
01067         
01068               return (MRESULT)TRUE;
01069         }
01070      case WM_COMMAND:
01071         if (SHORT1FROMMP(wParam) == DID_OK)
01072         {
01073             HWND hwndProfileList = WinWindowFromID(hDlg, IDC_PROFILELIST);
01074 
01075             // Get the selected profile from the list box and make it current
01076             LONG currentProfileIndex = (LONG)WinSendMsg(hwndProfileList, LM_QUERYSELECTION, (MPARAM)LIT_FIRST, (MPARAM)0);
01077             if (currentProfileIndex != LIT_ERROR)
01078             {
01079                 nsCOMPtr<nsIProfile> profileService = 
01080                          do_GetService(NS_PROFILE_CONTRACTID, &rv);
01081                 // Convert TCHAR name to unicode and make it current
01082                 INT profileNameLen = (INT)WinSendMsg(hwndProfileList, LM_QUERYITEMTEXTLENGTH, (MPARAM)currentProfileIndex, 0);
01083                 char *profileName = new char[profileNameLen + 1];
01084                 WinSendMsg(hwndProfileList, LM_QUERYITEMTEXT, MPFROM2SHORT(currentProfileIndex, profileNameLen + 1) ,(MPARAM)profileName);
01085                 nsAutoString newProfile; newProfile.AssignWithConversion(profileName);
01086                 rv = profileService->SetCurrentProfile(newProfile.get());
01087             }
01088                WinDismissDlg(hDlg, DID_OK);
01089         }
01090               else if (SHORT1FROMMP(wParam) == DID_CANCEL)
01091               {
01092                WinDismissDlg(hDlg, SHORT1FROMMP(wParam));
01093               }
01094         return (MRESULT)TRUE;
01095        }
01096 
01097     return WinDefDlgProc(hDlg, message, wParam, lParam);
01098 }
01099 
01100 
01101 
01103 // WebBrowserChromeUI
01104 
01105 //
01106 //  FUNCTION: CreateNativeWindow()
01107 //
01108 //  PURPOSE: Creates a new browser dialog.
01109 //
01110 //  COMMENTS:
01111 //
01112 //    This function loads the browser dialog from a resource template
01113 //    and returns the HWND for the webbrowser container dialog item
01114 //    to the caller.
01115 //
01116 nativeWindow WebBrowserChromeUI::CreateNativeWindow(nsIWebBrowserChrome* chrome)
01117 {
01118   // Load the browser dialog from resource
01119   HWND hwndDialog;
01120   PRUint32 chromeFlags;
01121 
01122   chrome->GetChromeFlags(&chromeFlags);
01123   if ((chromeFlags & nsIWebBrowserChrome::CHROME_ALL) == nsIWebBrowserChrome::CHROME_ALL)
01124     hwndDialog = WinLoadDlg(HWND_DESKTOP, HWND_DESKTOP, BrowserDlgProc, ghInstanceResources, IDD_BROWSER, NULL);
01125   else
01126     hwndDialog = WinLoadDlg(HWND_DESKTOP, HWND_DESKTOP, BrowserDlgProc, ghInstanceResources, IDD_BROWSER_NC, NULL);
01127   if (!hwndDialog)
01128     return NULL;
01129 
01130   // Stick a menu onto it
01131   if (chromeFlags & nsIWebBrowserChrome::CHROME_MENUBAR) {
01132     HWND hmenuDlg = WinLoadMenu(hwndDialog, 0, IDC_OS2EMBED);
01133     WinSendMsg(hwndDialog, WM_UPDATEFRAME, MPFROMLONG(FCF_MENU), 0);
01134   } else
01135     WinSendMsg(hwndDialog, WM_UPDATEFRAME, 0, 0);
01136 
01137   // Add some interesting URLs to the address drop down
01138   HWND hwndAddress = WinWindowFromID(hwndDialog, IDC_ADDRESS);
01139   if (hwndAddress) {
01140     for (int i = 0; i < sizeof(gDefaultURLs) / sizeof(gDefaultURLs[0]); i++)
01141     {
01142       WinSendMsg(hwndAddress, LM_INSERTITEM, (MPARAM)LIT_SORTASCENDING, (MPARAM)gDefaultURLs[i]);
01143     }
01144   }
01145 
01146   // Fetch the browser window handle
01147   HWND hwndBrowser = WinWindowFromID(hwndDialog, IDC_BROWSER);
01148   WinSetWindowULong(hwndBrowser, QWL_USER, (ULONG)chrome);  // save the browser LONG_PTR.
01149   WinSetWindowULong(hwndBrowser, QWL_STYLE, WinQueryWindowULong(hwndBrowser, QWL_STYLE) | WS_CLIPCHILDREN);
01150 
01151   // Activate the window
01152   WinPostMsg(hwndDialog, WM_ACTIVATE, MPFROMSHORT(TRUE), (MPARAM)0);
01153 
01154   gDialogCount++;
01155 
01156   return (void *)hwndBrowser;
01157 }
01158 
01159 
01160 //
01161 // FUNCTION: Destroy()
01162 //
01163 // PURPOSE: Destroy the window specified by the chrome
01164 //
01165 void WebBrowserChromeUI::Destroy(nsIWebBrowserChrome* chrome)
01166 {
01167   nsCOMPtr<nsIWebBrowser> webBrowser;
01168   nsCOMPtr<nsIWebNavigation> webNavigation;
01169 
01170   chrome->GetWebBrowser(getter_AddRefs(webBrowser));
01171   webNavigation = do_QueryInterface(webBrowser);
01172   if (webNavigation)
01173     webNavigation->Stop(nsIWebNavigation::STOP_ALL);
01174 
01175   chrome->ExitModalEventLoop(NS_OK);
01176 
01177   HWND hwndDlg = GetBrowserDlgFromChrome(chrome);
01178   if (hwndDlg == NULL)
01179     return;
01180 
01181   // Explicitly destroy the embedded browser and then the chrome
01182 
01183   // First the browser
01184   nsCOMPtr<nsIWebBrowser> browser = nsnull;
01185   chrome->GetWebBrowser(getter_AddRefs(browser));
01186   nsCOMPtr<nsIBaseWindow> browserAsWin = do_QueryInterface(browser);
01187   if (browserAsWin)
01188     browserAsWin->Destroy();
01189 
01190       // Now the chrome
01191   chrome->SetWebBrowser(nsnull);
01192   NS_RELEASE(chrome);
01193 }
01194 
01195 
01196 //
01197 // FUNCTION: Called as the final act of a chrome object during its destructor
01198 //
01199 void WebBrowserChromeUI::Destroyed(nsIWebBrowserChrome* chrome)
01200 {
01201     HWND hwndDlg = GetBrowserDlgFromChrome(chrome);
01202        if (hwndDlg == NULL)
01203        {
01204               return;
01205        }
01206 
01207     // Clear the window user data
01208     HWND hwndBrowser = WinWindowFromID(hwndDlg, IDC_BROWSER);
01209     WinSetWindowULong(hwndBrowser, QWL_USER, nsnull);
01210     WinDestroyWindow(hwndBrowser);
01211     WinDestroyWindow(hwndDlg);
01212 
01213     --gDialogCount;
01214     if (gDialogCount == 0)
01215     {
01216         if (gProfileSwitch)
01217         {
01218             gProfileSwitch = FALSE;
01219             OpenWebPage(gFirstURL);
01220         }
01221         else
01222         {
01223             // Quit when there are no more browser objects
01224             WinPostQueueMsg(0, WM_QUIT, 0, 0);
01225         }
01226     }
01227 }
01228 
01229 
01230 //
01231 // FUNCTION: Set the input focus onto the browser window
01232 //
01233 void WebBrowserChromeUI::SetFocus(nsIWebBrowserChrome *chrome)
01234 {
01235     HWND hwndDlg = GetBrowserDlgFromChrome(chrome);
01236        if (hwndDlg == NULL)
01237        {
01238               return;
01239        }
01240     
01241     HWND hwndBrowser = WinWindowFromID(hwndDlg, IDC_BROWSER);
01242     ::WinSetFocus(HWND_DESKTOP, hwndBrowser);
01243 }
01244 
01245 //
01246 //  FUNCTION: UpdateStatusBarText()
01247 //
01248 //  PURPOSE: Set the status bar text.
01249 //
01250 void WebBrowserChromeUI::UpdateStatusBarText(nsIWebBrowserChrome *aChrome, const PRUnichar* aStatusText)
01251 {
01252     HWND hwndDlg = GetBrowserDlgFromChrome(aChrome);
01253     nsCString status; 
01254     if (aStatusText)
01255         status.AssignWithConversion(aStatusText);
01256     WinSetDlgItemText(hwndDlg, IDC_STATUS, status.get());
01257 }
01258 
01259 
01260 //
01261 //  FUNCTION: UpdateCurrentURI()
01262 //
01263 //  PURPOSE: Updates the URL address field
01264 //
01265 void WebBrowserChromeUI::UpdateCurrentURI(nsIWebBrowserChrome *aChrome)
01266 {
01267     nsCOMPtr<nsIWebBrowser> webBrowser;
01268     nsCOMPtr<nsIWebNavigation> webNavigation;
01269     aChrome->GetWebBrowser(getter_AddRefs(webBrowser));
01270     webNavigation = do_QueryInterface(webBrowser);
01271 
01272     nsCOMPtr<nsIURI> currentURI;
01273     webNavigation->GetCurrentURI(getter_AddRefs(currentURI));
01274     if (currentURI)
01275     {
01276         nsCAutoString uriString;
01277         currentURI->GetAsciiSpec(uriString);
01278         HWND hwndDlg = GetBrowserDlgFromChrome(aChrome);
01279         WinSetDlgItemText(hwndDlg, IDC_ADDRESS, uriString.get());
01280     }
01281 }
01282 
01283 
01284 //
01285 //  FUNCTION: UpdateBusyState()
01286 //
01287 //  PURPOSE: Refreshes the stop/go buttons in the browser dialog
01288 //
01289 void WebBrowserChromeUI::UpdateBusyState(nsIWebBrowserChrome *aChrome, PRBool aBusy)
01290 {
01291     HWND hwndDlg = GetBrowserDlgFromChrome(aChrome);
01292     HWND button;
01293     button = WinWindowFromID(hwndDlg, IDC_STOP);
01294     if (button)
01295         WinEnableWindow(button, aBusy);
01296     button = WinWindowFromID(hwndDlg, IDC_GO);
01297     if (button)
01298         WinEnableWindow(button, !aBusy);
01299     UpdateUI(aChrome);
01300 }
01301 
01302 
01303 //
01304 //  FUNCTION: UpdateProgress()
01305 //
01306 //  PURPOSE: Refreshes the progress bar in the browser dialog
01307 //
01308 void WebBrowserChromeUI::UpdateProgress(nsIWebBrowserChrome *aChrome, PRInt32 aCurrent, PRInt32 aMax)
01309 {
01310     HWND hwndDlg = GetBrowserDlgFromChrome(aChrome);
01311     HWND hwndProgress = WinWindowFromID(hwndDlg, IDC_PROGRESS);
01312     if (aCurrent < 0)
01313     {
01314         aCurrent = 0;
01315     }
01316     if (aCurrent > aMax)
01317     {
01318         aMax = aCurrent + 20; // What to do?
01319     }
01320     if (hwndProgress)
01321     {
01322         ULONG value = (double)aCurrent/(double)aMax*(double)100;
01323         WinSendMsg(hwndProgress, SLM_SETSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), (MPARAM)(value == 100? value-1: value));
01324     }
01325 }
01326 
01327 //
01328 //  FUNCTION: ShowContextMenu()
01329 //
01330 //  PURPOSE: Display a context menu for the given node
01331 //
01332 void WebBrowserChromeUI::ShowContextMenu(nsIWebBrowserChrome *aChrome, PRUint32 aContextFlags, nsIDOMEvent *aEvent, nsIDOMNode *aNode)
01333 {
01334     // TODO code to test context flags and display a popup menu should go here
01335 }
01336 
01337 //
01338 //  FUNCTION: ShowTooltip()
01339 //
01340 //  PURPOSE: Show a tooltip
01341 //
01342 void WebBrowserChromeUI::ShowTooltip(nsIWebBrowserChrome *aChrome, PRInt32 aXCoords, PRInt32 aYCoords, const PRUnichar *aTipText)
01343 {
01344     // TODO code to show a tooltip should go here
01345 }
01346 
01347 //
01348 //  FUNCTION: HideTooltip()
01349 //
01350 //  PURPOSE: Hide the tooltip
01351 //
01352 void WebBrowserChromeUI::HideTooltip(nsIWebBrowserChrome *aChrome)
01353 {
01354     // TODO code to hide a tooltip should go here
01355 }
01356 
01357 void WebBrowserChromeUI::ShowWindow(nsIWebBrowserChrome *aChrome, PRBool aShow)
01358 {
01359   HWND win = GetBrowserDlgFromChrome(aChrome);
01360   ::WinShowWindow(win, aShow);
01361 }
01362 
01363 void WebBrowserChromeUI::SizeTo(nsIWebBrowserChrome *aChrome, PRInt32 aWidth, PRInt32 aHeight)
01364 {
01365   HWND hchrome = GetBrowserDlgFromChrome(aChrome);
01366   HWND hbrowser = GetBrowserFromChrome(aChrome);
01367   RECTL chromeRect, browserRect;
01368 
01369   ::WinQueryWindowRect(hchrome,  &chromeRect);
01370   ::WinQueryWindowRect(hbrowser, &browserRect);
01371 
01372   PRInt32 decoration_x = (browserRect.xLeft - chromeRect.xLeft) + 
01373                          (chromeRect.xRight - browserRect.xRight);
01374   PRInt32 decoration_y = (chromeRect.yTop - browserRect.yTop) + 
01375                          (browserRect.yBottom - chromeRect.yBottom);
01376 
01377   ::WinSetWindowPos(hchrome, HWND_TOP, WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN)/2 - (aWidth+decoration_x)/2,
01378                     WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN)/2 - (aHeight+decoration_y)/2, 
01379                     aWidth+decoration_x, aHeight+decoration_y, SWP_SIZE | SWP_MOVE | SWP_SHOW);
01380 }
01381 
01382 //
01383 //  FUNCTION: GetResourceStringByID()
01384 //
01385 //  PURPOSE: Get the resource string for the ID
01386 //
01387 void WebBrowserChromeUI::GetResourceStringById(PRInt32 aID, char ** aReturn)
01388 {
01389     char resBuf[MAX_LOADSTRING];
01390     int retval = WinLoadString((HAB)0, ghInstanceResources, aID, sizeof(resBuf), (PSZ)resBuf );
01391     if (retval != 0)
01392     {
01393         int resLen = strlen(resBuf);
01394         *aReturn = (char *)calloc(resLen+1, sizeof(char *));
01395         if (!*aReturn) return;
01396             PL_strncpy(*aReturn, (char *) resBuf, resLen);
01397     }
01398     return;
01399 }
01400 
01401 //-----------------------------------------------------------------------------
01402 
01403 nsresult CreateBrowserWindow(PRUint32 aChromeFlags,
01404                              nsIWebBrowserChrome *aParent,
01405                              nsIWebBrowserChrome **aNewWindow)
01406 {
01407   WebBrowserChrome * chrome = new WebBrowserChrome();
01408   if (!chrome)
01409     return NS_ERROR_FAILURE;
01410 
01411   // the interface to return and one addref, which we assume will be
01412   // immediately released
01413   CallQueryInterface(NS_STATIC_CAST(nsIWebBrowserChrome*, chrome), aNewWindow);
01414   // now an extra addref; the window owns itself (to be released by
01415   // WebBrowserChromeUI::Destroy)
01416   NS_ADDREF(*aNewWindow);
01417 
01418   chrome->SetChromeFlags(aChromeFlags);
01419   chrome->SetParent(aParent);
01420 
01421   // Insert the browser
01422   nsCOMPtr<nsIWebBrowser> newBrowser;
01423   chrome->CreateBrowser(-1, -1, -1, -1, getter_AddRefs(newBrowser));
01424   if (!newBrowser)
01425     return NS_ERROR_FAILURE;
01426 
01427   // Place it where we want it.
01428   ResizeEmbedding(NS_STATIC_CAST(nsIWebBrowserChrome*, chrome));
01429 
01430   // Subscribe new window to profile changes so it can kill itself when one happens
01431   nsCOMPtr<nsIObserverService> observerService(do_GetService("@mozilla.org/observer-service;1"));
01432   if (observerService)
01433     observerService->AddObserver(NS_STATIC_CAST(nsIObserver *, chrome),
01434                                  "profile-change-teardown", PR_TRUE);
01435 
01436   // if opened as chrome, it'll be made visible after the chrome has loaded.
01437   // otherwise, go ahead and show it now.
01438   if (!(aChromeFlags & nsIWebBrowserChrome::CHROME_OPENAS_CHROME))
01439     WebBrowserChromeUI::ShowWindow(*aNewWindow, PR_TRUE);
01440 
01441   return NS_OK;
01442 }
01443 
01444 void EnableChromeWindow(nsIWebBrowserChrome *aWindow,
01445                         PRBool aEnabled)
01446 {
01447   HWND hwnd = GetBrowserDlgFromChrome(aWindow);
01448   ::WinEnableWindow(hwnd, aEnabled ? TRUE : FALSE);
01449 }
01450 
01451 PRUint32 RunEventLoop(PRBool &aRunCondition)
01452 {
01453   QMSG msg;
01454   HEV hFakeEvent = 0; 
01455   ::DosCreateEventSem(NULL, &hFakeEvent, 0L, FALSE);
01456 
01457   while (aRunCondition ) {
01458     // Process pending messages
01459     while (::WinPeekMsg((HAB)0, &msg, NULL, 0, 0, PM_NOREMOVE)) {
01460       if (!::WinGetMsg((HAB)0, &msg, NULL, 0, 0)) {
01461         // WM_QUIT
01462         aRunCondition = PR_FALSE;
01463         break;
01464       }
01465 
01466       PRBool wasHandled = PR_FALSE;
01467       ::NS_HandleEmbeddingEvent(msg, wasHandled);
01468       if (wasHandled)
01469         continue;
01470 
01471       ::WinDispatchMsg((HAB)0, &msg);
01472     }
01473 
01474     // Do idle stuff
01475     ::DosWaitEventSem(hFakeEvent, 100);
01476   }
01477   ::DosCloseEventSem(hFakeEvent);
01478   return LONGFROMMP(msg.mp1);
01479 }