Logo ROOT  
Reference Guide
 
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
Loading...
Searching...
No Matches
Win32Splash.cxx
Go to the documentation of this file.
1// @(#)root/winnt:$Id$
2// Author: Bertrand Bellenot 30/07/02
3
4/*************************************************************************
5 * Copyright (C) 1995-2002, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#ifdef WIN32
13#include "RVersion.h"
14#include "strlcpy.h"
15#include <wincodec.h>
16#include <tchar.h>
17#include <iostream>
18#include <string>
19#define WIN32_LEAN_AND_MEAN
20#include <windows.h>
21#pragma comment(lib, "windowscodecs.lib")
22#pragma comment(lib, "msimg32.lib")
23
24#define ID_SPLASHSCREEN 25
25
26static const char *gConception[] = {
27 "Rene Brun",
28 "Fons Rademakers",
29 0
30};
31
32const char * gROOTCoreTeam[] = {
33 "Rene Brun",
34 "Fons Rademakers",
35 "Philippe Canal",
36 "Axel Naumann",
37 "Olivier Couet",
38 "Lorenzo Moneta",
39 "Vassil Vassilev",
40 "Gerardo Ganis",
41 "Bertrand Bellenot",
42 "Danilo Piparo",
43 "Wouter Verkerke",
44 "Timur Pocheptsov",
45 "Matevz Tadel",
46 "Pere Mato",
47 "Wim Lavrijsen",
48 "Ilka Antcheva",
49 "Paul Russo",
50 "Andrei Gheata",
51 "Anirudha Bose",
52 "Valeri Onuchine",
53 0
54};
55
56///////////////////////////////////////////////////////////////////////////////
57// Global Variables:
58static HINSTANCE gInst = 0; // Current instance
59static HWND gSplashWnd = 0; // Splash screen
60static bool gShow = FALSE;
61static DWORD gDelayVal = 0;
62static bool gAbout = false;
63static RECT gCreditsRect = { 115, 0, 580, 80 }; // clip rect in logo
64static unsigned int gCreditsWidth = gCreditsRect.right - gCreditsRect.left; // credits pixmap size
65
66///////////////////////////////////////////////////////////////////////////
67/// Create a bitmap and draw alpha blended text on it.
68
70{
72 if (TextLength <= 0) return NULL;
73
74 // Create DC and select font into it
76 HFONT hOldFont = (HFONT)SelectObject(hTextDC, inFont);
77 HBITMAP hMyDIB = NULL;
78
79 // Get text area
80 RECT TextArea = {0, 0, 0, 0};
82 if ((TextArea.right > TextArea.left) && (TextArea.bottom > TextArea.top)) {
84 memset(&BMIH, 0x0, sizeof(BITMAPINFOHEADER));
85 void *pvBits = NULL;
86
87 // Specify DIB setup
88 BMIH.biSize = sizeof(BMIH);
89 BMIH.biWidth = TextArea.right - TextArea.left;
90 BMIH.biHeight = TextArea.bottom - TextArea.top;
91 BMIH.biPlanes = 1;
92 BMIH.biBitCount = 32;
93 BMIH.biCompression = BI_RGB;
94
95 // Create and select DIB into DC
97 (LPVOID*)&pvBits, NULL, 0);
98 HBITMAP hOldBMP = (HBITMAP)SelectObject(hTextDC, hMyDIB);
99 if (hOldBMP != NULL) {
100 // Set up DC properties
101 SetTextColor(hTextDC, 0x00FFFFFF);
102 SetBkColor(hTextDC, 0x00000000);
104
105 // Draw text to buffer
107 BYTE* DataPtr = (BYTE*)pvBits;
108 BYTE FillR = GetRValue(inColour);
109 BYTE FillG = GetGValue(inColour);
110 BYTE FillB = GetBValue(inColour);
111 BYTE ThisA;
112 for (int LoopY = 0; LoopY < BMIH.biHeight; LoopY++) {
113 for (int LoopX = 0; LoopX < BMIH.biWidth; LoopX++) {
114 ThisA = *DataPtr; // Move alpha and pre-multiply with RGB
115 *DataPtr++ = (FillB * ThisA) >> 8;
116 *DataPtr++ = (FillG * ThisA) >> 8;
117 *DataPtr++ = (FillR * ThisA) >> 8;
118 *DataPtr++ = ThisA; // Set Alpha
119 }
120 }
121 // De-select bitmap
122 SelectObject(hTextDC, hOldBMP);
123 }
124 }
125 // De-select font and destroy temp DC
126 SelectObject(hTextDC, hOldFont);
128
129 // Return DIBSection
130 return hMyDIB;
131}
132///////////////////////////////////////////////////////////////////////////
133/// Draw alpha blended text on the splash screen.
134
136 const char *text, int inX, int inY)
137{
138 RECT TextArea = {0, 0, 0, 0};
140 if (MyBMP) {
141 // Create temporary DC and select new Bitmap into it
143 HBITMAP hOldBMP = (HBITMAP)SelectObject(hTempDC, MyBMP);
144 if (hOldBMP) {
145 // Get Bitmap image size
147 GetObject(MyBMP, sizeof(BITMAP), &BMInf);
148
149 // Fill blend function and blend new text to window
151 bf.BlendOp = AC_SRC_OVER;
152 bf.BlendFlags = 0;
153 bf.SourceConstantAlpha = 0xFF;
154 bf.AlphaFormat = AC_SRC_ALPHA;
155 AlphaBlend(inDC, inX, inY, BMInf.bmWidth, BMInf.bmHeight, hTempDC,
156 0, 0, BMInf.bmWidth, BMInf.bmHeight, bf);
157
158 // Clean up
159 SelectObject(hTempDC, hOldBMP);
162 }
163 }
164}
165
166////////////////////////////////////////////////////////////////////////////////
167/// Draw the ROOT version on the bottom right of the splash screen.
168
169static void DrawVersion(HDC hDC, HFONT inFont, COLORREF inColor)
170{
171 SIZE lpSize;
172 char version[256];
173 sprintf(version, "Version %s", ROOT_RELEASE);
175 DrawAlphaText(hDC, inFont, inColor, version, 580-lpSize.cx, 400);
176}
177
178////////////////////////////////////////////////////////////////////////////////
179/// Draw credit item.
180
182 const char *creditItem, const char **members, int y)
183{
184 char credit[1024];
187 int i;
188 int lineSpacing;
190 lineSpacing = lptm.tmAscent + lptm.tmDescent;
192 for (i = 0; members && members[i]; i++) {
193 if (i) strcat(credit, ", ");
196 if((lpSize1.cx + lpSize2.cx) > (int) gCreditsWidth) {
198 y += lineSpacing;
199 strcpy(credit, " ");
200 }
201 strcat(credit, members[i]);
202 }
204 return y;
205}
206
207////////////////////////////////////////////////////////////////////////////////
208/// Draw the credits on the splah window.
209
211{
213 int lineSpacing, y;
215 lineSpacing = lptm.tmAscent + lptm.tmDescent;
216 y = 305;
217 y = DrawCreditItem(hDC, inFont, inColor, "Conception: ", gConception, y);
218 y += 2 * lineSpacing - 4;
219 y = DrawCreditItem(hDC, inFont, inColor, "Core Engineering: ", gROOTCoreTeam, y);
220}
221
222////////////////////////////////////////////////////////////////////////////////
223/// Get a stream from the specified file name (using Windows Imaging Component).
224
226{
227 IWICStream *Stream = 0;
229
230#if(_WIN32_WINNT >= 0x0602) || defined(_WIN7_PLATFORM_UPDATE)
231 // WIC2 is available on Windows 8 and Windows 7 SP1 with KB 2670838 installed
233 if (FAILED(hr)) {
235 if (FAILED(hr)) {
236 return NULL;
237 }
238 }
239#else
241 if (FAILED(hr)) {
242 return NULL;
243 }
244#endif
245 if (SUCCEEDED(Factory->CreateStream(&Stream))) {
246 Stream->InitializeFromFilename(Filename, GENERIC_READ);
247 }
248 Factory->Release();
249 return Stream;
250}
251
252////////////////////////////////////////////////////////////////////////////////
253/// Loads a PNG image from the specified stream (using Windows Imaging
254/// Component).
255
257{
258 // initialize return value
260
261 // load WIC's PNG decoder
263
264#if(_WIN32_WINNT >= 0x0602) || defined(_WIN7_PLATFORM_UPDATE)
265 // WIC2 is available on Windows 8 and Windows 7 SP1 with KB 2670838 installed
267 if (FAILED(hr)) {
269 if (FAILED(hr)) {
270 return NULL;
271 }
272 }
273#else
275 if (FAILED(hr)) {
276 return NULL;
277 }
278#endif
279 // load the PNG
281 ipDecoder->Release();
282 return NULL;
283 }
284 // check for the presence of the first frame in the bitmap
285 UINT nFrameCount = 0;
286
287 if (FAILED(ipDecoder->GetFrameCount(&nFrameCount)) || nFrameCount != 1) {
288 ipDecoder->Release();
289 return NULL;
290 }
291 // load the first frame (i.e., the image)
293
294 if (FAILED(ipDecoder->GetFrame(0, &ipFrame))) {
295 ipDecoder->Release();
296 return NULL;
297 }
298 // convert the image to 32bpp BGRA format with pre-multiplied alpha
299 // (it may not be stored in that format natively in the PNG resource,
300 // but we need this format to create the DIB to use on-screen)
302 ipFrame->Release();
303
304 ipDecoder->Release();
305 return ipBitmap;
306}
307
308////////////////////////////////////////////////////////////////////////////////
309/// Create a 32-bit DIB from the specified WIC bitmap.
310
312{
313 // initialize return value
314 HBITMAP hbmp = NULL;
315
316 // get image attributes and check for valid image
317 UINT width = 0;
318 UINT height = 0;
319
320 if (FAILED(ipBitmap->GetSize(&width, &height)) || width == 0 || height == 0) {
321 return hbmp;
322 }
323
324 // prepare structure giving bitmap information (negative height indicates a top-down DIB)
326 ZeroMemory(&bminfo, sizeof(bminfo));
327 bminfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
328 bminfo.bmiHeader.biWidth = width;
329 bminfo.bmiHeader.biHeight = -((LONG) height);
330 bminfo.bmiHeader.biPlanes = 1;
331 bminfo.bmiHeader.biBitCount = 32;
332 bminfo.bmiHeader.biCompression = BI_RGB;
333
334 // create a DIB section that can hold the image
335 void *pvImageBits = NULL;
336 HDC hdcScreen = GetDC(NULL);
339
340 if (hbmp == NULL) {
341 return NULL;
342 }
343 // extract the image into the HBITMAP
344 const UINT cbStride = width * 4;
345 const UINT cbImage = cbStride * height;
346
347 if (FAILED(ipBitmap->CopyPixels(NULL, cbStride, cbImage, static_cast<BYTE *>(pvImageBits)))) {
348 // couldn't extract image; delete HBITMAP
350 hbmp = NULL;
351 }
352 return hbmp;
353}
354
355////////////////////////////////////////////////////////////////////////////////
356/// Loads the PNG containing the splash image into a HBITMAP.
357
358HBITMAP LoadSplashImage(LPCWSTR file_name)
359{
360 HBITMAP hbmpSplash = NULL;
361
362 // load the PNG image data into a stream
363 IStream *ipImageStream = FromFile(file_name);
364
365 if (ipImageStream == NULL) {
366 return hbmpSplash;
367 }
368 // load the bitmap with WIC
370
371 if (ipBitmap == NULL) {
372 ipImageStream->Release();
373 return NULL;
374 }
375 // create a HBITMAP containing the image
377 ipBitmap->Release();
378
379 ipImageStream->Release();
380 return hbmpSplash;
381}
382
383////////////////////////////////////////////////////////////////////////////////
384/// Destroy our splash screen window.
385
387{
388 if (IsWindow(gSplashWnd)) {
389 DestroyWindow(gSplashWnd);
390 gSplashWnd = 0;
391 UnregisterClass("SplashWindow", gInst);
392 }
393}
394
395///////////////////////////////////////////////////////////////////////////
396/// Message handler for the splash screen window.
397
399{
400 switch (message) {
401 case WM_CREATE:
402 if(!gAbout)
403 SetTimer(hWnd, ID_SPLASHSCREEN, gDelayVal, 0);
404 break;
405
406 case WM_TIMER:
407 if (wParam == ID_SPLASHSCREEN) {
410 }
411 break;
412
413 case WM_DESTROY:
415
416 default:
417 return DefWindowProc(hWnd, message, wParam, lParam);
418 }
419 return 0;
420}
421
422///////////////////////////////////////////////////////////////////////////
423/// Registers a window class for the splash and splash owner windows.
424
426{
427 WNDCLASS wc = { 0 };
428 wc.lpfnWndProc = (WNDPROC)SplashWndProc;//DefWindowProc;
429 wc.hInstance = g_hInstance;
430 //wc.hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(_T("SPLASH")));
431 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
432 wc.lpszClassName = _T("SplashWindow");
433 RegisterClass(&wc);
434}
435
436///////////////////////////////////////////////////////////////////////////
437/// Create the splash owner window and the splash window.
438
440{
442 _T("SplashWindow"), NULL, WS_POPUP | WS_VISIBLE,
443 0, 0, 0, 0, NULL, NULL, g_hInstance, NULL);
444}
445
446///////////////////////////////////////////////////////////////////////////
447/// Call UpdateLayeredWindow to set a bitmap (with alpha) as the content of
448/// the splash window.
449
451{
452 // get the size of the bitmap
453 BITMAP bm;
454 GetObject(hbmpSplash, sizeof(bm), &bm);
455 SIZE sizeSplash = { bm.bmWidth, bm.bmHeight };
456
457 // get the primary monitor's info
458 POINT ptZero = { 0 };
460 MONITORINFO monitorinfo = { 0 };
461 monitorinfo.cbSize = sizeof(monitorinfo);
463
464 // center the splash screen in the middle of the primary work area
465 const RECT &rcWork = monitorinfo.rcWork;
467 ptOrigin.x = rcWork.left + (rcWork.right - rcWork.left - sizeSplash.cx - 93) / 2;
468 ptOrigin.y = rcWork.top + (rcWork.bottom - rcWork.top - sizeSplash.cy - 104) / 2;
469
470 // create a memory DC holding the splash bitmap
471 HDC hdcScreen = GetDC(NULL);
473 HBITMAP hbmpOld = (HBITMAP) SelectObject(hdcMem, hbmpSplash);
474
475 // use the source image's alpha channel for blending
476 BLENDFUNCTION blend = { 0 };
477 blend.BlendOp = AC_SRC_OVER;
478 blend.SourceConstantAlpha = 255;
479 blend.AlphaFormat = AC_SRC_ALPHA;
480
482 HFONT hFont = CreateFont(14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Arial\0");
483 HFONT hOldFont = (HFONT)SelectObject(hdcMem, hFont);
484 DrawVersion(hdcMem, hFont, RGB(255,255,255));
485 DrawCredits(hdcMem, hFont, RGB(176,210,249));
486 SelectObject(hdcMem, hOldFont);
488
489 // paint the window (in the right location) with the alpha-blended bitmap
491 hdcMem, &ptZero, RGB(0, 0, 0), &blend, ULW_ALPHA);
492
493 // delete temporary objects
494 SelectObject(hdcMem, hbmpOld);
497}
498
499////////////////////////////////////////////////////////////////////////////////
500/// check for keybord or mouse event and destroy the splash screen accordingly.
501
503{
504 if (!IsWindow(gSplashWnd))
505 return FALSE;
506
507 // If we get a keyboard or mouse message, hide the splash screen.
508 if (pMsg->message == WM_KEYDOWN ||
509 pMsg->message == WM_SYSKEYDOWN ||
510 pMsg->message == WM_LBUTTONDOWN ||
511 pMsg->message == WM_RBUTTONDOWN ||
512 pMsg->message == WM_MBUTTONDOWN ||
513 pMsg->message == WM_NCLBUTTONDOWN ||
514 pMsg->message == WM_NCRBUTTONDOWN ||
515 pMsg->message == WM_NCMBUTTONDOWN) {
517 return TRUE; // message handled here
518 }
519 return FALSE; // message not handled
520}
521
522////////////////////////////////////////////////////////////////////////////////
523/// Create our splash screen.
524
525void CreateSplash(DWORD time, bool extended)
526{
527 MSG msg;
528 gShow = FALSE;
529 if (extended) gAbout = true;
530 if (time > 0) gDelayVal = time * 1000;
531 else return;
532
534
535 if (!_wgetenv(L"ROOTSYS")) return;
536 std::wstring RootSysDir = _wgetenv(L"ROOTSYS");
537 std::wstring splash_picture = RootSysDir + L"\icons\Root6Splash.png";
538 CoInitialize(0);
539 HBITMAP bkg_img = LoadSplashImage(splash_picture.c_str());
544 // Main message loop:
545 while (GetMessage(&msg, 0, 0, 0)) {
549 }
551}
552
553#endif
#define ROOT_RELEASE
Definition RVersion.hxx:44
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
#define CALLBACK
Option_t Option_t width
Option_t Option_t TPoint TPoint DrawText
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t height
Option_t Option_t TPoint TPoint const char text
void DestroySplashScreen()
void CreateSplash(DWORD time, bool extended)
pt SetTextColor(4)
Double_t y[n]
Definition legend1.C:17
#define TRUE
Definition mesh.c:42
#define FALSE
Definition mesh.c:45
RooArgList L(Args_t &&... args)
Definition RooArgList.h:156