[[20150917141348]] 『全てのウィンドウを最大化』(サラマンダ) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『全てのウィンドウを最大化』(サラマンダ)

 こんにちは、よろしくお願いいたします。

 開いている全てのウィンドウの最小化、最大化を行おうとしています。
 沢山開いているウィンドウをある 作業をするために一旦すべてを最小化、
 特定のウィンドウのみを表示して作業して、作業が終わったら全てのウィンドウ
 を元に戻す、というのは↓で出来ました。

 CreateObject("Shell.Application").MinimizeAll '全てのウィンドウの最小化
 CreateObject("Shell.Application").UndoMinimizeAll '全てのウィンドウを元に戻す

 いまやろうとしているのは、全てのウィンドウの最大化です。

 MinimizeAll を↓のようにMaximizeAllに変えて実行したら、

 実行時エラー438
 オブジェクトは、このプロパティまたはメソッドをサポートしていません 。

 とエラーになります。

 CreateObject("Shell.Application").MaxiimizeAll

 全てのウィンドウを最大化するにはどうすればいいでしょうか?

 ショートカットキーのWin+Dは「全てのウィンドウを元に戻す」と同じ結果(厳密には違うようですが)
 になります。

 方法がありましたらご教示お願いいたします。

 なお、↓の他の方の質問とは関係ありません。

[[20150910150338]] 『2013で一括最大化』(あめちぇちぇ)

< 使用 Excel:Excel2007、使用 OS:WindowsVista >


まじめに実現するならば、APIを使ってウィンドウハンドルの一覧を得て、片っ端から最大化するイベントを
投げることになるでしょう。Excelの範疇を超える方法なので、やる気があるならば、ご自分で調べてみてください。

Excelマクロでささっと実現する場合、以下のキー操作を片っ端から投げるとか。

ALT+SPACE+X (最大化します。ALT+SPACE+Rで元に戻します)
ALT+TAB (次のウィンドウをアクティブにします)

 Sub test()
    Dim i As Long

    For i = 1 To 10 'ウィンドウ数が判らないので、10は適当な回数
        SendKeys "%( X)", True
        SendKeys "%{TAB}", True
        DoEvents
    Next i
 End Sub
(???) 2015/09/17(木) 14:38

ちょっと安直すぎたようです。2ウィンドウしか最大化されませんでした…。
(毎回、マクロに戻ってきてしまい、マクロと次だけ最大化しているようです)

APIを使うにしても、WIN+M(SHIFTも押せば復帰)を送るだけで良い、とかならば簡単ですが、ウィンドウ列挙までは面倒です。
(APIに手を出す場合、SW_MAXIMIZE あたりで検索をかければ良いかも)
(???) 2015/09/17(木) 14:56


 ???さん、ご回答ありがとうございます。

 API ウィンドウハンドル 一覧
 と
 SW_MAXIMIZE
 で検索してみました。

 ↓が見つかりましたので
http://www.asahi-net.or.jp/~fq7y-krsk/vba_v1.2/Win32API_VBA/xShowWindow.html
http://www.geocities.co.jp/SiliconValley/4805/vbtips/vbtips078.htm

 参考に下記のコードを組んでみました。APIはまだあまり使ったことがないのですが、一応
 うまくいきました。

 ありがとうございました。

 ※最初、別のサイトの全てのウィンドウを列挙するコードにウィンドウを最大化する
 記述を組み込んだのですが、「全てのウィンドウ」だったので、最終的にはパソコンが
 ハングアップしました。普段は見られないものも見られたのでいい経験には?なりました。
 え?これも最大化するの?というのも最大化しました。

 ↓は可視ウィンドウのみを最大化するコードになっていると思います。

 '----------------------------------------------------------
 ' Module
 '----------------------------------------------------------
 Public Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long

 Public Declare Function IsWindowVisible Lib "user32" (ByVal hWnd As Long) As Long

 Public Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long

 Public Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As Long

 Public Declare Function GetWindow Lib "user32" (ByVal hWnd As Long, ByVal wCmd As Long) As Long

 Public Declare Function ShowWindow Lib "user32" (ByVal hwindow As Long, ByVal cmdshow As Long) As Long

 'GetWindowで使用する定数
 Public Const GW_OWNER = 4

 Private Const SW_MAXIMIZE = 3

 'コールバック関数
 Public Function EnumWndProc(ByVal hWnd As Long, lParam As Long) As Boolean
     Dim strWindowName As String * 128
     Dim strClassName As String * 128
     Dim lngRet As Long
     Dim ret As Long
     strWindowName = ""
     strClassName = ""
     lngRet = GetWindowText(hWnd, strWindowName, Len(strWindowName))
     Call GetClassName(hWnd, strClassName, Len(strClassName))

     'EnumWindowsでは不可視のウィンドウ(IME等)も列挙されてしまうため、抽出します。
     If IsWindowVisible(hWnd) Then             '可視状態か
         If GetWindow(hWnd, GW_OWNER) = 0 Then 'オーナーフォームか
             If lngRet <> 0 Then                 'キャプションを持っているか
                 If Left(strClassName, 7) <> "Progman" Then 'シェルでないか
                    ret = ShowWindow(hWnd, SW_MAXIMIZE)
                 End If
             End If
         End If
     End If
     EnumWndProc = True
 End Function

 Sub test()
  Call EnumWindows(AddressOf EnumWndProc, 0)
 End Sub
(サラマンダ) 2015/09/17(木) 15:56

