e084f151c44c604fe20648b166c443675a61ec06
[scilab.git] / scilab / modules / windows_tools / src / c / scilab_windows / splashScreen.cpp
1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) INRIA - Allan CORNET
4 * Copyright (C) DIGITEO - 2012 - Allan CORNET
5 *
6 * This file must be used under the terms of the CeCILL.
7 * This source file is licensed as described in the file COPYING, which
8 * you should have received as part of this distribution.  The terms
9 * are also available at
10 * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
11 *
12 */
13 /*--------------------------------------------------------------------------*/
14 #pragma comment (lib, "gdiplus.lib")
15 /*--------------------------------------------------------------------------*/
16 #include <Windows.h>
17 #include <stdio.h>
18 #include <CommCtrl.h>
19 #include <GdiPlus.h>
20 extern "C"
21 {
22 #include "splashScreen.h"
23 #include "localization.h"
24 #include "resource.h"
25 #include "version.h"
26 #include "WndThread.h"
27 #include "charEncoding.h"
28 #include "getScilabDirectory.h"
29 #include "InnosetupMutex.h"
30 #include "MALLOC.h"
31 };
32 /*--------------------------------------------------------------------------*/
33 #define SPLASH_WINDOW_CLASSNAME "Scilab splashscreen"
34 #define FORMAT_FULLPATH_SPLASH_IMAGE "%s/modules/gui/images/icons/aboutScilab.png"
35 /*--------------------------------------------------------------------------*/
36 static DWORD WINAPI ThreadSplashScreen(LPVOID lpParam);
37 static BOOL stopSplashScreen(UINT _time, UINT _timeMax);
38 static BOOL haveConsoleWindow(void);
39 /*--------------------------------------------------------------------------*/
40 static UINT timeSplashScreen = 0;
41 static Gdiplus::Image* pImage = NULL;
42 /*--------------------------------------------------------------------------*/
43 void splashScreen(void)
44 {
45     DWORD dwThreadId, dwThrdParam = 0;
46
47     if (!haveConsoleWindow() && !haveInnosetupMutex())
48     {
49         HANDLE hThreadSplashScreen = CreateThread(NULL, 0, ThreadSplashScreen, &dwThrdParam, 0, &dwThreadId);
50     }
51 }
52 /*--------------------------------------------------------------------------*/
53 LRESULT CALLBACK SplashWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
54 {
55     switch (uMsg)
56     {
57         case WM_PAINT:
58         {
59             if (pImage)
60             {
61                 Gdiplus::Graphics gdip(hwnd);
62                 gdip.DrawImage(pImage, 0, 0, pImage->GetWidth(), pImage->GetHeight());
63             }
64             ValidateRect(hwnd, NULL);
65             return 0;
66         }
67         break;
68         case WM_DESTROY:
69         {
70             if (pImage)
71             {
72                 delete pImage;
73                 pImage = NULL;
74             }
75         }
76     }
77
78     return DefWindowProc(hwnd, uMsg, wParam, lParam);
79 }
80 /*--------------------------------------------------------------------------*/
81 static DWORD WINAPI ThreadSplashScreen(LPVOID lpParam)
82 {
83     char *ScilabDirectory = NULL;
84     char *ImageFilename = NULL;
85     wchar_t *wImageFilename = NULL;
86
87     size_t len = 0;
88     Gdiplus::GdiplusStartupInput gdiplusStartupInput;
89
90     ULONG_PTR gdiplusToken = NULL;
91     Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
92
93     HINSTANCE hInstanceThisDll = (HINSTANCE)GetModuleHandle("scilab_windows");
94
95     ScilabDirectory = getScilabDirectory(TRUE);
96     if (ScilabDirectory == NULL)
97     {
98         return 0;
99     }
100
101     len = strlen(FORMAT_FULLPATH_SPLASH_IMAGE) + strlen(ScilabDirectory) + 1;
102     ImageFilename = (char*)MALLOC(sizeof(char) * len);
103     if (ImageFilename == NULL)
104     {
105         return 0;
106     }
107
108     sprintf(ImageFilename, FORMAT_FULLPATH_SPLASH_IMAGE, ScilabDirectory);
109     FREE(ScilabDirectory);
110     ScilabDirectory = NULL;
111
112     wImageFilename = to_wide_string(ImageFilename);
113     FREE(ImageFilename);
114     ImageFilename = NULL;
115     if (wImageFilename == NULL)
116     {
117         return 0;
118     }
119
120     pImage = Gdiplus::Image::FromFile((const WCHAR *)wImageFilename);
121     FREE(wImageFilename);
122     wImageFilename = NULL;
123     if (pImage == NULL)
124     {
125         return 0;
126     }
127
128     WNDCLASS wndcls = {0};
129
130     wndcls.style = CS_HREDRAW | CS_VREDRAW;
131     wndcls.lpfnWndProc = SplashWndProc;
132     wndcls.hInstance = GetModuleHandle(NULL);
133     wndcls.hCursor = LoadCursor(NULL, IDC_APPSTARTING);
134     wndcls.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
135     wndcls.lpszClassName = SPLASH_WINDOW_CLASSNAME;
136     wndcls.hIcon = LoadIcon(wndcls.hInstance, (char*)MAKEINTRESOURCE(IDI_APPLICATION));
137
138     if (!RegisterClass(&wndcls))
139     {
140         if (GetLastError() != 0x00000582) // already registered
141         {
142             return 0;
143         }
144     }
145
146     // try to find monitor where mouse was last time
147     POINT point = {0};
148     MONITORINFO mi = {sizeof(MONITORINFO), 0};
149     HMONITOR hMonitor = 0;
150     RECT rcArea = {0};
151
152     ::GetCursorPos(&point);
153     hMonitor = ::MonitorFromPoint(point, MONITOR_DEFAULTTONEAREST);
154     if (::GetMonitorInfo(hMonitor, &mi))
155     {
156         rcArea.left = (mi.rcMonitor.right + mi.rcMonitor.left - pImage->GetWidth()) / 2;
157         rcArea.top = (mi.rcMonitor.top + mi.rcMonitor.bottom - pImage->GetHeight()) / 2;
158     }
159     else
160     {
161         SystemParametersInfo(SPI_GETWORKAREA, NULL, &rcArea, NULL);
162         rcArea.left = (rcArea.right + rcArea.left - pImage->GetWidth()) / 2;
163         rcArea.top = (rcArea.top + rcArea.bottom - pImage->GetHeight()) / 2;
164     }
165
166     HWND hdlg = CreateWindowEx(WS_EX_TOOLWINDOW,
167                                SPLASH_WINDOW_CLASSNAME,
168                                SPLASH_WINDOW_CLASSNAME,
169                                WS_CLIPCHILDREN | WS_POPUP,
170                                rcArea.left,
171                                rcArea.top,
172                                pImage->GetWidth(),
173                                pImage->GetHeight(),
174                                NULL,
175                                NULL,
176                                wndcls.hInstance,
177                                NULL);
178
179     if (hdlg == NULL)
180     {
181         return 0;
182     }
183
184     ShowWindow(hdlg, SW_SHOWNORMAL);
185     UpdateWindow(hdlg);
186     SetWindowPos(hdlg, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
187
188     while (!stopSplashScreen(20, 1000))
189     {
190         Sleep(20);
191     }
192
193     DestroyWindow(hdlg);
194     return 0;
195 }
196 /*--------------------------------------------------------------------------*/
197 static BOOL stopSplashScreen(UINT _time, UINT _timeMax)
198 {
199     if (haveConsoleWindow() || (timeSplashScreen > _timeMax))
200     {
201         return TRUE;
202     }
203     else
204     {
205         if (timeSplashScreen < _timeMax)
206         {
207             timeSplashScreen = timeSplashScreen + _time;
208         }
209     }
210     return FALSE;
211 }
212 /*--------------------------------------------------------------------------*/
213 static BOOL haveConsoleWindow(void)
214 {
215     HWND hWndMainScilab = NULL;
216     char titleMainWindow[MAX_PATH];
217     int id = getCurrentScilabId();
218
219     wsprintf(titleMainWindow, "%s (%d)", SCI_VERSION_STRING, id);
220     hWndMainScilab = FindWindow(NULL, titleMainWindow);
221
222     if (hWndMainScilab == NULL)
223     {
224         wsprintf(titleMainWindow, _("Scilab Console"));
225         hWndMainScilab = FindWindow(NULL, titleMainWindow);
226     }
227
228     return (hWndMainScilab == NULL) ? FALSE : TRUE;
229 }
230 /*--------------------------------------------------------------------------*/