| 1 | using System; |
|---|
| 2 | using System.Diagnostics; |
|---|
| 3 | using System.IO; |
|---|
| 4 | using System.Reflection; |
|---|
| 5 | using System.Text; |
|---|
| 6 | using System.Windows.Forms; |
|---|
| 7 | using IronPython; |
|---|
| 8 | using Microsoft.Scripting; |
|---|
| 9 | using Microsoft.Scripting.Hosting; |
|---|
| 10 | |
|---|
| 11 | namespace Misuzilla.Applications.AppleWirelessKeyboardHelper |
|---|
| 12 | { |
|---|
| 13 | public class Program |
|---|
| 14 | { |
|---|
| 15 | private static NotifyIcon _notifyIcon; |
|---|
| 16 | private const String ApplicationName = "Apple Wireless Keyboard Helper"; |
|---|
| 17 | private static IScriptModule _module; |
|---|
| 18 | |
|---|
| 19 | public static Int32 BalloonTipTimeout = 1500; |
|---|
| 20 | |
|---|
| 21 | private const UInt32 JISAlphaNumericKeyScanCode = 113; // 113 |
|---|
| 22 | private const UInt32 JISKanaKeyScanCode = 114; // 114 |
|---|
| 23 | /// <summary> |
|---|
| 24 | /// �n���h���������Ȃ�������b�`���āA�X�^�b�N�g���[�X������ăf�o�b�O�ɖ𗧂Ă� /// </summary> |
|---|
| 25 | /// <param name="sender"></param> |
|---|
| 26 | /// <param name="e"></param> |
|---|
| 27 | private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) |
|---|
| 28 | { |
|---|
| 29 | Exception ex = e.ExceptionObject as Exception; // Exception �ȊO����ł����͒�����ꍇ�̂݁B |
|---|
| 30 | |
|---|
| 31 | if (MessageBox.Show( |
|---|
| 32 | String.Format("�A�v���P�[�V�����̎�s���ɗ\�����d���G���[���������܂����B\n\n�G���[��:\n{0}\n\n�G���[����@�C���ɕۑ����A���Ă����������Ƃŕs��̉�ɖ𗧂\�����������B�G���[����@�C���ɕۑ����܂���?", |
|---|
| 33 | ((Exception)(e.ExceptionObject)).Message) |
|---|
| 34 | , Application.ProductName |
|---|
| 35 | , MessageBoxButtons.YesNo |
|---|
| 36 | , MessageBoxIcon.Error |
|---|
| 37 | , MessageBoxDefaultButton.Button1 |
|---|
| 38 | ) == DialogResult.Yes) |
|---|
| 39 | { |
|---|
| 40 | using (SaveFileDialog saveFileDialog = new SaveFileDialog()) |
|---|
| 41 | { |
|---|
| 42 | //saveFileDialog.DefaultExt = "txt"; |
|---|
| 43 | //saveFileDialog.Filter = "�e�L�X�g�t�@�C��|*.txt"; |
|---|
| 44 | //saveFileDialog.FileName = String.Format("AppleWirelessKeyboardHelper_Stacktrace_{0:yyyyMMdd_HHmmss}.txt", DateTime.Now); |
|---|
| 45 | //if (saveFileDialog.ShowDialog() == DialogResult.OK) |
|---|
| 46 | { |
|---|
| 47 | String filePath = String.Format(Path.Combine(Assembly.GetExecutingAssembly().CodeBase, "AppleWirelessKeyboardHelper_Stacktrace_{0:yyyyMMdd_HHmmss}.txt"), DateTime.Now); |
|---|
| 48 | using (Stream stream = File.Open(filePath, FileMode.CreateNew)) |
|---|
| 49 | using (StreamWriter sw = new StreamWriter(stream)) |
|---|
| 50 | { |
|---|
| 51 | Assembly asm = Assembly.GetExecutingAssembly(); |
|---|
| 52 | |
|---|
| 53 | sw.WriteLine("��������: {0}", DateTime.Now); |
|---|
| 54 | sw.WriteLine(); |
|---|
| 55 | sw.WriteLine("AppleWirelessKeyboardHelper:"); |
|---|
| 56 | sw.WriteLine("========================"); |
|---|
| 57 | sw.WriteLine("�o�[�W����: {0}", Assembly.GetExecutingAssembly().GetName().Version); |
|---|
| 58 | sw.WriteLine("�A�Z���u��: {0}", Assembly.GetExecutingAssembly().FullName); |
|---|
| 59 | sw.WriteLine(); |
|---|
| 60 | sw.WriteLine("����:"); |
|---|
| 61 | sw.WriteLine("========================"); |
|---|
| 62 | sw.WriteLine("�I�y���[�e�B���O�V�X�e��: {0}", Environment.OSVersion); |
|---|
| 63 | sw.WriteLine("Microsoft .NET Framework: {0}", Environment.Version); |
|---|
| 64 | sw.WriteLine("IntPtr: {0}", IntPtr.Size); |
|---|
| 65 | sw.WriteLine(); |
|---|
| 66 | sw.WriteLine("�n���h���������Ȃ���: "); |
|---|
| 67 | sw.WriteLine("========================="); |
|---|
| 68 | sw.WriteLine(ex.ToString()); |
|---|
| 69 | } |
|---|
| 70 | } |
|---|
| 71 | } |
|---|
| 72 | |
|---|
| 73 | } |
|---|
| 74 | } |
|---|
| 75 | |
|---|
| 76 | //[STAThread] |
|---|
| 77 | static void Main() |
|---|
| 78 | { |
|---|
| 79 | AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; |
|---|
| 80 | using (Helper helper = new Helper()) |
|---|
| 81 | { |
|---|
| 82 | // TypeLib �� IDispatch ��悷�� ((PythonEngineOptions)(Script.GetEngine("py").Options)).PreferComDispatchOverTypeInfo = true; |
|---|
| 83 | |
|---|
| 84 | helper.FnKeyCombinationDown += delegate(Object sender, AppleKeyboardEventArgs e) |
|---|
| 85 | { |
|---|
| 86 | StringBuilder funcName = new StringBuilder("OnDown"); |
|---|
| 87 | if (e.AppleKeyState == AppleKeyboardKeys.Fn) |
|---|
| 88 | funcName.Append("_Fn"); |
|---|
| 89 | if (e.AppleKeyState == AppleKeyboardKeys.Eject) |
|---|
| 90 | funcName.Append("_Eject"); |
|---|
| 91 | |
|---|
| 92 | funcName.Append("_").Append(e.Key.ToString()); |
|---|
| 93 | |
|---|
| 94 | Call(funcName.ToString(), e); |
|---|
| 95 | |
|---|
| 96 | e.Handled = true; |
|---|
| 97 | }; |
|---|
| 98 | |
|---|
| 99 | helper.KeyUp += delegate(Object sender, AppleKeyboardEventArgs e) |
|---|
| 100 | { |
|---|
| 101 | if (e.KeyEventStruct.wScan != JISAlphaNumericKeyScanCode && e.KeyEventStruct.wScan != JISKanaKeyScanCode) |
|---|
| 102 | return; |
|---|
| 103 | |
|---|
| 104 | StringBuilder funcName = new StringBuilder("OnUp"); |
|---|
| 105 | if (e.AppleKeyState == AppleKeyboardKeys.Fn) |
|---|
| 106 | funcName.Append("_Fn"); |
|---|
| 107 | if (e.AppleKeyState == AppleKeyboardKeys.Eject) |
|---|
| 108 | funcName.Append("_Eject"); |
|---|
| 109 | |
|---|
| 110 | funcName.Append("_").Append((e.KeyEventStruct.wScan == JISAlphaNumericKeyScanCode) ? "JISAlphaNumeric" : "JISKana"); |
|---|
| 111 | |
|---|
| 112 | Call(funcName.ToString(), e); |
|---|
| 113 | |
|---|
| 114 | e.Handled = true; |
|---|
| 115 | }; |
|---|
| 116 | |
|---|
| 117 | helper.SpecialKeyDown += delegate(Object sender, KeyEventArgs e) |
|---|
| 118 | { |
|---|
| 119 | StringBuilder funcName = new StringBuilder("OnDown"); |
|---|
| 120 | if (e.AppleKeyboardKey == AppleKeyboardKeys.Fn) |
|---|
| 121 | funcName.Append("_Fn"); |
|---|
| 122 | if (e.AppleKeyboardKey == AppleKeyboardKeys.Eject) |
|---|
| 123 | funcName.Append("_Eject"); |
|---|
| 124 | if (e.IsPowerButtonDown) |
|---|
| 125 | funcName.Append("_Power"); |
|---|
| 126 | |
|---|
| 127 | Call(funcName.ToString(), e); |
|---|
| 128 | }; |
|---|
| 129 | |
|---|
| 130 | helper.Disconnected += delegate |
|---|
| 131 | { |
|---|
| 132 | ShowBalloonTip(Resources.Strings.KeyboardDisconnected, ToolTipIcon.Warning); |
|---|
| 133 | helper.Shutdown(); |
|---|
| 134 | while (!helper.Start()) |
|---|
| 135 | { |
|---|
| 136 | // retry at interval of 10sec |
|---|
| 137 | System.Threading.Thread.Sleep(10000); |
|---|
| 138 | } |
|---|
| 139 | ShowBalloonTip(Resources.Strings.KeyboardConnected, ToolTipIcon.Info); |
|---|
| 140 | }; |
|---|
| 141 | |
|---|
| 142 | if (!helper.Start()) |
|---|
| 143 | { |
|---|
| 144 | MessageBox.Show(Resources.Strings.KeyboardNotConnected, ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Error); |
|---|
| 145 | return; |
|---|
| 146 | } |
|---|
| 147 | |
|---|
| 148 | helper.Hook(); |
|---|
| 149 | |
|---|
| 150 | SetupNotifyIcon(); |
|---|
| 151 | LoadScripts(); |
|---|
| 152 | |
|---|
| 153 | Application.Run(); |
|---|
| 154 | |
|---|
| 155 | _notifyIcon.Visible = false; |
|---|
| 156 | } |
|---|
| 157 | } |
|---|
| 158 | |
|---|
| 159 | /// <summary> |
|---|
| 160 | /// |
|---|
| 161 | /// </summary> |
|---|
| 162 | /// <param name="funcName"></param> |
|---|
| 163 | /// <param name="e"></param> |
|---|
| 164 | private static void Call(String funcName, EventArgs e) |
|---|
| 165 | { |
|---|
| 166 | Object funcObj; |
|---|
| 167 | if (!_module.TryLookupVariable(funcName, out funcObj)) |
|---|
| 168 | return; |
|---|
| 169 | |
|---|
| 170 | FastCallable f = funcObj as FastCallable; |
|---|
| 171 | if (f == null) |
|---|
| 172 | return; |
|---|
| 173 | try |
|---|
| 174 | { |
|---|
| 175 | f.Call(InvariantContext.CodeContext); |
|---|
| 176 | } |
|---|
| 177 | catch (Exception ex) |
|---|
| 178 | { |
|---|
| 179 | MessageBox.Show(ex.ToString(), ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Error); |
|---|
| 180 | } |
|---|
| 181 | } |
|---|
| 182 | |
|---|
| 183 | |
|---|
| 184 | |
|---|
| 185 | /// <summary> |
|---|
| 186 | /// |
|---|
| 187 | /// </summary> |
|---|
| 188 | private static void LoadScripts() |
|---|
| 189 | { |
|---|
| 190 | // �Â�����ׂč폜 |
|---|
| 191 | OnUnload(EventArgs.Empty); |
|---|
| 192 | Unload = null; |
|---|
| 193 | Load = null; |
|---|
| 194 | |
|---|
| 195 | #pragma warning disable 0618 |
|---|
| 196 | DynamicHelpers.TopNamespace.LoadAssembly(Assembly.GetExecutingAssembly()); |
|---|
| 197 | DynamicHelpers.TopNamespace.LoadAssembly(Assembly.LoadWithPartialName("System.Windows.Forms")); |
|---|
| 198 | #pragma warning restore 0618 |
|---|
| 199 | |
|---|
| 200 | IScriptEnvironment scriptEnv = ScriptEnvironment.GetEnvironment(); |
|---|
| 201 | _module = scriptEnv.CreateModule("ScriptModule"); |
|---|
| 202 | |
|---|
| 203 | Boolean hasScripts = false; |
|---|
| 204 | if (Directory.Exists("Scripts")) |
|---|
| 205 | { |
|---|
| 206 | foreach (String path in Directory.GetFiles("Scripts", "*.py")) |
|---|
| 207 | { |
|---|
| 208 | Debug.WriteLine("Load Script: " + path); |
|---|
| 209 | try |
|---|
| 210 | { |
|---|
| 211 | IScriptEngine engine = scriptEnv.GetLanguageProviderByFileExtension(Path.GetExtension(path)).GetEngine(); |
|---|
| 212 | engine.ExecuteFileContent(path, _module); |
|---|
| 213 | hasScripts = true; |
|---|
| 214 | } |
|---|
| 215 | catch (SyntaxErrorException se) |
|---|
| 216 | { |
|---|
| 217 | MessageBox.Show(String.Format(Resources.Strings.ScriptSyntaxException, path, se.Line, se.Column, se.Message), ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Error); |
|---|
| 218 | } |
|---|
| 219 | catch (Exception e) |
|---|
| 220 | { |
|---|
| 221 | MessageBox.Show(String.Format(Resources.Strings.ScriptException, path, e.Message), ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Error); |
|---|
| 222 | } |
|---|
| 223 | } |
|---|
| 224 | } |
|---|
| 225 | |
|---|
| 226 | // �����ݍ�����Ȃ�������t�H���g |
|---|
| 227 | if (!hasScripts) |
|---|
| 228 | { |
|---|
| 229 | Script.GetEngine("py").Execute(Resources.Strings.DefaultPythonScript, _module); |
|---|
| 230 | } |
|---|
| 231 | |
|---|
| 232 | // ��s |
|---|
| 233 | _module.Execute(); |
|---|
| 234 | |
|---|
| 235 | OnLoad(EventArgs.Empty); |
|---|
| 236 | |
|---|
| 237 | ShowBalloonTip(Resources.Strings.ScriptsLoaded, ToolTipIcon.Info); |
|---|
| 238 | } |
|---|
| 239 | |
|---|
| 240 | /// <summary> |
|---|
| 241 | /// |
|---|
| 242 | /// </summary> |
|---|
| 243 | private static void SetupNotifyIcon() |
|---|
| 244 | { |
|---|
| 245 | _notifyIcon = new NotifyIcon(); |
|---|
| 246 | _notifyIcon.Icon = Resources.Common.AppleWirelessKeyboardHelperTrayIcon16x16; |
|---|
| 247 | _notifyIcon.Text = ApplicationName; |
|---|
| 248 | _notifyIcon.Visible = true; |
|---|
| 249 | _notifyIcon.ContextMenu = new ContextMenu(new MenuItem[]{ |
|---|
| 250 | new MenuItem(Resources.Strings.MenuItemReloadScripts, delegate { |
|---|
| 251 | LoadScripts(); |
|---|
| 252 | }) |
|---|
| 253 | , new MenuItem("-") |
|---|
| 254 | , new MenuItem(Resources.Strings.MenuItemExit, delegate { |
|---|
| 255 | Application.Exit(); |
|---|
| 256 | }) |
|---|
| 257 | }); |
|---|
| 258 | } |
|---|
| 259 | |
|---|
| 260 | public static void ShowBalloonTip(String text) |
|---|
| 261 | { |
|---|
| 262 | ShowBalloonTip(text, ToolTipIcon.Info); |
|---|
| 263 | } |
|---|
| 264 | |
|---|
| 265 | public static void ShowBalloonTip(String text, ToolTipIcon toolTipIcon) |
|---|
| 266 | { |
|---|
| 267 | _notifyIcon.ShowBalloonTip(BalloonTipTimeout, ApplicationName, text, toolTipIcon); |
|---|
| 268 | } |
|---|
| 269 | |
|---|
| 270 | public static event EventHandler Unload; |
|---|
| 271 | private static void OnUnload(EventArgs e) |
|---|
| 272 | { |
|---|
| 273 | try |
|---|
| 274 | { |
|---|
| 275 | if (Unload != null) |
|---|
| 276 | Unload(new Object(), e); |
|---|
| 277 | } |
|---|
| 278 | catch (Exception ex) |
|---|
| 279 | { |
|---|
| 280 | Debug.WriteLine(ex.ToString()); |
|---|
| 281 | } |
|---|
| 282 | } |
|---|
| 283 | public static event EventHandler Load; |
|---|
| 284 | private static void OnLoad(EventArgs e) |
|---|
| 285 | { |
|---|
| 286 | try |
|---|
| 287 | { |
|---|
| 288 | if (Load != null) |
|---|
| 289 | Load(new Object(), e); |
|---|
| 290 | } |
|---|
| 291 | catch (Exception ex) |
|---|
| 292 | { |
|---|
| 293 | Debug.WriteLine(ex.ToString()); |
|---|
| 294 | } |
|---|
| 295 | } |
|---|
| 296 | } |
|---|
| 297 | } |
|---|