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