#include "Splash.h" UINT timer; HWND splash_window; BOOL splash_done; HBITMAP splash_bmp; int splash_bmpheight; void CALLBACK splash_timerproc(HWND Window, UINT Message, UINT id, DWORD time) { splash_done = TRUE; KillTimer(NULL, 0); } long FAR PASCAL _export splash_windproc(HWND Window, UINT Message, WPARAM wParameter, LPARAM lParameter) { switch (Message) { case WM_CREATE: { timer = SetTimer(NULL, 0, 3000, (TIMERPROC) splash_timerproc); } break; case WM_TIMER: // valid id; just kill window after timer elapses splash_done = TRUE; KillTimer(Window, 0); break; case WM_DESTROY: splash_window = 0; break; case WM_PAINT: { PAINTSTRUCT PaintInfo; HDC dc, bmpDC; BITMAP bmpData; POINT origin, size; dc = BeginPaint(Window, &PaintInfo); bmpDC = CreateCompatibleDC(dc); SelectObject(bmpDC, splash_bmp); GetObject(splash_bmp, sizeof(BITMAP), (LPVOID) &bmpData); size.x = bmpData.bmWidth; size.y = bmpData.bmHeight; DPtoLP(dc, &size, 1); origin.x = 0; origin.y = 0; DPtoLP(dc, &origin, 1); BitBlt(dc, 0, 0, size.x, size.y, bmpDC, origin.x, origin.y, SRCCOPY); DeleteDC(bmpDC); EndPaint(Window, &PaintInfo); } break; case WM_COMMAND: break; default: return(DefWindowProc(Window, Message, wParameter, lParameter)); } return 0L; } void splash_register(HINSTANCE instance) { WNDCLASS Class; static bool registered = false; if (registered == false) { Class.lpszClassName = "Generic:Splash"; Class.hInstance = instance; Class.lpfnWndProc = (WNDPROC) splash_windproc; Class.hCursor = LoadCursor(NULL, IDC_ARROW); Class.hIcon = NULL; Class.lpszMenuName = NULL; Class.hbrBackground = (HBRUSH) (COLOR_WINDOW+1); Class.style = NULL; Class.cbClsExtra = 0; Class.cbWndExtra = 0; RegisterClass(&Class); registered = TRUE; } } void _export splash_show(HINSTANCE instance, unsigned int time) { MSG msg; RECT r; BITMAP bmpData; POINT size; int sx, sy; HDC dc; splash_register(instance); splash_bmp = LoadBitmap(instance, (LPCSTR) MAKEINTRESOURCE(9007)); splash_done = FALSE; GetObject(splash_bmp, sizeof(BITMAP), (LPVOID) &bmpData); size.x = bmpData.bmWidth; size.y = bmpData.bmHeight; r.left = 0; r.top = 0; r.right = size.x; r.bottom = size.y; AdjustWindowRect(&r, 0, TRUE); splash_bmpheight = size.y; dc = GetDC(GetDesktopWindow()); sx = GetDeviceCaps(dc, HORZRES); sy = GetDeviceCaps(dc, VERTRES); ReleaseDC(GetDesktopWindow(), dc); splash_window = CreateWindow("Generic:Splash", "Greenstone Installer", WS_DLGFRAME | WS_VISIBLE, (sx - r.right + r.left) / 2, (sy - r.bottom + r.top) / 2, r.right-r.left, r.bottom-r.top, 0, 0, instance, NULL); while (GetMessage(&msg, NULL, NULL, NULL) && splash_done == FALSE) { if (msg.message == WM_TIMER) { msg.hwnd = splash_window; } TranslateMessage(&msg); DispatchMessage(&msg); } DestroyWindow(splash_window); } #include #include #include #include "splash.h" #include "bmputil.h" // define the magic value used in GetWinFlags to show that this application // is running on a Windows NT box in 16-bit emulation mode. #define WF_WINNT 0x4000 #ifdef _WIN32 int GetWinFlags() { return 0; } #endif HWND app_window; HINSTANCE app_instance; char *app_cmdLine; typedef void (* splashfn) (HINSTANCE a, unsigned int time); typedef HBITMAP (* bmploadfn) (HDC device, LPSTR name); typedef struct { BYTE majorVersion; BYTE minorVersion; WORD buildNumber; BOOL debug; } win32sInfo, FAR * lpWin32sInfo; typedef enum { Windows2x, Windows3_0x, Windows3_1x, Windows9x, WindowsNT } gs16PlatformId; typedef struct { gs16PlatformId platform; bool win32s; } gs16PlatformInfo; //typedef int FAR PASCAL (* win32sInfoFn)(lpWin32sInfo); typedef int (FAR PASCAL * win32sInfoFn)(lpWin32sInfo); bool GS16bit_checkForWin32s() { // HANDLE w32sHandle; HINSTANCE w32sHandle; win32sInfoFn infoFnPtr; win32sInfo w32sInfo; bool reply = false; // try to get a handle onto the win32s library w32sHandle = LoadLibrary("W32SYS.DLL"); // if (w32sHandle > HINSTANCE_ERROR) if (w32sHandle != NULL) { // now get the address of the GetWin32sInfo function infoFnPtr = (win32sInfoFn) GetProcAddress(w32sHandle, "GETWIN32SINFO"); // if the function exists, we've got win32s1.1 or later if (infoFnPtr != NULL) { if ((*infoFnPtr)((lpWin32sInfo) &w32sInfo) == 0) // no error state { reply = true; } else // error - call didn't work; assume that we have a non-functional // win32s { reply = false; } } // else we've got win32s 1.0. TODO: We need to check if it's actually up and // running; else { reply = true; } // we need to free the library before finishing this function FreeLibrary(w32sHandle); } // no win32s at all else { reply = false; } return reply; } void GS16bit_getPlatformInfo(gs16PlatformInfo &info) { DWORD version = GetVersion(); /** * NB: Ignore ALL standard information on using GetVersion in the * standard Windows 3.1 SDK and Windows 32-bit SDK documentation; * the latter does not apply, and the former is (slightly but signif- * cantly) misdocumented. * * On 16-bit windows (i.e. this program) take the following comments * as gospel. Also refer to * * http://support.microsoft.com/support/kb/articles/Q131/3/71.asp */ BYTE majorVersion = LOBYTE(LOWORD(version)); BYTE minorVersion = HIBYTE(LOWORD(version)); BYTE dosVersion = HIBYTE(HIWORD(version)); if (majorVersion < 3) { info.platform = Windows2x; } else if (majorVersion == 3 && minorVersion >= 95) // it's Windows 95 from the // minor version; I guess that // 98 may have minor version == 98, // but I don't know! Hence the // cautious check { info.platform = Windows9x; } else // we're running in "some sort" of Windows 3.x environment { if (minorVersion == 10 && dosVersion == 5) // it could be running under WOW // (16-bit Windows emulation in // Windows NT) { if ((GetWinFlags() & WF_WINNT) == WF_WINNT) // check for NT in emulation mode { info.platform = WindowsNT; } else { info.platform = Windows3_1x; } } else if (minorVersion >= 10) // perhaps Windows 3.11 { info.platform = Windows3_1x; } else { info.platform = Windows3_0x; } } if (info.platform == Windows3_1x) { info.win32s = GS16bit_checkForWin32s(); } else { info.win32s = false; } } void GS16bit_checkWindowsVersion() { gs16PlatformInfo platformInfo; GS16bit_getPlatformInfo(platformInfo); if (platformInfo.platform == Windows3_0x || platformInfo.platform == Windows2x) { MessageBox(app_window, "Greenstone cannot be installed on this computer. It requires " "Windows 3.10 or later", "Greenstone Installer", MB_OK); } else if (platformInfo.platform == Windows3_1x && platformInfo.win32s == false) { MessageBox(app_window, "Greenstone requires 32 bit Windows. Win32s will now be installed " "on your computer to provide this, before continuing with the main " "installation.", "Greenstone Installer", MB_OK); } else { char buffer[20]; int result; /* MessageBox(app_window, "Greenstone will now install", "Greenstone Installer", MB_OK);*/ result = WinExec("gssetup.exe", SW_SHOWNORMAL); } } long FAR PASCAL GS16bitWindProc(HWND Window, WORD Message, WPARAM wParameter, LPARAM lParameter) { long reply = 0; switch(Message) { case WM_CREATE: { } break; case WM_COMMAND: break; case WM_CLOSE: DestroyWindow(Window); return 0L; case WM_DESTROY: { PostQuitMessage(0); } break; default: return(DefWindowProc(Window, Message, wParameter, lParameter)); } return reply; } void GS16bit_init(HINSTANCE instance, int Show) { FARPROC showsplash; FARPROC loadbmp; HDC dc; char buffer[20]; /* dc = GetDC(GetDesktopWindow()); bmpUtil loadBitmap(dc, "C:\\gs.bmp"); ReleaseDC(GetDesktopWindow(), dc); */ // showsplash = MakeProcInstance((FARPROC) splash_show, instance); // (*(splashfn) showsplash)(instance, 3000); GS16bit_checkWindowsVersion(); app_window = CreateWindow("GS16bit:Main", "GreenStone Installer", WS_OVERLAPPEDWINDOW | WS_MINIMIZE | CS_DBLCLKS, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, app_instance, NULL); ShowWindow(app_window, Show); PostQuitMessage(0); } void WinClassInit(void) { WNDCLASS Class; Class.lpszClassName = "GS16bit:Main"; Class.hInstance = app_instance; Class.lpfnWndProc = (WNDPROC) GS16bitWindProc; Class.hCursor = LoadCursor(NULL, IDC_ARROW); Class.hIcon = NULL; //LoadIcon(app_instance, "GSInstall"); Class.lpszMenuName = NULL; Class.hbrBackground = (HBRUSH) (COLOR_APPWORKSPACE+1); // Class.style = NULL; Class.style = 0; Class.cbClsExtra = 0; Class.cbWndExtra = 0; RegisterClass(&Class); } int PASCAL WinMain(HINSTANCE Current, HINSTANCE Previous, LPSTR CmdLine, int CmdShow) { MSG msg; app_cmdLine = (char *) LocalAlloc(LMEM_FIXED, lstrlen(CmdLine) + 1); lstrcpy(app_cmdLine, CmdLine); app_instance = Current; /* -- init application */ if (!Previous) { WinClassInit(); } /* -- init instance */ GS16bit_init(Current, CmdShow); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return (int) msg.wParam; }