diff --git a/native/WinLauncher/WinLauncher/WinLauncher.cpp b/native/WinLauncher/WinLauncher/WinLauncher.cpp index bd801390ec09..cc2d3562bd5a 100644 --- a/native/WinLauncher/WinLauncher/WinLauncher.cpp +++ b/native/WinLauncher/WinLauncher/WinLauncher.cpp @@ -563,6 +563,123 @@ bool CheckSingleInstance() } } +void DrawSplashImage(HWND hWnd) +{ + HBITMAP hSplashBitmap = (HBITMAP) GetWindowLongPtr(hWnd, GWLP_USERDATA); + PAINTSTRUCT ps; + HDC hDC = BeginPaint(hWnd, &ps); + HDC hMemDC = CreateCompatibleDC(hDC); + HBITMAP hOldBmp = (HBITMAP) SelectObject(hMemDC, hSplashBitmap); + BITMAP splashBitmap; + GetObject(hSplashBitmap, sizeof(splashBitmap), &splashBitmap); + BitBlt(hDC, 0, 0, splashBitmap.bmWidth, splashBitmap.bmHeight, hMemDC, 0, 0, SRCCOPY); + SelectObject(hMemDC, hOldBmp); + DeleteDC(hMemDC); + EndPaint(hWnd, &ps); +} + +LRESULT CALLBACK SplashScreenWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch(uMsg) + { + case WM_PAINT: + DrawSplashImage(hWnd); + break; + } + return DefWindowProc(hWnd, uMsg, wParam, lParam); +} + +const TCHAR *splashClassName = _T("IntelliJLauncherSplash"); + +void RegisterSplashScreenWndClass() +{ + WNDCLASSEX wcx; + wcx.cbSize = sizeof(wcx); + wcx.style = 0; + wcx.lpfnWndProc = SplashScreenWndProc; + wcx.cbClsExtra = 0; + wcx.cbWndExtra = 0; + wcx.hInstance = hInst; + wcx.hIcon = 0; + wcx.hCursor = LoadCursor(NULL, IDC_WAIT); + wcx.hbrBackground = (HBRUSH) GetStockObject(LTGRAY_BRUSH); + wcx.lpszMenuName = 0; + wcx.lpszClassName = splashClassName; + wcx.hIconSm = 0; + + RegisterClassEx(&wcx); +} + +HWND ShowSplashScreenWindow(HBITMAP hSplashBitmap) +{ + RECT workArea; + SystemParametersInfo(SPI_GETWORKAREA, 0, &workArea, 0); + BITMAP splashBitmap; + GetObject(hSplashBitmap, sizeof(splashBitmap), &splashBitmap); + int x = workArea.left + ((workArea.right - workArea.left) - splashBitmap.bmWidth) / 2; + int y = workArea.top + ((workArea.bottom - workArea.top) - splashBitmap.bmHeight) / 2; + + HWND splashWindow = CreateWindowEx(WS_EX_TOOLWINDOW, splashClassName, splashClassName, WS_POPUP, + x, y, splashBitmap.bmWidth, splashBitmap.bmHeight, NULL, NULL, NULL, NULL); + SetWindowLongPtr(splashWindow, GWLP_USERDATA, (LONG_PTR) hSplashBitmap); + ShowWindow(splashWindow, SW_SHOW); + UpdateWindow(splashWindow); + return splashWindow; +} + +BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam) +{ + static DWORD currentProcId = GetCurrentProcessId(); + DWORD procId = 0; + GetWindowThreadProcessId(hWnd, &procId); + if(currentProcId == procId) + { + TCHAR className[_MAX_PATH]; + GetClassName(hWnd, className, _MAX_PATH-1); + if (_tcscmp(className, splashClassName) != 0) + { + WINDOWINFO wi; + wi.cbSize = sizeof(WINDOWINFO); + GetWindowInfo(hWnd, &wi); + if((wi.dwStyle & WS_VISIBLE) != 0) + { + HWND *phNewWindow = (HWND *) lParam; + *phNewWindow = hWnd; + return FALSE; + } + } + } + return TRUE; +} + + +DWORD WINAPI SplashScreenThread(LPVOID args) +{ + HBITMAP hSplashBitmap = static_cast(args); + RegisterSplashScreenWndClass(); + HWND splashWindow = ShowSplashScreenWindow(hSplashBitmap); + + MSG msg; + while(true) + { + while (PeekMessage(&msg, splashWindow, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + Sleep(50); + HWND hNewWindow = NULL; + EnumWindows(EnumWindowsProc, (LPARAM) &hNewWindow); + if (hNewWindow) + { + BringWindowToTop(hNewWindow); + DeleteObject(hSplashBitmap); + DestroyWindow(splashWindow); + } + } + return 0; +} + int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, @@ -574,6 +691,12 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, hInst = hInstance; if (!CheckSingleInstance()) return 1; + + HANDLE hSplashBitmap = static_cast(LoadImage(hInst, MAKEINTRESOURCE(IDB_SPLASH), IMAGE_BITMAP, 0, 0, 0)); + if (hSplashBitmap) + { + CreateThread(NULL, 0, SplashScreenThread, hSplashBitmap, 0, NULL); + } if (!LocateJVM()) return 1; if (!LoadVMOptions()) return 1; diff --git a/native/WinLauncher/WinLauncher/WinLauncher.rc b/native/WinLauncher/WinLauncher/WinLauncher.rc index ea3440de34f7..d41e1456d74c 100644 Binary files a/native/WinLauncher/WinLauncher/WinLauncher.rc and b/native/WinLauncher/WinLauncher/WinLauncher.rc differ diff --git a/native/WinLauncher/WinLauncher/WinLauncher.vcxproj b/native/WinLauncher/WinLauncher/WinLauncher.vcxproj index e23d5c067976..754af7b729bd 100644 --- a/native/WinLauncher/WinLauncher/WinLauncher.vcxproj +++ b/native/WinLauncher/WinLauncher/WinLauncher.vcxproj @@ -137,6 +137,7 @@ + diff --git a/native/WinLauncher/WinLauncher/WinLauncher.vcxproj.filters b/native/WinLauncher/WinLauncher/WinLauncher.vcxproj.filters index ff46c65935f1..d86e9e9e1ce7 100644 --- a/native/WinLauncher/WinLauncher/WinLauncher.vcxproj.filters +++ b/native/WinLauncher/WinLauncher/WinLauncher.vcxproj.filters @@ -22,6 +22,9 @@ Resource Files + + Resource Files + diff --git a/native/WinLauncher/WinLauncher/resource.h b/native/WinLauncher/WinLauncher/resource.h index d7119bbbfc00..4e4a0057ec1a 100644 Binary files a/native/WinLauncher/WinLauncher/resource.h and b/native/WinLauncher/WinLauncher/resource.h differ diff --git a/native/WinLauncher/WinLauncher/splash.bmp b/native/WinLauncher/WinLauncher/splash.bmp new file mode 100644 index 000000000000..6a69474cf99b Binary files /dev/null and b/native/WinLauncher/WinLauncher/splash.bmp differ