embedding/tests/winEmbed/winEmbed.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
     2 /* ***** BEGIN LICENSE BLOCK *****
     3  * Version: Mozilla-sample-code 1.0
     4  *
     5  * Copyright (c) 2002 Netscape Communications Corporation and
     6  * other contributors
     7  *
     8  * Permission is hereby granted, free of charge, to any person obtaining a
     9  * copy of this Mozilla sample software and associated documentation files
    10  * (the "Software"), to deal in the Software without restriction, including
    11  * without limitation the rights to use, copy, modify, merge, publish,
    12  * distribute, sublicense, and/or sell copies of the Software, and to permit
    13  * persons to whom the Software is furnished to do so, subject to the
    14  * following conditions:
    15  *
    16  * The above copyright notice and this permission notice shall be included
    17  * in all copies or substantial portions of the Software.
    18  *
    19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    20  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    21  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
    22  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    23  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    24  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    25  * DEALINGS IN THE SOFTWARE.
    26  *
    27  * Contributor(s):
    28  *   Doug Turner <dougt@netscape.com>
    29  *   Adam Lock <adamlock@netscape.com>
    30  *
    31  * ***** END LICENSE BLOCK ***** */
    33 // C RunTime Header Files
    34 #include <stdio.h>
    35 #include <stdlib.h>
    36 #include <malloc.h>
    37 #include <memory.h>
    38 #include <tchar.h>
    40 // Win32 header files
    41 #include <windows.h>
    42 #include <commctrl.h>
    43 #include <commdlg.h>
    45 // Mozilla Frozen APIs
    46 #include "nsXULAppAPI.h"
    48 XRE_InitEmbedding2Type XRE_InitEmbedding2;
    49 XRE_TermEmbeddingType XRE_TermEmbedding;
    51 #include "nsAppDirectoryServiceDefs.h"
    52 #include "nsDirectoryServiceDefs.h"
    53 #include "nsProfileDirServiceProvider.h"
    54 #include "nsStringAPI.h"
    55 #include "nsXPCOMGlue.h"
    57 #include "nsIClipboardCommands.h"
    58 #include "nsIInterfaceRequestor.h"
    59 #include "nsIObserverService.h"
    60 #include "nsIObserver.h"
    61 #include "nsIURI.h"
    62 #include "nsIWebBrowserFocus.h"
    63 #include "nsIWindowWatcher.h"
    65 // NON-FROZEN APIs!
    66 #include "nsIBaseWindow.h"
    67 #include "nsIWebNavigation.h"
    69 // Local header files
    70 #include "winEmbed.h"
    71 #include "WebBrowserChrome.h"
    72 #include "WindowCreator.h"
    73 #include "resource.h"
    75 #define MAX_LOADSTRING 100
    77 const TCHAR *szWindowClass = _T("WINEMBED");
    79 // Foward declarations of functions included in this code module:
    80 static ATOM             MyRegisterClass(HINSTANCE hInstance);
    81 static LRESULT CALLBACK BrowserWndProc(HWND, UINT, WPARAM, LPARAM);
    82 static INT_PTR CALLBACK BrowserDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
    84 static nsresult InitializeWindowCreator();
    85 static nsresult OpenWebPage(const char * url);
    86 static nsresult ResizeEmbedding(nsIWebBrowserChrome* chrome);
    88 // Profile chooser stuff
    89 static nsresult StartupProfile();
    91 // Global variables
    92 static UINT gDialogCount = 0;
    93 static HINSTANCE ghInstanceApp = nullptr;
    94 static char gFirstURL[1024];
    96 // like strpbrk but finds the *last* char, not the first
    97 static char*
    98 ns_strrpbrk(char *string, const char *strCharSet)
    99 {
   100     char *found = nullptr;
   101     for (; *string; ++string) {
   102         for (const char *search = strCharSet; *search; ++search) {
   103             if (*search == *string) {
   104                 found = string;
   105                 // Since we're looking for the last char, we save "found"
   106                 // until we're at the end of the string.
   107             }
   108         }
   109     }
   111     return found;
   112 }
   114 // A list of URLs to populate the URL drop down list with
   115 static const TCHAR *gDefaultURLs[] = 
   116 {
   117     _T("http://www.mozilla.org/"),
   118     _T("http://www.netscape.com/"),
   119     _T("http://browsertest.web.aol.com/tests/javascript/javascpt/index.htm"),
   120     _T("http://127.0.0.1/"),
   121     _T("http://www.yahoo.com/"),
   122     _T("http://www.travelocity.com/"),
   123     _T("http://www.disney.com/"),
   124     _T("http://www.go.com/"),
   125     _T("http://www.google.com/"),
   126     _T("http://www.ebay.com/"),
   127     _T("http://www.shockwave.com/"),
   128     _T("http://www.slashdot.org/"),
   129     _T("http://www.quicken.com/"),
   130     _T("http://www.hotmail.com/"),
   131     _T("http://www.cnn.com/"),
   132     _T("http://www.javasoft.com/")
   133 };
   135 int main(int argc, char *argv[])
   136 {
   137     nsresult rv;
   139     printf("You are embedded, man!\n\n");
   140     printf("******************************************************************\n");
   141     printf("*                                                                *\n");
   142     printf("*  IMPORTANT NOTE:                                               *\n");
   143     printf("*                                                                *\n");
   144     printf("*  WinEmbed is not supported!!! Do not raise bugs on it unless   *\n");
   145     printf("*  it is badly broken (e.g. crash on start/exit, build errors)   *\n");
   146     printf("*  or you have the patch to make it better! MFCEmbed is now our  *\n");
   147     printf("*  embedding test application on Win32 and all testing should    *\n");
   148     printf("*  be done on that.                                              *\n");
   149     printf("*                                                                *\n");
   150     printf("******************************************************************\n");
   151     printf("\n\n");
   153     // Sophisticated command-line parsing in action
   154     char *szFirstURL = "http://www.mozilla.org/projects/embedding/";
   155 	int argn;
   156     for (argn = 1; argn < argc; argn++)
   157     {
   158 		szFirstURL = argv[argn];
   159     }
   160     strncpy(gFirstURL, szFirstURL, sizeof(gFirstURL) - 1);
   162     ghInstanceApp = GetModuleHandle(nullptr);
   164     // Initialize global strings
   165     TCHAR szTitle[MAX_LOADSTRING];
   166     LoadString(ghInstanceApp, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
   167     MyRegisterClass(ghInstanceApp);
   169     char path[_MAX_PATH];
   170     GetModuleFileName(ghInstanceApp, path, sizeof(path));
   171     char* lastslash = ns_strrpbrk(path, "/\\");
   172     if (!lastslash)
   173         return 7;
   175     strcpy(lastslash, "\\xulrunner\\xpcom.dll");
   177     rv = XPCOMGlueStartup(path);
   178     if (NS_FAILED(rv))
   179         return 3;
   181     strcpy(lastslash, "\\xulrunner\\xul.dll");
   183     HINSTANCE xulModule = LoadLibraryEx(path, nullptr, 0);
   184     if (!xulModule)
   185         return 4;
   187     XRE_InitEmbedding2 =
   188         (XRE_InitEmbedding2Type) GetProcAddress(xulModule, "XRE_InitEmbedding2");
   189     if (!XRE_InitEmbedding2) {
   190         fprintf(stderr, "Error: %i\n", GetLastError());
   191         return 5;
   192     }
   194     XRE_TermEmbedding =
   195         (XRE_TermEmbeddingType) GetProcAddress(xulModule, "XRE_TermEmbedding");
   196     if (!XRE_TermEmbedding) {
   197         fprintf(stderr, "Error: %i\n", GetLastError());
   198         return 5;
   199     }
   201     int result = 0;
   203     // Scope all the XPCOM stuff
   204     {
   205         strcpy(lastslash, "\\xulrunner");
   207         nsCOMPtr<nsIFile> xuldir;
   208         rv = NS_NewNativeLocalFile(nsCString(path), false,
   209                                    getter_AddRefs(xuldir));
   210         if (NS_FAILED(rv))
   211             return 6;
   213         *lastslash = '\0';
   215         nsCOMPtr<nsIFile> appdir;
   216         rv = NS_NewNativeLocalFile(nsCString(path), false,
   217                                    getter_AddRefs(appdir));
   218         if (NS_FAILED(rv))
   219             return 8;
   221         rv = XRE_InitEmbedding2(xuldir, appdir, nullptr);
   222         if (NS_FAILED(rv))
   223             return 9;
   225         if (NS_FAILED(StartupProfile())) {
   226             result = 8;
   227         }
   228         else {
   229             InitializeWindowCreator();
   231             // Open the initial browser window
   232             OpenWebPage(gFirstURL);
   234             // Main message loop.
   235             // NOTE: We use a fake event and a timeout in order to process idle stuff for
   236             //       Mozilla every 1/10th of a second.
   237             bool runCondition = true;
   239             result = AppCallbacks::RunEventLoop(runCondition);
   240         }
   241     }
   242     XRE_TermEmbedding();
   244     return result;
   245 }
   247 /* InitializeWindowCreator creates and hands off an object with a callback
   248    to a window creation function. This is how all new windows are opened,
   249    except any created directly by the embedding app. */
   250 nsresult
   251 InitializeWindowCreator()
   252 {
   253     // create an nsWindowCreator and give it to the WindowWatcher service
   254     nsCOMPtr<nsIWindowCreator> creator(new WindowCreator());
   255     if (!creator)
   256         return NS_ERROR_OUT_OF_MEMORY;
   258     nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
   259     if (!wwatch)
   260         return NS_ERROR_UNEXPECTED;
   262     return wwatch->SetWindowCreator(creator);
   263 }
   265 //-----------------------------------------------------------------------------
   267 //
   268 //  FUNCTION: OpenWebPage()
   269 //
   270 //  PURPOSE: Opens a new browser dialog and starts it loading to the
   271 //           specified url.
   272 //
   273 nsresult OpenWebPage(const char *url)
   274 {
   275     nsresult  rv;
   277     // Create the chrome object. Note that it leaves this function
   278     // with an extra reference so that it can released correctly during
   279     // destruction (via Win32UI::Destroy)
   281     nsCOMPtr<nsIWebBrowserChrome> chrome;
   282     rv = AppCallbacks::CreateBrowserWindow(nsIWebBrowserChrome::CHROME_ALL,
   283            nullptr, getter_AddRefs(chrome));
   284     if (NS_SUCCEEDED(rv))
   285     {
   286         // Start loading a page
   287         nsCOMPtr<nsIWebBrowser> newBrowser;
   288         chrome->GetWebBrowser(getter_AddRefs(newBrowser));
   289         nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(newBrowser));
   291         return webNav->LoadURI(NS_ConvertASCIItoUTF16(url).get(),
   292                                nsIWebNavigation::LOAD_FLAGS_NONE,
   293                                nullptr,
   294                                nullptr,
   295                                nullptr);
   296     }
   298     return rv;
   299 }   
   301 //
   302 //  FUNCTION: GetBrowserFromChrome()
   303 //
   304 //  PURPOSE: Returns the HWND for the webbrowser container associated
   305 //           with the specified chrome.
   306 //
   307 HWND GetBrowserFromChrome(nsIWebBrowserChrome *aChrome)
   308 {
   309     if (!aChrome)
   310     {
   311         return nullptr;
   312     }
   313     nsCOMPtr<nsIEmbeddingSiteWindow> baseWindow = do_QueryInterface(aChrome);
   314     HWND hwnd = nullptr;
   315     baseWindow->GetSiteWindow((void **) & hwnd);
   316     return hwnd;
   317 }
   320 //
   321 //  FUNCTION: GetBrowserDlgFromChrome()
   322 //
   323 //  PURPOSE: Returns the HWND for the browser dialog associated with
   324 //           the specified chrome.
   325 //
   326 HWND GetBrowserDlgFromChrome(nsIWebBrowserChrome *aChrome)
   327 {
   328     return GetParent(GetBrowserFromChrome(aChrome));
   329 }
   332 //
   333 //  FUNCTION: ResizeEmbedding()
   334 //
   335 //  PURPOSE: Resizes the webbrowser window to fit its container.
   336 //
   337 nsresult ResizeEmbedding(nsIWebBrowserChrome* chrome)
   338 {
   339     if (!chrome)
   340         return NS_ERROR_FAILURE;
   342     nsCOMPtr<nsIEmbeddingSiteWindow> embeddingSite = do_QueryInterface(chrome);
   343     HWND hWnd;
   344     embeddingSite->GetSiteWindow((void **) & hWnd);
   346     if (!hWnd)
   347         return NS_ERROR_NULL_POINTER;
   349     RECT rect;
   350     GetClientRect(hWnd, &rect);
   352     // Make sure the browser is visible and sized
   353     nsCOMPtr<nsIWebBrowser> webBrowser;
   354     chrome->GetWebBrowser(getter_AddRefs(webBrowser));
   355     nsCOMPtr<nsIBaseWindow> webBrowserAsWin = do_QueryInterface(webBrowser);
   356     if (webBrowserAsWin)
   357     {
   358         webBrowserAsWin->SetPositionAndSize(rect.left, 
   359                                    rect.top, 
   360                                    rect.right - rect.left, 
   361                                    rect.bottom - rect.top,
   362                                    true);
   363         webBrowserAsWin->SetVisibility(true);
   364     }
   366     return NS_OK;
   367 }
   370 //
   371 //  FUNCTION: MyRegisterClass()
   372 //
   373 //  PURPOSE: Registers the window class.
   374 //
   375 //  COMMENTS:
   376 //
   377 //    This function and its usage is only necessary if you want this code
   378 //    to be compatible with Win32 systems prior to the 'RegisterClassEx'
   379 //    function that was added to Windows 95. It is important to call this function
   380 //    so that the application will get 'well formed' small icons associated
   381 //    with it.
   382 //
   383 ATOM MyRegisterClass(HINSTANCE hInstance)
   384 {
   385     WNDCLASSEX wcex;
   387     memset(&wcex, 0, sizeof(wcex));
   388     wcex.cbSize = sizeof(WNDCLASSEX); 
   390     wcex.style            = CS_HREDRAW | CS_VREDRAW;
   391     wcex.lpfnWndProc    = (WNDPROC) BrowserWndProc;
   392     wcex.cbClsExtra        = 0;
   393     wcex.cbWndExtra        = 0;
   394     wcex.hInstance        = hInstance;
   395     wcex.hIcon            = LoadIcon(ghInstanceApp, (LPCTSTR)IDI_WINEMBED);
   396     wcex.hCursor        = LoadCursor(nullptr, IDC_ARROW);
   397     wcex.hbrBackground    = (HBRUSH)(COLOR_WINDOW+1);
   398     wcex.lpszClassName    = szWindowClass;
   399     wcex.hIconSm        = LoadIcon(ghInstanceApp, (LPCTSTR)IDI_SMALL);
   401     return RegisterClassEx(&wcex);
   402 }
   405 //
   406 //  FUNCTION: UpdateUI()
   407 //
   408 //  PURPOSE: Refreshes the buttons and menu items in the browser dialog
   409 //
   410 void UpdateUI(nsIWebBrowserChrome *aChrome)
   411 {
   412     HWND hwndDlg = GetBrowserDlgFromChrome(aChrome);
   413     nsCOMPtr<nsIWebBrowser> webBrowser;
   414     nsCOMPtr<nsIWebNavigation> webNavigation;
   415     aChrome->GetWebBrowser(getter_AddRefs(webBrowser));
   416     webNavigation = do_QueryInterface(webBrowser);
   418     bool canGoBack = false;
   419     bool canGoForward = false;
   420     if (webNavigation)
   421     {
   422         webNavigation->GetCanGoBack(&canGoBack);
   423         webNavigation->GetCanGoForward(&canGoForward);
   424     }
   426     bool canCutSelection = false;
   427     bool canCopySelection = false;
   428     bool canPaste = false;
   430     nsCOMPtr<nsIClipboardCommands> clipCmds = do_GetInterface(webBrowser);
   431     if (clipCmds)
   432     {
   433         clipCmds->CanCutSelection(&canCutSelection);
   434         clipCmds->CanCopySelection(&canCopySelection);
   435         clipCmds->CanPaste(&canPaste);
   436     }
   438     HMENU hmenu = GetMenu(hwndDlg);
   439     if (hmenu)
   440     {
   441         EnableMenuItem(hmenu, MOZ_GoBack, MF_BYCOMMAND |
   442             ((canGoBack) ? MF_ENABLED : (MF_DISABLED | MF_GRAYED)));
   443         EnableMenuItem(hmenu, MOZ_GoForward, MF_BYCOMMAND |
   444             ((canGoForward) ? MF_ENABLED : (MF_DISABLED | MF_GRAYED)));
   446         EnableMenuItem(hmenu, MOZ_Cut, MF_BYCOMMAND |
   447             ((canCutSelection) ? MF_ENABLED : (MF_DISABLED | MF_GRAYED)));
   448         EnableMenuItem(hmenu, MOZ_Copy, MF_BYCOMMAND |
   449             ((canCopySelection) ? MF_ENABLED : (MF_DISABLED | MF_GRAYED)));
   450         EnableMenuItem(hmenu, MOZ_Paste, MF_BYCOMMAND |
   451             ((canPaste) ? MF_ENABLED : (MF_DISABLED | MF_GRAYED)));
   452     }
   454     HWND button;
   455     button = GetDlgItem(hwndDlg, IDC_BACK);
   456     if (button)
   457       EnableWindow(button, canGoBack);
   458     button = GetDlgItem(hwndDlg, IDC_FORWARD);
   459     if (button)
   460       EnableWindow(button, canGoForward);
   461 }
   464 //
   465 //  FUNCTION: BrowserDlgProc()
   466 //
   467 //  PURPOSE: Browser dialog windows message handler.
   468 //
   469 //  COMMENTS:
   470 //
   471 //    The code for handling buttons and menu actions is here.
   472 //
   473 INT_PTR CALLBACK BrowserDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
   474 {
   475     // Get the browser and other pointers since they are used a lot below
   476     HWND hwndBrowser = GetDlgItem(hwndDlg, IDC_BROWSER);
   477     nsIWebBrowserChrome *chrome = nullptr ;
   478     if (hwndBrowser)
   479     {
   480         chrome = (nsIWebBrowserChrome *) GetWindowLongPtr(hwndBrowser, GWLP_USERDATA);
   481     }
   482     nsCOMPtr<nsIWebBrowser> webBrowser;
   483     nsCOMPtr<nsIWebNavigation> webNavigation;
   484     if (chrome)
   485     {
   486         chrome->GetWebBrowser(getter_AddRefs(webBrowser));
   487         webNavigation = do_QueryInterface(webBrowser);
   488     }
   490     // Test the message
   491     switch (uMsg)
   492     {
   493     case WM_INITDIALOG:
   494         return TRUE;
   496     case WM_INITMENU:
   497         UpdateUI(chrome);
   498         return TRUE;
   500     case WM_SYSCOMMAND:
   501         if (wParam == SC_CLOSE)
   502         {
   503             WebBrowserChromeUI::Destroy(chrome);
   504             return TRUE;
   505         }
   506         break;
   508     case WM_DESTROY:
   509         return TRUE;
   511     case WM_COMMAND:
   512         if (!webBrowser)
   513         {
   514             return TRUE;
   515         }
   517         // Test which command was selected
   518         switch (LOWORD(wParam))
   519         {
   520         case IDC_ADDRESS:
   521             if (HIWORD(wParam) == CBN_EDITCHANGE || HIWORD(wParam) == CBN_SELCHANGE)
   522             {
   523                 // User has changed the address field so enable the Go button
   524                 EnableWindow(GetDlgItem(hwndDlg, IDC_GO), TRUE);
   525             }
   526             break;
   528         case IDC_GO:
   529             {
   530                 TCHAR szURL[2048];
   531                 memset(szURL, 0, sizeof(szURL));
   532                 GetDlgItemText(hwndDlg, IDC_ADDRESS, szURL,
   533                     sizeof(szURL) / sizeof(szURL[0]) - 1);
   534                 webNavigation->LoadURI(
   535                     NS_ConvertASCIItoUTF16(szURL).get(),
   536                     nsIWebNavigation::LOAD_FLAGS_NONE,
   537                     nullptr,
   538                     nullptr,
   539                     nullptr);
   540             }
   541             break;
   543         case IDC_STOP:
   544             webNavigation->Stop(nsIWebNavigation::STOP_ALL);
   545             UpdateUI(chrome);
   546             break;
   548         case IDC_RELOAD:
   549             webNavigation->Reload(nsIWebNavigation::LOAD_FLAGS_NONE);
   550             break;
   552         case IDM_EXIT:
   553             PostMessage(hwndDlg, WM_SYSCOMMAND, SC_CLOSE, 0);
   554             break;
   556         // File menu commands
   558         case MOZ_NewBrowser:
   559             OpenWebPage(gFirstURL);
   560             break;
   562         // Edit menu commands
   564         case MOZ_Cut:
   565             {
   566                 nsCOMPtr<nsIClipboardCommands> clipCmds = do_GetInterface(webBrowser);
   567                 clipCmds->CutSelection();
   568             }
   569             break;
   571         case MOZ_Copy:
   572             {
   573                 nsCOMPtr<nsIClipboardCommands> clipCmds = do_GetInterface(webBrowser);
   574                 clipCmds->CopySelection();
   575             }
   576             break;
   578         case MOZ_Paste:
   579             {
   580                 nsCOMPtr<nsIClipboardCommands> clipCmds = do_GetInterface(webBrowser);
   581                 clipCmds->Paste();
   582             }
   583             break;
   585         case MOZ_SelectAll:
   586             {
   587                 nsCOMPtr<nsIClipboardCommands> clipCmds = do_GetInterface(webBrowser);
   588                 clipCmds->SelectAll();
   589             }
   590             break;
   592         case MOZ_SelectNone:
   593             {
   594                 nsCOMPtr<nsIClipboardCommands> clipCmds = do_GetInterface(webBrowser);
   595                 clipCmds->SelectNone();
   596             }
   597             break;
   599         // Go menu commands
   600         case IDC_BACK:
   601         case MOZ_GoBack:
   602             webNavigation->GoBack();
   603             UpdateUI(chrome);
   604             break;
   606         case IDC_FORWARD:
   607         case MOZ_GoForward:
   608             webNavigation->GoForward();
   609             UpdateUI(chrome);
   610             break;
   612         // Help menu commands
   613         case MOZ_About:
   614             {
   615                 TCHAR szAboutTitle[MAX_LOADSTRING];
   616                 TCHAR szAbout[MAX_LOADSTRING];
   617                 LoadString(ghInstanceApp, IDS_ABOUT_TITLE, szAboutTitle, MAX_LOADSTRING);
   618                 LoadString(ghInstanceApp, IDS_ABOUT, szAbout, MAX_LOADSTRING);
   619                 MessageBox(nullptr, szAbout, szAboutTitle, MB_OK);
   620             }
   621             break;
   622         }
   624         return TRUE;
   626     case WM_ACTIVATE:
   627         {
   628             nsCOMPtr<nsIWebBrowserFocus> focus(do_GetInterface(webBrowser));
   629             if(focus)
   630             {
   631                 switch (wParam)
   632                 {
   633                 case WA_ACTIVE:
   634                     focus->Activate();
   635                     break;
   636                 case WA_INACTIVE:
   637                     focus->Deactivate();
   638                     break;
   639                 default:
   640                     break;
   641                 }
   642             }
   643         }
   644         break;
   646     case WM_SIZE:
   647         {
   648             UINT newDlgWidth = LOWORD(lParam);
   649             UINT newDlgHeight = HIWORD(lParam);
   651             // TODO Reposition the control bar - for the moment it's fixed size
   653             // Reposition the status area. Status bar
   654             // gets any space that the fixed size progress bar doesn't use.
   655             int progressWidth;
   656             int statusWidth;
   657             int statusHeight;
   658             HWND hwndStatus = GetDlgItem(hwndDlg, IDC_STATUS);
   659             if (hwndStatus) {
   660               RECT rcStatus;
   661               GetWindowRect(hwndStatus, &rcStatus);
   662               statusHeight = rcStatus.bottom - rcStatus.top;
   663             } else
   664               statusHeight = 0;
   666             HWND hwndProgress = GetDlgItem(hwndDlg, IDC_PROGRESS);
   667             if (hwndProgress) {
   668               RECT rcProgress;
   669               GetWindowRect(hwndProgress, &rcProgress);
   670               progressWidth = rcProgress.right - rcProgress.left;
   671             } else
   672               progressWidth = 0;
   673             statusWidth = newDlgWidth - progressWidth;
   675             if (hwndStatus)
   676               SetWindowPos(hwndStatus,
   677                            HWND_TOP,
   678                            0, newDlgHeight - statusHeight,
   679                            statusWidth,
   680                            statusHeight,
   681                            SWP_NOZORDER);
   682             if (hwndProgress)
   683               SetWindowPos(hwndProgress,
   684                            HWND_TOP,
   685                            statusWidth, newDlgHeight - statusHeight,
   686                            0, 0,
   687                            SWP_NOSIZE | SWP_NOZORDER);
   689             // Resize the browser area (assuming the browse is
   690             // sandwiched between the control bar and status area)
   691             RECT rcBrowser;
   692             POINT ptBrowser;
   693             GetWindowRect(hwndBrowser, &rcBrowser);
   694             ptBrowser.x = rcBrowser.left;
   695             ptBrowser.y = rcBrowser.top;
   696             ScreenToClient(hwndDlg, &ptBrowser);
   697             int browserHeight = newDlgHeight - ptBrowser.y - statusHeight;
   698             if (browserHeight < 1)
   699             {
   700                 browserHeight = 1;
   701             }
   702             SetWindowPos(hwndBrowser,
   703                          HWND_TOP,
   704                          0, 0,
   705                          newDlgWidth,
   706                          newDlgHeight - ptBrowser.y - statusHeight,
   707                          SWP_NOMOVE | SWP_NOZORDER);
   708         }
   709         return TRUE;
   710     }
   711     return FALSE;
   712 }
   715 //
   716 //  FUNCTION: BrowserWndProc(HWND, UINT, WRAPAM, LPARAM)
   717 //
   718 //  PURPOSE:  Processes messages for the browser container window.
   719 //
   720 LRESULT CALLBACK BrowserWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
   721 {
   722     nsIWebBrowserChrome *chrome = (nsIWebBrowserChrome *) GetWindowLongPtr(hWnd, GWLP_USERDATA);
   723     switch (message) 
   724     {
   725     case WM_SIZE:
   726         // Resize the embedded browser
   727         ResizeEmbedding(chrome);
   728         return 0;
   729     case WM_ERASEBKGND:
   730         // Reduce flicker by not painting the non-visible background
   731         return 1;
   732     }
   733     return DefWindowProc(hWnd, message, wParam, lParam);
   734 }
   736 //
   737 //  FUNCTION: StartupProfile()
   738 //
   739 //  PURPOSE: 
   740 //
   741 nsresult StartupProfile()
   742 {
   744 	nsCOMPtr<nsIFile> appDataDir;
   745 	nsresult rv = NS_GetSpecialDirectory(NS_APP_APPLICATION_REGISTRY_DIR, getter_AddRefs(appDataDir));
   746 	if (NS_FAILED(rv))
   747       return rv;
   749 	appDataDir->AppendNative(nsCString("winembed"));
   751 	nsCOMPtr<nsProfileDirServiceProvider> locProvider;
   752     NS_NewProfileDirServiceProvider(true, getter_AddRefs(locProvider));
   753     if (!locProvider)
   754       return NS_ERROR_FAILURE;
   756 	rv = locProvider->Register();
   757     if (NS_FAILED(rv))
   758       return rv;
   760 	return locProvider->SetProfileDir(appDataDir);
   762 }
   765 ///////////////////////////////////////////////////////////////////////////////
   766 // WebBrowserChromeUI
   768 //
   769 //  FUNCTION: CreateNativeWindow()
   770 //
   771 //  PURPOSE: Creates a new browser dialog.
   772 //
   773 //  COMMENTS:
   774 //
   775 //    This function loads the browser dialog from a resource template
   776 //    and returns the HWND for the webbrowser container dialog item
   777 //    to the caller.
   778 //
   779 HWND WebBrowserChromeUI::CreateNativeWindow(nsIWebBrowserChrome* chrome)
   780 {
   781   // Load the browser dialog from resource
   782   HWND hwndDialog;
   783   uint32_t chromeFlags;
   785   chrome->GetChromeFlags(&chromeFlags);
   786   if ((chromeFlags & nsIWebBrowserChrome::CHROME_ALL) == nsIWebBrowserChrome::CHROME_ALL)
   787     hwndDialog = CreateDialog(ghInstanceApp,
   788                               MAKEINTRESOURCE(IDD_BROWSER),
   789                               nullptr,
   790                               BrowserDlgProc);
   791   else
   792     hwndDialog = CreateDialog(ghInstanceApp,
   793                               MAKEINTRESOURCE(IDD_BROWSER_NC),
   794                               nullptr,
   795                               BrowserDlgProc);
   796   if (!hwndDialog)
   797     return nullptr;
   799   // Stick a menu onto it
   800   if (chromeFlags & nsIWebBrowserChrome::CHROME_MENUBAR) {
   801     HMENU hmenuDlg = LoadMenu(ghInstanceApp, MAKEINTRESOURCE(IDC_WINEMBED));
   802     SetMenu(hwndDialog, hmenuDlg);
   803   } else
   804     SetMenu(hwndDialog, 0);
   806   // Add some interesting URLs to the address drop down
   807   HWND hwndAddress = GetDlgItem(hwndDialog, IDC_ADDRESS);
   808   if (hwndAddress) {
   809     for (int i = 0; i < sizeof(gDefaultURLs) / sizeof(gDefaultURLs[0]); i++)
   810     {
   811       SendMessage(hwndAddress, CB_ADDSTRING, 0, (LPARAM) gDefaultURLs[i]);
   812     }
   813   }
   815   // Fetch the browser window handle
   816   HWND hwndBrowser = GetDlgItem(hwndDialog, IDC_BROWSER);
   817   SetWindowLongPtr(hwndBrowser, GWLP_USERDATA, (LONG_PTR)chrome);  // save the browser LONG_PTR.
   818   SetWindowLongPtr(hwndBrowser, GWL_STYLE, GetWindowLongPtr(hwndBrowser, GWL_STYLE) | WS_CLIPCHILDREN);
   820   // Activate the window
   821   PostMessage(hwndDialog, WM_ACTIVATE, WA_ACTIVE, 0);
   823   gDialogCount++;
   825   return hwndBrowser;
   826 }
   829 //
   830 // FUNCTION: Destroy()
   831 //
   832 // PURPOSE: Destroy the window specified by the chrome
   833 //
   834 void WebBrowserChromeUI::Destroy(nsIWebBrowserChrome* chrome)
   835 {
   836   nsCOMPtr<nsIWebBrowser> webBrowser;
   837   nsCOMPtr<nsIWebNavigation> webNavigation;
   839   chrome->GetWebBrowser(getter_AddRefs(webBrowser));
   840   webNavigation = do_QueryInterface(webBrowser);
   841   if (webNavigation)
   842     webNavigation->Stop(nsIWebNavigation::STOP_ALL);
   844   chrome->ExitModalEventLoop(NS_OK);
   846   HWND hwndDlg = GetBrowserDlgFromChrome(chrome);
   847   if (hwndDlg == nullptr)
   848     return;
   850   // Explicitly destroy the embedded browser and then the chrome
   852   // First the browser
   853   nsCOMPtr<nsIWebBrowser> browser = nullptr;
   854   chrome->GetWebBrowser(getter_AddRefs(browser));
   855   nsCOMPtr<nsIBaseWindow> browserAsWin = do_QueryInterface(browser);
   856   if (browserAsWin)
   857     browserAsWin->Destroy();
   859       // Now the chrome
   860   chrome->SetWebBrowser(nullptr);
   861   NS_RELEASE(chrome);
   862 }
   865 //
   866 // FUNCTION: Called as the final act of a chrome object during its destructor
   867 //
   868 void WebBrowserChromeUI::Destroyed(nsIWebBrowserChrome* chrome)
   869 {
   870     HWND hwndDlg = GetBrowserDlgFromChrome(chrome);
   871     if (hwndDlg == nullptr)
   872     {
   873         return;
   874     }
   876     // Clear the window user data
   877     HWND hwndBrowser = GetDlgItem(hwndDlg, IDC_BROWSER);
   878     SetWindowLongPtr(hwndBrowser, GWLP_USERDATA, 0);
   879     DestroyWindow(hwndBrowser);
   880     DestroyWindow(hwndDlg);
   882     --gDialogCount;
   883     if (gDialogCount == 0)
   884     {
   885         // Quit when there are no more browser objects
   886         PostQuitMessage(0);
   887     }
   888 }
   891 //
   892 // FUNCTION: Set the input focus onto the browser window
   893 //
   894 void WebBrowserChromeUI::SetFocus(nsIWebBrowserChrome *chrome)
   895 {
   896     HWND hwndDlg = GetBrowserDlgFromChrome(chrome);
   897     if (hwndDlg == nullptr)
   898     {
   899         return;
   900     }
   902     HWND hwndBrowser = GetDlgItem(hwndDlg, IDC_BROWSER);
   903     ::SetFocus(hwndBrowser);
   904 }
   906 //
   907 //  FUNCTION: UpdateStatusBarText()
   908 //
   909 //  PURPOSE: Set the status bar text.
   910 //
   911 void WebBrowserChromeUI::UpdateStatusBarText(nsIWebBrowserChrome *aChrome, const char16_t* aStatusText)
   912 {
   913     HWND hwndDlg = GetBrowserDlgFromChrome(aChrome);
   914     nsCString status; 
   915     if (aStatusText) {
   916         nsString wStatusText(aStatusText);
   917         NS_UTF16ToCString(wStatusText, NS_CSTRING_ENCODING_NATIVE_FILESYSTEM,
   918                           status);
   919     }
   921     SetDlgItemText(hwndDlg, IDC_STATUS, status.get());
   922 }
   925 //
   926 //  FUNCTION: UpdateCurrentURI()
   927 //
   928 //  PURPOSE: Updates the URL address field
   929 //
   930 void WebBrowserChromeUI::UpdateCurrentURI(nsIWebBrowserChrome *aChrome)
   931 {
   932     nsCOMPtr<nsIWebBrowser> webBrowser;
   933     nsCOMPtr<nsIWebNavigation> webNavigation;
   934     aChrome->GetWebBrowser(getter_AddRefs(webBrowser));
   935     webNavigation = do_QueryInterface(webBrowser);
   937     nsCOMPtr<nsIURI> currentURI;
   938     webNavigation->GetCurrentURI(getter_AddRefs(currentURI));
   939     if (currentURI)
   940     {
   941         nsCString uriString;
   942         currentURI->GetAsciiSpec(uriString);
   943         HWND hwndDlg = GetBrowserDlgFromChrome(aChrome);
   944         SetDlgItemText(hwndDlg, IDC_ADDRESS, uriString.get());
   945     }
   946 }
   949 //
   950 //  FUNCTION: UpdateBusyState()
   951 //
   952 //  PURPOSE: Refreshes the stop/go buttons in the browser dialog
   953 //
   954 void WebBrowserChromeUI::UpdateBusyState(nsIWebBrowserChrome *aChrome, bool aBusy)
   955 {
   956     HWND hwndDlg = GetBrowserDlgFromChrome(aChrome);
   957     HWND button;
   958     button = GetDlgItem(hwndDlg, IDC_STOP);
   959     if (button)
   960         EnableWindow(button, aBusy);
   961     button = GetDlgItem(hwndDlg, IDC_GO);
   962     if (button)
   963         EnableWindow(button, !aBusy);
   964     UpdateUI(aChrome);
   965 }
   968 //
   969 //  FUNCTION: UpdateProgress()
   970 //
   971 //  PURPOSE: Refreshes the progress bar in the browser dialog
   972 //
   973 void WebBrowserChromeUI::UpdateProgress(nsIWebBrowserChrome *aChrome, int32_t aCurrent, int32_t aMax)
   974 {
   975     HWND hwndDlg = GetBrowserDlgFromChrome(aChrome);
   976     HWND hwndProgress = GetDlgItem(hwndDlg, IDC_PROGRESS);
   977     if (aCurrent < 0)
   978     {
   979         aCurrent = 0;
   980     }
   981     if (aCurrent > aMax)
   982     {
   983         aMax = aCurrent + 20; // What to do?
   984     }
   985     if (hwndProgress)
   986     {
   987         SendMessage(hwndProgress, PBM_SETRANGE, 0, MAKELPARAM(0, aMax));
   988         SendMessage(hwndProgress, PBM_SETPOS, aCurrent, 0);
   989     }
   990 }
   992 //
   993 //  FUNCTION: ShowContextMenu()
   994 //
   995 //  PURPOSE: Display a context menu for the given node
   996 //
   997 void WebBrowserChromeUI::ShowContextMenu(nsIWebBrowserChrome *aChrome, uint32_t aContextFlags, nsIDOMEvent *aEvent, nsIDOMNode *aNode)
   998 {
   999     // TODO code to test context flags and display a popup menu should go here
  1002 //
  1003 //  FUNCTION: ShowTooltip()
  1004 //
  1005 //  PURPOSE: Show a tooltip
  1006 //
  1007 void WebBrowserChromeUI::ShowTooltip(nsIWebBrowserChrome *aChrome, int32_t aXCoords, int32_t aYCoords, const char16_t *aTipText)
  1009     // TODO code to show a tooltip should go here
  1012 //
  1013 //  FUNCTION: HideTooltip()
  1014 //
  1015 //  PURPOSE: Hide the tooltip
  1016 //
  1017 void WebBrowserChromeUI::HideTooltip(nsIWebBrowserChrome *aChrome)
  1019     // TODO code to hide a tooltip should go here
  1022 void WebBrowserChromeUI::ShowWindow(nsIWebBrowserChrome *aChrome, bool aShow)
  1024   HWND win = GetBrowserDlgFromChrome(aChrome);
  1025   ::ShowWindow(win, aShow ? SW_RESTORE : SW_HIDE);
  1028 void WebBrowserChromeUI::SizeTo(nsIWebBrowserChrome *aChrome, int32_t aWidth, int32_t aHeight)
  1030   HWND hchrome = GetBrowserDlgFromChrome(aChrome);
  1031   HWND hbrowser = GetBrowserFromChrome(aChrome);
  1032   RECT chromeRect, browserRect;
  1034   ::GetWindowRect(hchrome,  &chromeRect);
  1035   ::GetWindowRect(hbrowser, &browserRect);
  1037   int32_t decoration_x = (browserRect.left - chromeRect.left) + 
  1038                          (chromeRect.right - browserRect.right);
  1039   int32_t decoration_y = (browserRect.top - chromeRect.top) + 
  1040                          (chromeRect.bottom - browserRect.bottom);
  1042   ::MoveWindow(hchrome, chromeRect.left, chromeRect.top,
  1043       aWidth+decoration_x,
  1044       aHeight+decoration_y, TRUE);
  1047 //
  1048 //  FUNCTION: GetResourceStringByID()
  1049 //
  1050 //  PURPOSE: Get the resource string for the ID
  1051 //
  1052 void WebBrowserChromeUI::GetResourceStringById(int32_t aID, char ** aReturn)
  1054     char resBuf[MAX_LOADSTRING];
  1055     int retval = LoadString( ghInstanceApp, aID, (LPTSTR)resBuf, sizeof(resBuf) );
  1056     if (retval != 0)
  1058         size_t resLen = strlen(resBuf);
  1059         *aReturn = (char *)calloc(resLen+1, sizeof(char *));
  1060         if (!*aReturn) return;
  1061             strncpy(*aReturn, resBuf, resLen);
  1063     return;
  1066 //-----------------------------------------------------------------------------
  1067 // AppCallbacks
  1068 //-----------------------------------------------------------------------------
  1070 nsresult AppCallbacks::CreateBrowserWindow(uint32_t aChromeFlags,
  1071            nsIWebBrowserChrome *aParent,
  1072            nsIWebBrowserChrome **aNewWindow)
  1074   WebBrowserChrome * chrome = new WebBrowserChrome();
  1075   if (!chrome)
  1076     return NS_ERROR_FAILURE;
  1078   // the interface to return and one addref, which we assume will be
  1079   // immediately released
  1080   *aNewWindow = static_cast<nsIWebBrowserChrome*>(chrome);
  1081   // now an extra addref; the window owns itself (to be released by
  1082   // WebBrowserChromeUI::Destroy)
  1083   NS_ADDREF(*aNewWindow);
  1085   chrome->SetChromeFlags(aChromeFlags);
  1086   chrome->SetParent(aParent);
  1088   // Insert the browser
  1089   nsCOMPtr<nsIWebBrowser> newBrowser;
  1090   chrome->CreateBrowser(-1, -1, -1, -1, getter_AddRefs(newBrowser));
  1091   if (!newBrowser)
  1092     return NS_ERROR_FAILURE;
  1094   // Place it where we want it.
  1095   ResizeEmbedding(static_cast<nsIWebBrowserChrome*>(chrome));
  1097   // if opened as chrome, it'll be made visible after the chrome has loaded.
  1098   // otherwise, go ahead and show it now.
  1099   if (!(aChromeFlags & nsIWebBrowserChrome::CHROME_OPENAS_CHROME))
  1100     WebBrowserChromeUI::ShowWindow(*aNewWindow, true);
  1102   return NS_OK;
  1105 void AppCallbacks::EnableChromeWindow(nsIWebBrowserChrome *aWindow,
  1106                       bool aEnabled)
  1108   HWND hwnd = GetBrowserDlgFromChrome(aWindow);
  1109   ::EnableWindow(hwnd, aEnabled ? TRUE : FALSE);
  1112 uint32_t AppCallbacks::RunEventLoop(bool &aRunCondition)
  1114   MSG msg;
  1115   HANDLE hFakeEvent = ::CreateEvent(nullptr, TRUE, FALSE, nullptr);
  1117   while (aRunCondition ) {
  1118     // Process pending messages
  1119     while (::PeekMessage(&msg, nullptr, 0, 0, PM_NOREMOVE)) {
  1120       if (!::GetMessage(&msg, nullptr, 0, 0)) {
  1121         // WM_QUIT
  1122         aRunCondition = false;
  1123         break;
  1126       ::TranslateMessage(&msg);
  1127       ::DispatchMessage(&msg);
  1130     // Do idle stuff
  1131     ::MsgWaitForMultipleObjects(1, &hFakeEvent, FALSE, 100, QS_ALLEVENTS);
  1133   ::CloseHandle(hFakeEvent);
  1134   return (uint32_t)msg.wParam;

mercurial