Skip to content

Instantly share code, notes, and snippets.

@dck-jp
Created August 29, 2012 17:13
Show Gist options
  • Save dck-jp/3515744 to your computer and use it in GitHub Desktop.
Save dck-jp/3515744 to your computer and use it in GitHub Desktop.
Arrange Word Windows Horizontal @ VBA (Word Only)
Private Declare Function IsWindowVisible Lib "user32" _
(ByVal hWnd&) As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
(ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" _
(ByVal hWnd As Long, ByVal lpClassName As String, _
ByVal nMaxCount As Long) As Long
Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function EnumWindows Lib "user32" _
(ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Dim windowHandles As Variant 'EnumWindowsProcで取得したハンドルの格納用
Private Function EnumWindowsProc _
(ByVal handle As Long, ByVal lParam As Object) As Long
If IsWindowVisible(handle) Then
windowHandles.Add (handle)
End If
EnumWindowsProc = True
End Function
' Word (ClassName: OpusApp)のウィンドウハンドルをまとめて取得
Public Function GetWindowHandlesOfWord() As Variant
Set windowHandles = New Collection
Call EnumWindows(AddressOf EnumWindowsProc, ByVal 0&) 'Long型を明示 ←末尾&で
Set windowHandles = FilterByClassName(windowHandles, "OpusApp")
Set GetWindowHandlesOfWord = windowHandles
End Function
Private Function FilterByClassName(handles, className As String) As Variant
Dim output As Variant
Set output = New Collection
Dim handle
For Each handle In handles
Call AddHandleIf(output, handle, className)
Next
Set FilterByClassName = output
End Function
Private Sub AddHandleIf(ByRef output, handle, className)
Dim strClassName As String * 100
Dim gettedClassName As String 'strClassNameは100文字に固定されているため。無駄な空白を除いた文字列を格納するための変数
GetClassName handle, strClassName, Len(strClassName)
gettedClassName = Trim(Left(strClassName, InStr(1, strClassName, vbNullChar) - 1))
If gettedClassName = className Then
output.Add (handle)
End If
End Sub
Option Explicit
Private Declare Function MoveWindow Lib "user32" _
(ByVal hWnd As Long, _
ByVal x As Long, ByVal y As Long, _
ByVal nWidth As Long, ByVal nHeight As Long, _
ByVal bRepaint As Long) As Long
Private Declare Function ShowWindow Lib "user32" _
(ByVal hWnd As Long, ByVal nCmdShow As Integer) As Boolean
Const SW_NORMAL = 1
Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" ( _
ByVal uAction As Long, ByVal uParam As Long, _
ByRef lpvParam As Any, ByVal fuWinIni As Long) As Long
Public Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Public Const SPI_GETWORKAREA = 48
Sub TileHorizontal()
Dim ttlHeight As Integer 'Word画面の横幅
Dim ttlWidth As Integer 'Word画面の縦幅
Dim indivWidth As Integer '個別のファイルの横幅
Dim i As Integer: i = 1 '※Forをやめて、For eachを使うため
Dim nDoc As Integer '開かれているファイルの数
'開かれているファイルの数を取得
nDoc = Documents.count
If nDoc < 1 Then Exit Sub
' ※ 作業領域(タスクバーを除くディスプレイ領域)を計算
Dim workArea As RECT
Call SystemParametersInfo(SPI_GETWORKAREA, 0, workArea, 0)
ttlWidth = workArea.Right - workArea.Left
ttlHeight = workArea.Bottom - workArea.Top
Dim windowHandles As New Collection
Dim windowHandle As Variant '※For eachで代入する為
Set windowHandles = GetWindowHandlesOfWord
'個別ファイルの横幅の設定(縦幅は画面全幅)※Documents.CountはWord2010で誤動作する場合あり
indivWidth = ttlWidth / windowHandles.count
For Each windowHandle In windowHandles
Call ShowWindow(windowHandle, SW_NORMAL)
'※ 有効画面領域の左・上端を基準に
Call MoveWindow(windowHandle, _
indivWidth * (i - 1) + workArea.Left, _
0 + workArea.Top, _
indivWidth, _
ttlHeight, _
1)
i = i + 1
Next
End Sub
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment