19#define WIN32_LEAN_AND_MEAN
21#pragma comment(lib, "windowscodecs.lib")
22#pragma comment(lib, "msimg32.lib")
24#define ID_SPLASHSCREEN 25
26static const char *gConception[] = {
32const char * gROOTCoreTeam[] = {
58static HINSTANCE gInst = 0;
59static HWND gSplashWnd = 0;
60static bool gShow =
FALSE;
61static DWORD gDelayVal = 0;
62static bool gAbout =
false;
63static RECT gCreditsRect = { 115, 0, 580, 80 };
64static unsigned int gCreditsWidth = gCreditsRect.right - gCreditsRect.left;
69HBITMAP CreateAlphaTextBitmap(LPCSTR inText, HFONT inFont, COLORREF inColour)
71 int TextLength = (
int)strlen(inText);
72 if (TextLength <= 0)
return NULL;
75 HDC hTextDC = CreateCompatibleDC(NULL);
76 HFONT hOldFont = (HFONT)SelectObject(hTextDC, inFont);
77 HBITMAP hMyDIB = NULL;
80 RECT TextArea = {0, 0, 0, 0};
81 DrawText(hTextDC, inText, TextLength, &TextArea, DT_CALCRECT);
82 if ((TextArea.right > TextArea.left) && (TextArea.bottom > TextArea.top)) {
83 BITMAPINFOHEADER BMIH;
84 memset(&BMIH, 0x0,
sizeof(BITMAPINFOHEADER));
88 BMIH.biSize =
sizeof(BMIH);
89 BMIH.biWidth = TextArea.right - TextArea.left;
90 BMIH.biHeight = TextArea.bottom - TextArea.top;
93 BMIH.biCompression = BI_RGB;
96 hMyDIB = CreateDIBSection(hTextDC, (LPBITMAPINFO)&BMIH, 0,
97 (LPVOID*)&pvBits, NULL, 0);
98 HBITMAP hOldBMP = (HBITMAP)SelectObject(hTextDC, hMyDIB);
99 if (hOldBMP != NULL) {
102 SetBkColor(hTextDC, 0x00000000);
103 SetBkMode(hTextDC, OPAQUE);
106 DrawText(hTextDC, inText, TextLength, &TextArea, DT_NOCLIP);
107 BYTE* DataPtr = (BYTE*)pvBits;
108 BYTE FillR = GetRValue(inColour);
109 BYTE FillG = GetGValue(inColour);
110 BYTE FillB = GetBValue(inColour);
112 for (
int LoopY = 0; LoopY < BMIH.biHeight; LoopY++) {
113 for (
int LoopX = 0; LoopX < BMIH.biWidth; LoopX++) {
115 *DataPtr++ = (FillB * ThisA) >> 8;
116 *DataPtr++ = (FillG * ThisA) >> 8;
117 *DataPtr++ = (FillR * ThisA) >> 8;
122 SelectObject(hTextDC, hOldBMP);
126 SelectObject(hTextDC, hOldFont);
135void DrawAlphaText(HDC inDC, HFONT inFont, COLORREF inColor,
136 const char *
text,
int inX,
int inY)
138 RECT TextArea = {0, 0, 0, 0};
139 HBITMAP MyBMP = CreateAlphaTextBitmap(
text, inFont, inColor);
142 HDC hTempDC = CreateCompatibleDC(inDC);
143 HBITMAP hOldBMP = (HBITMAP)SelectObject(hTempDC, MyBMP);
147 GetObject(MyBMP,
sizeof(BITMAP), &BMInf);
151 bf.BlendOp = AC_SRC_OVER;
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);
159 SelectObject(hTempDC, hOldBMP);
169static void DrawVersion(HDC hDC, HFONT inFont, COLORREF inColor)
174 GetTextExtentPoint32(hDC, version, strlen(version), &lpSize);
175 DrawAlphaText(hDC, inFont, inColor, version, 580-lpSize.cx, 400);
181static int DrawCreditItem(HDC hDC, HFONT inFont, COLORREF inColor,
182 const char *creditItem,
const char **members,
int y)
185 SIZE lpSize1, lpSize2;
189 GetTextMetrics(hDC, &lptm);
190 lineSpacing = lptm.tmAscent + lptm.tmDescent;
191 strcpy(credit, creditItem);
192 for (i = 0; members && members[i]; i++) {
193 if (i) strcat(credit,
", ");
194 GetTextExtentPoint32(hDC, credit, strlen(credit), &lpSize1);
195 GetTextExtentPoint32(hDC, members[i], strlen(members[i]), &lpSize2);
196 if((lpSize1.cx + lpSize2.cx) > (
int) gCreditsWidth) {
197 DrawAlphaText(hDC, inFont, inColor, credit, gCreditsRect.left,
y);
201 strcat(credit, members[i]);
203 DrawAlphaText(hDC, inFont, inColor, credit, gCreditsRect.left,
y);
210void DrawCredits(HDC hDC, HFONT inFont, COLORREF inColor)
214 GetTextMetrics(hDC, &lptm);
215 lineSpacing = lptm.tmAscent + lptm.tmDescent;
217 y = DrawCreditItem(hDC, inFont, inColor,
"Conception: ", gConception,
y);
218 y += 2 * lineSpacing - 4;
219 y = DrawCreditItem(hDC, inFont, inColor,
"Core Engineering: ", gROOTCoreTeam,
y);
225IStream *FromFile(LPCWSTR Filename)
227 IWICStream *Stream = 0;
228 IWICImagingFactory *
Factory = 0;
230#if(_WIN32_WINNT >= 0x0602) || defined(_WIN7_PLATFORM_UPDATE)
232 HRESULT hr = CoCreateInstance(CLSID_WICImagingFactory2, 0, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&
Factory));
234 hr = CoCreateInstance(CLSID_WICImagingFactory1, 0, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&
Factory));
240 HRESULT hr = CoCreateInstance(CLSID_WICImagingFactory, 0, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&
Factory));
245 if (SUCCEEDED(
Factory->CreateStream(&Stream))) {
246 Stream->InitializeFromFilename(Filename, GENERIC_READ);
256IWICBitmapSource *LoadBitmapFromStream(IStream *ipImageStream)
259 IWICBitmapSource *ipBitmap = NULL;
262 IWICBitmapDecoder *ipDecoder = NULL;
264#if(_WIN32_WINNT >= 0x0602) || defined(_WIN7_PLATFORM_UPDATE)
266 HRESULT hr = CoCreateInstance(CLSID_WICPngDecoder2, NULL, CLSCTX_INPROC_SERVER, __uuidof(ipDecoder),
reinterpret_cast<void **
>(&ipDecoder));
268 hr = CoCreateInstance(CLSID_WICPngDecoder1, NULL, CLSCTX_INPROC_SERVER, __uuidof(ipDecoder),
reinterpret_cast<void **
>(&ipDecoder));
274 HRESULT hr = CoCreateInstance(CLSID_WICPngDecoder, NULL, CLSCTX_INPROC_SERVER, __uuidof(ipDecoder),
reinterpret_cast<void **
>(&ipDecoder));
280 if (FAILED(ipDecoder->Initialize(ipImageStream, WICDecodeMetadataCacheOnLoad))) {
281 ipDecoder->Release();
285 UINT nFrameCount = 0;
287 if (FAILED(ipDecoder->GetFrameCount(&nFrameCount)) || nFrameCount != 1) {
288 ipDecoder->Release();
292 IWICBitmapFrameDecode *ipFrame = NULL;
294 if (FAILED(ipDecoder->GetFrame(0, &ipFrame))) {
295 ipDecoder->Release();
301 WICConvertBitmapSource(GUID_WICPixelFormat32bppPBGRA, ipFrame, &ipBitmap);
304 ipDecoder->Release();
311HBITMAP CreateHBITMAP(IWICBitmapSource *ipBitmap)
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;
335 void *pvImageBits = NULL;
336 HDC hdcScreen = GetDC(NULL);
337 hbmp = CreateDIBSection(hdcScreen, &bminfo, DIB_RGB_COLORS, &pvImageBits, NULL, 0);
338 ReleaseDC(NULL, hdcScreen);
344 const UINT cbStride =
width * 4;
345 const UINT cbImage = cbStride *
height;
347 if (FAILED(ipBitmap->CopyPixels(NULL, cbStride, cbImage,
static_cast<BYTE *
>(pvImageBits)))) {
358HBITMAP LoadSplashImage(LPCWSTR file_name)
360 HBITMAP hbmpSplash = NULL;
363 IStream *ipImageStream = FromFile(file_name);
365 if (ipImageStream == NULL) {
369 IWICBitmapSource *ipBitmap = LoadBitmapFromStream(ipImageStream);
371 if (ipBitmap == NULL) {
372 ipImageStream->Release();
376 hbmpSplash = CreateHBITMAP(ipBitmap);
379 ipImageStream->Release();
388 if (IsWindow(gSplashWnd)) {
389 DestroyWindow(gSplashWnd);
391 UnregisterClass(
"SplashWindow", gInst);
398LRESULT
CALLBACK SplashWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
403 SetTimer(hWnd, ID_SPLASHSCREEN, gDelayVal, 0);
407 if (wParam == ID_SPLASHSCREEN) {
408 KillTimer (hWnd, ID_SPLASHSCREEN);
417 return DefWindowProc(hWnd, message, wParam, lParam);
425void RegisterWindowClass(HINSTANCE g_hInstance)
428 wc.lpfnWndProc = (WNDPROC)SplashWndProc;
429 wc.hInstance = g_hInstance;
431 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
432 wc.lpszClassName = _T(
"SplashWindow");
439HWND CreateSplashWindow(HINSTANCE g_hInstance)
441 return CreateWindowEx(WS_EX_LAYERED | WS_EX_TOOLWINDOW | WS_EX_TOPMOST,
442 _T(
"SplashWindow"), NULL, WS_POPUP | WS_VISIBLE,
443 0, 0, 0, 0, NULL, NULL, g_hInstance, NULL);
450void SetSplashImage(HWND hwndSplash, HBITMAP hbmpSplash)
454 GetObject(hbmpSplash,
sizeof(bm), &bm);
455 SIZE sizeSplash = { bm.bmWidth, bm.bmHeight };
458 POINT ptZero = { 0 };
459 HMONITOR hmonPrimary = MonitorFromPoint(ptZero, MONITOR_DEFAULTTOPRIMARY);
460 MONITORINFO monitorinfo = { 0 };
461 monitorinfo.cbSize =
sizeof(monitorinfo);
462 GetMonitorInfo(hmonPrimary, &monitorinfo);
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;
471 HDC hdcScreen = GetDC(NULL);
472 HDC hdcMem = CreateCompatibleDC(hdcScreen);
473 HBITMAP hbmpOld = (HBITMAP) SelectObject(hdcMem, hbmpSplash);
476 BLENDFUNCTION blend = { 0 };
477 blend.BlendOp = AC_SRC_OVER;
478 blend.SourceConstantAlpha = 255;
479 blend.AlphaFormat = AC_SRC_ALPHA;
481 SetBkMode(hdcMem, TRANSPARENT);
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);
490 UpdateLayeredWindow(hwndSplash, hdcScreen, &ptOrigin, &sizeSplash,
491 hdcMem, &ptZero, RGB(0, 0, 0), &blend, ULW_ALPHA);
494 SelectObject(hdcMem, hbmpOld);
496 ReleaseDC(NULL, hdcScreen);
502bool PreTranslateMessage(MSG* pMsg)
504 if (!IsWindow(gSplashWnd))
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) {
529 if (extended) gAbout =
true;
530 if (time > 0) gDelayVal = time * 1000;
533 RegisterWindowClass(gInst);
535 if (!_wgetenv(L
"ROOTSYS"))
return;
536 std::wstring RootSysDir = _wgetenv(L
"ROOTSYS");
537 std::wstring splash_picture = RootSysDir +
L"\\icons\\Root6Splash.png";
539 HBITMAP bkg_img = LoadSplashImage(splash_picture.c_str());
540 gSplashWnd = CreateSplashWindow(gInst);
541 SetSplashImage(gSplashWnd, bkg_img);
542 DeleteObject(bkg_img);
545 while (GetMessage(&msg, 0, 0, 0)) {
546 PreTranslateMessage(&msg);
547 TranslateMessage(&msg);
548 DispatchMessage(&msg);
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)
RooArgList L(Args_t &&... args)