1
2
3
4
5
6 using System;
7 using System.Windows.API;
8
9 namespace System.Windows
10 {
11 public string CmajorRootDir()
12 {
13 string cmajorRootDir;
14 int stringHandle = RtmGetEnvironmentVariable("CMAJOR_ROOT");
15 if (stringHandle != -1)
16 {
17 cmajorRootDir = RtmGetString(stringHandle);
18 RtmFreeString(stringHandle);
19 }
20 if (cmajorRootDir.IsEmpty())
21 {
22 WinFatalError("please set \'CMAJOR_ROOT\' environment variable to contain /path/to/cmajor directory.");
23 }
24 return cmajorRootDir;
25 }
26
27 public string LogDir()
28 {
29 string cmajorRootDir = CmajorRootDir();
30 string logDir = Path.Combine(cmajorRootDir, "log");
31 Directory.CreateDirectories(logDir);
32 return logDir;
33 }
34
35 public string ApplicationLogFilePath()
36 {
37 return Path.Combine(LogDir(), "application.log");
38 }
39
40 public delegate bool MessageProcessorFunction(void* windowHandle, uint msg, ulong wparam, long lparam, long& result, void*& originalWndProc);
41
42 public class RunModalGuard
43 {
44 public RunModalGuard()
45 {
46 Application.SetRunningModal();
47 }
48 public ~RunModalGuard()
49 {
50 Application.ResetRunningModal();
51 }
52 }
53
54 public static class Application
55 {
56 static Application() : logView(null), activeWindow(null), runningModal(false), errorId(0)
57 {
58 MessageProcessorFunction messageProcessorFunction = ProcessMessage;
59 ModelessWindowKeyPreviewFunction keyPreviewFunction = ModelessWindowKeyPreview;
60 void* messageProcessorFunctionAddress = cast<void*>(messageProcessorFunction);
61 void* keyPreviewFunctionAddress = cast<void*>(keyPreviewFunction);
62 WinInit(messageProcessorFunctionAddress, keyPreviewFunctionAddress);
63 }
64 public static void Init()
65 {
66 }
67 public static int Run(Window& mainWindow)
68 {
69 mainWindow.SetAsMainWindow();
70 SetMainWindow(&mainWindow);
71 switch (mainWindow.GetWindowState())
72 {
73 case WindowState.normal:
74 {
75 auto result = mainWindow.ShowWindow(ShowCommand.SW_SHOWNORMAL);
76 if (result.Error())
77 {
78 errorId = result.GetErrorId();
79 return 1;
80 }
81 break;
82 }
83 case WindowState.minimized:
84 {
85 auto result = mainWindow.ShowWindow(ShowCommand.SW_MINIMIZE);
86 if (result.Error())
87 {
88 errorId = result.GetErrorId();
89 return 1;
90 }
91 break;
92 }
93 case WindowState.maximized:
94 {
95 auto result = mainWindow.ShowWindow(ShowCommand.SW_MAXIMIZE);
96 if (result.Error())
97 {
98 errorId = result.GetErrorId();
99 return 1;
100 }
101 break;
102 }
103 }
104 auto result = mainWindow.Show();
105 if (result.Error())
106 {
107 errorId = result.GetErrorId();
108 return 1;
109 }
110 mainWindow.Update();
111 int exitCode = WinRun();
112 return exitCode;
113 }
114 public static void RunModal()
115 {
116 RunModalGuard guard;
117 WinRunModal();
118 }
119 public static void EndModal()
120 {
121 WinPostMessage(MainWindow()->Handle(), CM_ENDMODAL, 0u, 0);
122 }
123 public static void Exit(int exitCode)
124 {
125 WinPostQuitMessage(exitCode);
126 }
127 public static void Exit()
128 {
129 Exit(0);
130 }
131 public static void ProcessMessages()
132 {
133 int retval = WinApplicationMessageLoop();
134 }
135 private static bool ProcessMessage(void* windowHandle, uint msg, ulong wparam, long lparam, long& result, void*& originalWndProc)
136 {
137 Control* window = windowManager.GetWindow(windowHandle);
138 if (window != null)
139 {
140 if (Debug.Messages())
141 {
142 System.IO.LogWriter writer(ApplicationLogFilePath());
143 writer << GetCurrentDateTime().ToString() << endl();
144 auto messageNameResult = MessageNameMap.Instance().GetMessageName(msg);
145 if (!messageNameResult.Error())
146 {
147 writer << ">" << messageNameResult.Value() << endl();
148 }
149 }
150 Message message(windowHandle, msg, wparam, lparam, result);
151 Result<bool> handledResult = window->ProcessMessageInternal(message);
152 if (handledResult.Error())
153 {
154 #if (DEBUG)
155 auto result = MessageBox.Show(handledResult.GetErrorMessage(), "error");
156 if (result.Error())
157 {
158 System.IO.LogWriter writer(ApplicationLogFilePath());
159 writer << GetCurrentDateTime().ToString() << result.GetErrorMessage() << endl();
160 }
161 #endif
162 return false;
163 }
164 bool handled = handledResult.Value();
165 if (message.originalWndProc != null)
166 {
167 originalWndProc = message.originalWndProc;
168 }
169 if (handled)
170 {
171 result = message.result;
172 }
173 if (Debug.Messages())
174 {
175 System.IO.LogWriter writer(ApplicationLogFilePath());
176 auto messageNameResult = MessageNameMap.Instance().GetMessageName(msg);
177 if (!messageNameResult.Error())
178 {
179 writer << "<" << messageNameResult.Value() << endl();
180 }
181 }
182 return handled;
183 }
184 return false;
185 }
186 public static WindowManager& GetWindowManager()
187 {
188 return windowManager;
189 }
190 public static ResourceManager& GetResourceManager()
191 {
192 return resourceManager;
193 }
194 public static LogView* GetLogView()
195 {
196 return logView;
197 }
198 public static void SetLogView(LogView* logView_)
199 {
200 logView = logView_;
201 }
202 public static Control* GetFocusedControl() const
203 {
204 void* focusedWindowHandle = WinGetFocus();
205 if (focusedWindowHandle == null)
206 {
207 return null;
208 }
209 Control* focusedControl = windowManager.GetWindow(focusedWindowHandle);
210 return focusedControl;
211 }
212 public static Window* GetActiveWindow()
213 {
214 return activeWindow;
215 }
216 public static void SetActiveWindow(Window* activeWindow_)
217 {
218 activeWindow = activeWindow_;
219 }
220 public static Window* MainWindow()
221 {
222 return mainWindow;
223 }
224 public static void SetMainWindow(Window* w)
225 {
226 mainWindow = w;
227 }
228 internal static void SetRunningModal()
229 {
230 runningModal = true;
231 }
232 internal static void ResetRunningModal()
233 {
234 runningModal = false;
235 }
236 public static bool RunningModal()
237 {
238 return runningModal;
239 }
240 public static bool Error()
241 {
242 return errorId != 0;
243 }
244 public static int ErrorId()
245 {
246 return errorId;
247 }
248 private static WindowManager windowManager;
249 private static ResourceManager resourceManager;
250 private static LogView* logView;
251 private static Window* activeWindow;
252 private static Window* mainWindow;
253 private static bool runningModal;
254 private static int errorId;
255 }