Back to index

lightning-sunbird  0.9+nobinonly
mozEmbed.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: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org Code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 2001
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Radha Kulkarni <radha@netscape.com>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either the GNU General Public License Version 2 or later (the "GPL"), or
00027  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #include <stdio.h>
00040 #include "stdafx.h"
00041 
00042 // Win32 header files
00043 #include "windows.h"
00044 #include "commctrl.h"
00045 #include "commdlg.h"
00046 
00047 // Mozilla header files
00048 #include "nsCOMPtr.h"
00049 #include "nsEmbedAPI.h"
00050 #include "nsWeakReference.h"
00051 #include "nsIClipboardCommands.h"
00052 #include "nsXPIDLString.h"
00053 #include "nsIWebBrowserPersist.h"
00054 #include "nsIWebBrowserFocus.h"
00055 #include "nsIWindowWatcher.h"
00056 #include "nsIProfile.h"
00057 //#include "nsIObserverService.h"
00058 #include "nsIObserver.h"
00059 #include "nsIProfileChangeStatus.h"
00060 #include "nsIURI.h"
00061 #include "plstr.h"
00062 #include "nsIInterfaceRequestor.h"
00063 #include "nsCRT.h"
00064 #include "nsString.h"
00065 
00066 #include "nsIWebBrowser.h"
00067 #include "nsIComponentManager.h"
00068 #include "nsServiceManagerUtils.h"
00069 #include "nsIEmbeddingSiteWindow.h"
00070 #include "nsIWebNavigation.h"
00071 #include "nsIWebBrowserChrome.h"
00072 #include "nsIInterfaceRequestorUtils.h"
00073 #include "nsIComponentRegistrar.h"
00074 #include "nsIModule.h"
00075 #include "nsIGenericFactory.h"
00076 
00077 // Local header files
00078 //#include "nsIQABrowserChrome.h"
00079 #include "mozEmbed.h"
00080 #include "nsQAWindowCreator.h"
00081 #include "resource.h"
00082 #include "nsQABrowserCID.h"
00083 #include "nsQABrowserUIGlue.h"
00084 //#include "nsIQABrowserView.h"
00085 
00086 
00087 // Printing header files
00088 #include "nsIPrintSettings.h"
00089 #include "nsIWebBrowserPrint.h"
00090 
00091 
00092 #define MAX_LOADSTRING 100
00093 #define MAX_BROWSER_ALLOWED 50
00094 
00095 const TCHAR *szWindowClass = _T("MOZEMBED");
00096 
00097 // Forward declarations of functions included in this code module:
00098 static ATOM             MyRegisterClass(HINSTANCE hInstance);
00099 static LRESULT CALLBACK BrowserWndProc(HWND, UINT, WPARAM, LPARAM);
00100 static BOOL    CALLBACK BrowserDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
00101 static nsresult InitializeWindowCreator();
00102 static nsresult OpenWebPage(const char * url);
00103 static nsresult ResizeEmbedding(nsIWebBrowserChrome* chrome);
00104 // Profile chooser stuff
00105 static BOOL ChooseNewProfile(BOOL bShowForMultipleProfilesOnly, const char *szDefaultProfile);
00106 static LRESULT CALLBACK ChooseProfileDlgProc(HWND, UINT, WPARAM, LPARAM);
00107 extern nsresult RegisterComponents();
00108 
00109 // Global variables
00110 static UINT gDialogCount = 0;
00111 static BOOL gProfileSwitch = FALSE;
00112 static HINSTANCE ghInstanceResources = NULL;
00113 static HINSTANCE ghInstanceApp = NULL;
00114 static char gFirstURL[1024];
00115 
00116 // A list of URLs to populate the URL drop down list with
00117 static const TCHAR *gDefaultURLs[] = 
00118 {
00119     _T("http://www.mozilla.org/"),
00120     _T("http://www.netscape.com/"),
00121     _T("http://browsertest.web.aol.com/tests/javascript/javascpt/index.htm"),
00122     _T("http://127.0.0.1/"),
00123     _T("http://www.yahoo.com/"),
00124     _T("http://www.travelocity.com/"),
00125     _T("http://www.disney.com/"),
00126     _T("http://www.go.com/"),
00127     _T("http://www.google.com/"),
00128     _T("http://www.ebay.com/"),
00129     _T("http://www.shockwave.com/"),
00130     _T("http://www.slashdot.org/"),
00131     _T("http://www.quicken.com/"),
00132     _T("http://www.hotmail.com/"),
00133     _T("http://www.cnn.com/"),
00134     _T("http://www.javasoft.com/")
00135 };
00136 
00137 //
00138 //  FUNCTION: GetBrowserFromChrome()
00139 //
00140 //  PURPOSE: Returns the HWND for the webbrowser container associated
00141 //           with the specified chrome.
00142 //
00143 HWND GetBrowserFromChrome(nsIWebBrowserChrome *aChrome)
00144 {
00145   if (!aChrome)
00146   {
00147       return NULL;
00148   }
00149        nsCOMPtr<nsIEmbeddingSiteWindow> baseWindow = do_QueryInterface(aChrome);
00150   HWND hwnd = NULL;
00151        baseWindow->GetSiteWindow((void **) & hwnd);
00152   return hwnd;
00153 }
00154 
00155 //
00156 //  FUNCTION: GetBrowserDlgFromChrome()
00157 //
00158 //  PURPOSE: Returns the HWND for the browser dialog associated with
00159 //           the specified chrome.
00160 //
00161 HWND GetBrowserDlgFromChrome(nsIWebBrowserChrome *aChrome)
00162 {
00163   return GetParent(GetBrowserFromChrome(aChrome));
00164 }
00165 
00166 
00167 //
00168 //  FUNCTION: UpdateUI()
00169 //
00170 //  PURPOSE: Refreshes the buttons and menu items in the browser dialog
00171 //
00172 void UpdateUI(nsIWebBrowserChrome *aChrome)
00173 {
00174     HWND hwndDlg = GetBrowserDlgFromChrome(aChrome);
00175     nsCOMPtr<nsIWebBrowser> webBrowser;
00176     nsCOMPtr<nsIWebNavigation> webNavigation;
00177     aChrome->GetWebBrowser(getter_AddRefs(webBrowser));
00178     webNavigation = do_QueryInterface(webBrowser);
00179 
00180     PRBool canGoBack = PR_FALSE;
00181     PRBool canGoForward = PR_FALSE;
00182     if (webNavigation)
00183     {
00184         webNavigation->GetCanGoBack(&canGoBack);
00185         webNavigation->GetCanGoForward(&canGoForward);
00186     }
00187 
00188     PRBool canCutSelection = PR_FALSE;
00189     PRBool canCopySelection = PR_FALSE;
00190     PRBool canPaste = PR_FALSE;
00191 
00192     nsCOMPtr<nsIClipboardCommands> clipCmds(do_GetInterface(webBrowser));
00193     if (clipCmds)
00194     {
00195         clipCmds->CanCutSelection(&canCutSelection);
00196         clipCmds->CanCopySelection(&canCopySelection);
00197         clipCmds->CanPaste(&canPaste);
00198     }
00199 
00200     HMENU hmenu = GetMenu(hwndDlg);
00201     if (hmenu)
00202     {
00203         EnableMenuItem(hmenu, MOZ_GoBack, MF_BYCOMMAND |
00204             ((canGoBack) ? MF_ENABLED : (MF_DISABLED | MF_GRAYED)));
00205         EnableMenuItem(hmenu, MOZ_GoForward, MF_BYCOMMAND |
00206             ((canGoForward) ? MF_ENABLED : (MF_DISABLED | MF_GRAYED)));
00207 
00208         EnableMenuItem(hmenu, MOZ_Cut, MF_BYCOMMAND |
00209             ((canCutSelection) ? MF_ENABLED : (MF_DISABLED | MF_GRAYED)));
00210         EnableMenuItem(hmenu, MOZ_Copy, MF_BYCOMMAND |
00211             ((canCopySelection) ? MF_ENABLED : (MF_DISABLED | MF_GRAYED)));
00212         EnableMenuItem(hmenu, MOZ_Paste, MF_BYCOMMAND |
00213             ((canPaste) ? MF_ENABLED : (MF_DISABLED | MF_GRAYED)));
00214     }
00215 
00216     HWND button;
00217     button = GetDlgItem(hwndDlg, IDC_BACK);
00218     if (button)
00219       EnableWindow(button, canGoBack);
00220     button = GetDlgItem(hwndDlg, IDC_FORWARD);
00221     if (button)
00222       EnableWindow(button, canGoForward);
00223 }
00224 
00225 
00226 
00227 
00229 // Main program
00231 
00232 int main(int argc, char *argv[])
00233 {
00234     printf("You are embedded, man!\n\n");
00235     printf("******************************************************************\n");
00236     printf("*                                                                *\n");
00237     printf("*  IMPORTANT NOTE:                                               *\n");
00238     printf("*                                                                *\n");
00239     printf("*  WinEmbed is not supported!!! Do not raise bugs on it unless   *\n");
00240     printf("*  it is badly broken (e.g. crash on start/exit, build errors)   *\n");
00241     printf("*  or you have the patch to make it better! MFCEmbed is now our  *\n");
00242     printf("*  embedding test application on Win32 and all testing should    *\n");
00243     printf("*  be done on that.                                              *\n");
00244     printf("*                                                                *\n");
00245     printf("******************************************************************\n");
00246     printf("\n\n");
00247     
00248     // Sophisticated command-line parsing in action
00249   char *szFirstURL = "http://www.mozilla.org/projects/embedding";
00250        char *szDefaultProfile = nsnull;
00251        int argn;
00252        for (argn = 1; argn < argc; argn++)
00253        {
00254               if (stricmp("-P", argv[argn]) == 0)
00255               {
00256                      if (argn + 1 < argc)
00257                      {
00258                             szDefaultProfile = argv[++argn];
00259                      }
00260               }
00261               else
00262               {
00263                szFirstURL = argv[argn];
00264               }
00265     }
00266        strncpy(gFirstURL, szFirstURL, sizeof(gFirstURL) - 1);
00267 
00268   ghInstanceApp = GetModuleHandle(NULL);
00269   ghInstanceResources = GetModuleHandle(NULL);
00270 
00271        // Initialize global strings
00272     TCHAR szTitle[MAX_LOADSTRING];
00273        LoadString(ghInstanceResources, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
00274        MyRegisterClass(ghInstanceApp);
00275 
00276   // Init Embedding APIs
00277   NS_InitEmbedding(nsnull, nsnull);
00278   RegisterComponents();
00279 
00280        // Choose the new profile
00281   // Have to do this to initialise global history
00282        if (!ChooseNewProfile(TRUE, szDefaultProfile))
00283     {
00284         NS_TermEmbedding();
00285         return 1;
00286     }
00287 
00288   WPARAM rv;
00289   {   
00290     InitializeWindowCreator();
00291 
00292     // Open the initial browser window
00293     OpenWebPage(gFirstURL);
00294 
00295          // Main message loop.
00296     // NOTE: We use a fake event and a timeout in order to process idle stuff for
00297     //       Mozilla every 1/10th of a second.
00298     PRBool runCondition = PR_TRUE;
00299 
00300     rv = AppCallbacks::RunEventLoop(runCondition);
00301 
00302     // observer->Release();
00303   }
00304   // Close down Embedding APIs
00305   NS_TermEmbedding();
00306 
00307   return rv;
00308 }
00309 
00310 
00311 /* InitializeWindowCreator creates and hands off an object with a callback
00312    to a window creation function. This is how all new windows are opened,
00313    except any created directly by the embedding app. */
00314 nsresult InitializeWindowCreator()
00315 {
00316 
00317     printf("In InitializeWindowCreator\n");
00318     // create an nsWindowCreator and give it to the WindowWatcher service
00319     WindowCreator *creatorCallback = new WindowCreator();
00320     if (creatorCallback)
00321     {
00322         nsCOMPtr<nsIWindowCreator> windowCreator(NS_STATIC_CAST(nsIWindowCreator *, creatorCallback));
00323         if (windowCreator)
00324         {
00325             nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService("@mozilla.org/embedcomp/window-watcher;1"));
00326             if (wwatch)
00327             {
00328                 wwatch->SetWindowCreator(windowCreator);
00329                 return NS_OK;
00330             }
00331         }
00332     }
00333     return NS_ERROR_FAILURE;
00334 }
00335 
00336 //-----------------------------------------------------------------------------
00337 
00338 //
00339 //  FUNCTION: OpenWebPage()
00340 //
00341 //  PURPOSE: Opens a new browser dialog and starts it loading to the
00342 //           specified url.
00343 //
00344 nsresult OpenWebPage(const char *url)
00345 {
00346   nsresult  rv;
00347   printf("In OpenWebpage\n");
00348   
00349   if (gDialogCount == MAX_BROWSER_ALLOWED)
00350     return NS_ERROR_FAILURE;
00351 
00352   // Create the UI Glue object. This is the glue between nsIWebBrowserChrome and
00353   // the native UI code.
00354   nsCOMPtr<nsIQABrowserUIGlue> browserUIGlue;
00355   browserUIGlue = do_CreateInstance(NS_QABROWSERUIGLUE_CONTRACTID, &rv);
00356  
00357   if (!browserUIGlue)
00358     return NS_ERROR_FAILURE;
00359   
00360   // Create a new browser  window
00361   nsIWebBrowserChrome *  chrome;
00362   rv = browserUIGlue->CreateNewBrowserWindow(nsIWebBrowserChrome::CHROME_ALL, nsnull,
00363                                         &chrome);
00364   if (NS_SUCCEEDED(rv)) {
00365     browserUIGlue->LoadURL(url);
00366   }
00367   return rv;
00368 
00369 }   
00370 
00371 
00372 
00373 //
00374 //  FUNCTION: SaveWebPage()
00375 //
00376 //  PURPOSE: Saves the contents of the web page to a file
00377 //
00378 void SaveWebPage(nsIWebBrowser *aWebBrowser)
00379 {
00380   // Use the browser window title as the initial file name
00381   nsCOMPtr<nsIBaseWindow> webBrowserAsWin = do_QueryInterface(aWebBrowser);
00382        nsXPIDLString windowTitle;
00383        webBrowserAsWin->GetTitle(getter_Copies(windowTitle));
00384   nsCString fileName; fileName.AssignWithConversion(windowTitle);
00385 
00386        // Sanitize the title of all illegal characters
00387   fileName.CompressWhitespace();     // Remove whitespace from the ends
00388   fileName.StripChars("\\*|:\"><?"); // Strip illegal characters
00389   fileName.ReplaceChar('.', L'_');   // Dots become underscores
00390   fileName.ReplaceChar('/', L'-');   // Forward slashes become hyphens
00391 
00392   // Copy filename to a character buffer
00393        char szFile[_MAX_PATH];
00394   memset(szFile, 0, sizeof(szFile));
00395   PL_strncpyz(szFile, fileName.get(), sizeof(szFile) - 1); // XXXldb probably should be just sizeof(szfile)
00396 
00397   // Initialize the file save as information structure
00398   OPENFILENAME saveFileNameInfo;
00399   memset(&saveFileNameInfo, 0, sizeof(saveFileNameInfo));
00400        saveFileNameInfo.lStructSize = sizeof(saveFileNameInfo);
00401        saveFileNameInfo.hwndOwner = NULL;
00402        saveFileNameInfo.hInstance = NULL;
00403        saveFileNameInfo.lpstrFilter =
00404         "Web Page, HTML Only (*.htm;*.html)\0*.htm;*.html\0"
00405         "Web Page, Complete (*.htm;*.html)\0*.htm;*.html\0"
00406         "Text File (*.txt)\0*.txt\0"; 
00407        saveFileNameInfo.lpstrCustomFilter = NULL; 
00408        saveFileNameInfo.nMaxCustFilter = NULL; 
00409        saveFileNameInfo.nFilterIndex = 1; 
00410        saveFileNameInfo.lpstrFile = szFile; 
00411        saveFileNameInfo.nMaxFile = sizeof(szFile); 
00412        saveFileNameInfo.lpstrFileTitle = NULL;
00413        saveFileNameInfo.nMaxFileTitle = 0; 
00414        saveFileNameInfo.lpstrInitialDir = NULL; 
00415        saveFileNameInfo.lpstrTitle = NULL; 
00416        saveFileNameInfo.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; 
00417        saveFileNameInfo.nFileOffset = NULL; 
00418        saveFileNameInfo.nFileExtension = NULL; 
00419        saveFileNameInfo.lpstrDefExt = "htm"; 
00420        saveFileNameInfo.lCustData = NULL; 
00421        saveFileNameInfo.lpfnHook = NULL; 
00422        saveFileNameInfo.lpTemplateName = NULL; 
00423 
00424        if (GetSaveFileName(&saveFileNameInfo))
00425        {
00426     // Does the user want to save the complete document including
00427     // all frames, images, scripts, stylesheets etc. ?
00428     char *pszDataPath = NULL;
00429     if (saveFileNameInfo.nFilterIndex == 2) // 2nd choice means save everything
00430     {
00431       static char szDataFile[_MAX_PATH];
00432       char szDataPath[_MAX_PATH];
00433       char drive[_MAX_DRIVE];
00434       char dir[_MAX_DIR];
00435       char fname[_MAX_FNAME];
00436       char ext[_MAX_EXT];
00437 
00438       _splitpath(szFile, drive, dir, fname, ext);
00439       sprintf(szDataFile, "%s_files", fname);
00440       _makepath(szDataPath, drive, dir, szDataFile, "");
00441 
00442       pszDataPath = szDataPath;
00443     }
00444 
00445      // Save away
00446      nsCOMPtr<nsIWebBrowserPersist> persist(do_QueryInterface(aWebBrowser));
00447 
00448      nsCOMPtr<nsILocalFile> file;
00449      NS_NewNativeLocalFile(nsDependentCString(szFile), TRUE, getter_AddRefs(file));
00450 
00451      nsCOMPtr<nsILocalFile> dataPath;
00452      if (pszDataPath)
00453      {
00454         NS_NewNativeLocalFile(nsDependentCString(pszDataPath), TRUE, getter_AddRefs(dataPath));
00455      }
00456 
00457      persist->SaveDocument(nsnull, file, dataPath, nsnull, 0, 0);
00458   }
00459 }
00460 
00461 
00462 //
00463 //  FUNCTION: ResizeEmbedding()
00464 //
00465 //  PURPOSE: Resizes the webbrowser window to fit its container.
00466 //
00467 nsresult ResizeEmbedding(nsIWebBrowserChrome* chrome)
00468 {
00469     if (!chrome)
00470         return NS_ERROR_FAILURE;
00471     
00472     nsCOMPtr<nsIEmbeddingSiteWindow> embeddingSite = do_QueryInterface(chrome);
00473     HWND hWnd;
00474          embeddingSite->GetSiteWindow((void **) & hWnd);
00475     
00476     if (!hWnd)
00477         return NS_ERROR_NULL_POINTER;
00478     
00479     RECT rect;
00480     GetClientRect(hWnd, &rect);
00481     
00482          // Make sure the browser is visible and sized
00483          nsCOMPtr<nsIWebBrowser> webBrowser;
00484          chrome->GetWebBrowser(getter_AddRefs(webBrowser));
00485     nsCOMPtr<nsIBaseWindow> webBrowserAsWin = do_QueryInterface(webBrowser);
00486          if (webBrowserAsWin)
00487          {
00488         webBrowserAsWin->SetPositionAndSize(rect.left, 
00489                                    rect.top, 
00490                                    rect.right - rect.left, 
00491                                    rect.bottom - rect.top,
00492                                    PR_TRUE);
00493                   webBrowserAsWin->SetVisibility(PR_TRUE);
00494     }
00495 
00496     return NS_OK;
00497 }
00498 
00499 
00500 //
00501 //  FUNCTION: MyRegisterClass()
00502 //
00503 //  PURPOSE: Registers the window class.
00504 //
00505 //  COMMENTS:
00506 //
00507 //    This function and its usage is only necessary if you want this code
00508 //    to be compatible with Win32 systems prior to the 'RegisterClassEx'
00509 //    function that was added to Windows 95. It is important to call this function
00510 //    so that the application will get 'well formed' small icons associated
00511 //    with it.
00512 //
00513 ATOM MyRegisterClass(HINSTANCE hInstance)
00514 {
00515        WNDCLASSEX wcex;
00516 
00517   memset(&wcex, 0, sizeof(wcex));
00518        wcex.cbSize = sizeof(WNDCLASSEX); 
00519 
00520        wcex.style                  = CS_HREDRAW | CS_VREDRAW;
00521        wcex.lpfnWndProc     = (WNDPROC) BrowserWndProc;
00522        wcex.cbClsExtra             = 0;
00523        wcex.cbWndExtra             = 0;
00524        wcex.hInstance              = hInstance;
00525        wcex.hIcon                  = LoadIcon(ghInstanceResources, (LPCTSTR)IDI_MOZEMBED);
00526        wcex.hCursor         = LoadCursor(NULL, IDC_ARROW);
00527        wcex.hbrBackground   = (HBRUSH)(COLOR_WINDOW+1);
00528        wcex.lpszClassName   = szWindowClass;
00529        wcex.hIconSm         = LoadIcon(ghInstanceResources, (LPCTSTR)IDI_SMALL);
00530 
00531        return RegisterClassEx(&wcex);
00532 }
00533 
00534 
00535 
00536 //
00537 //  FUNCTION: BrowserDlgProc()
00538 //
00539 //  PURPOSE: Browser dialog windows message handler.
00540 //
00541 //  COMMENTS:
00542 //
00543 //    The code for handling buttons and menu actions is here.
00544 //
00545 BOOL CALLBACK BrowserDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
00546 {
00547        if (uMsg == WM_COMMAND && LOWORD(wParam) == MOZ_SwitchProfile)
00548        {
00549         ChooseNewProfile(FALSE, NULL);
00550               return FALSE;
00551        }
00552 
00553     // Get the browser and other pointers since they are used a lot below
00554     HWND hwndBrowser = GetDlgItem(hwndDlg, IDC_BROWSER);
00555     nsIWebBrowserChrome *chrome = nsnull ;
00556     if (hwndBrowser)
00557     {
00558         chrome = (nsIWebBrowserChrome *) GetWindowLong(hwndBrowser, GWL_USERDATA);
00559     }
00560     nsCOMPtr<nsIWebBrowser> webBrowser;
00561     nsCOMPtr<nsIWebNavigation> webNavigation;
00562     nsCOMPtr<nsIWebBrowserPrint> webBrowserPrint;
00563     if (chrome)
00564     {
00565         chrome->GetWebBrowser(getter_AddRefs(webBrowser));
00566         webNavigation = do_QueryInterface(webBrowser);
00567         webBrowserPrint = do_GetInterface(webBrowser);
00568     }
00569 
00570     // Test the message
00571     switch (uMsg)
00572     {
00573     case WM_INITDIALOG:
00574         return TRUE;
00575 
00576     case WM_INITMENU:
00577         UpdateUI(chrome);
00578         return TRUE;
00579 
00580     case WM_SYSCOMMAND:
00581         if (wParam == SC_CLOSE)
00582         {
00583           if (!webNavigation || !webBrowser || !chrome)
00584             return FALSE;
00585           
00586           webNavigation->Stop(nsIWebNavigation::STOP_ALL);
00587           chrome->ExitModalEventLoop(NS_OK);
00588 
00589           // Explicitly destroy the embedded browser and then the chrome
00590           // First the browser
00591           nsCOMPtr<nsIBaseWindow> browserAsWin = do_QueryInterface(webBrowser);
00592           if (browserAsWin)
00593             browserAsWin->Destroy();
00594 
00595           // Now the chrome
00596           chrome->SetWebBrowser(nsnull);
00597           NS_RELEASE(chrome);
00598          
00599           return FALSE;        
00600         }
00601         break;
00602     case WM_DESTROY:
00603            return FALSE;
00604 
00605     case WM_COMMAND: 
00606       {
00607         if (!webBrowser)
00608         {
00609             return FALSE;
00610         }
00611 
00612         // Test which command was selected
00613         switch (LOWORD(wParam))
00614                   {
00615         case IDC_ADDRESS:
00616             if (HIWORD(wParam) == CBN_EDITCHANGE || HIWORD(wParam) == CBN_SELCHANGE)
00617             {
00618                 // User has changed the address field so enable the Go button
00619                 EnableWindow(GetDlgItem(hwndDlg, IDC_GO), TRUE);
00620             }
00621             break;
00622 
00623         case IDC_GO:
00624             {
00625                 TCHAR szURL[2048];
00626                 memset(szURL, 0, sizeof(szURL));
00627                 GetDlgItemText(hwndDlg, IDC_ADDRESS, szURL,
00628                     sizeof(szURL) / sizeof(szURL[0]) - 1);
00629                 webNavigation->LoadURI(
00630                     NS_ConvertASCIItoUCS2(szURL).get(),
00631                     nsIWebNavigation::LOAD_FLAGS_NONE,
00632                     nsnull,
00633                     nsnull,
00634                     nsnull);
00635             }
00636             break;
00637 
00638         case IDC_STOP:
00639             webNavigation->Stop(nsIWebNavigation::STOP_ALL);
00640             UpdateUI(chrome);
00641             break;
00642 
00643         case IDC_RELOAD:
00644             webNavigation->Reload(nsIWebNavigation::LOAD_FLAGS_NONE);
00645             break;
00646 
00647         case IDM_EXIT:
00648             PostMessage(hwndDlg, WM_SYSCOMMAND, SC_CLOSE, 0);
00649             break;
00650 
00651         // File menu commands
00652 
00653         case MOZ_NewBrowser:
00654             OpenWebPage(gFirstURL);
00655             break;
00656 
00657         case MOZ_Save:
00658             SaveWebPage(webBrowser);
00659             break;
00660 
00661         case MOZ_Print:
00662             {
00663                 // NOTE: Embedding code shouldn't need to get the docshell or
00664                 //       contentviewer AT ALL. This code below will break one
00665                 //       day but will have to do until the embedding API has
00666                 //       a cleaner way to do the same thing.
00667               if (webBrowserPrint)
00668               {
00669                   nsCOMPtr<nsIPrintSettings> printSettings;
00670                   webBrowserPrint->GetGlobalPrintSettings(getter_AddRefs(printSettings));
00671                   NS_ASSERTION(printSettings, "You can't PrintPreview without a PrintSettings!");
00672                   if (printSettings) 
00673                   {
00674                       printSettings->SetPrintSilent(PR_TRUE);
00675                       webBrowserPrint->Print(printSettings, (nsIWebProgressListener*)nsnull);
00676                   }
00677               }
00678             }
00679             break;
00680 
00681         // Edit menu commands
00682 
00683         case MOZ_Cut:
00684             {
00685                 nsCOMPtr<nsIClipboardCommands> clipCmds = do_GetInterface(webBrowser);
00686                 clipCmds->CutSelection();
00687             }
00688             break;
00689 
00690         case MOZ_Copy:
00691             {
00692                 nsCOMPtr<nsIClipboardCommands> clipCmds = do_GetInterface(webBrowser);
00693                 clipCmds->CopySelection();
00694             }
00695             break;
00696 
00697         case MOZ_Paste:
00698             {
00699                 nsCOMPtr<nsIClipboardCommands> clipCmds = do_GetInterface(webBrowser);
00700                 clipCmds->Paste();
00701             }
00702             break;
00703 
00704         case MOZ_SelectAll:
00705             {
00706                 nsCOMPtr<nsIClipboardCommands> clipCmds = do_GetInterface(webBrowser);
00707                 clipCmds->SelectAll();
00708             }
00709             break;
00710 
00711         case MOZ_SelectNone:
00712             {
00713                 nsCOMPtr<nsIClipboardCommands> clipCmds = do_GetInterface(webBrowser);
00714                 clipCmds->SelectNone();
00715             }
00716             break;
00717 
00718         // Go menu commands
00719         case IDC_BACK:
00720         case MOZ_GoBack:
00721             webNavigation->GoBack();
00722             UpdateUI(chrome);
00723             break;
00724 
00725         case IDC_FORWARD:
00726         case MOZ_GoForward:
00727             webNavigation->GoForward();
00728             UpdateUI(chrome);
00729             break;
00730 
00731         // Help menu commands
00732         case MOZ_About:
00733             {
00734                 TCHAR szAboutTitle[MAX_LOADSTRING];
00735                 TCHAR szAbout[MAX_LOADSTRING];
00736                 LoadString(ghInstanceResources, IDS_ABOUT_TITLE, szAboutTitle, MAX_LOADSTRING);
00737                 LoadString(ghInstanceResources, IDS_ABOUT, szAbout, MAX_LOADSTRING);
00738                 MessageBox(NULL, szAbout, szAboutTitle, MB_OK);
00739             }
00740             break;
00741           }
00742 
00743            return TRUE;
00744       }
00745 
00746     case WM_ACTIVATE:
00747         {
00748             nsCOMPtr<nsIWebBrowserFocus> focus(do_GetInterface(webBrowser));
00749             if(focus)
00750             {
00751                 switch (wParam)
00752                 {
00753                 case WA_ACTIVE:
00754                     focus->Activate();
00755                     break;
00756                 case WA_INACTIVE:
00757                     focus->Deactivate();
00758                     break;
00759                 default:
00760                     break;
00761                 }
00762             }
00763         }
00764         break;
00765 
00766     case WM_SIZE:
00767         {
00768             UINT newDlgWidth = LOWORD(lParam);
00769             UINT newDlgHeight = HIWORD(lParam);
00770 
00771             // TODO Reposition the control bar - for the moment it's fixed size
00772 
00773             // Reposition the status area. Status bar
00774             // gets any space that the fixed size progress bar doesn't use.
00775             int progressWidth;
00776             int statusWidth;
00777             int statusHeight;
00778             HWND hwndStatus = GetDlgItem(hwndDlg, IDC_STATUS);
00779             if (hwndStatus) {
00780               RECT rcStatus;
00781               GetWindowRect(hwndStatus, &rcStatus);
00782               statusHeight = rcStatus.bottom - rcStatus.top;
00783             } else
00784               statusHeight = 0;
00785 
00786             HWND hwndProgress = GetDlgItem(hwndDlg, IDC_PROGRESS);
00787             if (hwndProgress) {
00788               RECT rcProgress;
00789               GetWindowRect(hwndProgress, &rcProgress);
00790               progressWidth = rcProgress.right - rcProgress.left;
00791             } else
00792               progressWidth = 0;
00793             statusWidth = newDlgWidth - progressWidth;
00794 
00795             if (hwndStatus)
00796               SetWindowPos(hwndStatus,
00797                            HWND_TOP,
00798                            0, newDlgHeight - statusHeight,
00799                            statusWidth,
00800                            statusHeight,
00801                            SWP_NOZORDER);
00802             if (hwndProgress)
00803               SetWindowPos(hwndProgress,
00804                            HWND_TOP,
00805                            statusWidth, newDlgHeight - statusHeight,
00806                            0, 0,
00807                            SWP_NOSIZE | SWP_NOZORDER);
00808 
00809             // Resize the browser area (assuming the browse is
00810             // sandwiched between the control bar and status area)
00811             RECT rcBrowser;
00812             POINT ptBrowser;
00813             GetWindowRect(hwndBrowser, &rcBrowser);
00814             ptBrowser.x = rcBrowser.left;
00815             ptBrowser.y = rcBrowser.top;
00816             ScreenToClient(hwndDlg, &ptBrowser);
00817             int browserHeight = newDlgHeight - ptBrowser.y - statusHeight;
00818             if (browserHeight < 1)
00819             {
00820                 browserHeight = 1;
00821             }
00822             SetWindowPos(hwndBrowser,
00823                          HWND_TOP,
00824                          0, 0,
00825                          newDlgWidth,
00826                          newDlgHeight - ptBrowser.y - statusHeight,
00827                          SWP_NOMOVE | SWP_NOZORDER);
00828         }
00829         return TRUE;
00830     }
00831     return FALSE;
00832 }
00833 
00834 
00835 //
00836 //  FUNCTION: BrowserWndProc(HWND, unsigned, WORD, LONG)
00837 //
00838 //  PURPOSE:  Processes messages for the browser container window.
00839 //
00840 LRESULT CALLBACK BrowserWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
00841 {
00842     nsIWebBrowserChrome *chrome = (nsIWebBrowserChrome *) GetWindowLong(hWnd, GWL_USERDATA);
00843        switch (message) 
00844        {
00845     case WM_SIZE:
00846         // Resize the embedded browser
00847         ResizeEmbedding(chrome);
00848         return 0;
00849     case WM_ERASEBKGND:
00850         // Reduce flicker by not painting the non-visible background
00851         return 1;
00852     }
00853     return DefWindowProc(hWnd, message, wParam, lParam);
00854 }
00855 
00856 
00858 // Profile chooser dialog
00859 
00860 
00861 //
00862 //  FUNCTION: ChooseNewProfile()
00863 //
00864 //  PURPOSE: Allows the user to select a new profile from a list.
00865 //           The bShowForMultipleProfilesOnly argument specifies whether the
00866 //           function should automatically select the first profile and return
00867 //           without displaying a dialog box if there is only one profile to
00868 //           select.
00869 //
00870 BOOL ChooseNewProfile(BOOL bShowForMultipleProfilesOnly, const char *szDefaultProfile)
00871 {
00872     nsresult rv;
00873     nsCOMPtr<nsIProfile> profileService = 
00874              do_GetService(NS_PROFILE_CONTRACTID, &rv);
00875     if (NS_FAILED(rv))
00876     {
00877         return FALSE;
00878     }
00879 
00880     if (szDefaultProfile)
00881     {
00882         // Make a new default profile
00883         nsAutoString newProfileName; newProfileName.AssignWithConversion(szDefaultProfile);
00884         rv = profileService->CreateNewProfile(newProfileName.get(), nsnull, nsnull, PR_FALSE);
00885         if (NS_FAILED(rv)) return FALSE;
00886         rv = profileService->SetCurrentProfile(newProfileName.get());
00887         if (NS_FAILED(rv)) return FALSE;
00888         return TRUE;
00889     }
00890 
00891     PRInt32 profileCount = 0;
00892     rv = profileService->GetProfileCount(&profileCount);
00893     if (profileCount == 0)
00894     {
00895         // Make a new default profile
00896         NS_NAMED_LITERAL_STRING(newProfileName, "mozEmbed");
00897         rv = profileService->CreateNewProfile(newProfileName.get(), nsnull, nsnull, PR_FALSE);
00898         if (NS_FAILED(rv)) return FALSE;
00899         rv = profileService->SetCurrentProfile(newProfileName.get());
00900         if (NS_FAILED(rv)) return FALSE;
00901         return TRUE;
00902     }
00903     else if (profileCount == 1 && bShowForMultipleProfilesOnly)
00904     {
00905         // GetCurrentProfile returns the profile which was last used but is not nescesarily
00906         // active. Call SetCurrentProfile to make it installed and active.
00907         
00908         nsXPIDLString   currProfileName;
00909         rv = profileService->GetCurrentProfile(getter_Copies(currProfileName));
00910         if (NS_FAILED(rv)) return FALSE;
00911         rv = profileService->SetCurrentProfile(currProfileName);
00912         if (NS_FAILED(rv)) return FALSE;
00913         return TRUE;
00914     }
00915 
00916     INT nResult;
00917     nResult = DialogBox(ghInstanceResources, (LPCTSTR)IDD_CHOOSEPROFILE, NULL, (DLGPROC)ChooseProfileDlgProc);
00918     return (nResult == IDOK) ? TRUE : FALSE;
00919 }
00920 
00921 
00922 //
00923 //  FUNCTION: ChooseProfileDlgProc(HWND, unsigned, WORD, LONG)
00924 //
00925 //  PURPOSE:  Dialog handler procedure for the open uri dialog.
00926 //
00927 LRESULT CALLBACK ChooseProfileDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
00928 {
00929   nsresult rv;
00930        switch (message)
00931        {
00932        case WM_INITDIALOG:
00933         {
00934             HWND hwndProfileList = GetDlgItem(hDlg, IDC_PROFILELIST);
00935 
00936             nsCOMPtr<nsIProfile> profileService = 
00937                      do_GetService(NS_PROFILE_CONTRACTID, &rv);
00938 
00939             // Get the list of profile names and add them to the list box
00940             PRUint32 listLen = 0;
00941             PRUnichar **profileList = nsnull;
00942             rv = profileService->GetProfileList(&listLen, &profileList);
00943             for (PRUint32 index = 0; index < listLen; index++)
00944             {
00945 #ifdef UNICODE
00946                 SendMessageW(hwndProfileList, LB_ADDSTRING, 0, (LPARAM) profileList[index]);
00947 #else
00948                 nsCAutoString profile; profile.AssignWithConversion(profileList[index]);
00949                 SendMessageA(hwndProfileList, LB_ADDSTRING, 0, (LPARAM) profile.get());
00950 #endif
00951             }
00952 
00953             // Select the current profile (if there is one)
00954 
00955             // Get the current profile
00956 #ifdef UNICODE
00957             nsXPIDLString currProfile;
00958             profileService->GetCurrentProfile(getter_Copies(currProfile));
00959 #else
00960             nsXPIDLString currProfileUnicode;
00961             profileService->GetCurrentProfile(getter_Copies(currProfileUnicode));
00962             nsCAutoString currProfile; currProfile.AssignWithConversion(currProfileUnicode);
00963 #endif
00964 
00965             // Now find and select it
00966             INT currentProfileIndex = LB_ERR;
00967             currentProfileIndex = SendMessage(hwndProfileList, LB_FINDSTRINGEXACT, -1, (LPARAM) currProfile.get());
00968             if (currentProfileIndex != LB_ERR)
00969             {
00970                 SendMessage(hwndProfileList, LB_SETCURSEL, currentProfileIndex, 0);
00971             }
00972         }
00973               return TRUE;
00974 
00975        case WM_COMMAND:
00976               if (LOWORD(wParam) == IDOK ||
00977                      (HIWORD(wParam) & LBN_DBLCLK && LOWORD(wParam) == IDC_PROFILELIST))
00978         {
00979             HWND hwndProfileList = GetDlgItem(hDlg, IDC_PROFILELIST);
00980 
00981             // Get the selected profile from the list box and make it current
00982             INT currentProfileIndex = SendMessage(hwndProfileList, LB_GETCURSEL, 0, 0);
00983             if (currentProfileIndex != LB_ERR)
00984             {
00985                 nsCOMPtr<nsIProfile> profileService = 
00986                          do_GetService(NS_PROFILE_CONTRACTID, &rv);
00987                 // Convert TCHAR name to unicode and make it current
00988                 INT profileNameLen = SendMessage(hwndProfileList, LB_GETTEXTLEN, currentProfileIndex, 0);
00989                 TCHAR *profileName = new TCHAR[profileNameLen + 1];
00990                 SendMessage(hwndProfileList, LB_GETTEXT, currentProfileIndex, (LPARAM) profileName);
00991                 nsAutoString newProfile; newProfile.AssignWithConversion(profileName);
00992                 rv = profileService->SetCurrentProfile(newProfile.get());
00993             }
00994                EndDialog(hDlg, IDOK);
00995         }
00996               else if (LOWORD(wParam) == IDCANCEL)
00997               {
00998                EndDialog(hDlg, LOWORD(wParam));
00999               }
01000         return TRUE;
01001        }
01002 
01003     return FALSE;
01004 }
01005 
01006 
01007 //-----------------------------------------------------------------------------
01008 // AppCallbacks
01009 //-----------------------------------------------------------------------------
01010 
01011 
01012 void AppCallbacks::EnableChromeWindow(nsIWebBrowserChrome *aWindow,
01013                       PRBool aEnabled)
01014 {
01015   HWND hwnd = GetBrowserDlgFromChrome(aWindow);
01016   ::EnableWindow(hwnd, aEnabled ? TRUE : FALSE);
01017 }
01018 
01019 PRUint32 AppCallbacks::RunEventLoop(PRBool &aRunCondition)
01020 {
01021   MSG msg;
01022   HANDLE hFakeEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
01023 
01024   while (aRunCondition ) {
01025     // Process pending messages
01026     while (::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
01027       if (!::GetMessage(&msg, NULL, 0, 0)) {
01028         // WM_QUIT
01029         aRunCondition = PR_FALSE;
01030         break;
01031       }
01032 
01033       PRBool wasHandled = PR_FALSE;
01034       ::NS_HandleEmbeddingEvent(msg, wasHandled);
01035       if (wasHandled)
01036         continue;
01037  
01038       ::TranslateMessage(&msg);
01039       ::DispatchMessage(&msg);
01040     }
01041 
01042     // Do idle stuff
01043     ::MsgWaitForMultipleObjects(1, &hFakeEvent, FALSE, 100, QS_ALLEVENTS);
01044   }
01045   ::CloseHandle(hFakeEvent);
01046   return msg.wParam;
01047 }
01048 
01049 
01051 // nsQABrowserUIGlue
01053 
01054 nsQABrowserUIGlue::nsQABrowserUIGlue():mAllowNewWindows(PR_TRUE)
01055 {
01056 }
01057 
01058 nsQABrowserUIGlue::~nsQABrowserUIGlue()
01059 {
01060 
01061 }
01062 
01063 NS_IMPL_ISUPPORTS1(nsQABrowserUIGlue, nsIQABrowserUIGlue)
01064 
01065 
01066 // nsIQABrowserUIGlue
01068 
01069 NS_IMETHODIMP
01070 nsQABrowserUIGlue::CreateNewBrowserWindow(PRInt32 aChromeFlags,
01071                                           nsIWebBrowserChrome *aParent,
01072                                           nsIWebBrowserChrome **aNewWindow)
01073 {
01074 
01075   printf("In nsQABrowserUIGlue::CreateNewBrowserWindow\n");
01076 
01077   nsresult rv;
01078   
01079 
01080   // Create the chrome object. This implements all the interfaces
01081   // that an embedding application must implement. 
01082   nsCOMPtr<nsIQABrowserChrome> chrome(do_CreateInstance(NS_QABROWSERCHROME_CONTRACTID, &rv));
01083   if (!chrome)
01084     return NS_ERROR_FAILURE;
01085 
01086   nsCOMPtr<nsIWebBrowserChrome> webBrowserChrome(do_QueryInterface(chrome));
01087 
01088   if (!webBrowserChrome)
01089     return NS_ERROR_FAILURE;
01090 
01091   // now an extra addref; the window owns itself (to be released by
01092   // nsQABrowserUIGlue::Destroy) 
01093   *aNewWindow = webBrowserChrome.get();
01094   NS_ADDREF(*aNewWindow);
01095  
01096     // Set the chrome flags on the chrome. This may not be necessary.
01097   webBrowserChrome->SetChromeFlags(aChromeFlags);
01098   //  chrome->SetParent(aParent);
01099 
01100   // Create the browser view object. nsIBrowserView  creates and holds
01101   // handle to the nsIWebBrowser  object.   
01102   mBrowserView = do_CreateInstance(NS_QABROWSERVIEW_CONTRACTID, &rv);
01103   if (!mBrowserView)
01104     return NS_ERROR_FAILURE;
01105 
01106   // Create the native window.
01107   nativeWindow nativeWnd;
01108   nativeWnd = CreateNativeWindow(*aNewWindow);
01109   
01110   // Wire all the layers together.
01111   chrome->InitQAChrome(this,  nativeWnd);
01112 
01113     // Create the actual browser.
01114   mBrowserView->CreateBrowser(nativeWnd, webBrowserChrome);
01115  
01116   // Place it where we want it.
01117   ResizeEmbedding(webBrowserChrome);
01118 
01119   // if opened as chrome, it'll be made visible after the chrome has loaded.
01120   // otherwise, go ahead and show it now.
01121   if (!(aChromeFlags & nsIWebBrowserChrome::CHROME_OPENAS_CHROME))
01122     ShowWindow(*aNewWindow, PR_TRUE);
01123 
01124   return NS_OK;
01125 }
01126 
01127 
01128 //
01129 // FUNCTION: Destroy()
01130 //
01131 // PURPOSE: Destroy the window specified by the chrome
01132 //
01133 NS_IMETHODIMP
01134 nsQABrowserUIGlue::Destroy(nsIWebBrowserChrome* chrome)
01135 {
01136   nsCOMPtr<nsIWebBrowser> webBrowser;
01137   nsCOMPtr<nsIWebNavigation> webNavigation;
01138 
01139   chrome->GetWebBrowser(getter_AddRefs(webBrowser));
01140   webNavigation = do_QueryInterface(webBrowser);
01141   if (webNavigation)
01142     webNavigation->Stop(nsIWebNavigation::STOP_ALL);
01143 
01144   chrome->ExitModalEventLoop(NS_OK);
01145 
01146   // Explicitly destroy the embedded browser and then the chrome
01147   // First the browser
01148   nsCOMPtr<nsIBaseWindow> browserAsWin = do_QueryInterface(webBrowser);
01149   if (browserAsWin)
01150     browserAsWin->Destroy();
01151 
01152       // Now the chrome
01153   chrome->SetWebBrowser(nsnull);
01154   NS_RELEASE(chrome);
01155   return NS_OK;
01156 }
01157 
01158 
01159 //
01160 // FUNCTION: Called as the final act of a chrome object during its destructor
01161 //
01162 NS_IMETHODIMP
01163 nsQABrowserUIGlue::Destroyed(nsIWebBrowserChrome* chrome)
01164 {
01165     HWND hwndDlg = GetBrowserDlgFromChrome(chrome);
01166        if (hwndDlg == NULL)
01167        {
01168               return NS_ERROR_FAILURE;
01169        }
01170 
01171     // Clear the window user data
01172     HWND hwndBrowser = GetDlgItem(hwndDlg, IDC_BROWSER);
01173     SetWindowLong(hwndBrowser, GWL_USERDATA, nsnull);
01174          DestroyWindow(hwndBrowser);
01175     DestroyWindow(hwndDlg);
01176 
01177     --gDialogCount;
01178     if (gDialogCount == 0)
01179     {
01180         if (gProfileSwitch)
01181         {
01182             gProfileSwitch = FALSE;
01183             OpenWebPage(gFirstURL);
01184         }
01185         else
01186         {
01187             // Quit when there are no more browser objects
01188             PostQuitMessage(0);
01189         }
01190     }
01191     return NS_OK;
01192 }
01193 
01194 
01195 //
01196 // FUNCTION: Set the input focus onto the browser window
01197 //
01198 NS_IMETHODIMP
01199 nsQABrowserUIGlue::SetFocus(nsIWebBrowserChrome *chrome)
01200 {
01201   HWND hwndDlg = GetBrowserDlgFromChrome(chrome);
01202        if (hwndDlg == NULL)
01203        {
01204               return NS_ERROR_FAILURE;
01205        }
01206     
01207   HWND hwndBrowser = GetDlgItem(hwndDlg, IDC_BROWSER);
01208   ::SetFocus(hwndBrowser);
01209   return NS_OK;
01210 }
01211 
01212 //
01213 //  FUNCTION: UpdateStatusBarText()
01214 //
01215 //  PURPOSE: Set the status bar text.
01216 //
01217 NS_IMETHODIMP
01218 nsQABrowserUIGlue::UpdateStatusBarText(nsIWebBrowserChrome *aChrome, const PRUnichar* aStatusText)
01219 {
01220     HWND hwndDlg = GetBrowserDlgFromChrome(aChrome);
01221     nsCString status; 
01222     if (aStatusText)
01223         status.AssignWithConversion(aStatusText);
01224     SetDlgItemText(hwndDlg, IDC_STATUS, status.get());
01225     return NS_OK;
01226 }
01227 
01228 
01229 //
01230 //  FUNCTION: UpdateCurrentURI()
01231 //
01232 //  PURPOSE: Updates the URL address field
01233 //
01234 NS_IMETHODIMP
01235 nsQABrowserUIGlue::UpdateCurrentURI(nsIWebBrowserChrome *aChrome)
01236 {
01237     nsCOMPtr<nsIWebBrowser> webBrowser;
01238     nsCOMPtr<nsIWebNavigation> webNavigation;
01239     aChrome->GetWebBrowser(getter_AddRefs(webBrowser));
01240     webNavigation = do_QueryInterface(webBrowser);
01241 
01242     nsCOMPtr<nsIURI> currentURI;
01243     webNavigation->GetCurrentURI(getter_AddRefs(currentURI));
01244     if (currentURI)
01245     {
01246         nsCAutoString uriString;
01247         currentURI->GetAsciiSpec(uriString);
01248         HWND hwndDlg = GetBrowserDlgFromChrome(aChrome);
01249         SetDlgItemText(hwndDlg, IDC_ADDRESS, uriString.get());
01250     }
01251     return NS_OK;
01252 }
01253 
01254 
01255 //
01256 //  FUNCTION: UpdateBusyState()
01257 //
01258 //  PURPOSE: Refreshes the stop/go buttons in the browser dialog
01259 //
01260 NS_IMETHODIMP
01261 nsQABrowserUIGlue::UpdateBusyState(nsIWebBrowserChrome *aChrome, PRBool aBusy)
01262 {
01263     HWND hwndDlg = GetBrowserDlgFromChrome(aChrome);
01264     HWND button;
01265     button = GetDlgItem(hwndDlg, IDC_STOP);
01266     if (button)
01267         EnableWindow(button, aBusy);
01268     button = GetDlgItem(hwndDlg, IDC_GO);
01269     if (button)
01270         EnableWindow(button, !aBusy);
01271     UpdateUI(aChrome);
01272     return NS_OK;
01273 }
01274 
01275 
01276 //
01277 //  FUNCTION: UpdateProgress()
01278 //
01279 //  PURPOSE: Refreshes the progress bar in the browser dialog
01280 //
01281 NS_IMETHODIMP
01282 nsQABrowserUIGlue::UpdateProgress(nsIWebBrowserChrome *aChrome, PRInt32 aCurrent, PRInt32 aMax)
01283 {
01284     HWND hwndDlg = GetBrowserDlgFromChrome(aChrome);
01285     HWND hwndProgress = GetDlgItem(hwndDlg, IDC_PROGRESS);
01286     if (aCurrent < 0)
01287     {
01288         aCurrent = 0;
01289     }
01290     if (aCurrent > aMax)
01291     {
01292         aMax = aCurrent + 20; // What to do?
01293     }
01294     if (hwndProgress)
01295     {
01296         SendMessage(hwndProgress, PBM_SETRANGE, 0, MAKELPARAM(0, aMax));
01297         SendMessage(hwndProgress, PBM_SETPOS, aCurrent, 0);
01298     }
01299     return NS_OK;
01300 }
01301 
01302 //
01303 //  FUNCTION: ShowContextMenu()
01304 //
01305 //  PURPOSE: Display a context menu for the given node
01306 //
01307 NS_IMETHODIMP
01308 nsQABrowserUIGlue::ShowContextMenu(nsIWebBrowserChrome *aChrome, PRInt32 aContextFlags, nsIDOMEvent *aEvent, nsIDOMNode *aNode)
01309 {
01310     // TODO code to test context flags and display a popup menu should go here
01311   return NS_OK;
01312 }
01313 
01314 //
01315 //  FUNCTION: ShowTooltip()
01316 //
01317 //  PURPOSE: Show a tooltip
01318 //
01319 NS_IMETHODIMP
01320 nsQABrowserUIGlue::ShowTooltip(nsIWebBrowserChrome *aChrome, PRInt32 aXCoords, PRInt32 aYCoords, const PRUnichar *aTipText)
01321 {
01322     // TODO code to show a tooltip should go here
01323   return NS_OK;
01324 }
01325 
01326 //
01327 //  FUNCTION: HideTooltip()
01328 //
01329 //  PURPOSE: Hide the tooltip
01330 //
01331 NS_IMETHODIMP
01332 nsQABrowserUIGlue::HideTooltip(nsIWebBrowserChrome *aChrome)
01333 {
01334     // TODO code to hide a tooltip should go here
01335   return NS_OK;
01336 }
01337 
01338 NS_IMETHODIMP
01339 nsQABrowserUIGlue::ShowWindow(nsIWebBrowserChrome *aChrome, PRBool aShow)
01340 {
01341   HWND win = GetBrowserDlgFromChrome(aChrome);
01342   return ::ShowWindow(win, aShow ? SW_RESTORE : SW_HIDE);
01343 }
01344 
01345 NS_IMETHODIMP
01346 nsQABrowserUIGlue::SizeTo(nsIWebBrowserChrome *aChrome, PRInt32 aWidth, PRInt32 aHeight)
01347 {
01348   HWND win = GetBrowserDlgFromChrome(aChrome);
01349   RECT winRect;
01350 
01351   ::GetWindowRect(win, &winRect);
01352   return ::MoveWindow(win, winRect.left, winRect.top, aWidth, aHeight, TRUE);
01353 }
01354 
01355 //
01356 //  FUNCTION: GetResourceStringByID()
01357 //
01358 //  PURPOSE: Get the resource string for the ID
01359 //
01360 NS_IMETHODIMP
01361 nsQABrowserUIGlue::GetResourceStringById(PRInt32 aID, char ** aReturn)
01362 {
01363     char resBuf[MAX_LOADSTRING];
01364     int retval = LoadString( ghInstanceResources, aID, (LPTSTR)resBuf, sizeof(resBuf) );
01365     if (retval != 0)
01366     {
01367         int resLen = strlen(resBuf);
01368         *aReturn = (char *)calloc(resLen+1, sizeof(char *));
01369         if (!*aReturn) return NS_OK;
01370             PL_strncpy(*aReturn, (char *) resBuf, resLen);
01371     }
01372     return NS_OK; 
01373 }
01374 
01375 NS_IMETHODIMP
01376 nsQABrowserUIGlue::SetTitle(const PRUnichar * aTitle)
01377 {
01378   return NS_OK;
01379 }
01380 
01381 NS_IMETHODIMP
01382 nsQABrowserUIGlue::GetTitle(PRUnichar ** aTitle)
01383 {
01384   return NS_OK;
01385 }
01386 
01387 
01388 NS_IMETHODIMP
01389 nsQABrowserUIGlue::SetVisibility(PRBool aVisibility)
01390 {
01391   return NS_OK;
01392 }
01393 
01394 
01395 NS_IMETHODIMP
01396 nsQABrowserUIGlue::GetVisibility(PRBool * aVisibility)
01397 {
01398   *aVisibility = PR_TRUE;
01399   return NS_OK;
01400 }
01401 
01402 
01403 NS_IMETHODIMP
01404 nsQABrowserUIGlue::SetAllowNewBrowserWindows(PRBool aValue)
01405 {
01406   mAllowNewWindows = aValue;
01407   return NS_OK;
01408 }
01409 
01410 
01411 NS_IMETHODIMP
01412 nsQABrowserUIGlue::GetAllowNewBrowserWindows(PRBool * aReturn)
01413 {
01414   if (aReturn)
01415     *aReturn = mAllowNewWindows;
01416   return NS_OK;
01417 }
01418 
01419 NS_IMETHODIMP
01420 nsQABrowserUIGlue::LoadHomePage()
01421 {
01422   NS_NAMED_LITERAL_CSTRING (url, "http://www.mozilla.org/embedding");
01423   return LoadURL(url.get());
01424 
01425 }
01426 
01427 NS_IMETHODIMP
01428 nsQABrowserUIGlue::LoadURL(const char * aURL)
01429 {
01430   nsresult rv = NS_OK;
01431   // Start loading a page
01432   nsCOMPtr<nsIWebBrowser> newBrowser;
01433   mBrowserView->GetWebBrowser(getter_AddRefs(newBrowser));
01434   nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(newBrowser, &rv));
01435   if (webNav)
01436     return webNav->LoadURI(NS_ConvertASCIItoUCS2(aURL).get(),
01437                            nsIWebNavigation::LOAD_FLAGS_NONE,
01438                            nsnull,
01439                            nsnull,
01440                            nsnull);
01441   return rv;
01442 }
01443 
01444 
01445 //
01446 //  FUNCTION: CreateNativeWindow()
01447 //
01448 //  PURPOSE: Creates a new browser dialog.
01449 //  COMMENTS:
01450 //
01451 //    This function loads the browser dialog from a resource template
01452 //    and returns the HWND for the webbrowser container dialog item
01453 //    to the caller.
01454 //
01455 nativeWindow
01456 nsQABrowserUIGlue::CreateNativeWindow(nsIWebBrowserChrome* chrome)
01457 {
01458   // Load the browser dialog from resource
01459   HWND hwndDialog;
01460   PRUint32 chromeFlags;
01461 
01462   chrome->GetChromeFlags(&chromeFlags);
01463   if ((chromeFlags & nsIWebBrowserChrome::CHROME_ALL) == nsIWebBrowserChrome::CHROME_ALL)
01464     hwndDialog = CreateDialog(ghInstanceResources,
01465                               MAKEINTRESOURCE(IDD_BROWSER),
01466                               NULL,
01467                               BrowserDlgProc);
01468   else
01469     hwndDialog = CreateDialog(ghInstanceResources,
01470                               MAKEINTRESOURCE(IDD_BROWSER_NC),
01471                               NULL,
01472                               BrowserDlgProc);
01473   if (!hwndDialog)
01474     return (void *) nsnull;
01475 
01476   // Stick a menu onto it
01477   if (chromeFlags & nsIWebBrowserChrome::CHROME_MENUBAR) {
01478     HMENU hmenuDlg = LoadMenu(ghInstanceResources, MAKEINTRESOURCE(IDC_MOZEMBED));
01479     SetMenu(hwndDialog, hmenuDlg);
01480   } else
01481     SetMenu(hwndDialog, 0);
01482 
01483   // Add some interesting URLs to the address drop down
01484   HWND hwndAddress = GetDlgItem(hwndDialog, IDC_ADDRESS);
01485   if (hwndAddress) {
01486     for (int i = 0; i < sizeof(gDefaultURLs) / sizeof(gDefaultURLs[0]); i++)
01487     {
01488       SendMessage(hwndAddress, CB_ADDSTRING, 0, (LPARAM) gDefaultURLs[i]);
01489     }
01490   }
01491 
01492   // Fetch the browser window handle
01493   HWND hwndBrowser = GetDlgItem(hwndDialog, IDC_BROWSER);
01494   SetWindowLong(hwndBrowser, GWL_USERDATA, (LONG)chrome);  // save the browser LONG_PTR.
01495   SetWindowLong(hwndBrowser, GWL_STYLE, GetWindowLong(hwndBrowser, GWL_STYLE) | WS_CLIPCHILDREN);
01496 
01497   // Activate the window
01498   PostMessage(hwndDialog, WM_ACTIVATE, WA_ACTIVE, 0);
01499 
01500   gDialogCount++;
01501 
01502   return (void *) hwndBrowser;
01503 }