source: release-kits/shared/windows/wrapper/wrapper.cpp@ 17961

Last change on this file since 17961 was 17961, checked in by oranfry, 15 years ago

change to splash screen and added greenstone wiki link file

File size: 10.8 KB
RevLine 
[15023]1#include <windows.h>
2
3#include <fstream>
4#include <iostream>
[15095]5#include <conio.h>
6#include <string>
7#include <time.h>
[15689]8#include <shellapi.h>
9#include <direct.h>
10#include "libsearch4j.h"
[15023]11
12using namespace std;
13
[15689]14//globals
15HBITMAP g_splash = NULL; //the main splash bitmap
[16079]16HFONT g_hfFont = NULL; //the main splash bitmap
[15689]17char step[10] = "TMP"; //the current step
18char progress[4] = "0"; //progress in the current step
19HWND splashWnd;
20HINSTANCE mainInstance;
21int mainCmdShow;
22bool window_loaded = false;
[15023]23
[15689]24void set_splash_step( char* new_step ) {
25 strcpy( step, new_step );
26 InvalidateRect(splashWnd, NULL, FALSE);
27 UpdateWindow(splashWnd);
[15023]28}
29
[15689]30void set_splash_progress( int percent_progress ) {
31 percent_progress = ( percent_progress / 10 ) * 10;
32 char p[4] = {0};
33 strcpy( progress, itoa( percent_progress, p, 10 ) );
34 InvalidateRect(splashWnd, NULL, FALSE);
35 //RedrawWindow(splashWnd, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_ERASENOW | RDW_UPDATENOW | RDW_INTERNALPAINT);
36 UpdateWindow(splashWnd);
37}
[15023]38
[15689]39void spoof_progress( int interval ) {
40 int tenPercentWait = interval / 11;
41 for ( int i=0; i <= 100; i+=10 ) {
42 set_splash_progress( i );
43 Sleep( tenPercentWait );
44 }
45}
46
47//extracts a resource in chunks
[16079]48int extractResource( const char * basename, const char * type, char * file ) {
[15689]49
[15023]50 HMODULE hModule = GetModuleHandle(NULL);
[15689]51 set_splash_progress( 0 );
[15023]52
[16079]53 int no_chunks;
54 bool chunk_available = true;
55 for ( no_chunks = 0; chunk_available; no_chunks++ ) {
[15023]56
[15689]57 //construct the chunk name
58 char chunkname[127] = {0};
59 strcpy( chunkname, basename );
60 strcat( chunkname, "_" );
61 char chunknum[5] = {0};
[16079]62 itoa( no_chunks+1, chunknum, 10 );
63 strcat( chunkname, chunknum );
64
65 if ( FindResource(hModule, chunkname, type) == NULL ) {
66 chunk_available = false;
[17071]67 break;
[16079]68 }
69 }
70
[17307]71 if ( no_chunks == 0 ) {
72 return 1;
73 }
74
[16079]75 for ( int i=0; i<no_chunks; i++ ) {
76
77 //construct the chunk name
78 char chunkname[127] = {0};
79 strcpy( chunkname, basename );
80 strcat( chunkname, "_" );
81 char chunknum[5] = {0};
[15689]82 itoa( i+1, chunknum, 10 );
83 strcat( chunkname, chunknum );
84
[16079]85 //find it
[15689]86 HRSRC hRsrc = FindResource(hModule, chunkname, type);
[16079]87 if (hRsrc == NULL ) return 1; //couldn't find the chunk
[15689]88
89 //load it
90 HGLOBAL hGlobal = LoadResource(hModule, hRsrc);
91 if (hGlobal == NULL) return 1; //couldn't lock
[16079]92
93 //lock it
[15689]94 BYTE* pBytes = (BYTE*) LockResource(hGlobal);
95 if (pBytes == NULL) return 1; //couldn't lock
96
97 //put it on disk
98 DWORD dwLength = SizeofResource(hModule, hRsrc);
99 ofstream fStream(file, ios::binary | ios::out | ios::app );
100 fStream.write((char*) pBytes, dwLength);
101 fStream.close();
102
103 //unload
104 UnlockResource(hGlobal);
105 FreeResource(hGlobal);
106
107 //update the progress
108 set_splash_progress( i * 100 / no_chunks );
109
110 }
[15023]111
112 return 0;
113
114}
115
[15689]116//the splash window procedure
117LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
118 switch(msg) {
119
120 case WM_CREATE: {
121 //load in the reusable resources
122 g_splash = LoadBitmap(GetModuleHandle(NULL),"SPLASH");
[16079]123 g_hfFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
[15689]124 if(g_splash == NULL) {
125 MessageBox(hwnd, "Could not load splash bitmap!", "Error", MB_OK | MB_ICONEXCLAMATION);
126 }
127
128 //center the window automatically
129 RECT rect;
130 GetWindowRect(hwnd, &rect);
131 int x = (GetSystemMetrics(SM_CXSCREEN) - (rect.right - rect.left)) / 2;
132 int y = (GetSystemMetrics(SM_CYSCREEN) - (rect.bottom - rect.top)) / 2;
133 SetWindowPos(hwnd, HWND_TOP, x, y, 0, 0, SWP_NOSIZE);
134 }
135
136 case WM_PAINT: {
137 // Don't use MessageBox from inside WM_PAINT
138
139 //load in the correct resources
140 HBITMAP g_progress = NULL;
141 HBITMAP g_step = NULL;
142 char progress_res[20] = "PROGRESS_";
143 strcat( progress_res, progress );
144 char step_res[20] = "STEP_";
145 strcat( step_res, step );
146 g_progress = LoadBitmap(GetModuleHandle(NULL), progress_res );
147 g_step = LoadBitmap(GetModuleHandle(NULL), step_res );
148 if( g_progress == NULL || g_step == NULL ) {
149 MessageBox(hwnd, "Could not load an image!", "Error", MB_OK | MB_ICONEXCLAMATION);
150 }
151
152 BITMAP bm; //holds info about the width and height
153 PAINTSTRUCT ps;
154
155 HDC hdc = BeginPaint(hwnd, &ps);
156 HDC hdcMem = CreateCompatibleDC(hdc);
157
158 //paint the main splash screen
159 GetObject(g_splash, sizeof(bm), &bm);
160 HBITMAP hbmOld = (HBITMAP)SelectObject(hdcMem, g_splash);
161 BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);
162
163 //paint in the progress
164 GetObject(g_progress, sizeof(bm), &bm);
165 SelectObject(hdcMem, g_progress);
[17961]166 BitBlt(hdc, 0, 276, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);
[15689]167
168 //paint in the step with transparency
169 GetObject(g_step, sizeof(bm), &bm);
170 SelectObject(hdcMem, g_step);
171 BitBlt(hdc, 0, 276, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCPAINT);
172
[16079]173 //print the step with text
174 RECT rcClient;
175 GetClientRect(hwnd, &rcClient);
176 //DrawText(hdc, "This is the step", -1, &rcClient, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
177
[15689]178 //restore the hdc
179 SelectObject(hdcMem, hbmOld);
180
181 //release resources
182 DeleteDC(hdcMem);
183 EndPaint(hwnd, &ps);
184 DeleteObject(g_progress);
185 DeleteObject(g_step);
186
187 }
188 break;
189
[15813]190 /*
[15689]191 case WM_LBUTTONDOWN: {
192 DeleteObject(g_splash);
193 PostQuitMessage(0);
194 }
195 break;
[15813]196 */
[15689]197
198 case WM_CLOSE:
199 DestroyWindow(hwnd);
200 break;
201
202 case WM_DESTROY:
203 DeleteObject(g_splash);
204 PostQuitMessage(0);
205 break;
206
207 default:
208 return DefWindowProc(hwnd, msg, wParam, lParam);
209 }
210
211 return 0;
212
[15095]213}
214
[15689]215//function to process the window
216DWORD WINAPI ProcessWindow( LPVOID lpParam ) {
217
218 const char g_szClassName[] = "splash";
219 WNDCLASSEX wc;
220 MSG Msg;
[15095]221
[15689]222 //Step 1: Registering the Window Class
223 wc.cbSize = sizeof(WNDCLASSEX);
224 wc.style = 0;
225 wc.lpfnWndProc = WndProc;
226 wc.cbClsExtra = 0;
227 wc.cbWndExtra = 0;
228 wc.hInstance = mainInstance;
229 wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
230 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
231 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
232 wc.lpszMenuName = NULL;
233 wc.lpszClassName = g_szClassName;
234 wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
235 if(!RegisterClassEx(&wc)) {
236 MessageBox(NULL, "Window Registration Failed!", "Error!",
237 MB_ICONEXCLAMATION | MB_OK);
238 return 0;
239 }
[15095]240
[15689]241 // Step 2: Creating the Window
242 splashWnd = CreateWindowEx( WS_EX_TOOLWINDOW, g_szClassName, "", WS_POPUP | SS_BITMAP, 0, 0, 420, 300, NULL, NULL, mainInstance, NULL);
243 if( splashWnd == NULL ) {
244 MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
245 return 0;
246 }
247 ShowWindow(splashWnd, mainCmdShow);
248 UpdateWindow(splashWnd);
249
250 window_loaded = true;
[15023]251
[15689]252 // Step 3: The Message Loop
253 while(GetMessage(&Msg, NULL, 0, 0) > 0) {
254 TranslateMessage(&Msg);
255 DispatchMessage(&Msg);
256 }
257 return 0;
258}
259
260int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
[15023]261
[15689]262 const int SPOOF_TIME = 1000;
263 string command;
264 srand( time(0) );
265 mainInstance = hInstance;
266 mainCmdShow = nCmdShow;
[15095]267
[15689]268 //start the window
269 HANDLE hThread;
270 DWORD dwThreadId, dwThrdParam = 1;
271 hThread = CreateThread(
272 NULL, // no security attributes
273 0, // use default stack size
274 ProcessWindow, // thread function
275 &dwThrdParam, // argument to thread function
276 0, // use default creation flags
277 &dwThreadId); // returns the thread identifier
278 if ( hThread == NULL ) {
279 return -1;
280 //ErrorExit( "CreateThread failed." );
281 }
282 CloseHandle( hThread );
283
284 while ( !window_loaded ) {
285 Sleep( 100 );
286 }
287
288 //create the temp folder and change to it
289 set_splash_step( "TMP" );
290 spoof_progress( SPOOF_TIME );
[17905]291
292 // Now we are generating temporary files in a folder inside the current directory,
293 // instead of creating this folder in the system Temp directory(referenced by TMP)
294 // And we make this folder hidden
295 char* tmp = NULL; //char* tmp = getenv( "TMP" );
296 tmp = _getcwd(tmp, 1000);
[15689]297 char id[6]; for( int i=0; i<5; i++ ) id[i] = (char)((rand()%26) + 97); id[5] = '\0'; //id for this instance
[16203]298 string tempdir = ""; tempdir.append( tmp ); tempdir.append( "\\Greenstone-" ); tempdir.append( id );
[17905]299 const char* tmpdir = tempdir.c_str();
300 _mkdir( tmpdir );
301 SetFileAttributes(tmpdir, FILE_ATTRIBUTE_HIDDEN);
302 SetCurrentDirectory(tmpdir);
303 delete tmp; // deallocate memory
[17271]304
305 //rip out java archive if it is bundled
306 set_splash_step( "XJAVA" );
[17307]307 int javaIsBundled = (extractResource( "JAVA", "EXE", "@java.installer@" ) == 0);
[17271]308 if ( javaIsBundled ) {
[17342]309 process( "@java.installer@", false );
[17271]310 }
311
[15689]312 //find java
313 set_splash_step( "SEARCHING" );
314 spoof_progress( SPOOF_TIME );
315 bool use_minimum = true;
316 Jvm minimum;
317 minimum.setVersionFromString( "@java.min.version@" );
[17307]318 string phint = "@java.extracted@";
319 string hint = "";
[15689]320 bool verbose = true;
321 Jvm foundJvm;
[17307]322 bool jvmFound = find( foundJvm, use_minimum, minimum, phint, hint, verbose );
[15689]323
[15095]324 //if the jvm was not found, try to fix it and find it
325 if ( !jvmFound ) {
[15689]326
[15095]327 //did not find a good java
[16203]328 string message = "This version of Greenstone requires java @java.min.version@ or greater, but ";
[15023]329
[15095]330 //tell them if java is absent or just too old
[17307]331 if ( find( foundJvm, false, minimum, "", "", false ) ) {
[15689]332 message.append( "your java is too old.");
[15095]333 } else {
[15689]334 message.append( "java could not be found on your computer." );
[15095]335 }
[17271]336 message.append( "\n" );
[15095]337
[17271]338 string title = "Installation Failed: Couldn't find java";
339 MessageBox(NULL, message.c_str(), title.c_str(), MB_OK);
340
341 //if java was found, carry on
342 } else {
[15689]343
344 //extract the jar
[17919]345 string jarLocation = "greenstone.jar";
[17961]346
[15689]347 set_splash_step( "XJAR" );
[16079]348 extractResource( "JAR", "JAR", (char*) jarLocation.c_str() );
[17271]349
[15689]350 //launch the jar
351 set_splash_step( "LAUNCHING" );
352 spoof_progress( SPOOF_TIME );
353 string cmd = "\"";
354 cmd.append( foundJvm.getWinExecutable() );
[17271]355 cmd.append( "\" -jar greenstone.jar" );
[15689]356
357 //hide splash screen
358 ShowWindow(splashWnd, SW_HIDE);
359
360 //run the jar
361 int launch_exit_code = process( cmd, true );
362
[15146]363 //report how it went
[15689]364 if ( launch_exit_code != 0 ) {
365 string title = "Installation Error";
366 string message = "The installation exited with an error. Java may not be installed properly, or the installation may have been interrupted partway through. Please try again.";
367 MessageBox(NULL, message.c_str(), title.c_str(), MB_OK);
[15023]368 }
369 }
[15025]370
[15689]371 //clean up the temp directory
[17342]372 _unlink( "greenstone.jar" );
373 _unlink( "ant.install.log" );
374 _unlink( "@java.installer@" );
[17385]375 process( "cmd.exe /c rd /s /q @java.extracted@", false );
[17342]376 SetCurrentDirectory( ".." );
[15689]377 _rmdir( tempdir.c_str() );
[15095]378
[15689]379 return 0;
[15023]380
[15095]381}
Note: See TracBrowser for help on using the repository browser.