おぉ、頑張りましたね! そうなんですよ、APIだと何か問題があると、コケるんですよ。
私の方で作ってみた例なぞ。標準モジュールに以下を貼り付けて、testBigまたはtestNormalを実行してください。

 Declare Function EnumWindows Lib "user32.dll" (ByVal lpEnumFunc As Long, lParam As Long) As Long
 Declare Function IsWindowVisible Lib "user32.dll" (ByVal hWnd As Long) As Long
 Declare Function IsWindowEnabled Lib "user32.dll" (ByVal hWnd As Long) As Long
 Declare Function ShowWindow Lib "user32.dll" (ByVal lHwnd As Long, ByVal lCmdShow As Long) As Boolean

 Const SW_SHOWNORMAL As Long = 1
 Const SW_MAXIMIZE As Long = 3

 Sub testBig()
     Call EnumWindows(AddressOf f, SW_MAXIMIZE)
 End Sub

 Sub testNormal()
     Call EnumWindows(AddressOf f, SW_SHOWNORMAL)
 End Sub

 Function f(ByVal hWnd As Long, lParam As Long) As Long
     If IsWindowVisible(hWnd) = 1 And IsWindowEnabled(hWnd) = 1 Then
        Call ShowWindow(hWnd, lParam)
     End If
     f = 1
 End Function
(???) 2015/09/17(木) 16:05

 ???さん、ありがとうございます。

 testNormalは作動するのですが、testBigはハングアップしてしまいます。

 >APIだと何か問題があると、コケるんですよ。
 これの例でしょうか?
(サラマンダ) 2015/09/17(木) 17:06

VisibleでEnableなウィンドウだけ対象でいける、私の環境では大丈夫、という例だったのですが、
これだとプログラムマネージャも含まれていますね。うーん、クラス名チェックは必要という事ですかね。
(???) 2015/09/17(木) 17:32

というわけで、サラマンダさんのコードから、クラス名チェックを導入してみた例。

 Declare Function EnumWindows Lib "user32.dll" (ByVal lpEnumFunc As Long, lParam As Long) As Long
 Declare Function IsWindowVisible Lib "user32.dll" (ByVal hWnd As Long) As Long
 Declare Function IsWindowEnabled Lib "user32.dll" (ByVal hWnd As Long) As Long
 Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
 Declare Function ShowWindow Lib "user32.dll" (ByVal hWnd As Long, ByVal lCmdShow As Long) As Boolean
 Const SW_SHOWNORMAL As Long = 1
 Const SW_MAXIMIZE As Long = 3

 Sub testBig()
     Call EnumWindows(AddressOf f, SW_MAXIMIZE)
 End Sub

 Sub testNormal()
     Call EnumWindows(AddressOf f, SW_SHOWNORMAL)
 End Sub

 Function f(ByVal hWnd As Long, lParam As Long) As Long
    Dim strClassName As String * 128

    If IsWindowVisible(hWnd) = 1 And IsWindowEnabled(hWnd) = 1 Then
        Call GetClassName(hWnd, strClassName, Len(strClassName))
        If Left(strClassName, 7) <> "Progman" Then
            Call ShowWindow(hWnd, lParam)
        End If
    End If
    f = 1
 End Function

試していませんが、これでも、他のアプリでも問題がでるものがあるかも知れません。
各ウィンドウが最大化メニュー項目を持つかチェックし、有効だった場合だけ最大化すべき、な気がします。
(???) 2015/09/17(木) 17:47


ちょっと流れを変えてすいませんが、いろいろ調べてWordがあれば可能です
Sub window_max()
    Dim WD, task, n As Long
    Dim wdWindowStateMinimize
    Set WD = CreateObject("Word.Application")    ''Wordを起動します
    For Each task In WD.Tasks                    ''Word VBAのTasksコレクションを調べます
        If task.Visible = True Then              ''タスク(プロセス)が実行中だったら
        task.Activate
        task.WindowState = 1
        End If
    Next
    WD.Quit
    Set WD = Nothing
End Sub
(デイト) 2015/09/17(木) 17:49

 ???さん、ご回答ありがとうございます。

 >各ウィンドウが最大化メニュー項目を持つかチェックし、有効だった場合だけ最大化すべき、な気がします。

 開いているウィンドウのアプリケーションはそんなに種類がないので、特定のクラスのウィンドウのみを
 最大化の対象とする、ということで対応しようと思います。

 デイトさん、ご回答ありがとうございます。
 Wordオブジェクトを利用してこんなことができるのですね。他にもWordを間接的に利用してWordとは直接関係
 ない処理をするのを見たことがあるような気がします。Word恐るべし?ですね。

 ありがとうございました。
(サラマンダ) 2015/09/17(木) 18:01

WordのVBAならば、APIを使わずにタスク情報を得られるのですね。これは知らなかったです。安全で良いかも? メモメモ…。
(???) 2015/09/18(金) 09:08

 あまりこんなことやる人いないと思いますけど、もしこれと同じことをやろうとする人への情報
 提供です。

 API使用のコードの方です。

 専用のブックを作成し、ブック起動時に特定のクラスのウィンドウを最大化するコードを実行し、
 実行終了後にブックを自動で閉じる、というようにしたら、他に開いているブックのユーザー
 フォームの再表示がエラーになる(ブックが非アクティブになったらユーザーフォームをHideし、
 A1セルに配置したラベルのMouseMoveイベントでユーザーフォームを表示させる、というよう
 にしてあります)という現象がでました。

 いろいろ調べましたが原因がわからず。

 VBSから新規エクセルアプリケーションを立ち上げて、そのアプリケーションでウィンドウ最大
 化のブックを起動するようにしたら他のブックに影響が出ないようになりました。
(サラマンダ) 2015/09/18(金) 09:20

 補足です。

 ブック起動時やブック閉じるときに、ほかのブックと共通の作業をマクロで行ってるのと、
 独自のアドインが影響している可能性がありますので、コード自体には問題ないかもし
 れません。
(サラマンダ) 2015/09/18(金) 09:27

コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.