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

Last change on this file since 16203 was 16203, checked in by oranfry, 16 years ago

made the wrapper general, so it can be used with greenstone2 or greenstone3 release kits

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