// Vistaの効果を有効にするフラグ(不要の場合はコメントアウト) #define USE_VISTA_EFFECTS using System; using System.Runtime.InteropServices; using System.Windows.Forms; using System.Drawing; namespace AppliStation.Util { /// /// Win32ネイティブメソッドを叩いてGUI操作するための関数群のクラス /// public sealed class NativeMethods { /// /// 呼び出し禁止 /// private NativeMethods() { } /// /// WindowsVista向け、プログレスバーステータス(色)を設定する /// /// 対象のプログレスバー /// 状態。(1:Normal,2:Error,3:Paused) public static void ProgressBar_SetState(ProgressBar progBar, uint state) { #if USE_VISTA_EFFECTS try { // status := (PBST_NORMAL | PBST_ERROR | PBST_PAUSED) // SendMessage(progressBar.Handle, PBM_SETSTATE, state, 0); SendMessage(progBar.Handle, 0x410, new IntPtr(state), IntPtr.Zero); } catch (Exception) { } #endif } #region タスクバーおよびタイトルバーのフラッシュ /// /// タスクバーおよびタイトルバーボタンのフラッシュの設定フラグ /// public enum FlashFlag : uint { /// /// 点滅の停止 /// Stop = 0, /// /// タイトルバーを点滅 /// Caption = 1, /// /// タスクバーボタンを点滅 /// Tray = 2, /// /// タイトルバーとタスクバーボタンを点滅 /// All = 3, /// /// Stopが設定されるまで点滅する /// Timer = 4, /// /// フォアグラウンドの状態になるまで点滅 /// TimerNoFG = 12, } [StructLayout(LayoutKind.Sequential)] struct FLASHWINFO { public int cbSize; public IntPtr hWnd; public FlashFlag dwFlags; public uint uCount; public uint dwTimeout; } /// /// タスクバーおよびタイトルバーボタンを点滅させる /// /// 対象フォーム /// 点滅パラメータフラグ /// 点滅回数 /// 点滅の間隔(ミリ秒) /// public static bool Form_FlashWindow(Form form, FlashFlag flag, uint count, uint timeout) { try { FLASHWINFO info = new FLASHWINFO(); info.cbSize = Marshal.SizeOf(typeof(FLASHWINFO)); info.hWnd = form.Handle; info.dwFlags = flag; info.uCount = count; info.dwTimeout = timeout; return FlashWindowEx(ref info) == 0; } catch (Exception) { return false; } } [DllImport("user32.dll")] static extern Int32 FlashWindowEx(ref FLASHWINFO pwfi); #endregion #region ListView関連 /// /// リストビューにダブルバッファでの描画をするか否かを設定する /// /// マウスでの選択に半透明ツールを採用するか否かもこの設定に依存 /// 対象のリストビュー /// ダブルバッファでの描画をするときtrue public static void ListView_SetDoubleBuffer(ListView listView, bool bEnable) { try { // SendMessage(listView.Handle, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_DOUBLEBUFFER, bEnable? LVS_EX_DOUBLEBUFFER:0); SendMessage(listView.Handle, 0x1036, new IntPtr(0x00010000), new IntPtr((bEnable)? 0x00010000u:0x0u)); } catch (Exception) { } } /// /// 選択されたアイテムの部分の背景にグラデーションがかかった感じになる、 /// Vista以降でのエクスプローラの見た目をListViewに反映させる。 /// /// Vista未満のバージョンでは何もしない。 /// 対象のListView public static void ListView_EnableVistaExplorerTheme(ListView listView) { #if USE_VISTA_EFFECTS // Vista未満はなにもしない OperatingSystem os = Environment.OSVersion; if (os.Platform != PlatformID.Win32NT || os.Version.Major < 6) return; try { SetWindowTheme(listView.Handle, "explorer", null); } catch (Exception) { } #endif } /// /// ヘッダに"すべて選択"に似たチェックボックスを作るか否かを指定する /// /// このオプションを設定するとVistaエクスプローラでの「チェックボックスを使用して項目を選択する」と同様の動作になる /// 対象のListBox /// チェックボックスを使用して項目を選択するときtrue public static void ListView_SetAutoCheckSelect(ListView listView, bool bAutoCheckSelect) { #if USE_VISTA_EFFECTS try { // SendMessage(listView.Handle, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_AUTOCHECKSELECT, bAutoCheckSelect?LVS_EX_AUTOCHECKSELECT:0); SendMessage(listView.Handle, 0x1036, new IntPtr(0x08000000), new IntPtr((bAutoCheckSelect)?0x08000000u:0x0u)); } catch (Exception) { } #endif } #region ColumnHeaderのソートの三角印用 [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)] private struct HD_ITEM { public uint mask; public int cxy; [MarshalAs(UnmanagedType.LPTStr)]public string pszText; public IntPtr hbm; public int cchTextMax; public int fmt; [MarshalAs(UnmanagedType.LPTStr)]public string lParam; public int iImage; // index of bitmap in ImageList public int iOrder; } /// /// WinXP以降、ソートの矢印を表示 /// /// 対象のListView /// 表示する矢印のヘッダ /// ソートの昇順・降順 public static void ColumnHeader_SetSortState(ListView listView, int column, SortOrder order) { try { // SendMessage(hWnd, LVM_GETHEADER, NULL, NULL); IntPtr hWnd = SendMessage(listView.Handle, 0x101F, IntPtr.Zero, IntPtr.Zero); HD_ITEM hdi = new HD_ITEM(); hdi.mask = 0x0004; // HDI_FORMAT; for (int i = 0; i < listView.Columns.Count; i++) { // SendMessage(hWnd, HDM_GETITEMW, i, &hdi); SendMessage(hWnd, 0x120b, new IntPtr(i), ref hdi); const int HDF_SORTUP = 0x400; const int HDF_SORTDOWN = 0x200; if (i != column || order == SortOrder.None) { hdi.fmt = hdi.fmt & ~(HDF_SORTUP | HDF_SORTDOWN); } else if (order == SortOrder.Ascending) { // 昇順 hdi.fmt = hdi.fmt & ~HDF_SORTDOWN | HDF_SORTUP; } else if (order == SortOrder.Descending) { // 降順 hdi.fmt = hdi.fmt & ~HDF_SORTUP | HDF_SORTDOWN; } // SendMessage(hWnd, HDM_SETITEMW, i, &hdi); SendMessage(hWnd, 0x120c, new IntPtr(i), ref hdi); } } catch (Exception) { } } #endregion #endregion #region EnableWindow(コメントアウト) // /// // /// 指定されたコントロール(ウィンドウ)への、 // /// キーボード入力およびマウス入力を有効化または無効化 // /// // /// 対象のコントロールのハンドラ // /// 有効にするか無効にするかを指定 // /// 直前にウィンドウが無効状態だった場合はtrueを返す // public static bool Control_EnableWindow(Control ctrl, bool bEnable) // { // try { // return EnableWindow(ctrl.Handle, bEnable); // } catch { // ctrl.Enabled = bEnable; // return true; // } // } // // /// // /// 指定されたコントロール(ウィンドウ)への、 // /// キーボード入力およびマウス入力を有効化または無効化 // /// // /// 対象のコントロールのハンドラ // /// 有効にするか無効にするかを指定 // /// 直前にウィンドウが無効状態だった場合はtrueを返す // [DllImport("user32.dll")] // public static extern bool EnableWindow(IntPtr hWnd, bool bEnable); #endregion #region RichTextBox関連 [StructLayout(LayoutKind.Sequential)] private struct CHARFORMAT2 { public int cbSize; public uint dwMask; public uint dwEffects; public int yHeight; public int yOffset; public int crTextColor; public byte bCharSet; public byte bPitchAndFamily; [MarshalAs(UnmanagedType.ByValArray, SizeConst=32)] public char[] szFaceName; public short wWeight; public short sSpacing; public int crBackColor; public int LCID; public uint dwReserved; public short sStyle; public short wKerning; public byte bUnderlineType; public byte bAnimation; public byte bRevAuthor; public byte bReserved1; } /// /// リッチテキストの選択部分に文字フォーマット効果を与える /// /// 対象のリッチテキストボックス /// 有効な文字フォーマット効果 /// 文字フォーマット効果のフラグ public static void RichTextBox_SetSelectionFormat(RichTextBox richTextBox, uint dwMask, uint dwEffect) { CHARFORMAT2 cfmt = new CHARFORMAT2(); cfmt.cbSize = Marshal.SizeOf(typeof(CHARFORMAT2)); cfmt.dwMask = dwMask; cfmt.dwEffects = dwEffect; //SendMessage(richTextBox.Handle, EM_SETCHARFORMAT, SCF_SELECTION, ref cfmt); SendMessage(richTextBox.Handle, 0x0444, new IntPtr(0x0001), ref cfmt); } /// /// リッチテキストにテキストリンクを追加する /// /// 対象のリッチテキストボックス /// 追加するテキスト public static void RichTextBox_AddTextLink(RichTextBox richTextBox, string text) { int pos = richTextBox.TextLength; richTextBox.Select(pos,0); richTextBox.SelectedText = text; richTextBox.Select(pos, text.Length); // RichTextBox_SetSelectionFormat(richTextBox, CFM_LINK, CFE_LINK); RichTextBox_SetSelectionFormat(richTextBox, 0x00000020, 0x0020); richTextBox.Select(richTextBox.TextLength, 0); } #endregion #region アイコン関連 [DllImport("shell32.dll")] private static extern IntPtr ExtractIcon(IntPtr hInst, string lpszExeFileName, int nIconIndex); [DllImport("user32.dll", SetLastError=true)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool DestroyIcon(IntPtr hIcon); /// /// アイコンファイル(実行ファイル・DLL)を開いてアイコンを作る /// /// 内部でコピーされるのでWin32APIのDestroyIconを使わないでいいが、やや遅い動作 /// ハンドラ /// 対象ファイル /// アイコンインデックス /// 生成されたアイコン public static Icon ExtractIcon(Form form, string lpszExeFileName, uint nIconIndex) { Icon ico = null; if (! System.IO.File.Exists(lpszExeFileName)) { ico = Icon.ExtractAssociatedIcon(lpszExeFileName); // ExtractAssociatedIconに例外を吐いてもらう } else { IntPtr hInst = (form != null)? form.Handle : IntPtr.Zero; IntPtr hIcon = IntPtr.Zero; try { hIcon = ExtractIcon(hInst, lpszExeFileName, (int) nIconIndex); if ((hIcon != IntPtr.Zero) && (hIcon.ToInt32() != 2)) { ico = (Icon) Icon.FromHandle(hIcon).Clone(); DestroyIcon(hIcon); } } catch (System.Runtime.InteropServices.COMException) { // ExtraIconのP/Invoke失敗時用 } } return ico; } /// /// ユーザ昇格が必要か設定し、設定必要なときシールドアイコンを表示する。 /// /// 対象のボタン /// ユーザ昇格が必要か否か、すなわちシールドアイコンを表示するか public static void Button_SetElevationRequiredState(Button button, bool required) { if (Environment.OSVersion.Version.Major >= 6) { button.FlatStyle = FlatStyle.System; // SendMessage(hWnd, BCM_SETSHIELD, 0, required); SendMessage(button.Handle, 0x160C, IntPtr.Zero, new IntPtr((required)? 1u : 0u)); } else { // Legacy OS // FlatStyle.System に設定されている場合、Image プロパティに割り当てられているイメージは表示されない対策 if (button.FlatStyle == FlatStyle.System) { button.FlatStyle = FlatStyle.Standard; } button.TextImageRelation = TextImageRelation.ImageBeforeText; button.ImageAlign = ContentAlignment.MiddleLeft; using (Icon ico = new Icon(SystemIcons.Shield, 16, 16)) { button.Image = ico.ToBitmap(); } button.AutoSize = true; } } #endregion [DllImport("user32.dll", CharSet = CharSet.Auto)] internal static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam); [DllImport("user32.dll", CharSet=CharSet.Auto)] private static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, ref HD_ITEM lParam); [DllImport("user32.dll", CharSet=CharSet.Auto)] private static extern IntPtr SendMessage(IntPtr hWnd, Int32 Msg, IntPtr wParam, ref CHARFORMAT2 lParam); [DllImport("uxtheme.dll", ExactSpelling=true, CharSet=CharSet.Unicode)] internal static extern int SetWindowTheme(IntPtr hWnd, String pszSubAppName, String pszSubIdList); } }