embedding/tests/winEmbed/winEmbed.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial