f368ffc77bc7cdc32f3435b2bf32178e129d6850
[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 "sci_path.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
69             ValidateRect(hwnd, NULL);
70             return 0;
71         }
72         break;
73         case WM_DESTROY:
74         {
75             if (pImage)
76             {
77                 delete pImage;
78                 pImage = NULL;
79             }
80         }
81     }
82
83     return DefWindowProc(hwnd, uMsg, wParam, lParam);
84 }
85 /*--------------------------------------------------------------------------*/
86 static DWORD WINAPI ThreadSplashScreen(LPVOID lpParam)
87 {
88     char *ScilabDirectory = NULL;
89     char *ImageFilename = NULL;
90     wchar_t *wImageFilename = NULL;
91
92     size_t len = 0;
93     Gdiplus::GdiplusStartupInput gdiplusStartupInput;
94
95     ULONG_PTR gdiplusToken = NULL;
96     Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
97
98     HINSTANCE hInstanceThisDll = (HINSTANCE)GetModuleHandle("scilab_windows");
99
100     ScilabDirectory = computeSCI();
101     if (ScilabDirectory == NULL)
102     {
103         return 0;
104     }
105
106     len = strlen(FORMAT_FULLPATH_SPLASH_IMAGE) + strlen(ScilabDirectory) + 1;
107     ImageFilename = (char*)MALLOC(sizeof(char) * len);
108     if (ImageFilename == NULL)
109     {
110         return 0;
111     }
112
113     sprintf(ImageFilename, FORMAT_FULLPATH_SPLASH_IMAGE, ScilabDirectory);
114     FREE(ScilabDirectory);
115     ScilabDirectory = NULL;
116
117     wImageFilename = to_wide_string(ImageFilename);
118     FREE(ImageFilename);
119     ImageFilename = NULL;
120     if (wImageFilename == NULL)
121     {
122         return 0;
123     }
124
125     pImage = Gdiplus::Image::FromFile((const WCHAR *)wImageFilename);
126     FREE(wImageFilename);
127     wImageFilename = NULL;
128     if (pImage == NULL)
129     {
130         return 0;
131     }
132
133     WNDCLASS wndcls = {0};
134
135     wndcls.style = CS_HREDRAW | CS_VREDRAW;
136     wndcls.lpfnWndProc = SplashWndProc;
137     wndcls.hInstance = GetModuleHandle(NULL);
138     wndcls.hCursor = LoadCursor(NULL, IDC_APPSTARTING);
139     wndcls.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
140     wndcls.lpszClassName = SPLASH_WINDOW_CLASSNAME;
141     wndcls.hIcon = LoadIcon(wndcls.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
142
143     if (!RegisterClass(&wndcls))
144     {
145         if (GetLastError() != 0x00000582) // already registered
146         {
147             return 0;
148         }
149     }
150
151     // try to find monitor where mouse was last time
152     POINT point = {0};
153     MONITORINFO mi = {sizeof(MONITORINFO), 0};
154     HMONITOR hMonitor = 0;
155     RECT rcArea = {0};
156
157     ::GetCursorPos(&point);
158     hMonitor = ::MonitorFromPoint(point, MONITOR_DEFAULTTONEAREST);
159     if (::GetMonitorInfo(hMonitor, &mi))
160     {
161         rcArea.left = (mi.rcMonitor.right + mi.rcMonitor.left - pImage->GetWidth()) / 2;
162         rcArea.top = (mi.rcMonitor.top + mi.rcMonitor.bottom - pImage->GetHeight()) / 2;
163     }
164     else
165     {
166         SystemParametersInfo(SPI_GETWORKAREA, NULL, &rcArea, NULL);
167         rcArea.left = (rcArea.right + rcArea.left - pImage->GetWidth()) / 2;
168         rcArea.top = (rcArea.top + rcArea.bottom - pImage->GetHeight()) / 2;
169     }
170
171     HWND hdlg = CreateWindowEx(WS_EX_TOOLWINDOW,
172                                SPLASH_WINDOW_CLASSNAME,
173                                SPLASH_WINDOW_CLASSNAME,
174                                WS_CLIPCHILDREN | WS_POPUP,
175                                rcArea.left,
176                                rcArea.top,
177                                pImage->GetWidth(),
178                                pImage->GetHeight(),
179                                NULL,
180                                NULL,
181                                wndcls.hInstance,
182                                NULL);
183
184     if (hdlg == NULL)
185     {
186         return 0;
187     }
188
189     ShowWindow(hdlg, SW_SHOWNORMAL);
190     UpdateWindow(hdlg);
191     SetWindowPos(hdlg, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
192
193     while (!stopSplashScreen(20, 1000))
194     {
195         Sleep(20);
196     }
197
198     DestroyWindow(hdlg);
199     return 0;
200 }
201 /*--------------------------------------------------------------------------*/
202 static BOOL stopSplashScreen(UINT _time, UINT _timeMax)
203 {
204     if (haveConsoleWindow() || (timeSplashScreen >= _timeMax))
205     {
206         return TRUE;
207     }
208     else
209     {
210         if (timeSplashScreen < _timeMax)
211         {
212             timeSplashScreen = timeSplashScreen + _time;
213         }
214     }
215     return FALSE;
216 }
217 /*--------------------------------------------------------------------------*/
218 static BOOL haveConsoleWindow(void)
219 {
220     HWND hWndMainScilab = NULL;
221     char titleMainWindow[MAX_PATH];
222     int id = getCurrentScilabId();
223
224     wsprintf(titleMainWindow, "%s (%d)", SCI_VERSION_STRING, id);
225     hWndMainScilab = FindWindow(NULL, titleMainWindow);
226
227     if (hWndMainScilab == NULL)
228     {
229         wsprintf(titleMainWindow, _("Scilab %s Console"),  std::string(SCI_VERSION_STRING).substr(strlen("scilab-"), std::string::npos).c_str());
230         hWndMainScilab = FindWindow(NULL, titleMainWindow);
231     }
232
233     return (hWndMainScilab == NULL) ? FALSE : TRUE;
234 }
235 /*--------------------------------------------------------------------------*/