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 Egtra (@egtra) <http://dev.activebasic.com/egtra/>
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.Diagnostics;
31 using System.Runtime.InteropServices;
32 using System.Threading;
33 using System.Windows.Forms;
34 using OpenTween.Connection;
38 internal static class NativeMethods
40 // 指定されたウィンドウへ、指定されたメッセージを送信します
41 [DllImport("user32.dll")]
42 private extern static IntPtr SendMessage(
48 // SendMessageで送信するメッセージ
49 private enum SendMessageType : uint
51 WM_SETREDRAW = 0x000B, //再描画を許可するかを設定
52 WM_USER = 0x400, //ユーザー定義メッセージ
54 TCM_FIRST = 0x1300, //タブコントロールメッセージ
55 TCM_SETMINTABWIDTH = TCM_FIRST + 49, //タブアイテムの最小幅を設定
57 LVM_FIRST = 0x1000, //リストビューメッセージ
58 LVM_GETSELECTIONMARK = LVM_FIRST + 66, //複数選択時の起点になるアイテムの位置を取得
59 LVM_SETSELECTIONMARK = LVM_FIRST + 67, //複数選択時の起点になるアイテムを設定
63 /// コントロールの再描画を許可するかを設定します
65 /// <param name="control">対象となるコントロール</param>
66 /// <param name="redraw">再描画を許可する場合は true、抑制する場合は false</param>
67 /// <returns>このメッセージを処理する場合、アプリケーションは 0 を返します</returns>
68 public static int SetRedrawState(Control control, bool redraw)
70 var state = redraw ? new IntPtr(1) : IntPtr.Zero;
71 return (int)SendMessage(control.Handle, SendMessageType.WM_SETREDRAW, state, IntPtr.Zero);
75 /// タブコントロールのアイテムの最小幅を設定します
77 /// <param name="tabControl">対象となるタブコントロール</param>
78 /// <param name="width">アイテムの最小幅。-1 を指定するとデフォルトの幅が使用されます</param>
79 /// <returns>設定前の最小幅</returns>
80 public static int SetMinTabWidth(TabControl tabControl, int width)
82 return (int)SendMessage(tabControl.Handle, SendMessageType.TCM_SETMINTABWIDTH, IntPtr.Zero, (IntPtr)width);
86 private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
89 /// 最小化状態のウィンドウを最小化する前の状態に復元します。
91 /// <param name="window">復元するウィンドウ。</param>
92 /// <exception cref="System.ArgumentNullException"><paramref name="window"/> が null です。</exception>
93 public static void RestoreWindow(IWin32Window window)
97 throw new ArgumentNullException("window");
100 ShowWindow(window.Handle, /* SW_RESTORE */ 9);
104 public static bool FlashMyWindow(IntPtr hwnd,
105 FlashSpecification flashType,
108 var fInfo = new FLASHWINFO();
109 fInfo.cbSize = Convert.ToInt32(Marshal.SizeOf(fInfo));
111 fInfo.dwFlags = (int)FlashSpecification.FlashAll;
112 fInfo.uCount = flashCount;
115 return FlashWindowEx(ref fInfo);
118 public enum FlashSpecification : uint
120 FlashStop = FLASHW_STOP,
121 FlashCaption = FLASHW_CAPTION,
122 FlashTray = FLASHW_TRAY,
123 FlashAll = FLASHW_ALL,
124 FlashTimer = FLASHW_TIMER,
125 FlashTimerNoForeground = FLASHW_TIMERNOFG,
127 /// http://www.atmarkit.co.jp/fdotnet/dotnettips/723flashwindow/flashwindow.html
128 [DllImport("user32.dll")]
129 private static extern bool FlashWindowEx(
130 ref FLASHWINFO FWInfo);
133 private struct FLASHWINFO
135 public Int32 cbSize; // FLASHWINFO構造体のサイズ
136 public IntPtr hwnd; // 点滅対象のウィンドウ・ハンドル
137 public Int32 dwFlags; // 以下の「FLASHW_XXX」のいずれか
138 public Int32 uCount; // 点滅する回数
139 public Int32 dwTimeout; // 点滅する間隔(ミリ秒単位)
143 private const Int32 FLASHW_STOP = 0;
145 private const Int32 FLASHW_CAPTION = 0x1;
147 private const Int32 FLASHW_TRAY = 0x2;
148 // タスクバー・ボタンとタイトルバーを点滅させる
149 private const Int32 FLASHW_ALL = 0x3;
150 // FLASHW_STOPが指定されるまでずっと点滅させる
151 private const Int32 FLASHW_TIMER = 0x4;
152 // ウィンドウが最前面に来るまでずっと点滅させる
153 private const Int32 FLASHW_TIMERNOFG = 0xC;
156 [DllImport("user32.dll")]
157 public static extern bool ValidateRect(
161 #region "selection mark"
162 // 複数選択時の起点になるアイテム (selection mark) の位置を取得する
163 public static int ListView_GetSelectionMark(IntPtr hwndLV)
165 return SendMessage(hwndLV, SendMessageType.LVM_GETSELECTIONMARK, IntPtr.Zero, IntPtr.Zero).ToInt32();
168 // 複数選択時の起点になるアイテム (selection mark) を設定する
169 public static void ListView_SetSelectionMark(IntPtr hwndLV, int itemIndex)
171 SendMessage(hwndLV, SendMessageType.LVM_SETSELECTIONMARK, IntPtr.Zero, (IntPtr)itemIndex);
175 #region "スクリーンセーバー起動中か判定"
176 [DllImport("user32", CharSet = CharSet.Auto)]
177 private static extern int SystemParametersInfo(
182 // returns non-zero value if function succeeds
184 //スクリーンセーバーが起動中かを取得する定数
185 private const int SPI_GETSCREENSAVERRUNNING = 0x0072;
187 public static bool IsScreenSaverRunning()
189 var isRunning = false;
190 SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0, ref isRunning, 0);
196 [DllImport("user32")]
197 private static extern int RegisterHotKey(IntPtr hwnd, int id,
198 int fsModifiers, int vk);
199 [DllImport("user32")]
200 private static extern int UnregisterHotKey(IntPtr hwnd, int id);
201 [DllImport("kernel32", CharSet = CharSet.Auto, BestFitMapping = false, ThrowOnUnmappableChar = true)]
202 private static extern ushort GlobalAddAtom([MarshalAs(UnmanagedType.LPTStr)] string lpString);
203 [DllImport("kernel32")]
204 private static extern ushort GlobalDeleteAtom(ushort nAtom);
206 private static int registerCount = 0;
207 // register a global hot key
208 public static int RegisterGlobalHotKey(int hotkeyValue, int modifiers, Form targetForm)
213 // use the GlobalAddAtom API to get a unique ID (as suggested by MSDN docs)
215 var atomName = Thread.CurrentThread.ManagedThreadId.ToString("X8") + targetForm.Name + registerCount.ToString();
216 hotkeyID = GlobalAddAtom(atomName);
219 throw new Exception("Unable to generate unique hotkey ID. Error code: " +
220 Marshal.GetLastWin32Error().ToString());
223 // register the hotkey, throw if any error
224 if (RegisterHotKey(targetForm.Handle, hotkeyID, modifiers, hotkeyValue) == 0)
226 throw new Exception("Unable to register hotkey. Error code: " +
227 Marshal.GetLastWin32Error().ToString());
233 // clean up if hotkey registration failed
234 UnregisterGlobalHotKey(hotkeyID, targetForm);
239 // unregister a global hotkey
240 public static void UnregisterGlobalHotKey(ushort hotkeyID, Form targetForm)
244 UnregisterHotKey(targetForm.Handle, hotkeyID);
245 // clean up the atom list
246 GlobalDeleteAtom(hotkeyID);
252 #region "プロセスのProxy設定"
253 [DllImport("wininet.dll", SetLastError =true)]
254 private static extern bool InternetSetOption(IntPtr hInternet,
257 int lpdwBufferLength);
259 private struct INTERNET_PROXY_INFO : IDisposable
261 public int dwAccessType;
263 public IntPtr proxyBypass;
265 public void Dispose()
270 private void Dispose(bool disposing)
272 if (proxy != IntPtr.Zero) Marshal.FreeHGlobal(proxy);
273 if (proxyBypass != IntPtr.Zero) Marshal.FreeHGlobal(proxyBypass);
277 private static void RefreshProxySettings(string strProxy)
279 const int INTERNET_OPTION_PROXY = 38;
280 //const int INTERNET_OPEN_TYPE_PRECONFIG = 0; //IE setting
281 const int INTERNET_OPEN_TYPE_DIRECT = 1; //Direct
282 const int INTERNET_OPEN_TYPE_PROXY = 3; //Custom
284 INTERNET_PROXY_INFO ipi;
286 // Filling in structure
287 if (!string.IsNullOrEmpty(strProxy))
289 ipi.dwAccessType = INTERNET_OPEN_TYPE_PROXY;
290 ipi.proxy = Marshal.StringToHGlobalAnsi(strProxy);
291 ipi.proxyBypass = Marshal.StringToHGlobalAnsi("local");
293 else if (strProxy == null)
296 var p = WebRequest.GetSystemWebProxy();
297 if (p.IsBypassed(new Uri("http://www.google.com/")))
299 ipi.dwAccessType = INTERNET_OPEN_TYPE_DIRECT;
300 ipi.proxy = IntPtr.Zero;
301 ipi.proxyBypass = IntPtr.Zero;
305 ipi.dwAccessType = INTERNET_OPEN_TYPE_PROXY;
306 ipi.proxy = Marshal.StringToHGlobalAnsi(p.GetProxy(new Uri("http://www.google.com/")).Authority);
307 ipi.proxyBypass = Marshal.StringToHGlobalAnsi("local");
312 ipi.dwAccessType = INTERNET_OPEN_TYPE_DIRECT;
313 ipi.proxy = IntPtr.Zero;
314 ipi.proxyBypass = IntPtr.Zero;
320 var pIpi = Marshal.AllocCoTaskMem(Marshal.SizeOf(ipi));
321 if (pIpi.Equals(IntPtr.Zero)) return;
324 // Converting structure to IntPtr
325 Marshal.StructureToPtr(ipi, pIpi, true);
326 var ret = InternetSetOption(IntPtr.Zero,
327 INTERNET_OPTION_PROXY,
329 Marshal.SizeOf(ipi));
333 Marshal.FreeCoTaskMem(pIpi);
342 private static void RefreshProxyAccount(string username, string password)
344 const int INTERNET_OPTION_PROXY_USERNAME = 43;
345 const int INTERNET_OPTION_PROXY_PASSWORD = 44;
347 if (!string.IsNullOrEmpty(username) || !string.IsNullOrEmpty(password))
349 var ret = InternetSetOption(IntPtr.Zero, INTERNET_OPTION_PROXY_USERNAME, IntPtr.Zero, 0);
350 ret = InternetSetOption(IntPtr.Zero, INTERNET_OPTION_PROXY_PASSWORD, IntPtr.Zero, 0);
354 var pUser = Marshal.StringToBSTR(username);
355 var pPass = Marshal.StringToBSTR(password);
358 var ret = InternetSetOption(IntPtr.Zero, INTERNET_OPTION_PROXY_USERNAME, pUser, username.Length + 1);
359 ret = InternetSetOption(IntPtr.Zero, INTERNET_OPTION_PROXY_PASSWORD, pPass, password.Length + 1);
363 Marshal.FreeBSTR(pUser);
364 Marshal.FreeBSTR(pPass);
369 public static void SetProxy(ProxyType pType, string host, int port, string username, string password)
380 case ProxyType.Specified:
381 proxy = host + (port > 0 ? ":" + port.ToString() : "");
384 RefreshProxySettings(proxy);
385 RefreshProxyAccount(username, password);