From 2e8e6df7a21d7e33619cf375970ad84af412a786 Mon Sep 17 00:00:00 2001 From: LoRd_MuldeR Date: Sat, 26 Sep 2020 18:51:42 +0200 Subject: [PATCH] Added support for splash screen. --- LICENSE.txt | 133 ++++------------------------ res/launcher.ico | Bin 0 -> 25214 bytes res/resources.rc | 20 +++++ res/splash_screen.bmp | Bin 0 -> 49078 bytes src/main.c | 199 ++++++++++++++++++++++++++++++++++++------ src/resource.h | 18 ++++ 6 files changed, 226 insertions(+), 144 deletions(-) create mode 100644 res/launcher.ico create mode 100644 res/resources.rc create mode 100644 res/splash_screen.bmp create mode 100644 src/resource.h diff --git a/LICENSE.txt b/LICENSE.txt index 0e259d4..3f56a63 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,121 +1,18 @@ -Creative Commons Legal Code +Copyright 2020 LoRd_MuldeR -CC0 1.0 Universal +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: - CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE - LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN - ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS - INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES - REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS - PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM - THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED - HEREUNDER. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. -Statement of Purpose - -The laws of most jurisdictions throughout the world automatically confer -exclusive Copyright and Related Rights (defined below) upon the creator -and subsequent owner(s) (each and all, an "owner") of an original work of -authorship and/or a database (each, a "Work"). - -Certain owners wish to permanently relinquish those rights to a Work for -the purpose of contributing to a commons of creative, cultural and -scientific works ("Commons") that the public can reliably and without fear -of later claims of infringement build upon, modify, incorporate in other -works, reuse and redistribute as freely as possible in any form whatsoever -and for any purposes, including without limitation commercial purposes. -These owners may contribute to the Commons to promote the ideal of a free -culture and the further production of creative, cultural and scientific -works, or to gain reputation or greater distribution for their Work in -part through the use and efforts of others. - -For these and/or other purposes and motivations, and without any -expectation of additional consideration or compensation, the person -associating CC0 with a Work (the "Affirmer"), to the extent that he or she -is an owner of Copyright and Related Rights in the Work, voluntarily -elects to apply CC0 to the Work and publicly distribute the Work under its -terms, with knowledge of his or her Copyright and Related Rights in the -Work and the meaning and intended legal effect of CC0 on those rights. - -1. Copyright and Related Rights. A Work made available under CC0 may be -protected by copyright and related or neighboring rights ("Copyright and -Related Rights"). Copyright and Related Rights include, but are not -limited to, the following: - - i. the right to reproduce, adapt, distribute, perform, display, - communicate, and translate a Work; - ii. moral rights retained by the original author(s) and/or performer(s); -iii. publicity and privacy rights pertaining to a person's image or - likeness depicted in a Work; - iv. rights protecting against unfair competition in regards to a Work, - subject to the limitations in paragraph 4(a), below; - v. rights protecting the extraction, dissemination, use and reuse of data - in a Work; - vi. database rights (such as those arising under Directive 96/9/EC of the - European Parliament and of the Council of 11 March 1996 on the legal - protection of databases, and under any national implementation - thereof, including any amended or successor version of such - directive); and -vii. other similar, equivalent or corresponding rights throughout the - world based on applicable law or treaty, and any national - implementations thereof. - -2. Waiver. To the greatest extent permitted by, but not in contravention -of, applicable law, Affirmer hereby overtly, fully, permanently, -irrevocably and unconditionally waives, abandons, and surrenders all of -Affirmer's Copyright and Related Rights and associated claims and causes -of action, whether now known or unknown (including existing as well as -future claims and causes of action), in the Work (i) in all territories -worldwide, (ii) for the maximum duration provided by applicable law or -treaty (including future time extensions), (iii) in any current or future -medium and for any number of copies, and (iv) for any purpose whatsoever, -including without limitation commercial, advertising or promotional -purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each -member of the public at large and to the detriment of Affirmer's heirs and -successors, fully intending that such Waiver shall not be subject to -revocation, rescission, cancellation, termination, or any other legal or -equitable action to disrupt the quiet enjoyment of the Work by the public -as contemplated by Affirmer's express Statement of Purpose. - -3. Public License Fallback. Should any part of the Waiver for any reason -be judged legally invalid or ineffective under applicable law, then the -Waiver shall be preserved to the maximum extent permitted taking into -account Affirmer's express Statement of Purpose. In addition, to the -extent the Waiver is so judged Affirmer hereby grants to each affected -person a royalty-free, non transferable, non sublicensable, non exclusive, -irrevocable and unconditional license to exercise Affirmer's Copyright and -Related Rights in the Work (i) in all territories worldwide, (ii) for the -maximum duration provided by applicable law or treaty (including future -time extensions), (iii) in any current or future medium and for any number -of copies, and (iv) for any purpose whatsoever, including without -limitation commercial, advertising or promotional purposes (the -"License"). The License shall be deemed effective as of the date CC0 was -applied by Affirmer to the Work. Should any part of the License for any -reason be judged legally invalid or ineffective under applicable law, such -partial invalidity or ineffectiveness shall not invalidate the remainder -of the License, and in such case Affirmer hereby affirms that he or she -will not (i) exercise any of his or her remaining Copyright and Related -Rights in the Work or (ii) assert any associated claims and causes of -action with respect to the Work, in either case contrary to Affirmer's -express Statement of Purpose. - -4. Limitations and Disclaimers. - - a. No trademark or patent rights held by Affirmer are waived, abandoned, - surrendered, licensed or otherwise affected by this document. - b. Affirmer offers the Work as-is and makes no representations or - warranties of any kind concerning the Work, express, implied, - statutory or otherwise, including without limitation warranties of - title, merchantability, fitness for a particular purpose, non - infringement, or the absence of latent or other defects, accuracy, or - the present or absence of errors, whether or not discoverable, all to - the greatest extent permissible under applicable law. - c. Affirmer disclaims responsibility for clearing rights of other persons - that may apply to the Work or any use thereof, including without - limitation any person's Copyright and Related Rights in the Work. - Further, Affirmer disclaims responsibility for obtaining any necessary - consents, permissions or other rights required for any use of the - Work. - d. Affirmer understands and acknowledges that Creative Commons is not a - party to this document and has no duty or obligation with respect to - this CC0 or use of the Work. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/res/launcher.ico b/res/launcher.ico new file mode 100644 index 0000000000000000000000000000000000000000..8d2c9571ed9e536a5fc46e043731b65759b928f8 GIT binary patch literal 25214 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 z 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 */ +/* Java JAR wrapper for creating Windows native executables */ +/* https://github.com/lordmulder/ */ +/* */ +/* This work has been released under the MIT license. */ +/* Please see LICENSE.TXT for details! */ +/* */ +/* ACKNOWLEDGEMENT */ +/* This project is partly inspired by the Launch4j project: */ +/* https://sourceforge.net/p/launch4j/ */ +/************************************************************/ + +#include "../src/resource.h" + +// ICON +ID_APP_ICON ICON "launcher.ico" + +// BITMAP +ID_SPLASH_BITMAP BITMAP "splash_screen.bmp" diff --git a/res/splash_screen.bmp b/res/splash_screen.bmp new file mode 100644 index 0000000000000000000000000000000000000000..51301f9402726f7811d57e5e14cac04102695db2 GIT binary patch literal 49078 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 */ +/* Java JAR wrapper for creating Windows native executables */ +/* https://github.com/lordmulder/ */ +/* */ +/* This work has been released under the MIT license. */ +/* Please see LICENSE.TXT for details! */ +/* */ +/* ACKNOWLEDGEMENT */ +/* This project is partly inspired by the Launch4j project: */ +/* https://sourceforge.net/p/launch4j/ */ +/************************************************************/ + +#define WIN32_LEAN_AND_MEAN 1 + +#include #include #include #include #include #include #include +#include "resource.h" -#define WIN32_LEAN_AND_MEAN 1 -#include - +// Const +static const DWORD SPLASH_SCREEN_TIMEOUT = 30U; static const wchar_t *const JRE_RELATIVE_PATH = L"runtime\\bin\\javaw.exe"; +// Options +#define ENABLE_SPLASH 1 +#define WAIT_FOR_INPUT_IDLE 1 +//#define JAR_FILE_WRAPPED 1 + /* ======================================================================== */ /* String routines */ /* ======================================================================== */ @@ -156,6 +177,7 @@ static const wchar_t *get_executable_directory(const wchar_t *const executable_p static const wchar_t *get_jarfile_path(const wchar_t *const executable_path, const wchar_t *const executable_directory) { +#ifndef JAR_FILE_WRAPPED const wchar_t *jarfile_path = NULL; const wchar_t *const path_prefix = remove_file_extension(executable_path); @@ -175,6 +197,9 @@ static const wchar_t *get_jarfile_path(const wchar_t *const executable_path, con free((void*)path_prefix); return jarfile_path; +#else + return wcsdup(executable_path); /*JAR file is wrapped*/ +#endif } /* ======================================================================== */ @@ -201,6 +226,49 @@ static const BOOL set_current_directory(const wchar_t *const path) } } +/* ======================================================================== */ +/* Splash screen */ +/* ======================================================================== */ + +static BOOL create_splash_screen(const HWND hwnd, const HANDLE splash_image) +{ + if (hwnd && splash_image) + { + RECT rect; + SendMessageW(hwnd, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM) splash_image); + GetWindowRect(hwnd, &rect); + const int x = (GetSystemMetrics(SM_CXSCREEN) - (rect.right - rect.left)) / 2; + const int y = (GetSystemMetrics(SM_CYSCREEN) - (rect.bottom - rect.top)) / 2; + SetWindowPos(hwnd, HWND_TOP, x, y, 0, 0, SWP_NOSIZE); + ShowWindow(hwnd, SW_SHOW); + return UpdateWindow(hwnd); + } + return FALSE; +} + +static BOOL process_window_messages(const HWND hwnd) +{ + BOOL result = FALSE; + if (hwnd != NULL) + { + MSG msg = {}; + for (DWORD k = 0U; k < MAXWORD; ++k) + { + if (PeekMessageW(&msg, hwnd, 0U, 0U, PM_REMOVE)) + { + result = TRUE; + TranslateMessage(&msg); + DispatchMessageW(&msg); + } + else + { + break; /*no more messages!*/ + } + } + } + return result; +} + /* ======================================================================== */ /* Message box */ /* ======================================================================== */ @@ -236,32 +304,79 @@ while(0) } \ while(0) +/* ======================================================================== */ +/* Utilities */ +/* ======================================================================== */ + +static void close_handle(HANDLE *const handle) +{ + if(*handle) + { + CloseHandle(*handle); + *handle = NULL; + } +} + +static void delete_object(HGDIOBJ *const handle) +{ + if(*handle) + { + DeleteObject(*handle); + *handle = NULL; + } +} + +static void destroy_window(HWND *const hwnd) +{ + if(*hwnd) + { + DestroyWindow(*hwnd); + *hwnd = NULL; + } +} + /* ======================================================================== */ /* MAIN */ /* ======================================================================== */ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow) { - int exit_code = -1; + int result = -1; const wchar_t *executable_path = NULL, *executable_directory = NULL, *jarfile_path = NULL, *java_runtime_path = NULL, *command_line = NULL; - STARTUPINFOW startup_info; + HGDIOBJ splash_image = NULL; + DWORD exit_code = 0U; PROCESS_INFORMATION process_info; + STARTUPINFOW startup_info; // Initialize SecureZeroMemory(&startup_info, sizeof(STARTUPINFOW)); SecureZeroMemory(&process_info, sizeof(PROCESS_INFORMATION)); + // Create the window + HWND hwnd = CreateWindowExW(WS_EX_TOOLWINDOW | WS_EX_TOPMOST, L"STATIC", L"", WS_POPUP | SS_BITMAP, 0, 0, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); + + // Show the splash screen +#ifdef ENABLE_SPLASH + if(splash_image = LoadImage(hInstance, MAKEINTRESOURCE(ID_SPLASH_BITMAP), IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE)) + { + if(create_splash_screen(hwnd, splash_image)) + { + process_window_messages(hwnd); + } + } +#endif + // Find executable path if(!(executable_path = get_executable_path())) { - show_message(NULL, MB_ICONERROR | MB_SYSTEMMODAL, L"System Error", L"The path of the executable could not be determined!"); + show_message(hwnd, MB_ICONERROR | MB_TOPMOST, L"System Error", L"The path of the executable could not be determined!"); goto cleanup; } // Find executable directory if(!(executable_directory = get_executable_directory(executable_path))) { - show_message(NULL, MB_ICONERROR | MB_SYSTEMMODAL, L"System Error", L"The executable directory could not be determined!"); + show_message(hwnd, MB_ICONERROR | MB_TOPMOST, L"System Error", L"The executable directory could not be determined!"); goto cleanup; } @@ -274,28 +389,30 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine // Find the JAR file path if(!(jarfile_path = get_jarfile_path(executable_path, executable_directory))) { - show_message(NULL, MB_ICONERROR | MB_SYSTEMMODAL, L"System Error", L"The path of the JAR file could not be determined!"); + show_message(hwnd, MB_ICONERROR | MB_TOPMOST, L"System Error", L"The path of the JAR file could not be determined!"); goto cleanup; } - // Find the Java runtime path + // Find the Java runtime executable path if(!(java_runtime_path = awprintf(L"%ls\\%ls", executable_directory, JRE_RELATIVE_PATH))) { - show_message(NULL, MB_ICONERROR | MB_SYSTEMMODAL, L"System Error", L"The path of the Java runtime could not be determined!"); + show_message(hwnd, MB_ICONERROR | MB_TOPMOST, L"System Error", L"The path of the Java runtime could not be determined!"); goto cleanup; } - // Does JAR file exist? + // Does the JAR file exist? +#ifndef JAR_FILE_WRAPPED if(!file_exists(jarfile_path)) { - show_message_format(NULL, MB_ICONERROR | MB_SYSTEMMODAL, L"JAR not found", L"The required JAR file could not be found:\n\n%ls\n\n\nRe-installing the application may fix the problem!", jarfile_path); + show_message_format(hwnd, MB_ICONERROR | MB_TOPMOST, L"JAR not found", L"The required JAR file could not be found:\n\n%ls\n\n\nRe-installing the application may fix the problem!", jarfile_path); goto cleanup; } +#endif - // Does the Java runtime exist? + // Does the Java runtime executable exist? if(!file_exists(java_runtime_path)) { - show_message_format(NULL, MB_ICONERROR | MB_SYSTEMMODAL, L"Java not found", L"The required Java runtime could not be found:\n\n%ls\n\n\nRe-installing the application may fix the problem!", java_runtime_path); + show_message_format(hwnd, MB_ICONERROR | MB_TOPMOST, L"Java not found", L"The required Java runtime could not be found:\n\n%ls\n\n\nRe-installing the application may fix the problem!", java_runtime_path); goto cleanup; } @@ -303,37 +420,67 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine command_line = NOT_EMPTY(pCmdLine) ? awprintf(L"\"%ls\" -jar \"%ls\" %ls", java_runtime_path, jarfile_path, pCmdLine) : awprintf(L"\"%ls\" -jar \"%ls\"", java_runtime_path, jarfile_path); if(!command_line) { - show_message(NULL, MB_ICONERROR | MB_SYSTEMMODAL, L"System Error", L"The Java command-line could not be generated!"); + show_message(hwnd, MB_ICONERROR | MB_TOPMOST, L"System Error", L"The Java command-line could not be generated!"); goto cleanup; } + // Process pending window messages +#ifdef ENABLE_SPLASH + process_window_messages(hwnd); +#endif + // Now actually start the process! if(!CreateProcessW(NULL, (LPWSTR)command_line, NULL, NULL, FALSE, 0U, NULL, executable_directory, &startup_info, &process_info)) { const wchar_t *const error_text = describe_system_error(GetLastError()); if(error_text) { - show_message_format(NULL, MB_ICONERROR | MB_SYSTEMMODAL, L"System Error", L"Failed to create the Java process:\n\n%ls\n\n\n%ls", command_line, error_text); + show_message_format(hwnd, MB_ICONERROR | MB_TOPMOST, L"System Error", L"Failed to create the Java process:\n\n%ls\n\n\n%ls", command_line, error_text); free((void*)error_text); } else { - show_message_format(NULL, MB_ICONERROR | MB_SYSTEMMODAL, L"System Error", L"Failed to create the Java process:\n\n%ls", command_line); + show_message_format(hwnd, MB_ICONERROR | MB_TOPMOST, L"System Error", L"Failed to create the Java process:\n\n%ls", command_line); } goto cleanup; } + // Process pending window messages +#ifdef ENABLE_SPLASH + process_window_messages(hwnd); +#ifdef WAIT_FOR_INPUT_IDLE + for (DWORD t = 0U; t < SPLASH_SCREEN_TIMEOUT; ++t) + { + if (WaitForInputIdle(process_info.hProcess, 1000U) != WAIT_TIMEOUT) + { + break; /*child-process is ready!*/ + } + if (WaitForSingleObject(process_info.hProcess, 1U) != WAIT_TIMEOUT) + { + break; /*child process terminated!*/ + } + process_window_messages(hwnd); + } +#endif + destroy_window(&hwnd); +#endif + + // Wait for process to exit + WaitForSingleObject(process_info.hProcess, INFINITE); + + // Get the exit code + if(GetExitCodeProcess(process_info.hProcess, &exit_code)) + { + result = (int) exit_code; + } + cleanup: - if(process_info.hThread) - { - CloseHandle(process_info.hThread); - } + close_handle(&process_info.hThread); + close_handle(&process_info.hProcess); - if(process_info.hProcess) - { - CloseHandle(process_info.hProcess); - } + destroy_window(&hwnd); + delete_object(splash_image); free((void*)command_line); free((void*)java_runtime_path); @@ -341,5 +488,5 @@ cleanup: free((void*)executable_directory); free((void*)executable_path); - return exit_code; + return result; } diff --git a/src/resource.h b/src/resource.h new file mode 100644 index 0000000..e6eec6c --- /dev/null +++ b/src/resource.h @@ -0,0 +1,18 @@ +/************************************************************/ +/* Launch5j, by LoRd_MuldeR */ +/* Java JAR wrapper for creating Windows native executables */ +/* https://github.com/lordmulder/ */ +/* */ +/* This work has been released under the MIT license. */ +/* Please see LICENSE.TXT for details! */ +/* */ +/* ACKNOWLEDGEMENT */ +/* This project is partly inspired by the Launch4j project: */ +/* https://sourceforge.net/p/launch4j/ */ +/************************************************************/ + +// ICON +#define ID_APP_ICON 1 + +// BITMAP +#define ID_SPLASH_BITMAP 1