root/release-kits/shared/windows/wrapper/wrapper.cpp @ 17937

Revision 17937, 10.8 KB (checked in by oranfry, 11 years ago)

splash screen changes

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            break;
68        }
69    }
70   
71    if ( no_chunks == 0 ) {
72        return 1;
73    }
74   
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};
82        itoa( i+1, chunknum, 10 );
83        strcat( chunkname, chunknum );
84       
85        //find it
86        HRSRC hRsrc = FindResource(hModule, chunkname, type);
87        if (hRsrc == NULL ) return 1; //couldn't find the chunk
88       
89        //load it
90        HGLOBAL hGlobal = LoadResource(hModule, hRsrc);
91        if (hGlobal == NULL) return 1; //couldn't lock
92       
93        //lock it
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    }
111
112    return 0;
113
114}
115
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");
123            g_hfFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
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);
166            BitBlt(hdc, 0, 270, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);
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           
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           
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       
190        /*
191        case WM_LBUTTONDOWN: {
192            DeleteObject(g_splash);
193            PostQuitMessage(0);
194        }
195        break;
196        */
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
213}
214
215//function to process the window
216DWORD WINAPI ProcessWindow( LPVOID lpParam ) {
217   
218    const char g_szClassName[] = "splash";
219    WNDCLASSEX wc;
220    MSG Msg;
221
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    }
240
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;
251   
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) {
261   
262    const int SPOOF_TIME = 1000;
263    string command;
264    srand( time(0) );
265    mainInstance = hInstance;
266    mainCmdShow = nCmdShow;
267   
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 );
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);
297    char id[6]; for( int i=0; i<5; i++ ) id[i] = (char)((rand()%26) + 97); id[5] = '\0'; //id for this instance
298    string tempdir = ""; tempdir.append( tmp ); tempdir.append( "\\Greenstone-" ); tempdir.append( id );
299    const char* tmpdir = tempdir.c_str();
300    _mkdir( tmpdir );
301    SetFileAttributes(tmpdir, FILE_ATTRIBUTE_HIDDEN);
302    SetCurrentDirectory(tmpdir);
303    delete tmp; //  deallocate memory
304   
305    //rip out java archive if it is bundled
306    set_splash_step( "XJAVA" );
307    int javaIsBundled = (extractResource( "JAVA", "EXE", "@java.installer@" ) == 0);
308    if ( javaIsBundled ) {
309        process( "@java.installer@", false );
310    }
311
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@" );
318    string phint = "@java.extracted@";
319    string hint = "";
320    bool verbose = true;
321    Jvm foundJvm;
322    bool jvmFound = find( foundJvm, use_minimum, minimum, phint, hint, verbose );
323   
324    //if the jvm was not found, try to fix it and find it
325    if ( !jvmFound ) {
326
327        //did not find a good java
328        string message = "This version of Greenstone requires java @java.min.version@ or greater, but ";
329       
330        //tell them if java is absent or just too old
331        if ( find( foundJvm, false, minimum, "", "", false ) ) {
332            message.append( "your java is too old.");
333        } else {
334            message.append( "java could not be found on your computer." );
335        }
336        message.append( "\n" );
337       
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 {
343
344        //extract the jar
345        string jarLocation = "greenstone.jar";
346               
347        set_splash_step( "XJAR" );
348        extractResource( "JAR", "JAR", (char*) jarLocation.c_str() );
349
350        //launch the jar
351        set_splash_step( "LAUNCHING" );
352        spoof_progress( SPOOF_TIME );
353        string cmd = "\"";
354        cmd.append( foundJvm.getWinExecutable() );
355        cmd.append( "\" -jar greenstone.jar" );
356       
357        //hide splash screen
358        ShowWindow(splashWnd, SW_HIDE);
359       
360        //run the jar
361        int launch_exit_code = process( cmd, true );
362       
363        //report how it went
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);
368        }
369    }
370   
371    //clean up the temp directory
372    _unlink( "greenstone.jar" );
373    _unlink( "ant.install.log" );
374    _unlink( "@java.installer@" );
375    process( "cmd.exe /c rd /s /q @java.extracted@", false );
376    SetCurrentDirectory( ".." );
377    _rmdir( tempdir.c_str() );
378
379    return 0;
380   
381}
Note: See TracBrowser for help on using the browser.