Follow-on fix for bug 457825. Use sheet principal for agent and user sheets. r=dbaron...
[wine-gecko.git] / embedding / tests / os2Embed / os2Embed.cpp
blobe590cb6843fad8f14438e212a34a3839043d3a9d
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
5 * Copyright (c) 2002 Netscape Communications Corporation and
6 * other contributors
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:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
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.
27 * Contributor(s):
28 * Doug Turner <dougt@netscape.com>
29 * Adam Lock <adamlock@netscape.com>
31 * ***** END LICENSE BLOCK ***** */
33 #include <stdio.h>
35 // OS/2 header files
36 #define INCL_WIN
37 #define INCL_DOS
38 #include <os2.h>
40 // Mozilla header files
41 #include "nsEmbedAPI.h"
42 #include "nsWeakReference.h"
43 #include "nsIClipboardCommands.h"
44 #include "nsXPIDLString.h"
45 #include "nsIWebBrowserPersist.h"
46 #include "nsIWebBrowserFocus.h"
47 #include "nsIWindowWatcher.h"
48 #include "nsIProfile.h"
49 #include "nsIObserverService.h"
50 #include "nsIObserver.h"
51 #include "nsIProfileChangeStatus.h"
52 #include "nsIURI.h"
53 #include "plstr.h"
54 #include "nsIInterfaceRequestor.h"
55 #include "nsCRT.h"
57 // Local header files
58 #include "os2Embed.h"
59 #include "WebBrowserChrome.h"
60 #include "WindowCreator.h"
61 #include "resource.h"
62 #include "nsStaticComponents.h"
64 // Printing header files
65 #include "nsIPrintSettings.h"
66 #include "nsIWebBrowserPrint.h"
68 #define MAX_LOADSTRING 100
71 #ifndef _BUILD_STATIC_BIN
72 nsStaticModuleInfo const *const kPStaticModules = nsnull;
73 PRUint32 const kStaticModuleCount = 0;
74 #endif
76 const CHAR *szWindowClass = "OS2EMBED";
78 // Foward declarations of functions included in this code module:
79 static void MyRegisterClass();
80 static MRESULT EXPENTRY BrowserWndProc(HWND, ULONG, MPARAM, MPARAM);
81 static MRESULT EXPENTRY BrowserDlgProc(HWND hwndDlg, ULONG uMsg, MPARAM wParam, MPARAM lParam);
83 static nsresult InitializeWindowCreator();
84 static nsresult OpenWebPage(const char * url);
85 static nsresult ResizeEmbedding(nsIWebBrowserChrome* chrome);
87 // Profile chooser stuff
88 static BOOL ChooseNewProfile(BOOL bShowForMultipleProfilesOnly, const char *szDefaultProfile);
89 static MRESULT EXPENTRY ChooseProfileDlgProc(HWND, ULONG, MPARAM, MPARAM);
91 // Global variables
92 static UINT gDialogCount = 0;
93 static BOOL gProfileSwitch = FALSE;
94 static HMODULE ghInstanceResources = NULL;
95 static char gFirstURL[1024];
97 // A list of URLs to populate the URL drop down list with
98 static const CHAR *gDefaultURLs[] =
100 ("http://www.mozilla.org/"),
101 ("http://www.netscape.com/"),
102 ("http://browsertest.web.aol.com/tests/javascript/javascpt/index.htm"),
103 ("http://127.0.0.1/"),
104 ("http://www.yahoo.com/"),
105 ("http://www.travelocity.com/"),
106 ("http://www.disney.com/"),
107 ("http://www.go.com/"),
108 ("http://www.google.com/"),
109 ("http://www.ebay.com/"),
110 ("http://www.shockwave.com/"),
111 ("http://www.slashdot.org/"),
112 ("http://www.quicken.com/"),
113 ("http://www.hotmail.com/"),
114 ("http://www.cnn.com/"),
115 ("http://www.javasoft.com/")
118 class ProfileChangeObserver : public nsIObserver,
119 public nsSupportsWeakReference
122 public:
123 ProfileChangeObserver();
125 NS_DECL_ISUPPORTS
126 NS_DECL_NSIOBSERVER
130 int main(int argc, char *argv[])
132 printf("You are embedded, man!\n\n");
134 // Sophisticated command-line parsing in action
135 char *szFirstURL = "http://www.mozilla.org/projects/embedding";
136 char *szDefaultProfile = nsnull;
137 int argn;
138 for (argn = 1; argn < argc; argn++)
140 if (stricmp("-P", argv[argn]) == 0)
142 if (argn + 1 < argc)
144 szDefaultProfile = argv[++argn];
147 else
149 szFirstURL = argv[argn];
152 strncpy(gFirstURL, szFirstURL, sizeof(gFirstURL) - 1);
154 // Initialize global strings
155 CHAR szTitle[MAX_LOADSTRING];
156 WinLoadString((HAB)0, ghInstanceResources, IDS_APP_TITLE, MAX_LOADSTRING, szTitle);
157 MyRegisterClass();
159 // Init Embedding APIs
160 NS_InitEmbedding(nsnull, nsnull, kPStaticModules, kStaticModuleCount);
162 // Choose the new profile
163 if (!ChooseNewProfile(TRUE, szDefaultProfile))
165 NS_TermEmbedding();
166 return 1;
168 MPARAM rv;
170 // Now register an observer to watch for profile changes
171 nsCOMPtr<nsIObserverService> observerService(do_GetService("@mozilla.org/observer-service;1"));
173 ProfileChangeObserver *observer = new ProfileChangeObserver;
174 observer->AddRef();
175 observerService->AddObserver(static_cast<nsIObserver *>(observer), "profile-approve-change", PR_TRUE);
176 observerService->AddObserver(static_cast<nsIObserver *>(observer), "profile-change-teardown", PR_TRUE);
177 observerService->AddObserver(static_cast<nsIObserver *>(observer), "profile-after-change", PR_TRUE);
179 InitializeWindowCreator();
181 // Open the initial browser window
182 OpenWebPage(gFirstURL);
184 // Main message loop.
185 // NOTE: We use a fake event and a timeout in order to process idle stuff for
186 // Mozilla every 1/10th of a second.
187 PRBool runCondition = PR_TRUE;
189 rv = (MPARAM)RunEventLoop(runCondition);
191 observer->Release();
193 // Close down Embedding APIs
194 NS_TermEmbedding();
196 return (int)rv;
199 //-----------------------------------------------------------------------------
200 // ProfileChangeObserver
201 //-----------------------------------------------------------------------------
203 NS_IMPL_THREADSAFE_ISUPPORTS2(ProfileChangeObserver, nsIObserver, nsISupportsWeakReference)
205 ProfileChangeObserver::ProfileChangeObserver()
209 // ---------------------------------------------------------------------------
210 // CMfcEmbedApp : nsIObserver
211 // ---------------------------------------------------------------------------
213 NS_IMETHODIMP ProfileChangeObserver::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *someData)
215 nsresult rv = NS_OK;
217 if (nsCRT::strcmp(aTopic, "profile-approve-change") == 0)
219 // The profile is about to change!
221 // Ask the user if they want to
222 int result = ::WinMessageBox(HWND_DESKTOP, NULL, "Do you want to close all windows in order to switch the profile?", "Confirm", 101, MB_YESNO | MB_ICONQUESTION);
223 if (result != MBID_YES)
225 nsCOMPtr<nsIProfileChangeStatus> status = do_QueryInterface(aSubject);
226 NS_ENSURE_TRUE(status, NS_ERROR_FAILURE);
227 status->VetoChange();
230 else if (nsCRT::strcmp(aTopic, "profile-change-teardown") == 0)
232 // The profile is changing!
234 // Prevent WM_QUIT by incrementing the dialog count
235 gDialogCount++;
237 else if (nsCRT::strcmp(aTopic, "profile-after-change") == 0)
239 // Decrease the dialog count so WM_QUIT can once more happen
240 gDialogCount--;
241 if (gDialogCount == 0)
243 // All the dialogs have been torn down so open new page
244 OpenWebPage(gFirstURL);
246 else
248 // The profile has changed, but dialogs are still being
249 // torn down. Set this flag so when the last one goes
250 // it can finish the switch.
251 gProfileSwitch = TRUE;
255 return rv;
258 /* InitializeWindowCreator creates and hands off an object with a callback
259 to a window creation function. This is how all new windows are opened,
260 except any created directly by the embedding app. */
261 nsresult InitializeWindowCreator()
263 // create an nsWindowCreator and give it to the WindowWatcher service
264 WindowCreator *creatorCallback = new WindowCreator();
265 if (creatorCallback)
267 nsCOMPtr<nsIWindowCreator> windowCreator(static_cast<nsIWindowCreator *>(creatorCallback));
268 if (windowCreator)
270 nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
271 if (wwatch)
273 wwatch->SetWindowCreator(windowCreator);
274 return NS_OK;
278 return NS_ERROR_FAILURE;
281 //-----------------------------------------------------------------------------
284 // FUNCTION: OpenWebPage()
286 // PURPOSE: Opens a new browser dialog and starts it loading to the
287 // specified url.
289 nsresult OpenWebPage(const char *url)
291 nsresult rv;
293 // Create the chrome object. Note that it leaves this function
294 // with an extra reference so that it can released correctly during
295 // destruction (via Win32UI::Destroy)
297 nsCOMPtr<nsIWebBrowserChrome> chrome;
298 rv = CreateBrowserWindow(nsIWebBrowserChrome::CHROME_ALL,
299 nsnull, getter_AddRefs(chrome));
300 if (NS_SUCCEEDED(rv))
302 // Start loading a page
303 nsCOMPtr<nsIWebBrowser> newBrowser;
304 chrome->GetWebBrowser(getter_AddRefs(newBrowser));
305 nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(newBrowser));
306 return webNav->LoadURI(NS_ConvertASCIItoUTF16(url).get(),
307 nsIWebNavigation::LOAD_FLAGS_NONE,
308 nsnull,
309 nsnull,
310 nsnull);
313 return rv;
317 // FUNCTION: GetBrowserFromChrome()
319 // PURPOSE: Returns the HWND for the webbrowser container associated
320 // with the specified chrome.
322 HWND GetBrowserFromChrome(nsIWebBrowserChrome *aChrome)
324 if (!aChrome)
326 return NULL;
328 nsCOMPtr<nsIEmbeddingSiteWindow> baseWindow = do_QueryInterface(aChrome);
329 HWND hwnd = NULL;
330 baseWindow->GetSiteWindow((void **) & hwnd);
331 return hwnd;
336 // FUNCTION: GetBrowserDlgFromChrome()
338 // PURPOSE: Returns the HWND for the browser dialog associated with
339 // the specified chrome.
341 HWND GetBrowserDlgFromChrome(nsIWebBrowserChrome *aChrome)
343 return WinQueryWindow(GetBrowserFromChrome(aChrome), QW_PARENT);
348 // FUNCTION: SaveWebPage()
350 // PURPOSE: Saves the contents of the web page to a file
352 void SaveWebPage(HWND hDlg, nsIWebBrowser *aWebBrowser)
354 // Use the browser window title as the initial file name
355 nsCOMPtr<nsIBaseWindow> webBrowserAsWin = do_QueryInterface(aWebBrowser);
356 nsXPIDLString windowTitle;
357 webBrowserAsWin->GetTitle(getter_Copies(windowTitle));
358 nsCString fileName; fileName.AssignWithConversion(windowTitle);
360 // Sanitize the title of all illegal characters
361 fileName.CompressWhitespace(); // Remove whitespace from the ends
362 fileName.StripChars("\\*|:\"><?"); // Strip illegal characters
363 fileName.ReplaceChar('.', L'_'); // Dots become underscores
364 fileName.ReplaceChar('/', L'-'); // Forward slashes become hyphens
365 fileName.ReplaceChar(' ', L'_'); // Spaces become underscores
367 // Initialize the file save as information structure
368 FILEDLG saveFileNameInfo;
369 memset(&saveFileNameInfo, 0, sizeof(saveFileNameInfo));
370 saveFileNameInfo.cbSize = sizeof(saveFileNameInfo);
371 PL_strncpyz(saveFileNameInfo.szFullFile, fileName.get(), CCHMAXPATH);
372 strcat(saveFileNameInfo.szFullFile, ".html");
374 PSZ *apszTypeList = (PSZ *)malloc(3 * sizeof(PSZ) + 1);
375 apszTypeList[0] = "Web Page, HTML Only (*.htm;*.html)";
376 apszTypeList[1] = "Web Page, Complete (*.htm;*.html)";
377 apszTypeList[2] = "Text File (*.txt)";
378 apszTypeList[3] = 0;
379 saveFileNameInfo.papszITypeList = (PAPSZ)apszTypeList;
380 saveFileNameInfo.pszTitle = NULL;
381 saveFileNameInfo.fl = FDS_SAVEAS_DIALOG | FDS_CENTER | FDS_ENABLEFILELB;
382 saveFileNameInfo.pszIType = apszTypeList[0];
384 WinFileDlg(HWND_DESKTOP, hDlg, &saveFileNameInfo);
385 if (saveFileNameInfo.lReturn == DID_OK)
387 char *pszDataPath = NULL;
388 static char szDataFile[_MAX_PATH];
389 char szDataPath[_MAX_PATH];
390 char drive[_MAX_DRIVE];
391 char dir[_MAX_DIR];
392 char fname[_MAX_FNAME];
393 char ext[_MAX_EXT];
395 _splitpath(saveFileNameInfo.szFullFile, drive, dir, fname, ext);
396 //add the extension to the filename if there is no extension already
397 if (strcmp(ext, "") == 0) {
398 if ((saveFileNameInfo.sEAType == 2) && (stricmp(ext, ".txt") != 0)) {
399 strcat(saveFileNameInfo.szFullFile, ".txt");
400 strcpy(ext, ".txt");
401 } else
402 if ((stricmp(ext, ".html") != 0) && (stricmp(ext, ".htm") != 0)) {
403 strcat(saveFileNameInfo.szFullFile, ".html");
404 strcpy(ext, ".html");
408 // Does the user want to save the complete document including
409 // all frames, images, scripts, stylesheets etc. ?
410 if (saveFileNameInfo.sEAType == 1) //apszTypeList[1] means save everything
412 sprintf(szDataFile, "%s_files", fname);
413 _makepath(szDataPath, drive, dir, szDataFile, "");
415 pszDataPath = szDataPath;
418 // Save away
419 nsCOMPtr<nsIWebBrowserPersist> persist(do_QueryInterface(aWebBrowser));
421 nsCOMPtr<nsILocalFile> file;
422 NS_NewNativeLocalFile(nsDependentCString(saveFileNameInfo.szFullFile), TRUE, getter_AddRefs(file));
424 nsCOMPtr<nsILocalFile> dataPath;
425 if (pszDataPath)
427 NS_NewNativeLocalFile(nsDependentCString(pszDataPath), TRUE, getter_AddRefs(dataPath));
430 persist->SaveDocument(nsnull, file, dataPath, nsnull, 0, 0);
432 if (saveFileNameInfo.papszFQFilename)
433 WinFreeFileDlgList(saveFileNameInfo.papszFQFilename);
434 for (int i = 0; i < 3; i++)
435 free(saveFileNameInfo.papszITypeList[i]);
436 free(saveFileNameInfo.papszITypeList);
441 // FUNCTION: ResizeEmbedding()
443 // PURPOSE: Resizes the webbrowser window to fit its container.
445 nsresult ResizeEmbedding(nsIWebBrowserChrome* chrome)
447 if (!chrome)
448 return NS_ERROR_FAILURE;
450 nsCOMPtr<nsIEmbeddingSiteWindow> embeddingSite = do_QueryInterface(chrome);
451 HWND hWnd;
452 embeddingSite->GetSiteWindow((void **) & hWnd);
454 if (!hWnd)
455 return NS_ERROR_NULL_POINTER;
457 RECTL rect;
458 WinQueryWindowRect(hWnd, &rect);
460 // Make sure the browser is visible and sized
461 nsCOMPtr<nsIWebBrowser> webBrowser;
462 chrome->GetWebBrowser(getter_AddRefs(webBrowser));
463 nsCOMPtr<nsIBaseWindow> webBrowserAsWin = do_QueryInterface(webBrowser);
464 if (webBrowserAsWin)
466 webBrowserAsWin->SetPositionAndSize(rect.xLeft,
467 rect.yBottom,
468 rect.xRight - rect.xLeft,
469 rect.yTop - rect.yBottom,
470 PR_TRUE);
471 webBrowserAsWin->SetVisibility(PR_TRUE);
474 return NS_OK;
479 // FUNCTION: MyRegisterClass()
481 // PURPOSE: Registers the window class.
483 // COMMENTS:
486 void MyRegisterClass()
488 WinRegisterClass((HAB)0, szWindowClass, BrowserWndProc, CS_SIZEREDRAW, sizeof(ULONG));
493 // FUNCTION: UpdateUI()
495 // PURPOSE: Refreshes the buttons and menu items in the browser dialog
497 void UpdateUI(nsIWebBrowserChrome *aChrome)
499 HWND hwndDlg = GetBrowserDlgFromChrome(aChrome);
500 nsCOMPtr<nsIWebBrowser> webBrowser;
501 nsCOMPtr<nsIWebNavigation> webNavigation;
502 aChrome->GetWebBrowser(getter_AddRefs(webBrowser));
503 webNavigation = do_QueryInterface(webBrowser);
505 PRBool canGoBack = PR_FALSE;
506 PRBool canGoForward = PR_FALSE;
507 if (webNavigation)
509 webNavigation->GetCanGoBack(&canGoBack);
510 webNavigation->GetCanGoForward(&canGoForward);
513 PRBool canCutSelection = PR_FALSE;
514 PRBool canCopySelection = PR_FALSE;
515 PRBool canPaste = PR_FALSE;
517 nsCOMPtr<nsIClipboardCommands> clipCmds = do_GetInterface(webBrowser);
518 if (clipCmds)
520 clipCmds->CanCutSelection(&canCutSelection);
521 clipCmds->CanCopySelection(&canCopySelection);
522 clipCmds->CanPaste(&canPaste);
525 HWND hmenu = WinWindowFromID(hwndDlg, FID_MENU);
526 if (hmenu)
528 MENUITEM goMenu, editMenu;
529 WinSendMsg(hmenu, MM_QUERYITEM, MPFROM2SHORT(MOZ_Go, TRUE), (MPARAM)&goMenu);
530 WinEnableMenuItem(goMenu.hwndSubMenu, MOZ_GoBack, canGoBack);
531 WinEnableMenuItem(goMenu.hwndSubMenu, MOZ_GoForward, canGoForward);
533 WinSendMsg(hmenu, MM_QUERYITEM, MPFROM2SHORT(MOZ_Edit, TRUE), (MPARAM)&editMenu);
534 WinEnableMenuItem(editMenu.hwndSubMenu, MOZ_Cut, canCutSelection);
535 WinEnableMenuItem(editMenu.hwndSubMenu, MOZ_Copy, canCopySelection);
536 WinEnableMenuItem(editMenu.hwndSubMenu, MOZ_Paste, canPaste);
539 HWND button;
540 button = WinWindowFromID(hwndDlg, IDC_BACK);
541 if (button)
542 WinEnableWindow(button, canGoBack);
543 button = WinWindowFromID(hwndDlg, IDC_FORWARD);
544 if (button)
545 WinEnableWindow(button, canGoForward);
550 // FUNCTION: BrowserDlgProc()
552 // PURPOSE: Browser dialog windows message handler.
554 // COMMENTS:
556 // The code for handling buttons and menu actions is here.
558 MRESULT EXPENTRY BrowserDlgProc(HWND hwndDlg, ULONG uMsg, MPARAM wParam, MPARAM lParam)
560 if (uMsg == WM_COMMAND && SHORT1FROMMP(wParam) == MOZ_SwitchProfile)
562 ChooseNewProfile(FALSE, NULL);
563 return (MRESULT)FALSE;
566 // Get the browser and other pointers since they are used a lot below
567 HWND hwndBrowser = WinWindowFromID(hwndDlg, IDC_BROWSER);
568 nsIWebBrowserChrome *chrome = nsnull ;
569 if (hwndBrowser)
571 chrome = (nsIWebBrowserChrome *) WinQueryWindowULong(hwndBrowser, QWL_USER);
573 nsCOMPtr<nsIWebBrowser> webBrowser;
574 nsCOMPtr<nsIWebNavigation> webNavigation;
575 nsCOMPtr<nsIWebBrowserPrint> webBrowserPrint;
576 if (chrome)
578 chrome->GetWebBrowser(getter_AddRefs(webBrowser));
579 webNavigation = do_QueryInterface(webBrowser);
580 webBrowserPrint = do_GetInterface(webBrowser);
583 // Test the message
584 switch (uMsg)
586 case WM_INITDLG:
587 return (MRESULT)TRUE;
589 case WM_INITMENU:
590 UpdateUI(chrome);
591 return (MRESULT)TRUE;
593 case WM_SYSCOMMAND:
594 if (SHORT1FROMMP(wParam) == SC_CLOSE)
596 WebBrowserChromeUI::Destroy(chrome);
597 return (MRESULT)TRUE;
599 break;
601 case WM_DESTROY:
602 return (MRESULT)TRUE;
604 case WM_COMMAND:
605 if (!webBrowser)
607 return (MRESULT)TRUE;
610 // Test which command was selected
611 switch (SHORT1FROMMP(wParam))
613 case IDC_ADDRESS:
614 if (SHORT1FROMMP(wParam) == CBN_EFCHANGE || SHORT1FROMMP(wParam) == CBN_LBSELECT)
616 // User has changed the address field so enable the Go button
617 WinEnableWindow(WinWindowFromID(hwndDlg, IDC_GO), TRUE);
619 break;
621 case IDC_GO:
623 char szURL[2048];
624 memset(szURL, 0, sizeof(szURL));
625 WinQueryDlgItemText(hwndDlg, IDC_ADDRESS, sizeof(szURL) / sizeof(szURL[0]) - 1, szURL);
626 webNavigation->LoadURI(
627 NS_ConvertASCIItoUTF16(szURL).get(),
628 nsIWebNavigation::LOAD_FLAGS_NONE,
629 nsnull,
630 nsnull,
631 nsnull);
633 break;
635 case IDC_STOP:
636 webNavigation->Stop(nsIWebNavigation::STOP_ALL);
637 UpdateUI(chrome);
638 break;
640 case IDC_RELOAD:
641 webNavigation->Reload(nsIWebNavigation::LOAD_FLAGS_NONE);
642 break;
644 case IDM_EXIT:
645 WinPostMsg(hwndDlg, WM_SYSCOMMAND, MPFROMSHORT(SC_CLOSE), 0);
646 break;
648 // File menu commands
650 case MOZ_NewBrowser:
651 OpenWebPage(gFirstURL);
652 break;
654 case MOZ_Save:
655 SaveWebPage(hwndDlg, webBrowser);
656 break;
658 case MOZ_Print:
660 // NOTE: Embedding code shouldn't need to get the docshell or
661 // contentviewer AT ALL. This code below will break one
662 // day but will have to do until the embedding API has
663 // a cleaner way to do the same thing.
664 if (webBrowserPrint)
666 nsCOMPtr<nsIPrintSettings> printSettings;
667 webBrowserPrint->GetGlobalPrintSettings(getter_AddRefs(printSettings));
668 NS_ASSERTION(printSettings, "You can't PrintPreview without a PrintSettings!");
669 if (printSettings)
671 printSettings->SetPrintSilent(PR_TRUE);
672 webBrowserPrint->Print(printSettings, (nsIWebProgressListener*)nsnull);
676 break;
678 // Edit menu commands
680 case MOZ_Cut:
682 nsCOMPtr<nsIClipboardCommands> clipCmds = do_GetInterface(webBrowser);
683 clipCmds->CutSelection();
685 break;
687 case MOZ_Copy:
689 nsCOMPtr<nsIClipboardCommands> clipCmds = do_GetInterface(webBrowser);
690 clipCmds->CopySelection();
692 break;
694 case MOZ_Paste:
696 nsCOMPtr<nsIClipboardCommands> clipCmds = do_GetInterface(webBrowser);
697 clipCmds->Paste();
699 break;
701 case MOZ_SelectAll:
703 nsCOMPtr<nsIClipboardCommands> clipCmds = do_GetInterface(webBrowser);
704 clipCmds->SelectAll();
706 break;
708 case MOZ_SelectNone:
710 nsCOMPtr<nsIClipboardCommands> clipCmds = do_GetInterface(webBrowser);
711 clipCmds->SelectNone();
713 break;
715 // Go menu commands
716 case IDC_BACK:
717 case MOZ_GoBack:
718 webNavigation->GoBack();
719 UpdateUI(chrome);
720 break;
722 case IDC_FORWARD:
723 case MOZ_GoForward:
724 webNavigation->GoForward();
725 UpdateUI(chrome);
726 break;
728 // Help menu commands
729 case MOZ_About:
731 char szAboutTitle[MAX_LOADSTRING];
732 char szAbout[MAX_LOADSTRING];
733 WinLoadString((HAB)0, ghInstanceResources, IDS_ABOUT_TITLE, MAX_LOADSTRING, szAboutTitle);
734 WinLoadString((HAB)0, ghInstanceResources, IDS_ABOUT, MAX_LOADSTRING, szAbout);
735 WinMessageBox(HWND_DESKTOP, NULL, szAbout, szAboutTitle, 0, MB_OK | MB_APPLMODAL);
737 break;
740 return (MRESULT)TRUE;
742 case WM_ACTIVATE:
744 nsCOMPtr<nsIWebBrowserFocus> focus(do_GetInterface(webBrowser));
745 if(focus)
747 switch (SHORT1FROMMP(wParam))
749 case TRUE: //WA_ACTIVE:
750 focus->Activate();
751 break;
752 case FALSE: //WA_INACTIVE:
753 focus->Deactivate();
754 break;
755 default:
756 break;
760 break;
762 case WM_ADJUSTWINDOWPOS:
764 PSWP swp = (PSWP)wParam;
765 if (swp->fl & (SWP_SIZE)) {
766 UINT newDlgWidth = swp->cx;
767 UINT newDlgHeight = swp->cy;
769 // TODO Reposition the control bar - for the moment it's fixed size
770 // Reposition all buttons, combobox, status, progress bar, and browser
771 // Status bar gets any space that the fixed size progress bar doesn't use.
772 // Address combobox gets any space not used by buttons and 'Address:'
773 int progressWidth, statusWidth, addressWidth, goWidth, forwardWidth, reloadWidth, stopWidth, backWidth, staticWidth;
774 int statusHeight, backHeight, buttonHeight, addressHeight, comboboxHeight;
776 HWND hwndStatus = WinWindowFromID(hwndDlg, IDC_STATUS);
777 if (hwndStatus) {
778 RECTL rcStatus;
779 WinQueryWindowRect(hwndStatus, &rcStatus);
780 statusHeight = rcStatus.yTop - rcStatus.yBottom;
781 } else
782 statusHeight = 0;
784 HWND hwndProgress = WinWindowFromID(hwndDlg, IDC_PROGRESS);
785 if (hwndProgress) {
786 RECTL rcProgress;
787 WinQueryWindowRect(hwndProgress, &rcProgress);
788 progressWidth = rcProgress.xRight - rcProgress.xLeft;
789 } else
790 progressWidth = 0;
791 statusWidth = newDlgWidth - progressWidth;
793 HWND hwndBack = WinWindowFromID(hwndDlg, IDC_BACK);
794 if (hwndBack) {
795 RECTL rcBack;
796 WinQueryWindowRect(hwndBack, &rcBack);
797 backHeight = rcBack.yTop - rcBack.yBottom;
798 backWidth = rcBack.xRight - rcBack.xLeft;
799 } else {
800 backHeight = 0;
801 backWidth = 0;
803 buttonHeight = newDlgHeight - backHeight - 50;//24;
805 HWND hwndForward = WinWindowFromID(hwndDlg, IDC_FORWARD);
806 if (hwndForward) {
807 RECTL rcForward;
808 WinQueryWindowRect(hwndForward, &rcForward);
809 forwardWidth = rcForward.xRight - rcForward.xLeft;
810 } else
811 forwardWidth = 0;
813 HWND hwndReload = WinWindowFromID(hwndDlg, IDC_RELOAD);
814 if (hwndReload) {
815 RECTL rcReload;
816 WinQueryWindowRect(hwndReload, &rcReload);
817 reloadWidth = rcReload.xRight - rcReload.xLeft;
818 } else
819 reloadWidth = 0;
821 HWND hwndStop = WinWindowFromID(hwndDlg, IDC_STOP);
822 if (hwndStop) {
823 RECTL rcStop;
824 WinQueryWindowRect(hwndStop, &rcStop);
825 stopWidth = rcStop.xRight - rcStop.xLeft;
826 } else
827 stopWidth = 0;
829 HWND hwndStatic = WinWindowFromID(hwndDlg, IDC_ADDRESSLABEL);
830 if (hwndStatic) {
831 RECTL rcStatic;
832 WinQueryWindowRect(hwndStatic, &rcStatic);
833 staticWidth = rcStatic.xRight - rcStatic.xLeft;
834 } else
835 staticWidth = 0;
837 HWND hwndGo = WinWindowFromID(hwndDlg, IDC_GO);
838 if (hwndGo) {
839 RECTL rcGo;
840 WinQueryWindowRect(hwndGo, &rcGo);
841 goWidth = rcGo.xRight - rcGo.xLeft;
842 } else
843 goWidth = 0;
845 HWND hwndAddress = WinWindowFromID(hwndDlg, IDC_ADDRESS);
846 if (hwndAddress) {
847 RECTL rcAddress;
848 WinQueryWindowRect(hwndAddress, &rcAddress);
849 addressHeight = rcAddress.yTop - rcAddress.yBottom;
850 comboboxHeight = buttonHeight + backHeight - addressHeight;
851 } else {
852 addressHeight = 0;
853 comboboxHeight = 0;
855 addressWidth = newDlgWidth - goWidth - backWidth - forwardWidth - reloadWidth - stopWidth - staticWidth - 15;
857 if (hwndStatus)
858 WinSetWindowPos(hwndStatus,
859 HWND_TOP,
860 0, 0,
861 statusWidth,
862 statusHeight,
863 SWP_MOVE | SWP_SIZE | SWP_SHOW);
864 if (hwndProgress)
865 WinSetWindowPos(hwndProgress,
866 HWND_TOP,
867 statusWidth, 0,
868 0, 0,
869 SWP_MOVE | SWP_SHOW);
870 if (hwndBack)
871 WinSetWindowPos(hwndBack,
872 HWND_TOP,
873 2, buttonHeight,
874 0, 0,
875 SWP_MOVE | SWP_SHOW);
876 if (hwndForward)
877 WinSetWindowPos(hwndForward,
878 HWND_TOP,
879 2 + backWidth, buttonHeight,
880 0, 0,
881 SWP_MOVE | SWP_SHOW);
882 if (hwndReload)
883 WinSetWindowPos(hwndReload,
884 HWND_TOP,
885 4 + backWidth + forwardWidth, buttonHeight,
886 0, 0,
887 SWP_MOVE | SWP_SHOW);
888 if (hwndStop)
889 WinSetWindowPos(hwndStop,
890 HWND_TOP,
891 5 + backWidth + forwardWidth + reloadWidth, buttonHeight,
892 0, 0,
893 SWP_MOVE | SWP_SHOW);
894 if (hwndStatic)
895 WinSetWindowPos(hwndStatic,
896 HWND_TOP,
897 9 + backWidth + forwardWidth + reloadWidth + stopWidth, buttonHeight + 3,
898 0, 0,
899 SWP_MOVE | SWP_SHOW);
900 if (hwndAddress)
901 WinSetWindowPos(hwndAddress,
902 HWND_TOP,
903 12 + backWidth + forwardWidth + reloadWidth + stopWidth + staticWidth, comboboxHeight,
904 addressWidth, addressHeight,
905 SWP_MOVE | SWP_SIZE | SWP_SHOW);
906 if (hwndGo)
907 WinSetWindowPos(hwndGo,
908 HWND_TOP,
909 13 + backWidth + forwardWidth + reloadWidth + stopWidth + staticWidth + addressWidth, buttonHeight,
910 0, 0,
911 SWP_MOVE | SWP_SHOW);
913 // Resize the browser area (assuming the browser is
914 // sandwiched between the control bar and status area)
915 WinSetWindowPos(hwndBrowser,
916 HWND_TOP,
917 2, statusHeight,
918 newDlgWidth - 4,
919 newDlgHeight - backHeight - statusHeight - 52,
920 SWP_MOVE | SWP_SIZE | SWP_SHOW);
923 return (MRESULT)TRUE;
925 return WinDefDlgProc(hwndDlg, uMsg, wParam, lParam);
930 // FUNCTION: BrowserWndProc(HWND, unsigned, WORD, LONG)
932 // PURPOSE: Processes messages for the browser container window.
934 MRESULT EXPENTRY BrowserWndProc(HWND hWnd, ULONG message, MPARAM wParam, MPARAM lParam)
936 nsIWebBrowserChrome *chrome = (nsIWebBrowserChrome *) WinQueryWindowULong(hWnd, QWL_USER);
937 switch (message)
939 case WM_SIZE:
940 // Resize the embedded browser
941 ResizeEmbedding(chrome);
942 return (MRESULT)0;
943 case WM_ERASEBACKGROUND:
944 // Reduce flicker by not painting the non-visible background
945 return (MRESULT)1;
947 return WinDefWindowProc(hWnd, message, wParam, lParam);
951 ///////////////////////////////////////////////////////////////////////////////
952 // Profile chooser dialog
956 // FUNCTION: ChooseNewProfile()
958 // PURPOSE: Allows the user to select a new profile from a list.
959 // The bShowForMultipleProfilesOnly argument specifies whether the
960 // function should automatically select the first profile and return
961 // without displaying a dialog box if there is only one profile to
962 // select.
964 BOOL ChooseNewProfile(BOOL bShowForMultipleProfilesOnly, const char *szDefaultProfile)
966 nsresult rv;
967 nsCOMPtr<nsIProfile> profileService =
968 do_GetService(NS_PROFILE_CONTRACTID, &rv);
969 if (NS_FAILED(rv))
971 return FALSE;
974 if (szDefaultProfile)
976 // Make a new default profile
977 nsAutoString newProfileName; newProfileName.AssignWithConversion(szDefaultProfile);
978 rv = profileService->CreateNewProfile(newProfileName.get(), nsnull, nsnull, PR_FALSE);
979 if (NS_FAILED(rv)) return FALSE;
980 rv = profileService->SetCurrentProfile(newProfileName.get());
981 if (NS_FAILED(rv)) return FALSE;
982 return TRUE;
985 PRInt32 profileCount = 0;
986 rv = profileService->GetProfileCount(&profileCount);
987 if (profileCount == 0)
989 // Make a new default profile
990 NS_NAMED_LITERAL_STRING(newProfileName, "os2Embed");
991 rv = profileService->CreateNewProfile(newProfileName.get(), nsnull, nsnull, PR_FALSE);
992 if (NS_FAILED(rv)) return FALSE;
993 rv = profileService->SetCurrentProfile(newProfileName.get());
994 if (NS_FAILED(rv)) return FALSE;
995 return TRUE;
997 else if (profileCount == 1 && bShowForMultipleProfilesOnly)
999 // GetCurrentProfile returns the profile which was last used but is not nescesarily
1000 // active. Call SetCurrentProfile to make it installed and active.
1002 nsXPIDLString currProfileName;
1003 rv = profileService->GetCurrentProfile(getter_Copies(currProfileName));
1004 if (NS_FAILED(rv)) return FALSE;
1005 rv = profileService->SetCurrentProfile(currProfileName);
1006 if (NS_FAILED(rv)) return FALSE;
1007 return TRUE;
1010 INT nResult;
1011 nResult = WinDlgBox(HWND_DESKTOP, HWND_DESKTOP, (PFNWP)ChooseProfileDlgProc, NULL, IDD_CHOOSEPROFILE, (PVOID)ghInstanceResources);
1012 return (nResult == DID_OK) ? TRUE : FALSE;
1017 // FUNCTION: ChooseProfileDlgProc(HWND, unsigned, WORD, LONG)
1019 // PURPOSE: Dialog handler procedure for the open uri dialog.
1021 MRESULT EXPENTRY ChooseProfileDlgProc(HWND hDlg, ULONG message, MPARAM wParam, MPARAM lParam)
1023 nsresult rv;
1024 switch (message)
1026 case WM_INITDLG:
1028 WinSetActiveWindow(HWND_DESKTOP, hDlg);
1029 HWND hwndProfileList = WinWindowFromID(hDlg, IDC_PROFILELIST);
1031 nsCOMPtr<nsIProfile> profileService =
1032 do_GetService(NS_PROFILE_CONTRACTID, &rv);
1034 // Get the list of profile names and add them to the list box
1035 PRUint32 listLen = 0;
1036 PRUnichar **profileList = nsnull;
1037 rv = profileService->GetProfileList(&listLen, &profileList);
1038 for (PRUint32 index = 0; index < listLen; index++)
1040 #ifdef UNICODE
1041 WinSendMsg(hwndProfileList, LM_INSERTITEM, (MPARAM)LIT_END, (MPARAM) profileList[index]);
1042 #else
1043 nsCAutoString profile; profile.AssignWithConversion(profileList[index]);
1044 WinSendMsg(hwndProfileList, LM_INSERTITEM, (MPARAM)LIT_END, (MPARAM) profile.get());
1045 #endif
1048 // Select the current profile (if there is one)
1050 // Get the current profile
1051 #ifdef UNICODE
1052 nsXPIDLString currProfile;
1053 profileService->GetCurrentProfile(getter_Copies(currProfile));
1054 #else
1055 nsXPIDLString currProfileUnicode;
1056 profileService->GetCurrentProfile(getter_Copies(currProfileUnicode));
1057 nsCAutoString currProfile; currProfile.AssignWithConversion(currProfileUnicode);
1058 #endif
1060 // Now find and select it
1061 LONG currentProfileIndex = LIT_ERROR;
1062 currentProfileIndex = (LONG)WinSendMsg(hwndProfileList, LM_SEARCHSTRING, MPFROM2SHORT(LSS_CASESENSITIVE, LIT_FIRST), (MPARAM) currProfile.get());
1063 if (currentProfileIndex != LIT_ERROR)
1065 WinSendMsg(hwndProfileList, LM_SELECTITEM, (MPARAM)currentProfileIndex, (MPARAM)TRUE);
1068 return (MRESULT)TRUE;
1070 case WM_COMMAND:
1071 if (SHORT1FROMMP(wParam) == DID_OK)
1073 HWND hwndProfileList = WinWindowFromID(hDlg, IDC_PROFILELIST);
1075 // Get the selected profile from the list box and make it current
1076 LONG currentProfileIndex = (LONG)WinSendMsg(hwndProfileList, LM_QUERYSELECTION, (MPARAM)LIT_FIRST, (MPARAM)0);
1077 if (currentProfileIndex != LIT_ERROR)
1079 nsCOMPtr<nsIProfile> profileService =
1080 do_GetService(NS_PROFILE_CONTRACTID, &rv);
1081 // Convert TCHAR name to unicode and make it current
1082 INT profileNameLen = (INT)WinSendMsg(hwndProfileList, LM_QUERYITEMTEXTLENGTH, (MPARAM)currentProfileIndex, 0);
1083 char *profileName = new char[profileNameLen + 1];
1084 WinSendMsg(hwndProfileList, LM_QUERYITEMTEXT, MPFROM2SHORT(currentProfileIndex, profileNameLen + 1) ,(MPARAM)profileName);
1085 nsAutoString newProfile; newProfile.AssignWithConversion(profileName);
1086 rv = profileService->SetCurrentProfile(newProfile.get());
1088 WinDismissDlg(hDlg, DID_OK);
1090 else if (SHORT1FROMMP(wParam) == DID_CANCEL)
1092 WinDismissDlg(hDlg, SHORT1FROMMP(wParam));
1094 return (MRESULT)TRUE;
1097 return WinDefDlgProc(hDlg, message, wParam, lParam);
1102 ///////////////////////////////////////////////////////////////////////////////
1103 // WebBrowserChromeUI
1106 // FUNCTION: CreateNativeWindow()
1108 // PURPOSE: Creates a new browser dialog.
1110 // COMMENTS:
1112 // This function loads the browser dialog from a resource template
1113 // and returns the HWND for the webbrowser container dialog item
1114 // to the caller.
1116 nativeWindow WebBrowserChromeUI::CreateNativeWindow(nsIWebBrowserChrome* chrome)
1118 // Load the browser dialog from resource
1119 HWND hwndDialog;
1120 PRUint32 chromeFlags;
1122 chrome->GetChromeFlags(&chromeFlags);
1123 if ((chromeFlags & nsIWebBrowserChrome::CHROME_ALL) == nsIWebBrowserChrome::CHROME_ALL)
1124 hwndDialog = WinLoadDlg(HWND_DESKTOP, HWND_DESKTOP, BrowserDlgProc, ghInstanceResources, IDD_BROWSER, NULL);
1125 else
1126 hwndDialog = WinLoadDlg(HWND_DESKTOP, HWND_DESKTOP, BrowserDlgProc, ghInstanceResources, IDD_BROWSER_NC, NULL);
1127 if (!hwndDialog)
1128 return NULL;
1130 // Stick a menu onto it
1131 if (chromeFlags & nsIWebBrowserChrome::CHROME_MENUBAR) {
1132 HWND hmenuDlg = WinLoadMenu(hwndDialog, 0, IDC_OS2EMBED);
1133 WinSendMsg(hwndDialog, WM_UPDATEFRAME, MPFROMLONG(FCF_MENU), 0);
1134 } else
1135 WinSendMsg(hwndDialog, WM_UPDATEFRAME, 0, 0);
1137 // Add some interesting URLs to the address drop down
1138 HWND hwndAddress = WinWindowFromID(hwndDialog, IDC_ADDRESS);
1139 if (hwndAddress) {
1140 for (int i = 0; i < sizeof(gDefaultURLs) / sizeof(gDefaultURLs[0]); i++)
1142 WinSendMsg(hwndAddress, LM_INSERTITEM, (MPARAM)LIT_SORTASCENDING, (MPARAM)gDefaultURLs[i]);
1146 // Fetch the browser window handle
1147 HWND hwndBrowser = WinWindowFromID(hwndDialog, IDC_BROWSER);
1148 WinSetWindowULong(hwndBrowser, QWL_USER, (ULONG)chrome); // save the browser LONG_PTR.
1149 WinSetWindowULong(hwndBrowser, QWL_STYLE, WinQueryWindowULong(hwndBrowser, QWL_STYLE) | WS_CLIPCHILDREN);
1151 // Activate the window
1152 WinPostMsg(hwndDialog, WM_ACTIVATE, MPFROMSHORT(TRUE), (MPARAM)0);
1154 gDialogCount++;
1156 return (void *)hwndBrowser;
1161 // FUNCTION: Destroy()
1163 // PURPOSE: Destroy the window specified by the chrome
1165 void WebBrowserChromeUI::Destroy(nsIWebBrowserChrome* chrome)
1167 nsCOMPtr<nsIWebBrowser> webBrowser;
1168 nsCOMPtr<nsIWebNavigation> webNavigation;
1170 chrome->GetWebBrowser(getter_AddRefs(webBrowser));
1171 webNavigation = do_QueryInterface(webBrowser);
1172 if (webNavigation)
1173 webNavigation->Stop(nsIWebNavigation::STOP_ALL);
1175 chrome->ExitModalEventLoop(NS_OK);
1177 HWND hwndDlg = GetBrowserDlgFromChrome(chrome);
1178 if (hwndDlg == NULL)
1179 return;
1181 // Explicitly destroy the embedded browser and then the chrome
1183 // First the browser
1184 nsCOMPtr<nsIWebBrowser> browser = nsnull;
1185 chrome->GetWebBrowser(getter_AddRefs(browser));
1186 nsCOMPtr<nsIBaseWindow> browserAsWin = do_QueryInterface(browser);
1187 if (browserAsWin)
1188 browserAsWin->Destroy();
1190 // Now the chrome
1191 chrome->SetWebBrowser(nsnull);
1192 NS_RELEASE(chrome);
1197 // FUNCTION: Called as the final act of a chrome object during its destructor
1199 void WebBrowserChromeUI::Destroyed(nsIWebBrowserChrome* chrome)
1201 HWND hwndDlg = GetBrowserDlgFromChrome(chrome);
1202 if (hwndDlg == NULL)
1204 return;
1207 // Clear the window user data
1208 HWND hwndBrowser = WinWindowFromID(hwndDlg, IDC_BROWSER);
1209 WinSetWindowULong(hwndBrowser, QWL_USER, nsnull);
1210 WinDestroyWindow(hwndBrowser);
1211 WinDestroyWindow(hwndDlg);
1213 --gDialogCount;
1214 if (gDialogCount == 0)
1216 if (gProfileSwitch)
1218 gProfileSwitch = FALSE;
1219 OpenWebPage(gFirstURL);
1221 else
1223 // Quit when there are no more browser objects
1224 WinPostQueueMsg(0, WM_QUIT, 0, 0);
1231 // FUNCTION: Set the input focus onto the browser window
1233 void WebBrowserChromeUI::SetFocus(nsIWebBrowserChrome *chrome)
1235 HWND hwndDlg = GetBrowserDlgFromChrome(chrome);
1236 if (hwndDlg == NULL)
1238 return;
1241 HWND hwndBrowser = WinWindowFromID(hwndDlg, IDC_BROWSER);
1242 ::WinSetFocus(HWND_DESKTOP, hwndBrowser);
1246 // FUNCTION: UpdateStatusBarText()
1248 // PURPOSE: Set the status bar text.
1250 void WebBrowserChromeUI::UpdateStatusBarText(nsIWebBrowserChrome *aChrome, const PRUnichar* aStatusText)
1252 HWND hwndDlg = GetBrowserDlgFromChrome(aChrome);
1253 nsCString status;
1254 if (aStatusText)
1255 status.AssignWithConversion(aStatusText);
1256 WinSetDlgItemText(hwndDlg, IDC_STATUS, status.get());
1261 // FUNCTION: UpdateCurrentURI()
1263 // PURPOSE: Updates the URL address field
1265 void WebBrowserChromeUI::UpdateCurrentURI(nsIWebBrowserChrome *aChrome)
1267 nsCOMPtr<nsIWebBrowser> webBrowser;
1268 nsCOMPtr<nsIWebNavigation> webNavigation;
1269 aChrome->GetWebBrowser(getter_AddRefs(webBrowser));
1270 webNavigation = do_QueryInterface(webBrowser);
1272 nsCOMPtr<nsIURI> currentURI;
1273 webNavigation->GetCurrentURI(getter_AddRefs(currentURI));
1274 if (currentURI)
1276 nsCAutoString uriString;
1277 currentURI->GetAsciiSpec(uriString);
1278 HWND hwndDlg = GetBrowserDlgFromChrome(aChrome);
1279 WinSetDlgItemText(hwndDlg, IDC_ADDRESS, uriString.get());
1285 // FUNCTION: UpdateBusyState()
1287 // PURPOSE: Refreshes the stop/go buttons in the browser dialog
1289 void WebBrowserChromeUI::UpdateBusyState(nsIWebBrowserChrome *aChrome, PRBool aBusy)
1291 HWND hwndDlg = GetBrowserDlgFromChrome(aChrome);
1292 HWND button;
1293 button = WinWindowFromID(hwndDlg, IDC_STOP);
1294 if (button)
1295 WinEnableWindow(button, aBusy);
1296 button = WinWindowFromID(hwndDlg, IDC_GO);
1297 if (button)
1298 WinEnableWindow(button, !aBusy);
1299 UpdateUI(aChrome);
1304 // FUNCTION: UpdateProgress()
1306 // PURPOSE: Refreshes the progress bar in the browser dialog
1308 void WebBrowserChromeUI::UpdateProgress(nsIWebBrowserChrome *aChrome, PRInt32 aCurrent, PRInt32 aMax)
1310 HWND hwndDlg = GetBrowserDlgFromChrome(aChrome);
1311 HWND hwndProgress = WinWindowFromID(hwndDlg, IDC_PROGRESS);
1312 if (aCurrent < 0)
1314 aCurrent = 0;
1316 if (aCurrent > aMax)
1318 aMax = aCurrent + 20; // What to do?
1320 if (hwndProgress)
1322 ULONG value = (double)aCurrent/(double)aMax*(double)100;
1323 WinSendMsg(hwndProgress, SLM_SETSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), (MPARAM)(value == 100? value-1: value));
1328 // FUNCTION: ShowContextMenu()
1330 // PURPOSE: Display a context menu for the given node
1332 void WebBrowserChromeUI::ShowContextMenu(nsIWebBrowserChrome *aChrome, PRUint32 aContextFlags, nsIDOMEvent *aEvent, nsIDOMNode *aNode)
1334 // TODO code to test context flags and display a popup menu should go here
1338 // FUNCTION: ShowTooltip()
1340 // PURPOSE: Show a tooltip
1342 void WebBrowserChromeUI::ShowTooltip(nsIWebBrowserChrome *aChrome, PRInt32 aXCoords, PRInt32 aYCoords, const PRUnichar *aTipText)
1344 // TODO code to show a tooltip should go here
1348 // FUNCTION: HideTooltip()
1350 // PURPOSE: Hide the tooltip
1352 void WebBrowserChromeUI::HideTooltip(nsIWebBrowserChrome *aChrome)
1354 // TODO code to hide a tooltip should go here
1357 void WebBrowserChromeUI::ShowWindow(nsIWebBrowserChrome *aChrome, PRBool aShow)
1359 HWND win = GetBrowserDlgFromChrome(aChrome);
1360 ::WinShowWindow(win, aShow);
1363 void WebBrowserChromeUI::SizeTo(nsIWebBrowserChrome *aChrome, PRInt32 aWidth, PRInt32 aHeight)
1365 HWND hchrome = GetBrowserDlgFromChrome(aChrome);
1366 HWND hbrowser = GetBrowserFromChrome(aChrome);
1367 RECTL chromeRect, browserRect;
1369 ::WinQueryWindowRect(hchrome, &chromeRect);
1370 ::WinQueryWindowRect(hbrowser, &browserRect);
1372 PRInt32 decoration_x = (browserRect.xLeft - chromeRect.xLeft) +
1373 (chromeRect.xRight - browserRect.xRight);
1374 PRInt32 decoration_y = (chromeRect.yTop - browserRect.yTop) +
1375 (browserRect.yBottom - chromeRect.yBottom);
1377 ::WinSetWindowPos(hchrome, HWND_TOP, WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN)/2 - (aWidth+decoration_x)/2,
1378 WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN)/2 - (aHeight+decoration_y)/2,
1379 aWidth+decoration_x, aHeight+decoration_y, SWP_SIZE | SWP_MOVE | SWP_SHOW);
1383 // FUNCTION: GetResourceStringByID()
1385 // PURPOSE: Get the resource string for the ID
1387 void WebBrowserChromeUI::GetResourceStringById(PRInt32 aID, char ** aReturn)
1389 char resBuf[MAX_LOADSTRING];
1390 int retval = WinLoadString((HAB)0, ghInstanceResources, aID, sizeof(resBuf), (PSZ)resBuf );
1391 if (retval != 0)
1393 int resLen = strlen(resBuf);
1394 *aReturn = (char *)calloc(resLen+1, sizeof(char *));
1395 if (!*aReturn) return;
1396 PL_strncpy(*aReturn, (char *) resBuf, resLen);
1398 return;
1401 //-----------------------------------------------------------------------------
1403 nsresult CreateBrowserWindow(PRUint32 aChromeFlags,
1404 nsIWebBrowserChrome *aParent,
1405 nsIWebBrowserChrome **aNewWindow)
1407 WebBrowserChrome * chrome = new WebBrowserChrome();
1408 if (!chrome)
1409 return NS_ERROR_FAILURE;
1411 // the interface to return and one addref, which we assume will be
1412 // immediately released
1413 CallQueryInterface(static_cast<nsIWebBrowserChrome*>(chrome), aNewWindow);
1414 // now an extra addref; the window owns itself (to be released by
1415 // WebBrowserChromeUI::Destroy)
1416 NS_ADDREF(*aNewWindow);
1418 chrome->SetChromeFlags(aChromeFlags);
1419 chrome->SetParent(aParent);
1421 // Insert the browser
1422 nsCOMPtr<nsIWebBrowser> newBrowser;
1423 chrome->CreateBrowser(-1, -1, -1, -1, getter_AddRefs(newBrowser));
1424 if (!newBrowser)
1425 return NS_ERROR_FAILURE;
1427 // Place it where we want it.
1428 ResizeEmbedding(static_cast<nsIWebBrowserChrome*>(chrome));
1430 // Subscribe new window to profile changes so it can kill itself when one happens
1431 nsCOMPtr<nsIObserverService> observerService(do_GetService("@mozilla.org/observer-service;1"));
1432 if (observerService)
1433 observerService->AddObserver(static_cast<nsIObserver *>(chrome),
1434 "profile-change-teardown", PR_TRUE);
1436 // if opened as chrome, it'll be made visible after the chrome has loaded.
1437 // otherwise, go ahead and show it now.
1438 if (!(aChromeFlags & nsIWebBrowserChrome::CHROME_OPENAS_CHROME))
1439 WebBrowserChromeUI::ShowWindow(*aNewWindow, PR_TRUE);
1441 return NS_OK;
1444 void EnableChromeWindow(nsIWebBrowserChrome *aWindow,
1445 PRBool aEnabled)
1447 HWND hwnd = GetBrowserDlgFromChrome(aWindow);
1448 ::WinEnableWindow(hwnd, aEnabled ? TRUE : FALSE);
1451 PRUint32 RunEventLoop(PRBool &aRunCondition)
1453 QMSG msg;
1454 HEV hFakeEvent = 0;
1455 ::DosCreateEventSem(NULL, &hFakeEvent, 0L, FALSE);
1457 while (aRunCondition ) {
1458 // Process pending messages
1459 while (::WinPeekMsg((HAB)0, &msg, NULL, 0, 0, PM_NOREMOVE)) {
1460 if (!::WinGetMsg((HAB)0, &msg, NULL, 0, 0)) {
1461 // WM_QUIT
1462 aRunCondition = PR_FALSE;
1463 break;
1466 PRBool wasHandled = PR_FALSE;
1467 ::NS_HandleEmbeddingEvent(msg, wasHandled);
1468 if (wasHandled)
1469 continue;
1471 ::WinDispatchMsg((HAB)0, &msg);
1474 // Do idle stuff
1475 ::DosWaitEventSem(hFakeEvent, 100);
1477 ::DosCloseEventSem(hFakeEvent);
1478 return LONGFROMMP(msg.mp1);