1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * The Original Code is mozilla.org Code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 2001
20 * the Initial Developer. All Rights Reserved.
23 * Radha Kulkarni <radha@netscape.com>
25 * Alternatively, the contents of this file may be used under the terms of
26 * either the GNU General Public License Version 2 or later (the "GPL"), or
27 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 * in which case the provisions of the GPL or the LGPL are applicable instead
29 * of those above. If you wish to allow use of your version of this file only
30 * under the terms of either the GPL or the LGPL, and not to allow others to
31 * use your version of this file under the terms of the MPL, indicate your
32 * decision by deleting the provisions above and replace them with the notice
33 * and other provisions required by the GPL or the LGPL. If you do not delete
34 * the provisions above, a recipient may use your version of this file under
35 * the terms of any one of the MPL, the GPL or the LGPL.
37 * ***** END LICENSE BLOCK ***** */
47 // Mozilla header files
49 #include "nsEmbedAPI.h"
50 #include "nsWeakReference.h"
51 #include "nsIClipboardCommands.h"
52 #include "nsXPIDLString.h"
53 #include "nsIWebBrowserPersist.h"
54 #include "nsIWebBrowserFocus.h"
55 #include "nsIWindowWatcher.h"
56 #include "nsIProfile.h"
57 //#include "nsIObserverService.h"
58 #include "nsIObserver.h"
59 #include "nsIProfileChangeStatus.h"
62 #include "nsIInterfaceRequestor.h"
66 #include "nsIWebBrowser.h"
67 #include "nsIComponentManager.h"
68 #include "nsServiceManagerUtils.h"
69 #include "nsIEmbeddingSiteWindow.h"
70 #include "nsIWebNavigation.h"
71 #include "nsIWebBrowserChrome.h"
72 #include "nsIInterfaceRequestorUtils.h"
73 #include "nsIComponentRegistrar.h"
74 #include "nsIModule.h"
75 #include "nsIGenericFactory.h"
78 //#include "nsIQABrowserChrome.h"
80 #include "nsQAWindowCreator.h"
82 #include "nsQABrowserCID.h"
83 #include "nsQABrowserUIGlue.h"
84 //#include "nsIQABrowserView.h"
87 // Printing header files
88 #include "nsIPrintSettings.h"
89 #include "nsIWebBrowserPrint.h"
92 #define MAX_LOADSTRING 100
93 #define MAX_BROWSER_ALLOWED 50
95 const TCHAR
*szWindowClass
= _T("MOZEMBED");
97 // Forward declarations of functions included in this code module:
98 static ATOM
MyRegisterClass(HINSTANCE hInstance
);
99 static LRESULT CALLBACK
BrowserWndProc(HWND
, UINT
, WPARAM
, LPARAM
);
100 static BOOL CALLBACK
BrowserDlgProc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
);
101 static nsresult
InitializeWindowCreator();
102 static nsresult
OpenWebPage(const char * url
);
103 static nsresult
ResizeEmbedding(nsIWebBrowserChrome
* chrome
);
104 // Profile chooser stuff
105 static BOOL
ChooseNewProfile(BOOL bShowForMultipleProfilesOnly
, const char *szDefaultProfile
);
106 static LRESULT CALLBACK
ChooseProfileDlgProc(HWND
, UINT
, WPARAM
, LPARAM
);
107 extern nsresult
RegisterComponents();
110 static UINT gDialogCount
= 0;
111 static BOOL gProfileSwitch
= FALSE
;
112 static HINSTANCE ghInstanceResources
= NULL
;
113 static HINSTANCE ghInstanceApp
= NULL
;
114 static char gFirstURL
[1024];
116 // A list of URLs to populate the URL drop down list with
117 static const TCHAR
*gDefaultURLs
[] =
119 _T("http://www.mozilla.org/"),
120 _T("http://www.netscape.com/"),
121 _T("http://browsertest.web.aol.com/tests/javascript/javascpt/index.htm"),
122 _T("http://127.0.0.1/"),
123 _T("http://www.yahoo.com/"),
124 _T("http://www.travelocity.com/"),
125 _T("http://www.disney.com/"),
126 _T("http://www.go.com/"),
127 _T("http://www.google.com/"),
128 _T("http://www.ebay.com/"),
129 _T("http://www.shockwave.com/"),
130 _T("http://www.slashdot.org/"),
131 _T("http://www.quicken.com/"),
132 _T("http://www.hotmail.com/"),
133 _T("http://www.cnn.com/"),
134 _T("http://www.javasoft.com/")
138 // FUNCTION: GetBrowserFromChrome()
140 // PURPOSE: Returns the HWND for the webbrowser container associated
141 // with the specified chrome.
143 HWND
GetBrowserFromChrome(nsIWebBrowserChrome
*aChrome
)
149 nsCOMPtr
<nsIEmbeddingSiteWindow
> baseWindow
= do_QueryInterface(aChrome
);
151 baseWindow
->GetSiteWindow((void **) & hwnd
);
156 // FUNCTION: GetBrowserDlgFromChrome()
158 // PURPOSE: Returns the HWND for the browser dialog associated with
159 // the specified chrome.
161 HWND
GetBrowserDlgFromChrome(nsIWebBrowserChrome
*aChrome
)
163 return GetParent(GetBrowserFromChrome(aChrome
));
168 // FUNCTION: UpdateUI()
170 // PURPOSE: Refreshes the buttons and menu items in the browser dialog
172 void UpdateUI(nsIWebBrowserChrome
*aChrome
)
174 HWND hwndDlg
= GetBrowserDlgFromChrome(aChrome
);
175 nsCOMPtr
<nsIWebBrowser
> webBrowser
;
176 nsCOMPtr
<nsIWebNavigation
> webNavigation
;
177 aChrome
->GetWebBrowser(getter_AddRefs(webBrowser
));
178 webNavigation
= do_QueryInterface(webBrowser
);
180 PRBool canGoBack
= PR_FALSE
;
181 PRBool canGoForward
= PR_FALSE
;
184 webNavigation
->GetCanGoBack(&canGoBack
);
185 webNavigation
->GetCanGoForward(&canGoForward
);
188 PRBool canCutSelection
= PR_FALSE
;
189 PRBool canCopySelection
= PR_FALSE
;
190 PRBool canPaste
= PR_FALSE
;
192 nsCOMPtr
<nsIClipboardCommands
> clipCmds(do_GetInterface(webBrowser
));
195 clipCmds
->CanCutSelection(&canCutSelection
);
196 clipCmds
->CanCopySelection(&canCopySelection
);
197 clipCmds
->CanPaste(&canPaste
);
200 HMENU hmenu
= GetMenu(hwndDlg
);
203 EnableMenuItem(hmenu
, MOZ_GoBack
, MF_BYCOMMAND
|
204 ((canGoBack
) ? MF_ENABLED
: (MF_DISABLED
| MF_GRAYED
)));
205 EnableMenuItem(hmenu
, MOZ_GoForward
, MF_BYCOMMAND
|
206 ((canGoForward
) ? MF_ENABLED
: (MF_DISABLED
| MF_GRAYED
)));
208 EnableMenuItem(hmenu
, MOZ_Cut
, MF_BYCOMMAND
|
209 ((canCutSelection
) ? MF_ENABLED
: (MF_DISABLED
| MF_GRAYED
)));
210 EnableMenuItem(hmenu
, MOZ_Copy
, MF_BYCOMMAND
|
211 ((canCopySelection
) ? MF_ENABLED
: (MF_DISABLED
| MF_GRAYED
)));
212 EnableMenuItem(hmenu
, MOZ_Paste
, MF_BYCOMMAND
|
213 ((canPaste
) ? MF_ENABLED
: (MF_DISABLED
| MF_GRAYED
)));
217 button
= GetDlgItem(hwndDlg
, IDC_BACK
);
219 EnableWindow(button
, canGoBack
);
220 button
= GetDlgItem(hwndDlg
, IDC_FORWARD
);
222 EnableWindow(button
, canGoForward
);
228 ////////////////////////////////////////////////////////////////////////////////////////////
230 ////////////////////////////////////////////////////////////////////////////////////////////
232 int main(int argc
, char *argv
[])
234 printf("You are embedded, man!\n\n");
235 printf("******************************************************************\n");
237 printf("* IMPORTANT NOTE: *\n");
239 printf("* WinEmbed is not supported!!! Do not raise bugs on it unless *\n");
240 printf("* it is badly broken (e.g. crash on start/exit, build errors) *\n");
241 printf("* or you have the patch to make it better! MFCEmbed is now our *\n");
242 printf("* embedding test application on Win32 and all testing should *\n");
243 printf("* be done on that. *\n");
245 printf("******************************************************************\n");
248 // Sophisticated command-line parsing in action
249 char *szFirstURL
= "http://www.mozilla.org/projects/embedding";
250 char *szDefaultProfile
= nsnull
;
252 for (argn
= 1; argn
< argc
; argn
++)
254 if (stricmp("-P", argv
[argn
]) == 0)
258 szDefaultProfile
= argv
[++argn
];
263 szFirstURL
= argv
[argn
];
266 strncpy(gFirstURL
, szFirstURL
, sizeof(gFirstURL
) - 1);
268 ghInstanceApp
= GetModuleHandle(NULL
);
269 ghInstanceResources
= GetModuleHandle(NULL
);
271 // Initialize global strings
272 TCHAR szTitle
[MAX_LOADSTRING
];
273 LoadString(ghInstanceResources
, IDS_APP_TITLE
, szTitle
, MAX_LOADSTRING
);
274 MyRegisterClass(ghInstanceApp
);
276 // Init Embedding APIs
277 NS_InitEmbedding(nsnull
, nsnull
);
278 RegisterComponents();
280 // Choose the new profile
281 // Have to do this to initialise global history
282 if (!ChooseNewProfile(TRUE
, szDefaultProfile
))
290 InitializeWindowCreator();
292 // Open the initial browser window
293 OpenWebPage(gFirstURL
);
295 // Main message loop.
296 // NOTE: We use a fake event and a timeout in order to process idle stuff for
297 // Mozilla every 1/10th of a second.
298 PRBool runCondition
= PR_TRUE
;
300 rv
= AppCallbacks::RunEventLoop(runCondition
);
302 // observer->Release();
304 // Close down Embedding APIs
311 /* InitializeWindowCreator creates and hands off an object with a callback
312 to a window creation function. This is how all new windows are opened,
313 except any created directly by the embedding app. */
314 nsresult
InitializeWindowCreator()
317 printf("In InitializeWindowCreator\n");
318 // create an nsWindowCreator and give it to the WindowWatcher service
319 WindowCreator
*creatorCallback
= new WindowCreator();
322 nsCOMPtr
<nsIWindowCreator
> windowCreator(static_cast<nsIWindowCreator
*>(creatorCallback
));
325 nsCOMPtr
<nsIWindowWatcher
> wwatch(do_GetService("@mozilla.org/embedcomp/window-watcher;1"));
328 wwatch
->SetWindowCreator(windowCreator
);
333 return NS_ERROR_FAILURE
;
336 //-----------------------------------------------------------------------------
339 // FUNCTION: OpenWebPage()
341 // PURPOSE: Opens a new browser dialog and starts it loading to the
344 nsresult
OpenWebPage(const char *url
)
347 printf("In OpenWebpage\n");
349 if (gDialogCount
== MAX_BROWSER_ALLOWED
)
350 return NS_ERROR_FAILURE
;
352 // Create the UI Glue object. This is the glue between nsIWebBrowserChrome and
353 // the native UI code.
354 nsCOMPtr
<nsIQABrowserUIGlue
> browserUIGlue
;
355 browserUIGlue
= do_CreateInstance(NS_QABROWSERUIGLUE_CONTRACTID
, &rv
);
358 return NS_ERROR_FAILURE
;
360 // Create a new browser window
361 nsIWebBrowserChrome
* chrome
;
362 rv
= browserUIGlue
->CreateNewBrowserWindow(nsIWebBrowserChrome::CHROME_ALL
, nsnull
,
364 if (NS_SUCCEEDED(rv
)) {
365 browserUIGlue
->LoadURL(url
);
374 // FUNCTION: SaveWebPage()
376 // PURPOSE: Saves the contents of the web page to a file
378 void SaveWebPage(nsIWebBrowser
*aWebBrowser
)
380 // Use the browser window title as the initial file name
381 nsCOMPtr
<nsIBaseWindow
> webBrowserAsWin
= do_QueryInterface(aWebBrowser
);
382 nsXPIDLString windowTitle
;
383 webBrowserAsWin
->GetTitle(getter_Copies(windowTitle
));
384 nsCString fileName
; fileName
.AssignWithConversion(windowTitle
);
386 // Sanitize the title of all illegal characters
387 fileName
.CompressWhitespace(); // Remove whitespace from the ends
388 fileName
.StripChars("\\*|:\"><?"); // Strip illegal characters
389 fileName
.ReplaceChar('.', L
'_'); // Dots become underscores
390 fileName
.ReplaceChar('/', L
'-'); // Forward slashes become hyphens
392 // Copy filename to a character buffer
393 char szFile
[_MAX_PATH
];
394 memset(szFile
, 0, sizeof(szFile
));
395 PL_strncpyz(szFile
, fileName
.get(), sizeof(szFile
) - 1); // XXXldb probably should be just sizeof(szfile)
397 // Initialize the file save as information structure
398 OPENFILENAME saveFileNameInfo
;
399 memset(&saveFileNameInfo
, 0, sizeof(saveFileNameInfo
));
400 saveFileNameInfo
.lStructSize
= sizeof(saveFileNameInfo
);
401 saveFileNameInfo
.hwndOwner
= NULL
;
402 saveFileNameInfo
.hInstance
= NULL
;
403 saveFileNameInfo
.lpstrFilter
=
404 "Web Page, HTML Only (*.htm;*.html)\0*.htm;*.html\0"
405 "Web Page, Complete (*.htm;*.html)\0*.htm;*.html\0"
406 "Text File (*.txt)\0*.txt\0";
407 saveFileNameInfo
.lpstrCustomFilter
= NULL
;
408 saveFileNameInfo
.nMaxCustFilter
= NULL
;
409 saveFileNameInfo
.nFilterIndex
= 1;
410 saveFileNameInfo
.lpstrFile
= szFile
;
411 saveFileNameInfo
.nMaxFile
= sizeof(szFile
);
412 saveFileNameInfo
.lpstrFileTitle
= NULL
;
413 saveFileNameInfo
.nMaxFileTitle
= 0;
414 saveFileNameInfo
.lpstrInitialDir
= NULL
;
415 saveFileNameInfo
.lpstrTitle
= NULL
;
416 saveFileNameInfo
.Flags
= OFN_HIDEREADONLY
| OFN_OVERWRITEPROMPT
;
417 saveFileNameInfo
.nFileOffset
= NULL
;
418 saveFileNameInfo
.nFileExtension
= NULL
;
419 saveFileNameInfo
.lpstrDefExt
= "htm";
420 saveFileNameInfo
.lCustData
= NULL
;
421 saveFileNameInfo
.lpfnHook
= NULL
;
422 saveFileNameInfo
.lpTemplateName
= NULL
;
424 if (GetSaveFileName(&saveFileNameInfo
))
426 // Does the user want to save the complete document including
427 // all frames, images, scripts, stylesheets etc. ?
428 char *pszDataPath
= NULL
;
429 if (saveFileNameInfo
.nFilterIndex
== 2) // 2nd choice means save everything
431 static char szDataFile
[_MAX_PATH
];
432 char szDataPath
[_MAX_PATH
];
433 char drive
[_MAX_DRIVE
];
435 char fname
[_MAX_FNAME
];
438 _splitpath(szFile
, drive
, dir
, fname
, ext
);
439 sprintf(szDataFile
, "%s_files", fname
);
440 _makepath(szDataPath
, drive
, dir
, szDataFile
, "");
442 pszDataPath
= szDataPath
;
446 nsCOMPtr
<nsIWebBrowserPersist
> persist(do_QueryInterface(aWebBrowser
));
448 nsCOMPtr
<nsILocalFile
> file
;
449 NS_NewNativeLocalFile(nsDependentCString(szFile
), TRUE
, getter_AddRefs(file
));
451 nsCOMPtr
<nsILocalFile
> dataPath
;
454 NS_NewNativeLocalFile(nsDependentCString(pszDataPath
), TRUE
, getter_AddRefs(dataPath
));
457 persist
->SaveDocument(nsnull
, file
, dataPath
, nsnull
, 0, 0);
463 // FUNCTION: ResizeEmbedding()
465 // PURPOSE: Resizes the webbrowser window to fit its container.
467 nsresult
ResizeEmbedding(nsIWebBrowserChrome
* chrome
)
470 return NS_ERROR_FAILURE
;
472 nsCOMPtr
<nsIEmbeddingSiteWindow
> embeddingSite
= do_QueryInterface(chrome
);
474 embeddingSite
->GetSiteWindow((void **) & hWnd
);
477 return NS_ERROR_NULL_POINTER
;
480 GetClientRect(hWnd
, &rect
);
482 // Make sure the browser is visible and sized
483 nsCOMPtr
<nsIWebBrowser
> webBrowser
;
484 chrome
->GetWebBrowser(getter_AddRefs(webBrowser
));
485 nsCOMPtr
<nsIBaseWindow
> webBrowserAsWin
= do_QueryInterface(webBrowser
);
488 webBrowserAsWin
->SetPositionAndSize(rect
.left
,
490 rect
.right
- rect
.left
,
491 rect
.bottom
- rect
.top
,
493 webBrowserAsWin
->SetVisibility(PR_TRUE
);
501 // FUNCTION: MyRegisterClass()
503 // PURPOSE: Registers the window class.
507 // This function and its usage is only necessary if you want this code
508 // to be compatible with Win32 systems prior to the 'RegisterClassEx'
509 // function that was added to Windows 95. It is important to call this function
510 // so that the application will get 'well formed' small icons associated
513 ATOM
MyRegisterClass(HINSTANCE hInstance
)
517 memset(&wcex
, 0, sizeof(wcex
));
518 wcex
.cbSize
= sizeof(WNDCLASSEX
);
520 wcex
.style
= CS_HREDRAW
| CS_VREDRAW
;
521 wcex
.lpfnWndProc
= (WNDPROC
) BrowserWndProc
;
524 wcex
.hInstance
= hInstance
;
525 wcex
.hIcon
= LoadIcon(ghInstanceResources
, (LPCTSTR
)IDI_MOZEMBED
);
526 wcex
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
527 wcex
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+1);
528 wcex
.lpszClassName
= szWindowClass
;
529 wcex
.hIconSm
= LoadIcon(ghInstanceResources
, (LPCTSTR
)IDI_SMALL
);
531 return RegisterClassEx(&wcex
);
537 // FUNCTION: BrowserDlgProc()
539 // PURPOSE: Browser dialog windows message handler.
543 // The code for handling buttons and menu actions is here.
545 BOOL CALLBACK
BrowserDlgProc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
547 if (uMsg
== WM_COMMAND
&& LOWORD(wParam
) == MOZ_SwitchProfile
)
549 ChooseNewProfile(FALSE
, NULL
);
553 // Get the browser and other pointers since they are used a lot below
554 HWND hwndBrowser
= GetDlgItem(hwndDlg
, IDC_BROWSER
);
555 nsIWebBrowserChrome
*chrome
= nsnull
;
558 chrome
= (nsIWebBrowserChrome
*) GetWindowLong(hwndBrowser
, GWL_USERDATA
);
560 nsCOMPtr
<nsIWebBrowser
> webBrowser
;
561 nsCOMPtr
<nsIWebNavigation
> webNavigation
;
562 nsCOMPtr
<nsIWebBrowserPrint
> webBrowserPrint
;
565 chrome
->GetWebBrowser(getter_AddRefs(webBrowser
));
566 webNavigation
= do_QueryInterface(webBrowser
);
567 webBrowserPrint
= do_GetInterface(webBrowser
);
581 if (wParam
== SC_CLOSE
)
583 if (!webNavigation
|| !webBrowser
|| !chrome
)
586 webNavigation
->Stop(nsIWebNavigation::STOP_ALL
);
587 chrome
->ExitModalEventLoop(NS_OK
);
589 // Explicitly destroy the embedded browser and then the chrome
591 nsCOMPtr
<nsIBaseWindow
> browserAsWin
= do_QueryInterface(webBrowser
);
593 browserAsWin
->Destroy();
596 chrome
->SetWebBrowser(nsnull
);
612 // Test which command was selected
613 switch (LOWORD(wParam
))
616 if (HIWORD(wParam
) == CBN_EDITCHANGE
|| HIWORD(wParam
) == CBN_SELCHANGE
)
618 // User has changed the address field so enable the Go button
619 EnableWindow(GetDlgItem(hwndDlg
, IDC_GO
), TRUE
);
626 memset(szURL
, 0, sizeof(szURL
));
627 GetDlgItemText(hwndDlg
, IDC_ADDRESS
, szURL
,
628 sizeof(szURL
) / sizeof(szURL
[0]) - 1);
629 webNavigation
->LoadURI(
630 NS_ConvertASCIItoUTF16(szURL
).get(),
631 nsIWebNavigation::LOAD_FLAGS_NONE
,
639 webNavigation
->Stop(nsIWebNavigation::STOP_ALL
);
644 webNavigation
->Reload(nsIWebNavigation::LOAD_FLAGS_NONE
);
648 PostMessage(hwndDlg
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
651 // File menu commands
654 OpenWebPage(gFirstURL
);
658 SaveWebPage(webBrowser
);
663 // NOTE: Embedding code shouldn't need to get the docshell or
664 // contentviewer AT ALL. This code below will break one
665 // day but will have to do until the embedding API has
666 // a cleaner way to do the same thing.
669 nsCOMPtr
<nsIPrintSettings
> printSettings
;
670 webBrowserPrint
->GetGlobalPrintSettings(getter_AddRefs(printSettings
));
671 NS_ASSERTION(printSettings
, "You can't PrintPreview without a PrintSettings!");
674 printSettings
->SetPrintSilent(PR_TRUE
);
675 webBrowserPrint
->Print(printSettings
, (nsIWebProgressListener
*)nsnull
);
681 // Edit menu commands
685 nsCOMPtr
<nsIClipboardCommands
> clipCmds
= do_GetInterface(webBrowser
);
686 clipCmds
->CutSelection();
692 nsCOMPtr
<nsIClipboardCommands
> clipCmds
= do_GetInterface(webBrowser
);
693 clipCmds
->CopySelection();
699 nsCOMPtr
<nsIClipboardCommands
> clipCmds
= do_GetInterface(webBrowser
);
706 nsCOMPtr
<nsIClipboardCommands
> clipCmds
= do_GetInterface(webBrowser
);
707 clipCmds
->SelectAll();
713 nsCOMPtr
<nsIClipboardCommands
> clipCmds
= do_GetInterface(webBrowser
);
714 clipCmds
->SelectNone();
721 webNavigation
->GoBack();
727 webNavigation
->GoForward();
731 // Help menu commands
734 TCHAR szAboutTitle
[MAX_LOADSTRING
];
735 TCHAR szAbout
[MAX_LOADSTRING
];
736 LoadString(ghInstanceResources
, IDS_ABOUT_TITLE
, szAboutTitle
, MAX_LOADSTRING
);
737 LoadString(ghInstanceResources
, IDS_ABOUT
, szAbout
, MAX_LOADSTRING
);
738 MessageBox(NULL
, szAbout
, szAboutTitle
, MB_OK
);
748 nsCOMPtr
<nsIWebBrowserFocus
> focus(do_GetInterface(webBrowser
));
768 UINT newDlgWidth
= LOWORD(lParam
);
769 UINT newDlgHeight
= HIWORD(lParam
);
771 // TODO Reposition the control bar - for the moment it's fixed size
773 // Reposition the status area. Status bar
774 // gets any space that the fixed size progress bar doesn't use.
778 HWND hwndStatus
= GetDlgItem(hwndDlg
, IDC_STATUS
);
781 GetWindowRect(hwndStatus
, &rcStatus
);
782 statusHeight
= rcStatus
.bottom
- rcStatus
.top
;
786 HWND hwndProgress
= GetDlgItem(hwndDlg
, IDC_PROGRESS
);
789 GetWindowRect(hwndProgress
, &rcProgress
);
790 progressWidth
= rcProgress
.right
- rcProgress
.left
;
793 statusWidth
= newDlgWidth
- progressWidth
;
796 SetWindowPos(hwndStatus
,
798 0, newDlgHeight
- statusHeight
,
803 SetWindowPos(hwndProgress
,
805 statusWidth
, newDlgHeight
- statusHeight
,
807 SWP_NOSIZE
| SWP_NOZORDER
);
809 // Resize the browser area (assuming the browse is
810 // sandwiched between the control bar and status area)
813 GetWindowRect(hwndBrowser
, &rcBrowser
);
814 ptBrowser
.x
= rcBrowser
.left
;
815 ptBrowser
.y
= rcBrowser
.top
;
816 ScreenToClient(hwndDlg
, &ptBrowser
);
817 int browserHeight
= newDlgHeight
- ptBrowser
.y
- statusHeight
;
818 if (browserHeight
< 1)
822 SetWindowPos(hwndBrowser
,
826 newDlgHeight
- ptBrowser
.y
- statusHeight
,
827 SWP_NOMOVE
| SWP_NOZORDER
);
836 // FUNCTION: BrowserWndProc(HWND, unsigned, WORD, LONG)
838 // PURPOSE: Processes messages for the browser container window.
840 LRESULT CALLBACK
BrowserWndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
842 nsIWebBrowserChrome
*chrome
= (nsIWebBrowserChrome
*) GetWindowLong(hWnd
, GWL_USERDATA
);
846 // Resize the embedded browser
847 ResizeEmbedding(chrome
);
850 // Reduce flicker by not painting the non-visible background
853 return DefWindowProc(hWnd
, message
, wParam
, lParam
);
857 ///////////////////////////////////////////////////////////////////////////////
858 // Profile chooser dialog
862 // FUNCTION: ChooseNewProfile()
864 // PURPOSE: Allows the user to select a new profile from a list.
865 // The bShowForMultipleProfilesOnly argument specifies whether the
866 // function should automatically select the first profile and return
867 // without displaying a dialog box if there is only one profile to
870 BOOL
ChooseNewProfile(BOOL bShowForMultipleProfilesOnly
, const char *szDefaultProfile
)
873 nsCOMPtr
<nsIProfile
> profileService
=
874 do_GetService(NS_PROFILE_CONTRACTID
, &rv
);
880 if (szDefaultProfile
)
882 // Make a new default profile
883 nsAutoString newProfileName
; newProfileName
.AssignWithConversion(szDefaultProfile
);
884 rv
= profileService
->CreateNewProfile(newProfileName
.get(), nsnull
, nsnull
, PR_FALSE
);
885 if (NS_FAILED(rv
)) return FALSE
;
886 rv
= profileService
->SetCurrentProfile(newProfileName
.get());
887 if (NS_FAILED(rv
)) return FALSE
;
891 PRInt32 profileCount
= 0;
892 rv
= profileService
->GetProfileCount(&profileCount
);
893 if (profileCount
== 0)
895 // Make a new default profile
896 NS_NAMED_LITERAL_STRING(newProfileName
, "mozEmbed");
897 rv
= profileService
->CreateNewProfile(newProfileName
.get(), nsnull
, nsnull
, PR_FALSE
);
898 if (NS_FAILED(rv
)) return FALSE
;
899 rv
= profileService
->SetCurrentProfile(newProfileName
.get());
900 if (NS_FAILED(rv
)) return FALSE
;
903 else if (profileCount
== 1 && bShowForMultipleProfilesOnly
)
905 // GetCurrentProfile returns the profile which was last used but is not nescesarily
906 // active. Call SetCurrentProfile to make it installed and active.
908 nsXPIDLString currProfileName
;
909 rv
= profileService
->GetCurrentProfile(getter_Copies(currProfileName
));
910 if (NS_FAILED(rv
)) return FALSE
;
911 rv
= profileService
->SetCurrentProfile(currProfileName
);
912 if (NS_FAILED(rv
)) return FALSE
;
917 nResult
= DialogBox(ghInstanceResources
, (LPCTSTR
)IDD_CHOOSEPROFILE
, NULL
, (DLGPROC
)ChooseProfileDlgProc
);
918 return (nResult
== IDOK
) ? TRUE
: FALSE
;
923 // FUNCTION: ChooseProfileDlgProc(HWND, unsigned, WORD, LONG)
925 // PURPOSE: Dialog handler procedure for the open uri dialog.
927 LRESULT CALLBACK
ChooseProfileDlgProc(HWND hDlg
, UINT message
, WPARAM wParam
, LPARAM lParam
)
934 HWND hwndProfileList
= GetDlgItem(hDlg
, IDC_PROFILELIST
);
936 nsCOMPtr
<nsIProfile
> profileService
=
937 do_GetService(NS_PROFILE_CONTRACTID
, &rv
);
939 // Get the list of profile names and add them to the list box
940 PRUint32 listLen
= 0;
941 PRUnichar
**profileList
= nsnull
;
942 rv
= profileService
->GetProfileList(&listLen
, &profileList
);
943 for (PRUint32 index
= 0; index
< listLen
; index
++)
946 SendMessageW(hwndProfileList
, LB_ADDSTRING
, 0, (LPARAM
) profileList
[index
]);
948 nsCAutoString profile
; profile
.AssignWithConversion(profileList
[index
]);
949 SendMessageA(hwndProfileList
, LB_ADDSTRING
, 0, (LPARAM
) profile
.get());
953 // Select the current profile (if there is one)
955 // Get the current profile
957 nsXPIDLString currProfile
;
958 profileService
->GetCurrentProfile(getter_Copies(currProfile
));
960 nsXPIDLString currProfileUnicode
;
961 profileService
->GetCurrentProfile(getter_Copies(currProfileUnicode
));
962 nsCAutoString currProfile
; currProfile
.AssignWithConversion(currProfileUnicode
);
965 // Now find and select it
966 INT currentProfileIndex
= LB_ERR
;
967 currentProfileIndex
= SendMessage(hwndProfileList
, LB_FINDSTRINGEXACT
, -1, (LPARAM
) currProfile
.get());
968 if (currentProfileIndex
!= LB_ERR
)
970 SendMessage(hwndProfileList
, LB_SETCURSEL
, currentProfileIndex
, 0);
976 if (LOWORD(wParam
) == IDOK
||
977 (HIWORD(wParam
) & LBN_DBLCLK
&& LOWORD(wParam
) == IDC_PROFILELIST
))
979 HWND hwndProfileList
= GetDlgItem(hDlg
, IDC_PROFILELIST
);
981 // Get the selected profile from the list box and make it current
982 INT currentProfileIndex
= SendMessage(hwndProfileList
, LB_GETCURSEL
, 0, 0);
983 if (currentProfileIndex
!= LB_ERR
)
985 nsCOMPtr
<nsIProfile
> profileService
=
986 do_GetService(NS_PROFILE_CONTRACTID
, &rv
);
987 // Convert TCHAR name to unicode and make it current
988 INT profileNameLen
= SendMessage(hwndProfileList
, LB_GETTEXTLEN
, currentProfileIndex
, 0);
989 TCHAR
*profileName
= new TCHAR
[profileNameLen
+ 1];
990 SendMessage(hwndProfileList
, LB_GETTEXT
, currentProfileIndex
, (LPARAM
) profileName
);
991 nsAutoString newProfile
; newProfile
.AssignWithConversion(profileName
);
992 rv
= profileService
->SetCurrentProfile(newProfile
.get());
994 EndDialog(hDlg
, IDOK
);
996 else if (LOWORD(wParam
) == IDCANCEL
)
998 EndDialog(hDlg
, LOWORD(wParam
));
1007 //-----------------------------------------------------------------------------
1009 //-----------------------------------------------------------------------------
1012 void AppCallbacks::EnableChromeWindow(nsIWebBrowserChrome
*aWindow
,
1015 HWND hwnd
= GetBrowserDlgFromChrome(aWindow
);
1016 ::EnableWindow(hwnd
, aEnabled
? TRUE
: FALSE
);
1019 PRUint32
AppCallbacks::RunEventLoop(PRBool
&aRunCondition
)
1022 HANDLE hFakeEvent
= ::CreateEvent(NULL
, TRUE
, FALSE
, NULL
);
1024 while (aRunCondition
) {
1025 // Process pending messages
1026 while (::PeekMessage(&msg
, NULL
, 0, 0, PM_NOREMOVE
)) {
1027 if (!::GetMessage(&msg
, NULL
, 0, 0)) {
1029 aRunCondition
= PR_FALSE
;
1033 PRBool wasHandled
= PR_FALSE
;
1034 ::NS_HandleEmbeddingEvent(msg
, wasHandled
);
1038 ::TranslateMessage(&msg
);
1039 ::DispatchMessage(&msg
);
1043 ::MsgWaitForMultipleObjects(1, &hFakeEvent
, FALSE
, 100, QS_ALLEVENTS
);
1045 ::CloseHandle(hFakeEvent
);
1050 ///////////////////////////////////////////////////////////////////////////////
1051 // nsQABrowserUIGlue
1052 ///////////////////////////////////////////////////////////////////////////////
1054 nsQABrowserUIGlue::nsQABrowserUIGlue():mAllowNewWindows(PR_TRUE
)
1058 nsQABrowserUIGlue::~nsQABrowserUIGlue()
1063 NS_IMPL_ISUPPORTS1(nsQABrowserUIGlue
, nsIQABrowserUIGlue
)
1065 ////////////////////////////////////////////////////////////////////////////////
1066 // nsIQABrowserUIGlue
1067 ////////////////////////////////////////////////////////////////////////////////
1070 nsQABrowserUIGlue::CreateNewBrowserWindow(PRInt32 aChromeFlags
,
1071 nsIWebBrowserChrome
*aParent
,
1072 nsIWebBrowserChrome
**aNewWindow
)
1075 printf("In nsQABrowserUIGlue::CreateNewBrowserWindow\n");
1080 // Create the chrome object. This implements all the interfaces
1081 // that an embedding application must implement.
1082 nsCOMPtr
<nsIQABrowserChrome
> chrome(do_CreateInstance(NS_QABROWSERCHROME_CONTRACTID
, &rv
));
1084 return NS_ERROR_FAILURE
;
1086 nsCOMPtr
<nsIWebBrowserChrome
> webBrowserChrome(do_QueryInterface(chrome
));
1088 if (!webBrowserChrome
)
1089 return NS_ERROR_FAILURE
;
1091 // now an extra addref; the window owns itself (to be released by
1092 // nsQABrowserUIGlue::Destroy)
1093 *aNewWindow
= webBrowserChrome
.get();
1094 NS_ADDREF(*aNewWindow
);
1096 // Set the chrome flags on the chrome. This may not be necessary.
1097 webBrowserChrome
->SetChromeFlags(aChromeFlags
);
1098 // chrome->SetParent(aParent);
1100 // Create the browser view object. nsIBrowserView creates and holds
1101 // handle to the nsIWebBrowser object.
1102 mBrowserView
= do_CreateInstance(NS_QABROWSERVIEW_CONTRACTID
, &rv
);
1104 return NS_ERROR_FAILURE
;
1106 // Create the native window.
1107 nativeWindow nativeWnd
;
1108 nativeWnd
= CreateNativeWindow(*aNewWindow
);
1110 // Wire all the layers together.
1111 chrome
->InitQAChrome(this, nativeWnd
);
1113 // Create the actual browser.
1114 mBrowserView
->CreateBrowser(nativeWnd
, webBrowserChrome
);
1116 // Place it where we want it.
1117 ResizeEmbedding(webBrowserChrome
);
1119 // if opened as chrome, it'll be made visible after the chrome has loaded.
1120 // otherwise, go ahead and show it now.
1121 if (!(aChromeFlags
& nsIWebBrowserChrome::CHROME_OPENAS_CHROME
))
1122 ShowWindow(*aNewWindow
, PR_TRUE
);
1129 // FUNCTION: Destroy()
1131 // PURPOSE: Destroy the window specified by the chrome
1134 nsQABrowserUIGlue::Destroy(nsIWebBrowserChrome
* chrome
)
1136 nsCOMPtr
<nsIWebBrowser
> webBrowser
;
1137 nsCOMPtr
<nsIWebNavigation
> webNavigation
;
1139 chrome
->GetWebBrowser(getter_AddRefs(webBrowser
));
1140 webNavigation
= do_QueryInterface(webBrowser
);
1142 webNavigation
->Stop(nsIWebNavigation::STOP_ALL
);
1144 chrome
->ExitModalEventLoop(NS_OK
);
1146 // Explicitly destroy the embedded browser and then the chrome
1147 // First the browser
1148 nsCOMPtr
<nsIBaseWindow
> browserAsWin
= do_QueryInterface(webBrowser
);
1150 browserAsWin
->Destroy();
1153 chrome
->SetWebBrowser(nsnull
);
1160 // FUNCTION: Called as the final act of a chrome object during its destructor
1163 nsQABrowserUIGlue::Destroyed(nsIWebBrowserChrome
* chrome
)
1165 HWND hwndDlg
= GetBrowserDlgFromChrome(chrome
);
1166 if (hwndDlg
== NULL
)
1168 return NS_ERROR_FAILURE
;
1171 // Clear the window user data
1172 HWND hwndBrowser
= GetDlgItem(hwndDlg
, IDC_BROWSER
);
1173 SetWindowLong(hwndBrowser
, GWL_USERDATA
, nsnull
);
1174 DestroyWindow(hwndBrowser
);
1175 DestroyWindow(hwndDlg
);
1178 if (gDialogCount
== 0)
1182 gProfileSwitch
= FALSE
;
1183 OpenWebPage(gFirstURL
);
1187 // Quit when there are no more browser objects
1196 // FUNCTION: Set the input focus onto the browser window
1199 nsQABrowserUIGlue::SetFocus(nsIWebBrowserChrome
*chrome
)
1201 HWND hwndDlg
= GetBrowserDlgFromChrome(chrome
);
1202 if (hwndDlg
== NULL
)
1204 return NS_ERROR_FAILURE
;
1207 HWND hwndBrowser
= GetDlgItem(hwndDlg
, IDC_BROWSER
);
1208 ::SetFocus(hwndBrowser
);
1213 // FUNCTION: UpdateStatusBarText()
1215 // PURPOSE: Set the status bar text.
1218 nsQABrowserUIGlue::UpdateStatusBarText(nsIWebBrowserChrome
*aChrome
, const PRUnichar
* aStatusText
)
1220 HWND hwndDlg
= GetBrowserDlgFromChrome(aChrome
);
1223 status
.AssignWithConversion(aStatusText
);
1224 SetDlgItemText(hwndDlg
, IDC_STATUS
, status
.get());
1230 // FUNCTION: UpdateCurrentURI()
1232 // PURPOSE: Updates the URL address field
1235 nsQABrowserUIGlue::UpdateCurrentURI(nsIWebBrowserChrome
*aChrome
)
1237 nsCOMPtr
<nsIWebBrowser
> webBrowser
;
1238 nsCOMPtr
<nsIWebNavigation
> webNavigation
;
1239 aChrome
->GetWebBrowser(getter_AddRefs(webBrowser
));
1240 webNavigation
= do_QueryInterface(webBrowser
);
1242 nsCOMPtr
<nsIURI
> currentURI
;
1243 webNavigation
->GetCurrentURI(getter_AddRefs(currentURI
));
1246 nsCAutoString uriString
;
1247 currentURI
->GetAsciiSpec(uriString
);
1248 HWND hwndDlg
= GetBrowserDlgFromChrome(aChrome
);
1249 SetDlgItemText(hwndDlg
, IDC_ADDRESS
, uriString
.get());
1256 // FUNCTION: UpdateBusyState()
1258 // PURPOSE: Refreshes the stop/go buttons in the browser dialog
1261 nsQABrowserUIGlue::UpdateBusyState(nsIWebBrowserChrome
*aChrome
, PRBool aBusy
)
1263 HWND hwndDlg
= GetBrowserDlgFromChrome(aChrome
);
1265 button
= GetDlgItem(hwndDlg
, IDC_STOP
);
1267 EnableWindow(button
, aBusy
);
1268 button
= GetDlgItem(hwndDlg
, IDC_GO
);
1270 EnableWindow(button
, !aBusy
);
1277 // FUNCTION: UpdateProgress()
1279 // PURPOSE: Refreshes the progress bar in the browser dialog
1282 nsQABrowserUIGlue::UpdateProgress(nsIWebBrowserChrome
*aChrome
, PRInt32 aCurrent
, PRInt32 aMax
)
1284 HWND hwndDlg
= GetBrowserDlgFromChrome(aChrome
);
1285 HWND hwndProgress
= GetDlgItem(hwndDlg
, IDC_PROGRESS
);
1290 if (aCurrent
> aMax
)
1292 aMax
= aCurrent
+ 20; // What to do?
1296 SendMessage(hwndProgress
, PBM_SETRANGE
, 0, MAKELPARAM(0, aMax
));
1297 SendMessage(hwndProgress
, PBM_SETPOS
, aCurrent
, 0);
1303 // FUNCTION: ShowContextMenu()
1305 // PURPOSE: Display a context menu for the given node
1308 nsQABrowserUIGlue::ShowContextMenu(nsIWebBrowserChrome
*aChrome
, PRInt32 aContextFlags
, nsIDOMEvent
*aEvent
, nsIDOMNode
*aNode
)
1310 // TODO code to test context flags and display a popup menu should go here
1315 // FUNCTION: ShowTooltip()
1317 // PURPOSE: Show a tooltip
1320 nsQABrowserUIGlue::ShowTooltip(nsIWebBrowserChrome
*aChrome
, PRInt32 aXCoords
, PRInt32 aYCoords
, const PRUnichar
*aTipText
)
1322 // TODO code to show a tooltip should go here
1327 // FUNCTION: HideTooltip()
1329 // PURPOSE: Hide the tooltip
1332 nsQABrowserUIGlue::HideTooltip(nsIWebBrowserChrome
*aChrome
)
1334 // TODO code to hide a tooltip should go here
1339 nsQABrowserUIGlue::ShowWindow(nsIWebBrowserChrome
*aChrome
, PRBool aShow
)
1341 HWND win
= GetBrowserDlgFromChrome(aChrome
);
1342 return ::ShowWindow(win
, aShow
? SW_RESTORE
: SW_HIDE
);
1346 nsQABrowserUIGlue::SizeTo(nsIWebBrowserChrome
*aChrome
, PRInt32 aWidth
, PRInt32 aHeight
)
1348 HWND win
= GetBrowserDlgFromChrome(aChrome
);
1351 ::GetWindowRect(win
, &winRect
);
1352 return ::MoveWindow(win
, winRect
.left
, winRect
.top
, aWidth
, aHeight
, TRUE
);
1356 // FUNCTION: GetResourceStringByID()
1358 // PURPOSE: Get the resource string for the ID
1361 nsQABrowserUIGlue::GetResourceStringById(PRInt32 aID
, char ** aReturn
)
1363 char resBuf
[MAX_LOADSTRING
];
1364 int retval
= LoadString( ghInstanceResources
, aID
, (LPTSTR
)resBuf
, sizeof(resBuf
) );
1367 int resLen
= strlen(resBuf
);
1368 *aReturn
= (char *)calloc(resLen
+1, sizeof(char *));
1369 if (!*aReturn
) return NS_OK
;
1370 PL_strncpy(*aReturn
, (char *) resBuf
, resLen
);
1376 nsQABrowserUIGlue::SetTitle(const PRUnichar
* aTitle
)
1382 nsQABrowserUIGlue::GetTitle(PRUnichar
** aTitle
)
1389 nsQABrowserUIGlue::SetVisibility(PRBool aVisibility
)
1396 nsQABrowserUIGlue::GetVisibility(PRBool
* aVisibility
)
1398 *aVisibility
= PR_TRUE
;
1404 nsQABrowserUIGlue::SetAllowNewBrowserWindows(PRBool aValue
)
1406 mAllowNewWindows
= aValue
;
1412 nsQABrowserUIGlue::GetAllowNewBrowserWindows(PRBool
* aReturn
)
1415 *aReturn
= mAllowNewWindows
;
1420 nsQABrowserUIGlue::LoadHomePage()
1422 NS_NAMED_LITERAL_CSTRING (url
, "http://www.mozilla.org/embedding");
1423 return LoadURL(url
.get());
1428 nsQABrowserUIGlue::LoadURL(const char * aURL
)
1430 nsresult rv
= NS_OK
;
1431 // Start loading a page
1432 nsCOMPtr
<nsIWebBrowser
> newBrowser
;
1433 mBrowserView
->GetWebBrowser(getter_AddRefs(newBrowser
));
1434 nsCOMPtr
<nsIWebNavigation
> webNav(do_QueryInterface(newBrowser
, &rv
));
1436 return webNav
->LoadURI(NS_ConvertASCIItoUTF16(aURL
).get(),
1437 nsIWebNavigation::LOAD_FLAGS_NONE
,
1446 // FUNCTION: CreateNativeWindow()
1448 // PURPOSE: Creates a new browser dialog.
1451 // This function loads the browser dialog from a resource template
1452 // and returns the HWND for the webbrowser container dialog item
1456 nsQABrowserUIGlue::CreateNativeWindow(nsIWebBrowserChrome
* chrome
)
1458 // Load the browser dialog from resource
1460 PRUint32 chromeFlags
;
1462 chrome
->GetChromeFlags(&chromeFlags
);
1463 if ((chromeFlags
& nsIWebBrowserChrome::CHROME_ALL
) == nsIWebBrowserChrome::CHROME_ALL
)
1464 hwndDialog
= CreateDialog(ghInstanceResources
,
1465 MAKEINTRESOURCE(IDD_BROWSER
),
1469 hwndDialog
= CreateDialog(ghInstanceResources
,
1470 MAKEINTRESOURCE(IDD_BROWSER_NC
),
1474 return (void *) nsnull
;
1476 // Stick a menu onto it
1477 if (chromeFlags
& nsIWebBrowserChrome::CHROME_MENUBAR
) {
1478 HMENU hmenuDlg
= LoadMenu(ghInstanceResources
, MAKEINTRESOURCE(IDC_MOZEMBED
));
1479 SetMenu(hwndDialog
, hmenuDlg
);
1481 SetMenu(hwndDialog
, 0);
1483 // Add some interesting URLs to the address drop down
1484 HWND hwndAddress
= GetDlgItem(hwndDialog
, IDC_ADDRESS
);
1486 for (int i
= 0; i
< sizeof(gDefaultURLs
) / sizeof(gDefaultURLs
[0]); i
++)
1488 SendMessage(hwndAddress
, CB_ADDSTRING
, 0, (LPARAM
) gDefaultURLs
[i
]);
1492 // Fetch the browser window handle
1493 HWND hwndBrowser
= GetDlgItem(hwndDialog
, IDC_BROWSER
);
1494 SetWindowLong(hwndBrowser
, GWL_USERDATA
, (LONG
)chrome
); // save the browser LONG_PTR.
1495 SetWindowLong(hwndBrowser
, GWL_STYLE
, GetWindowLong(hwndBrowser
, GWL_STYLE
) | WS_CLIPCHILDREN
);
1497 // Activate the window
1498 PostMessage(hwndDialog
, WM_ACTIVATE
, WA_ACTIVE
, 0);
1502 return (void *) hwndBrowser
;