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