同類のタスクバーウィンドウをグループ化/グループ化解除する
この設定はAPIだけで完全に処理されるわけではありません。この設定は実際には次のレジストリキーの下に格納されています。
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\ Explorer\Advanced
設定名はTaskBarGlomming
です。値が0ならボタンのグループ化が解除され、1ならボタンがグループ化されます。従って、やるべきことは、このキーに1または0を書き込んでから、タスクバーウィンドウの表示を更新することです。これを行わないと、「explorer.exe」の再起動(コンピュータの再起動)まで、この設定は適用されません。タスクバーを更新するには、SendMessage APIを使用し、WM_WININIChange
メッセージをShellTrayWnd
に送信します。コードは次のようになります。
Private Sub btnGroup_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnGroup.Click Select Case btnGroup.Text Case "Group Similar TaskBar Buttons" Dim GroupRet As Long 'Used With SendMessage Dim TaskBarWin As Long 'Find TaskBar TaskBarWin = FindWindow("Shell_TrayWnd", vbNullString) 'Open Registry Key Dim GroupKey As RegistryKey = _ Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows _ \\CurrentVersion\\Explorer\\Advanced", True) 'Set Grouping On GroupKey.SetValue("TaskBarGlomming", 1, RegistryValueKind.DWord) 'Store New Setting GroupRet = SendMessage(TaskBarWin, WM_WININICHANGE, 0&, 0&) btnGroup.Text = "Don't Group Similar TaskBar Buttons" Case "Don't Group Similar TaskBar Buttons" Dim GroupRet As Long Dim TaskBarWin As Long TaskBarWin = FindWindow("Shell_TrayWnd", vbNullString) Dim GroupKey As RegistryKey = _ Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows _ \\CurrentVersion\\Explorer\\Advanced", True) 'Set Grouping Off GroupKey.SetValue("TaskBarGlomming", 0, RegistryValueKind.DWord) GroupRet = SendMessage(TaskBarWin, WM_WININICHANGE, 0&, 0&) btnGroup.Text = "Group Similar TaskBar Buttons" End Select End Sub
タスクバーのアクティブなウィンドウを隠す/表示する
この操作の全体的なロジックは、前述の時計を隠す/表示する場合とほとんど同じです。ただし、幸いなことにタスクバーウィンドウと"Buttons"ウィンドウ(ReBarWindow32
)だけを扱えば済みます。
従って、やるべきことは、ReBarWindow32
へのハンドルを取得してから、ShowWindow APIを使って開いているアクティブなウィンドウのボタンを隠す/表示することです。
Private Sub btnContents_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnContents.Click Select Case btnContents.Text Case "Show TaskBar Contents" Dim TaskBarWin As Long, TaskButtonWin As Long 'Find TaskBar TaskBarWin = FindWindow("Shell_TrayWnd", vbNullString) 'Find TaskBar Button Area TaskButtonWin = _ FindWindowEx(TaskBarWin, 0, "ReBarWindow32", vbNullString) ShowWindow(TaskButtonWin, 1) 'Show Active Buttons btnContents.Text = "Hide TaskBar Contents" Case "Hide TaskBar Contents" Dim TaskBarWin As Long, TaskButtonWin As Long TaskBarWin = FindWindow("Shell_TrayWnd", vbNullString) TaskButtonWin = _ FindWindowEx(TaskBarWin, 0, "ReBarWindow32", vbNullString) ShowWindow(TaskButtonWin, 0) 'Hide Active Buttons btnContents.Text = "Show TaskBar Contents" End Select End Sub
このボタンをクリックすると、開いているウィンドウの数にかかわらずタスクバーが空になり、図3のようになります。
アクティブでないアイコンを隠す設定をアクティブ/非アクティブにする
次のコードセグメントから分かるように、基本的な仕組みはタスクバーのグループ化設定とまったく同じです。
Private Sub btnInactiveTrayIcons_Click( _ ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnInactiveTrayIcons.Click Select Case btnInactiveTrayIcons.Text Case "AutoHide Inactive Tray Icons Off" Dim TrayWinRet As Long Dim TrayWindow As Long 'Find TaskBar TrayWindow = FindWindow("Shell_TrayWnd", vbNullString) Dim InactiveKey As RegistryKey = _ Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows _ \\CurrentVersion\\Explorer\\Advanced", True) 'Set Enable AutoTray Off InactiveKey.SetValue("EnableAutoTray", 0, RegistryValueKind.DWord) 'Store TrayWinRet = SendMessage(TrayWindow, WM_WININICHANGE, 0&, 0&) btnInactiveTrayIcons.Text = "AutoHide Inactive Tray Icons On" EnvRefresh() 'Refresh Explorer.exe Case "AutoHide Inactive Tray Icons On" Dim TrayWinRet As Long Dim TrayWindow As Long TrayWindow = FindWindow("Shell_TrayWnd", vbNullString) Dim InactiveKey As RegistryKey = _ Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows _ \\CurrentVersion\\Explorer\\Advanced", True) 'Set Enable AutoTray On InactiveKey.SetValue("EnableAutoTray", 1, RegistryValueKind.DWord) TrayWinRet = SendMessage(TrayWindow, WM_WININICHANGE, 0&, 0&) btnInactiveTrayIcons.Text = "AutoHide Inactive Tray Icons Off" EnvRefresh() End Select End Sub
EnvRefresh
上記のコードセグメントの最後の行では、EnvRefresh
という関数を呼び出しています。この関数は次のようなものです。
Public Sub EnvRefresh() ' Refresh Explorer Dim EnvResult As IntPtr 'Result SendMessageTimeout(HWND_BROADCAST, _ Convert.ToUInt32(WM_SETTINGCHANGE), _ 0, 0, _ Convert.ToUInt32(SMTO_ABORTIFHUNG), _ Convert.ToUInt32(2000), _ EnvResult) 'Broadcast A Setting Change To All End Sub
これをフォームのクラスに追加してください。この関数の役割は、コンピュータを再起動せずに、変更したレジストリ設定を適用することです。この関数はSendMessageTimeout APIを使って、すべてのWM_SETTINGCHANGE
メッセージをブロードキャストします。何かまずいことがあれば異常終了し、そうでなければ2秒以内に「explorer.exe」に対して変更内容の適用を試みます。