Bug 575870 - Enable the firefox button on xp themed, classic, and aero basic. r=dao...
[mozilla-central.git] / toolkit / xre / nsSplashScreenWin.cpp
blob460e8d00fff4ec1158529cc8bc0244a3cb57c517
1 /* -*- Mode: C++; tab-width: 40; 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
13 * License.
15 * The Original Code is Mozilla code.
17 * The Initial Developer of the Original Code is
18 * mozilla.org
19 * Portions created by the Initial Developer are Copyright (C) 2009
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
23 * Vladimir Vukicevic <vladimir@pobox.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 ***** */
39 #include "nsSplashScreen.h"
41 #include <windows.h>
43 static ATOM gSplashScreenClass = 0;
45 class nsSplashScreenWin;
47 static nsSplashScreenWin *gSplashScreen = NULL;
49 class nsSplashScreenWin :
50 public nsSplashScreen
52 public:
53 nsSplashScreenWin();
55 virtual void Open();
56 virtual void Close();
57 virtual void Update(PRInt32 progress);
59 protected:
60 HWND mDialog;
61 HBITMAP mSplashBitmap, mOldBitmap;
62 HDC mSplashBitmapDC;
63 int mWidth, mHeight;
65 static DWORD WINAPI ThreadProc(LPVOID splashScreen);
67 static LRESULT CALLBACK DialogProc (HWND hWnd,
68 UINT uMsg,
69 WPARAM wParam,
70 LPARAM lParam);
72 void OnPaint(HDC dc, const PAINTSTRUCT *ps);
74 PRInt32 mProgress;
77 nsSplashScreen *
78 nsSplashScreen::GetOrCreate()
80 if (!gSplashScreen)
81 gSplashScreen = new nsSplashScreenWin();
83 return gSplashScreen;
86 nsSplashScreen *
87 nsSplashScreen::Get()
89 return gSplashScreen;
92 nsSplashScreenWin::nsSplashScreenWin()
93 : mDialog(NULL), mSplashBitmap(NULL), mOldBitmap(NULL),
94 mSplashBitmapDC(NULL),
95 mWidth(200), mHeight(100),
96 mProgress(-1)
100 void
101 nsSplashScreenWin::Open()
103 if (mIsOpen || mDialog)
104 return;
106 mIsOpen = PR_TRUE;
108 if (gSplashScreenClass == 0) {
109 WNDCLASS wc;
110 memset(&wc, 0, sizeof(WNDCLASS));
112 wc.style = CS_NOCLOSE;
113 wc.lpfnWndProc = (WNDPROC) DialogProc;
114 wc.hInstance = GetModuleHandle(0);
115 wc.hIcon = NULL;
116 wc.hCursor = NULL;
117 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
118 wc.lpszMenuName = NULL;
119 wc.lpszClassName = TEXT("MozillaSplashScreen");
121 gSplashScreenClass = RegisterClass(&wc);
124 if (mSplashBitmap == NULL) {
125 wchar_t path[_MAX_PATH];
126 if (::GetModuleFileNameW(0, path, _MAX_PATH)) {
127 wchar_t *slash = wcsrchr(path, '\\');
128 if (slash != NULL)
129 slash[1] = 0;
131 wcscat(path, L"splash.bmp");
133 #ifdef WINCE
134 mSplashBitmap = ::SHLoadDIBitmap(path);
135 #else
136 #warning splashscreen needs some code to load bitmaps on non-WinCE
137 mSplashBitmap = nsnull;
138 #endif
140 if (mSplashBitmap) {
141 BITMAP bmo;
142 if (GetObject(mSplashBitmap, sizeof(BITMAP), &bmo) > 0) {
143 mWidth = bmo.bmWidth;
144 mHeight = bmo.bmHeight;
146 mSplashBitmapDC = CreateCompatibleDC(NULL);
147 mOldBitmap = (HBITMAP) SelectObject(mSplashBitmapDC, mSplashBitmap);
148 } else {
149 DeleteObject(mSplashBitmap);
150 mSplashBitmap = NULL;
156 DWORD threadID = 0;
157 CreateThread(0, 0, (LPTHREAD_START_ROUTINE)ThreadProc, this, 0, &threadID);
160 DWORD WINAPI
161 nsSplashScreenWin::ThreadProc(LPVOID splashScreen)
163 nsSplashScreenWin *sp = (nsSplashScreenWin*) splashScreen;
165 int screenWidth = GetSystemMetrics(SM_CXSCREEN);
166 int screenHeight = GetSystemMetrics(SM_CYSCREEN);
168 LONG horizPad = (screenWidth - sp->mWidth) / 2;
169 LONG vertPad = (screenHeight - sp->mHeight) / 2;
170 RECT r = { horizPad,
171 vertPad,
172 horizPad + sp->mWidth,
173 vertPad + sp->mHeight };
175 DWORD winStyle = (WS_POPUP | WS_BORDER);
176 DWORD winStyleEx = WS_EX_NOACTIVATE;
178 if(!::AdjustWindowRectEx(&r, winStyle, FALSE, winStyleEx))
179 return 0;
181 HWND dlg = CreateWindowEx(
182 winStyleEx,
183 TEXT("MozillaSplashScreen"),
184 TEXT("Starting up..."),
185 winStyle,
186 r.left, r.top,
187 (r.right - r.left), (r.bottom - r.top),
188 HWND_DESKTOP,
189 NULL,
190 GetModuleHandle(0),
191 NULL);
193 sp->mDialog = dlg;
195 ShowWindow(dlg, SW_SHOW);
196 SetForegroundWindow(dlg);
198 MSG msg;
199 while (::GetMessage(&msg, NULL, 0, 0)) {
200 DispatchMessage(&msg);
203 // window was destroyed, nothing to do
204 return 0;
207 void
208 nsSplashScreenWin::Close()
210 if (mDialog) {
211 ShowWindow(mDialog, SW_HIDE);
212 PostMessage(mDialog, WM_QUIT, 0, 0);
213 mDialog = NULL;
216 if (mSplashBitmap) {
217 SelectObject(mSplashBitmapDC, mOldBitmap);
218 DeleteObject(mSplashBitmapDC);
219 DeleteObject(mSplashBitmap);
220 mOldBitmap = NULL;
221 mSplashBitmapDC = NULL;
222 mSplashBitmap = NULL;
225 mIsOpen = PR_FALSE;
228 void
229 nsSplashScreenWin::Update(PRInt32 progress)
231 if (progress >= 0)
232 mProgress = progress > 100 ? 100 : progress;
234 InvalidateRect(mDialog, NULL, FALSE);
237 void
238 nsSplashScreenWin::OnPaint(HDC dc, const PAINTSTRUCT *ps)
240 RECT progressBar;
242 // Paint the splash screen
243 if (mSplashBitmapDC) {
244 BitBlt(dc,
245 0, 0, gSplashScreen->mWidth, gSplashScreen->mHeight,
246 gSplashScreen->mSplashBitmapDC,
247 0, 0,
248 SRCCOPY);
249 } else {
250 HBRUSH bkgr = CreateSolidBrush(RGB(200,200,200));
251 RECT r = { 0, 0, mWidth, mHeight };
252 FillRect(dc, &r, bkgr);
253 DeleteObject(bkgr);
256 // Size of progress bar area
257 if (mSplashBitmapDC &&
258 gSplashScreen->mWidth == 440 &&
259 gSplashScreen->mHeight == 180) {
260 // For now we're tightly tied to a specific splash.bmp design,
261 // ideally we would determine the region automagically.
262 progressBar.left = 183;
263 progressBar.right = 410;
264 progressBar.top = 148;
265 progressBar.bottom = 153;
266 } else {
267 // The default progress bar will be 2/3 the width of the splash box,
268 // 9 pixels tall, 10 pixels from the bottom.
269 progressBar.left = (mWidth / 6);
270 progressBar.right = mWidth - (mWidth / 6);
271 progressBar.top = mHeight - 19;
272 progressBar.bottom = mHeight - 10;
275 if (mProgress != -1) {
276 HBRUSH fill = CreateSolidBrush(RGB(0x77,0xC7,0x1C));
278 int maxWidth = progressBar.right - progressBar.left;
279 progressBar.right = progressBar.left + maxWidth * mProgress / 100;
280 FillRect(dc, &progressBar, fill);
282 DeleteObject(fill);
286 LRESULT CALLBACK
287 nsSplashScreenWin::DialogProc (HWND hWnd,
288 UINT uMsg,
289 WPARAM wParam,
290 LPARAM lParam)
292 switch (uMsg) {
293 case WM_PAINT: {
294 PAINTSTRUCT ps;
295 HDC dc = BeginPaint(hWnd, &ps);
297 if (gSplashScreen)
298 gSplashScreen->OnPaint(dc, &ps);
300 EndPaint(hWnd, &ps);
301 return TRUE;
303 break;
305 case WM_DESTROY:
306 return TRUE;
308 case WM_QUIT:
309 DestroyWindow(hWnd);
310 return TRUE;
312 default:
313 return DefWindowProc(hWnd, uMsg, wParam, lParam);
316 return FALSE;