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 import core.runtime;
17 import std.utf;
18 
19 import ae.sys.windows.imports;
20 mixin(importWin32!q{windef});
21 mixin(importWin32!q{winuser});
22 
23 import ae.ui.app.application;
24 import ae.utils.exception;
25 
26 /// A generic entry point for applications running on Windows.
27 extern (Windows)
28 int WinMain(HINSTANCE hInstance,
29             HINSTANCE hPrevInstance,
30             LPSTR lpCmdLine,
31             int nCmdShow)
32 {
33 	int result;
34 
35 	try
36 	{		
37 		Runtime.initialize();
38 		result = runApplication(getArgs());
39 		Runtime.terminate();
40 	}
41 
42 	catch (Throwable o)				// catch any uncaught exceptions
43 	{
44 		MessageBoxA(null, toUTFz!LPCSTR(formatException(o)), "Error",
45 					MB_OK | MB_ICONEXCLAMATION);
46 		result = 1;				// failed
47 	}
48 
49 	return result;
50 }
51 
52 private:
53 // Following code is adapted from D's druntime\src\rt\dmain2.d
54 
55 import core.stdc.wchar_;
56 import core.stdc.stdlib;
57 
58 mixin(importWin32!q{winbase});
59 mixin(importWin32!q{shellapi});
60 mixin(importWin32!q{winnls});
61 
62 string[] getArgs()
63 {
64 	wchar_t*  wcbuf = GetCommandLineW();
65 	size_t    wclen = wcslen(wcbuf);
66 	int       wargc = 0;
67 	wchar_t** wargs = CommandLineToArgvW(wcbuf, &wargc);
68 
69 	size_t    cargl = WideCharToMultiByte(CP_UTF8, 0, wcbuf, cast(uint)wclen, null, 0, null, null);
70 
71 	char*     cargp = cast(char*) malloc(cargl);
72 	char[][]  args  = ((cast(char[]*) malloc(wargc * (char[]).sizeof)))[0 .. wargc];
73 
74 	for (size_t i = 0, p = 0; i < wargc; i++)
75 	{
76 		size_t wlen = wcslen(wargs[i]);
77 		size_t clen = WideCharToMultiByte(CP_UTF8, 0, &wargs[i][0], cast(uint)wlen, null, 0, null, null);
78 		args[i]  = cargp[p .. p+clen];
79 		p += clen; assert(p <= cargl);
80 		WideCharToMultiByte(CP_UTF8, 0, &wargs[i][0], cast(uint)wlen, &args[i][0], cast(uint)clen, null, null);
81 	}
82 	LocalFree(cast(HLOCAL)wargs);
83 	wargs = null;
84 	wargc = 0;
85 
86 	return cast(string[])args;
87 }