1 // OpenTween - Client of Twitter
2 // Copyright (c) 2007-2011 kiri_feather (@kiri_feather) <kiri.feather@gmail.com>
3 // (c) 2008-2011 Moz (@syo68k)
4 // (c) 2008-2011 takeshik (@takeshik) <http://www.takeshik.org/>
5 // (c) 2010-2011 anis774 (@anis774) <http://d.hatena.ne.jp/anis774/>
6 // (c) 2010-2011 fantasticswallow (@f_swallow) <http://twitter.com/f_swallow>
7 // (c) 2011 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
8 // All rights reserved.
10 // This file is part of OpenTween.
12 // This program is free software; you can redistribute it and/or modify it
13 // under the terms of the GNU General public License as published by the Free
14 // Software Foundation; either version 3 of the License, or (at your option)
17 // This program is distributed in the hope that it will be useful, but
18 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License
22 // You should have received a copy of the GNU General public License along
23 // with this program. If not, see <http://www.gnu.org/licenses/>, or write to
24 // the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
25 // Boston, MA 02110-1301, USA.
28 using System.Collections.Generic;
31 using System.Reflection;
34 using System.Drawing.Imaging;
35 using System.Windows.Forms;
36 using System.ComponentModel;
37 using System.Collections;
41 public class GrowlHelper
43 private Assembly _connector = null;
44 private Assembly _core = null;
46 private object _growlNTreply;
47 private object _growlNTdm;
48 private object _growlNTnew;
49 private object _growlNTusevent;
50 private object _growlApp;
52 private object _targetConnector;
54 private string _appName = "";
55 bool _initialized = false;
57 public class NotifyCallbackEventArgs : EventArgs
59 public long StatusId { get; set; }
60 public NotifyType NotifyType { get; set; }
61 public NotifyCallbackEventArgs(NotifyType notifyType, string statusId)
63 if (statusId.Length > 1)
65 this.StatusId = long.Parse(statusId);
66 this.NotifyType = notifyType;
71 public event EventHandler<NotifyCallbackEventArgs> NotifyClicked;
75 get { return _appName; }
78 public enum NotifyType
86 public GrowlHelper(string appName)
91 public bool IsAvailable
95 if (_connector == null || _core == null || !_initialized)
102 private byte[] IconToByteArray(string filename)
104 using (Icon ic = new Icon(filename))
106 return IconToByteArray(ic);
110 private byte[] IconToByteArray(Icon icondata)
112 using (MemoryStream ms = new MemoryStream())
114 using (Icon ic = new Icon(icondata, 48, 48))
116 ic.ToBitmap().Save(ms, ImageFormat.Png);
122 public static bool IsDllExists
126 string dir = Application.StartupPath;
127 string connectorPath = Path.Combine(dir, "Growl.Connector.dll");
128 string corePath = Path.Combine(dir, "Growl.CoreLibrary.dll");
129 if (File.Exists(connectorPath) && File.Exists(corePath))
136 public bool RegisterGrowl()
138 _initialized = false;
139 string dir = Application.StartupPath;
140 string connectorPath = Path.Combine(dir, "Growl.Connector.dll");
141 string corePath = Path.Combine(dir, "Growl.CoreLibrary.dll");
145 if (!IsDllExists) return false;
146 _connector = Assembly.LoadFile(connectorPath);
147 _core = Assembly.LoadFile(corePath);
156 _targetConnector = _connector.CreateInstance("Growl.Connector.GrowlConnector");
157 Type _t = _connector.GetType("Growl.Connector.NotificationType");
159 _growlNTreply = _t.InvokeMember(null,
160 BindingFlags.CreateInstance, null, null, new object[] { "REPLY", "Reply" });
162 _growlNTdm = _t.InvokeMember(null,
163 BindingFlags.CreateInstance, null, null, new object[] { "DIRECT_MESSAGE", "DirectMessage" });
165 _growlNTnew = _t.InvokeMember(null,
166 BindingFlags.CreateInstance, null, null, new object[] { "NOTIFY", "新着通知" });
168 _growlNTusevent = _t.InvokeMember(null,
169 BindingFlags.CreateInstance, null, null, new object[] { "USERSTREAM_EVENT", "UserStream Event" });
172 _connector.GetType("Growl.Connector.Cryptography+SymmetricAlgorithmType").InvokeMember(
173 "PlainText", BindingFlags.GetField, null, null, null);
174 _targetConnector.GetType().InvokeMember("EncryptionAlgorithm", BindingFlags.SetProperty, null, _targetConnector, new object[] { encryptType });
176 _growlApp = _connector.CreateInstance(
177 "Growl.Connector.Application", false, BindingFlags.Default, null, new object[] { _appName }, null, null);
180 if (File.Exists(Path.Combine(Application.StartupPath, "Icons\\Tween.png")))
182 // Icons\Tween.pngを使用
183 ConstructorInfo ci = _core.GetType(
184 "Growl.CoreLibrary.Resource").GetConstructor(
185 BindingFlags.NonPublic | BindingFlags.Instance,
186 null, new Type[] { typeof(string) }, null);
188 object data = ci.Invoke(new object[] { Path.Combine(Application.StartupPath, "Icons\\Tween.png") });
189 PropertyInfo pi = _growlApp.GetType().GetProperty("Icon");
190 pi.SetValue(_growlApp, data, null);
193 else if (File.Exists(Path.Combine(Application.StartupPath, "Icons\\MIcon.ico")))
195 // アイコンセットにMIcon.icoが存在する場合それを使用
196 ConstructorInfo cibd = _core.GetType(
197 "Growl.CoreLibrary.BinaryData").GetConstructor(
198 BindingFlags.Public | BindingFlags.Instance,
199 null, new Type[] { typeof(byte[]) }, null);
200 object bdata = cibd.Invoke(
201 new object[] { IconToByteArray(Path.Combine(Application.StartupPath, "Icons\\MIcon.ico")) });
203 ConstructorInfo ciRes = _core.GetType(
204 "Growl.CoreLibrary.Resource").GetConstructor(
205 BindingFlags.NonPublic | BindingFlags.Instance,
206 null, new Type[] { bdata.GetType() }, null);
208 object data = ciRes.Invoke(new object[] { bdata });
209 PropertyInfo pi = _growlApp.GetType().GetProperty("Icon");
210 pi.SetValue(_growlApp, data, null);
215 ConstructorInfo cibd = _core.GetType(
216 "Growl.CoreLibrary.BinaryData").GetConstructor(
217 BindingFlags.Public | BindingFlags.Instance,
218 null, new Type[] { typeof(byte[]) }, null);
219 object bdata = cibd.Invoke(
220 new object[] { IconToByteArray(Properties.Resources.MIcon) });
222 ConstructorInfo ciRes = _core.GetType(
223 "Growl.CoreLibrary.Resource").GetConstructor(
224 BindingFlags.NonPublic | BindingFlags.Instance,
225 null, new Type[] { bdata.GetType() }, null);
227 object data = ciRes.Invoke(new object[] { bdata });
228 PropertyInfo pi = _growlApp.GetType().GetProperty("Icon");
229 pi.SetValue(_growlApp, data, null);
232 MethodInfo mi = _targetConnector.GetType().GetMethod("Register", new Type[] { _growlApp.GetType(), _connector.GetType("Growl.Connector.NotificationType[]") });
234 _t = _connector.GetType("Growl.Connector.NotificationType");
236 ArrayList arglist = new ArrayList();
237 arglist.Add(_growlNTreply);
238 arglist.Add(_growlNTdm);
239 arglist.Add(_growlNTnew);
240 arglist.Add(_growlNTusevent);
242 mi.Invoke(_targetConnector, new object[] { _growlApp, arglist.ToArray(_t) });
245 Type tGrowlConnector = _connector.GetType("Growl.Connector.GrowlConnector");
246 EventInfo evNotificationCallback = tGrowlConnector.GetEvent("NotificationCallback");
247 Type tDelegate = evNotificationCallback.EventHandlerType;
248 MethodInfo miHandler = typeof(GrowlHelper).GetMethod("GrowlCallbackHandler", BindingFlags.NonPublic | BindingFlags.Instance);
249 Delegate d = Delegate.CreateDelegate(tDelegate, this, miHandler);
250 MethodInfo miAddHandler = evNotificationCallback.GetAddMethod();
251 object[] addHandlerArgs = { d };
252 miAddHandler.Invoke(_targetConnector, addHandlerArgs);
258 _initialized = false;
265 public void Notify(NotifyType notificationType, string id, string title, string text, Image icon = null, string url = "")
267 if (!_initialized) return;
268 string notificationName = "";
269 switch (notificationType)
271 case NotifyType.Reply:
272 notificationName = "REPLY";
274 case NotifyType.DirectMessage:
275 notificationName = "DIRECT_MESSAGE";
277 case NotifyType.Notify:
278 notificationName = "NOTIFY";
280 case NotifyType.UserStreamEvent:
281 notificationName = "USERSTREAM_EVENT";
285 if (icon != null || !string.IsNullOrEmpty(url))
287 Type gCore = _core.GetType("Growl.CoreLibrary.Resource");
291 res = gCore.InvokeMember("op_Implicit",
292 BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod,
295 new object[] { icon });
299 res = gCore.InvokeMember("op_Implicit",
300 BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod,
303 new object[] { url });
306 _connector.GetType("Growl.Connector.Priority").InvokeMember(
307 "Normal", BindingFlags.GetField, null, null, null);
308 n = _connector.GetType("Growl.Connector.Notification").InvokeMember(
310 BindingFlags.CreateInstance,
313 new object[] {_appName,
325 n = _connector.GetType("Growl.Connector.Notification").InvokeMember(
327 BindingFlags.CreateInstance,
330 new object[] {_appName,
336 //_targetConnector.GetType.InvokeMember("Notify", BindingFlags.InvokeMethod, null, _targetConnector, new object[] {n});
337 object cc = _connector.GetType("Growl.Connector.CallbackContext").InvokeMember(
338 null, BindingFlags.CreateInstance, null, _connector,
339 new object[] { "some fake information", notificationName });
340 _targetConnector.GetType().InvokeMember("Notify", BindingFlags.InvokeMethod, null, _targetConnector, new object[] { n, cc });
343 private void GrowlCallbackHandler(object response, object callbackData, object state)
349 _core.GetType("Growl.CoreLibrary.CallbackResult").GetField(
351 BindingFlags.Public | BindingFlags.Static).GetRawConstantValue();
353 object vResult = callbackData.GetType().GetProperty(
355 BindingFlags.Public | BindingFlags.Instance).GetGetMethod().Invoke(callbackData, null);
356 vResult = (int)vResult;
357 string notifyId = (string)callbackData.GetType().GetProperty("NotificationID").GetGetMethod().Invoke(callbackData, null);
358 string notifyName = (string)callbackData.GetType().GetProperty("Type").GetGetMethod().Invoke(callbackData, null);
359 if (vCLICK.Equals(vResult))
365 nt = NotifyType.Reply;
367 case "DIRECT_MESSAGE":
368 nt = NotifyType.DirectMessage;
371 nt = NotifyType.Notify;
373 case "USERSTREAM_EVENT":
374 nt = NotifyType.UserStreamEvent;
380 if (NotifyClicked != null)
381 NotifyClicked(this, new NotifyCallbackEventArgs(nt, notifyId));