1 /**
2  * ae.ui.app.windows.main
3  *
4  * License:
5  *   This Source Code Form is subject to the terms of
6  *   the Mozilla Public License, v. 2.0. If a copy of
7  *   the MPL was not distributed with this file, You
8  *   can obtain one at http://mozilla.org/MPL/2.0/.
9  *
10  * Authors:
11  *   Vladimir Panteleev <ae@cy.md>
12  */
13 
14 module ae.ui.app.windows.main;
15 
16 version (Windows):
17 
18 import core.runtime;
19 import std.utf;
20 
21 import ae.sys.windows.imports;
22 mixin(importWin32!q{windef});
23 mixin(importWin32!q{winuser});
24 
25 import ae.ui.app.application;
26 import ae.utils.exception;
27 
28 /// A generic entry point for applications running on Windows.
29 extern (Windows)
30 int WinMain(HINSTANCE hInstance,
31             HINSTANCE hPrevInstance,
32             LPSTR lpCmdLine,
33             int nCmdShow)
34 {
35 	int result;
36 
37 	try
38 	{		
39 		Runtime.initialize();
40 		result = runApplication(getArgs());
41 		Runtime.terminate();
42 	}
43 
44 	catch (Throwable o)				// catch any uncaught exceptions
45 	{
46 		MessageBoxA(null, toUTFz!LPCSTR(formatException(o)), "Error",
47 					MB_OK | MB_ICONEXCLAMATION);
48 		result = 1;				// failed
49 	}
50 
51 	return result;
52 }
53 
54 private:
55 // Following code is adapted from D's druntime\src\rt\dmain2.d
56 
57 import core.stdc.wchar_;
58 import core.stdc.stdlib;
59 
60 mixin(importWin32!q{winbase});
61 mixin(importWin32!q{shellapi});
62 mixin(importWin32!q{winnls});
63 
64 string[] getArgs()
65 {
66 	wchar_t*  wcbuf = GetCommandLineW();
67 	size_t    wclen = wcslen(wcbuf);
68 	int       wargc = 0;
69 	wchar_t** wargs = CommandLineToArgvW(wcbuf, &wargc);
70 
71 	size_t    cargl = WideCharToMultiByte(CP_UTF8, 0, wcbuf, cast(uint)wclen, null, 0, null, null);
72 
73 	char*     cargp = cast(char*) malloc(cargl);
74 	char[][]  args  = ((cast(char[]*) malloc(wargc * (char[]).sizeof)))[0 .. wargc];
75 
76 	for (size_t i = 0, p = 0; i < wargc; i++)
77 	{
78 		size_t wlen = wcslen(wargs[i]);
79 		size_t clen = WideCharToMultiByte(CP_UTF8, 0, &wargs[i][0], cast(uint)wlen, null, 0, null, null);
80 		args[i]  = cargp[p .. p+clen];
81 		p += clen; assert(p <= cargl);
82 		WideCharToMultiByte(CP_UTF8, 0, &wargs[i][0], cast(uint)wlen, &args[i][0], cast(uint)clen, null, null);
83 	}
84 	LocalFree(cast(HLOCAL)wargs);
85 	wargs = null;
86 	wargc = 0;
87 
88 	return cast(string[])args;
89 }