156 lines
4.6 KiB
C
156 lines
4.6 KiB
C
![]() |
/*
|
||
|
|
||
|
launch4j :: Cross-platform Java application wrapper for creating Windows native executables
|
||
|
Copyright (C) 2004-2005 Grzegorz Kowal
|
||
|
|
||
|
Compiled with Mingw port of GCC, Bloodshed Dev-C++ IDE (http://www.bloodshed.net/devcpp.html)
|
||
|
|
||
|
This library is free software; you can redistribute it and/or
|
||
|
modify it under the terms of the GNU Lesser General Public
|
||
|
License as published by the Free Software Foundation; either
|
||
|
version 2.1 of the License, or (at your option) any later version.
|
||
|
|
||
|
This library is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
Lesser General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU Lesser General Public
|
||
|
License along with this library; if not, write to the Free Software
|
||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||
|
|
||
|
*/
|
||
|
|
||
|
#include "../resource.h"
|
||
|
#include "../head.h"
|
||
|
#include "guihead.h"
|
||
|
|
||
|
extern PROCESS_INFORMATION pi;
|
||
|
|
||
|
HWND hWnd;
|
||
|
DWORD dwExitCode = 0;
|
||
|
BOOL stayAlive = FALSE;
|
||
|
BOOL splash = FALSE;
|
||
|
BOOL splashTimeoutErr;
|
||
|
BOOL waitForWindow;
|
||
|
int splashTimeout; // tick count (s)
|
||
|
|
||
|
int APIENTRY WinMain(HINSTANCE hInstance,
|
||
|
HINSTANCE hPrevInstance,
|
||
|
LPSTR lpCmdLine,
|
||
|
int nCmdShow) {
|
||
|
HMODULE hLibrary = NULL;
|
||
|
if (!prepare(hLibrary, lpCmdLine)) {
|
||
|
if (hLibrary != NULL) {
|
||
|
FreeLibrary(hLibrary);
|
||
|
}
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
splash = loadBoolString(hLibrary, SHOW_SPLASH);
|
||
|
stayAlive = loadBoolString(hLibrary, GUI_HEADER_STAYS_ALIVE);
|
||
|
if (splash || stayAlive) {
|
||
|
hWnd = CreateWindowEx(WS_EX_TOOLWINDOW, "STATIC", "",
|
||
|
WS_POPUP | SS_BITMAP,
|
||
|
0, 0, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
|
||
|
if (splash) {
|
||
|
char timeout[10] = "";
|
||
|
if (!loadString(hLibrary, SPLASH_TIMEOUT, timeout)) {
|
||
|
msgBox("Cannot load splash timeout property.");
|
||
|
return 1;
|
||
|
}
|
||
|
splashTimeout = atoi(timeout);
|
||
|
if (splashTimeout <= 0 || splashTimeout > 60 * 15 /* 15 minutes */) {
|
||
|
msgBox("Invalid splash timeout property.");
|
||
|
return 1;
|
||
|
}
|
||
|
splashTimeoutErr = loadBoolString(hLibrary, SPLASH_TIMEOUT_ERR);
|
||
|
waitForWindow = loadBoolString(hLibrary, SPLASH_WAITS_FOR_WINDOW);
|
||
|
HANDLE hImage = LoadImage(hInstance, // handle of the instance containing the image
|
||
|
MAKEINTRESOURCE(SPLASH_BITMAP), // name or identifier of image
|
||
|
IMAGE_BITMAP, // type of image
|
||
|
0, // desired width
|
||
|
0, // desired height
|
||
|
LR_DEFAULTSIZE);
|
||
|
if (hImage == NULL) {
|
||
|
msgBox("Cannot load splash screen.");
|
||
|
return 1;
|
||
|
}
|
||
|
SendMessage(hWnd, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM) hImage);
|
||
|
RECT rect;
|
||
|
GetWindowRect(hWnd, &rect);
|
||
|
int x = (GetSystemMetrics(SM_CXSCREEN) - (rect.right - rect.left)) / 2;
|
||
|
int y = (GetSystemMetrics(SM_CYSCREEN) - (rect.bottom - rect.top)) / 2;
|
||
|
SetWindowPos(hWnd, HWND_TOP, x, y, 0, 0, SWP_NOSIZE);
|
||
|
ShowWindow(hWnd, nCmdShow);
|
||
|
UpdateWindow (hWnd);
|
||
|
}
|
||
|
if (!SetTimer (hWnd, ID_TIMER, 1000 /* 1s */, TimerProc)) {
|
||
|
return 1;
|
||
|
}
|
||
|
}
|
||
|
FreeLibrary(hLibrary);
|
||
|
if (execute(FALSE) == -1) {
|
||
|
char errMsg[BIG_STR] = "Error occured while starting the application...\n";
|
||
|
strcat(errMsg, strerror(errno));
|
||
|
msgBox(errMsg);
|
||
|
return 1;
|
||
|
}
|
||
|
if (!(splash || stayAlive)) {
|
||
|
closeHandles();
|
||
|
return 0;
|
||
|
}
|
||
|
MSG msg;
|
||
|
while (GetMessage(&msg, NULL, 0, 0)) {
|
||
|
TranslateMessage(&msg);
|
||
|
DispatchMessage(&msg);
|
||
|
}
|
||
|
closeHandles();
|
||
|
return dwExitCode;
|
||
|
}
|
||
|
|
||
|
BOOL CALLBACK enumwndfn(HWND hwnd, LPARAM lParam) {
|
||
|
DWORD processId;
|
||
|
GetWindowThreadProcessId(hwnd, &processId);
|
||
|
if (pi.dwProcessId == processId) {
|
||
|
LONG styles = GetWindowLong(hwnd, GWL_STYLE);
|
||
|
if ((styles & WS_VISIBLE) != 0) {
|
||
|
splash = FALSE;
|
||
|
ShowWindow(hWnd, SW_HIDE);
|
||
|
return FALSE;
|
||
|
}
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
VOID CALLBACK TimerProc(
|
||
|
HWND hwnd, // handle of window for timer messages
|
||
|
UINT uMsg, // WM_TIMER message
|
||
|
UINT idEvent, // timer identifier
|
||
|
DWORD dwTime) { // current system time
|
||
|
|
||
|
if (splash) {
|
||
|
if (splashTimeout == 0) {
|
||
|
splash = FALSE;
|
||
|
ShowWindow(hWnd, SW_HIDE);
|
||
|
if (waitForWindow && splashTimeoutErr) {
|
||
|
KillTimer(hwnd, ID_TIMER);
|
||
|
msgBox("Could not start the application, operation timed out.");
|
||
|
PostQuitMessage(0);
|
||
|
}
|
||
|
} else {
|
||
|
splashTimeout--;
|
||
|
if (waitForWindow) {
|
||
|
EnumWindows(enumwndfn, 0);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
GetExitCodeProcess(pi.hProcess, &dwExitCode);
|
||
|
if (dwExitCode != STILL_ACTIVE
|
||
|
|| !(splash || stayAlive)) {
|
||
|
KillTimer(hWnd, ID_TIMER);
|
||
|
PostQuitMessage(0);
|
||
|
return;
|
||
|
}
|
||
|
}
|