GUIウィンドウにリストビューコントロールを追加する。列や項目の操作を行う組み込み関数も用意されている。
Gui, Add, ListView [, Options, ColumnTitles]
| 引数名 | 説明 |
|---|---|
| Options |
オプションを半角スペース区切りで列挙。 共通のオプションについては、Gui,Addの項参照。 固有のオプションは後述。 「V」オプションで変数を関連付けても、変数に情報が格納されることはない。ただし、GuiControlなどのコマンドでコントロールを指定するために利用できる。 Gでラベル名を指定すると、各種の操作が行われるごとにサブルーチンが実行される。詳しくはイベントの節を参照。 |
| ColumnTitles |
詳細表示の列の見出しを「|」で区切って列挙する。(例:「名前|サイズ|更新日時」) 「Gui,+Delimiter`n」のようにすると、区切り文字を「|」以外のもの(この例では改行)に変更できる。 各列の幅の初期状態は、テキストが収まる幅になる。 |
リストビューを操作するために、多数の機能が関数として用意されている。
LV系の関数が操作対象とするリストビューは、デフォルトGUIウィンドウ上のカレントリストビューである。
カレントリストビューは、通常は最後に項目を追加したリストビューだが、「Gui,ListView,LVName」のようにして変更できる。
GUIウィンドウが存在しなかったり、デフォルトGUIウィンドウ上にリストビューコントロールが存在しなかった場合、LV系関数は「0」を返す。
これらの関数で使用される「項目番号」は、一番上が「1」になる。
リストなどに表示するアイコンは、イメージリストに登録しておく。
IL_Createでイメージリストを作成し、LV_SetImageListでリストビューに割り当てる必要がある。
大きいアイコンと小さいアイコンは別々のイメージリストに保持する。
LV_ModifyCol、LV_InsertColのOptions引数に指定できるオプションには以下のものがある。
項目操作系の関数のOptions引数に指定できるオプションには以下のものがある。
「G」オプションでラベル名を指定していると、下記のイベントが発生するたびにサブルーチンが実行される。
このとき、A_GuiEvent変数にイベント名が格納される。
「E」と「e」など大文字と小文字と小文字の違うイベント名は別物である。
なお、イベントは今後も追加される可能性がある。
AltSubmitオプションを指定すると、上記のイベントに加え、下記のイベント時にもサブルーチンが呼び出される。
これらのイベントの動作を確かめるには、以下のサンプルスクリプトを利用するとよい。
Gui,Add,ListView,h600 -ReadOnly AltSubmit gLV R10,A_GuiEvent|A_EventInfo|日時
Gui,Add,Button,gClear,&Clear
Gui,Show
return
LV:
FormatTime,t,%A_Now%,yyyy/MM/dd hh:mm:ss
Lv_Add("",A_GuiEvent,A_EventInfo,t)
return
Clear:
Lv_Delete()
return
項目の各列に表示可能なテキストの上限は260バイトである。
LV_GetTextで取得できるのは8191バイトまでである。
実際に格納できるテキスト長には上限はない。
列見出しのクリックや「LV_ModifyCol(1, "Sort") 」のような関数によるソートは、その時点でソートされるのみで、後から追加される項目には影響しない。
ListViewコントロールのオプションの「Sort」と「SortDesc」は、項目が追加されるときに動作する。
ただし、すでに存在する項目はソートされないので、あらかじめ項目がソートされていないと正しい位置に挿入されない。
リストビューにフォーカスがあるときにキーボードで文字列を入力したり、IMEで変換文字列を確定させると、1列目のテキストがその内容で始まる項目にフォーカスが移動する。
リストビューコントロールでは、Shift+クリックで最終選択位置からクリック位置までを選択、Shift+矢印キーで範囲選択、Ctrl+矢印キーの上下でフォーカスだけを移動、Ctrl+Spaceでフォーカスのある項目の選択状態を反転できる。
リストビューコントロールはEnterキーが押されたことを知ることができない。
Enterキーが押されたときに特定の動作をさせたいときは、下記の例のようにウィンドウにデフォルトボタンを設定する。
デフォルトボタンは非表示にすることも可能である。
Gui,Add,ListView,gLVEvent,col1|col2
Gui,Add,Button,gOnEnter Hidden Default
;その他の初期化動作
return
OnEnter:
GuiControlGet, FocusedControl, Focus
if FocusedControl = SysListView321
Selected(LV_GetNext(1,"F"))
return
LVEvent:
if A_GuiEvent = DoubleClick
Selected(A_EventInfo)
return
Selected(row)
{
;項目決定時の動作
}
; Create the ListView with two columns, Name and Size:
Gui, Add, ListView, r20 w700 gMyListView, Name|Size (KB)
; Gather a list of file names from a folder and put them into the ListView:
Loop, %A_MyDocuments%\*.*
LV_Add("", A_LoopFileName, A_LoopFileSizeKB)
LV_ModifyCol() ; Auto-size each column to fit its contents.
LV_ModifyCol(2, "Integer") ; For sorting purposes, indicate that column 2 is an integer.
; Display the window and return. The script will be notified whenever the user double clicks a row.
Gui, Show
return
MyListView:
if A_GuiEvent = DoubleClick
{
LV_GetText(RowText, A_EventInfo) ; Get the row's first-column text.
MsgBox You double-clicked row number %A_EventInfo%. Text: "%RowText%"
}
return
GuiClose: ; Indicate that the script should exit automatically when the window is closed.
ExitApp; Select or de-select all rows by specifying 0 as the row number: LV_Modify(0, "Select") ; Select all. LV_Modify(0, "-Select") ; De-select all. ; Auto-size all columns to fit their contents: LV_ModifyCol() ; There are no parameters in this mode.
; MAIN EXAMPLE
; The following is a working script that is more elaborate than the one near the top of this page.
; It displays the files in a folder chosen by the user, with each file assigned the icon associated with
; its type. The user can double-click a file, or right-click one or more files to display a context menu.
; Allow the user to maximize or drag-resize the window:
Gui +Resize
; Create some buttons:
Gui, Add, Button, Default gButtonLoadFolder, Load a folder
Gui, Add, Button, x+20 gButtonClear, Clear List
Gui, Add, Button, x+20, Switch View
; Create the ListView and its columns:
Gui, Add, ListView, xm r20 w700 vMyListView gMyListView, Name|In Folder|Size (KB)|Type
LV_ModifyCol(3, "Integer") ; For sorting, indicate that the Size column is an integer.
; Create an ImageList so that the ListView can display some icons:
ImageListID1 := IL_Create(10)
ImageListID2 := IL_Create(10, 10, true) ; A list of large icons to go with the small ones.
; Attach the ImageLists to the ListView so that it can later display the icons:
LV_SetImageList(ImageListID1)
LV_SetImageList(ImageListID2)
; Create a popup menu to be used as the context menu:
Menu, MyContextMenu, Add, Open, ContextOpenFile
Menu, MyContextMenu, Add, Properties, ContextProperties
Menu, MyContextMenu, Add, Clear from ListView, ContextClearRows
Menu, MyContextMenu, Default, Open ; Make "Open" a bold font to indicate that double-click does the same thing.
; Display the window and return. The OS will notify the script whenever the user
; performs an eligible action:
Gui, Show
return
ButtonLoadFolder:
Gui +OwnDialogs ; Forces user to dismiss the following dialog before using main window.
FileSelectFolder, Folder,, 3, Select a folder to read:
if not Folder ; The user canceled the dialog.
return
; Check if the last character of the folder name is a backslash, which happens for root
; directories such as C:\. If it is, remove it to prevent a double-backslash later on.
StringRight, LastChar, Folder, 1
if LastChar = \
StringTrimRight, Folder, Folder, 1 ; Remove the trailing backslash.
; Ensure the variable has enough capacity to hold the longest file path. This is done
; because ExtractAssociatedIconA() needs to be able to store a new filename in it.
VarSetCapacity(Filename, 260)
; Gather a list of file names from the selected folder and append them to the ListView:
Loop %Folder%\*.*
{
FileName := A_LoopFileFullPath ; Must save it to a writable variable for use below.
; Build a unique extension ID to avoid characters that are illegal in variable names,
; such as dashes. This unique ID method also performs better because finding an item
; in the array does not require search-loop.
SplitPath, FileName,,, FileExt ; Get the file's extension.
if FileExt = EXE
{
ExtID = EXE ; Special ID as a placeholder.
IconNumber = 0 ; Flag it as not found so that EXEs can each have a unique icon.
}
else ; Non-EXE, so calculate this extension's unique ID.
{
ExtID = 0 ; Initializize to handle extensions that are shorter than others.
Loop 7 ; Limit the extension to 7 characters so that it fits in a 64-bit value.
{
StringMid, ExtChar, FileExt, A_Index, 1
if not ExtChar ; No more characters.
break
; Derive a Unique ID by assigning a different bit position to each character:
ExtID := ExtID | (Asc(ExtChar) << (8 * (A_Index - 1)))
}
; Check if this file extension already has an icon in the ImageLists. If it does,
; several calls can be avoided and loading performance is greatly improved,
; especially for a folder containing hundreds of files:
IconNumber := IconArray%ExtID%
}
if not IconNumber ; There is not yet any icon for this extension, so load it.
{
; Get the icon associated with this file extension:
hIcon := DllCall("Shell32\ExtractAssociatedIconA", UInt, 0, Str, FileName, UShortP, iIndex)
if not hIcon ; Failed to load/find icon.
IconNumber = 9999999 ; Set it out of bounds to display a blank icon.
else
{
; Add the HICON directly to the small-icon and large-icon lists.
; Below uses +1 to convert the returned index from zero-based to one-based:
IconNumber := DllCall("ImageList_ReplaceIcon", UInt, ImageListID1, Int, -1, UInt, hIcon) + 1
DllCall("ImageList_ReplaceIcon", UInt, ImageListID2, Int, -1, UInt, hIcon)
; Now that it's been copied into the ImageLists, the original should be destroyed:
DllCall("DestroyIcon", Uint, hIcon)
; Cache the icon to save memory and improve loading performance:
IconArray%ExtID% := IconNumber
}
}
; Create the new row in the ListView and assign it the icon number determined above:
LV_Add("Icon" . IconNumber, A_LoopFileName, A_LoopFileDir, A_LoopFileSizeKB, FileExt)
}
LV_ModifyCol() ; Auto-size each column to fit its contents.
LV_ModifyCol(3, 60) ; Make the Size column at little wider to reveal its header.
return
ButtonClear:
LV_Delete() ; Clear the ListView, but keep icon cache intact for simplicity.
return
ButtonSwitchView:
if not IconView
GuiControl, +Icon, MyListView ; Switch to icon view.
else
GuiControl, +Report, MyListView ; Switch back to details view.
IconView := not IconView ; Invert in preparation for next time.
return
MyListView:
if A_GuiEvent = DoubleClick ; There are many other possible values the script can check.
{
LV_GetText(FileName, A_EventInfo, 1) ; Get the text of the first field.
LV_GetText(FileDir, A_EventInfo, 2) ; Get the text of the second field.
Run %FileDir%\%FileName%,, UseErrorLevel
if ErrorLevel
MsgBox Could not open "%FileDir%\%FileName%".
}
return
GuiContextMenu: ; Launched in response to a right-click or press of the Apps key.
if A_GuiControl <> MyListView ; Display the menu only for clicks inside the ListView.
return
; Show the menu at the provided coordinates, A_GuiX and A_GuiY. These should be used
; because they provide correct coordinates even if the user pressed the Apps key:
Menu, MyContextMenu, Show, %A_GuiX%, %A_GuiY%
return
ContextOpenFile: ; The user selected "Open" in the context menu.
ContextProperties: ; The user selected "Properties" in the context menu.
; For simplicitly, operate upon only the focused row rather than all selected rows:
FocusedRowNumber := LV_GetNext(0, "F") ; Find the focused row.
if not FocusedRowNumber ; No row is focused.
return
LV_GetText(FileName, FocusedRowNumber, 1) ; Get the text of the first field.
LV_GetText(FileDir, FocusedRowNumber, 2) ; Get the text of the second field.
IfInString A_ThisMenuItem, Open ; User selected "Open" from the context menu.
Run %FileDir%\%FileName%,, UseErrorLevel
else ; User selected "Properties" from the context menu.
Run Properties "%FileDir%\%FileName%",, UseErrorLevel
if ErrorLevel
MsgBox Could not perform requested action on "%FileDir%\%FileName%".
return
ContextClearRows: ; The user selected "Clear" in the context menu.
RowNumber = 0 ; This causes the first iteration to start the search at the top.
Loop
{
; Since deleting a row reduces the RowNumber of all other rows beneath it,
; subtract 1 so that the search includes the same row number that was previously
; found (in case adjacent rows are selected):
RowNumber := LV_GetNext(RowNumber - 1)
if not RowNumber ; The above returned zero, so there are no more selected rows.
break
LV_Delete(RowNumber) ; Clear the row from the ListView.
}
return
GuiSize: ; Allows the ListView to grow or shrink in response user's resizing of window.
if A_EventInfo = 1 ; The window has been minimized. No action needed.
return
; Otherwise, the window has been resized or maximized. Resize the ListView to match.
GuiControl, Move, MyListView, % "W" . (A_GuiWidth - 20) . " H" . (A_GuiHeight - 40)
return
GuiClose: ; When the window is closed, exit the script automatically:
ExitApp