实现一个带有复选框的多列 ListView
控件,支持对单元格的复选框进行点击切换和状态读取。
; https://www.autohotkey.com/boards/viewtopic.php?p=311203&sid=0781c8c9cac0e8d478419974e92b94d2#p311203 #NoEnv SetBatchLines, -1 ; State image list HSIL := LV_GetStateImageList() ; LVS_EX_DOUBLEBUFFER = 0x0010000, LVS_EX_SUBITEMIMAGES = 0x02 Gui, Add, ListView, w400 r10 vCBLV hwndHLV +LV0x00010002, Col1|Col2|Col3|Col4|Col5 ; Set 'Explorer' theme DllCall("UxTheme.dll\SetWindowTheme", "Ptr", HLV, "WStr", "Explorer", "Ptr", 0) ColCnt := LV_GetCount("Col") LV_SetImageList(HSIL, 1) Loop, 10 { Row := LV_Add("", A_Index . "-1", A_Index . "-2", A_Index . "-3", A_Index . "-4", A_Index . "-5") Col := 2 Loop { LV_GetText(Txt, Row, Col) If Trim(Txt) LV_SetSubItemCB(HLV, Row, Col) Col++ } Until (Col > ColCnt) } LV_ModifyCol() Gui, Show, , CheckBoxListView OnMessage(0x0201, "On_WM_LBUTTONDOWN") Return GuiClose: Rows := LV_GetCount() Cols := LV_GetCount("Col") Checked := "" Loop, %Rows% { Row := A_Index Loop, %Cols% { Col := A_Index If LV_IsChecked(HLV, Row, Col) Checked .= Row . " - " . Col . "`n" } } MsgBOx, 0, Checked, %Checked% ExitApp ; ---------------------------------------------------------------------------------------------------------------------- ; Left mouse button click handler ; ---------------------------------------------------------------------------------------------------------------------- On_WM_LBUTTONDOWN(W, L, M, H) { ; LVM_GETITEMA = 0x1005, LVM_SETITEMA = 0x1006, LVM_SUBITEMHITTEST = 0x1039 If (A_GuiControl = "CBLV") && LV_IsClickOnIcon(H, L, Row, Col) LV_ToggleCheck(H, Row, Col) } ; ---------------------------------------------------------------------------------------------------------------------- ; Gets a copy of the state image list of a list view control ; ---------------------------------------------------------------------------------------------------------------------- LV_GetStateImagelist() { ; LVM_GETIMAGELIST = 0x1002, LVM_SETEXTENDEDLISTVIEWSTYLE = 0x1036 ; LVSIL_STATE = 0x02, LVS_EX_CHECKBOXES = 0x04 HLV := DllCall("CreateWindowEx", "UInt", 0x0200, "Str", "SysListView32", "Ptr", 0, "UInt", 0x01 , "Int", 0, "Int", 0, "Int", 100, "Int", 100, "Ptr", 0, "Ptr", 0, "Ptr", 0, "Ptr", 0, "UPtr") DllCall("SendMessage", "Ptr", HLV, "UInt", 0x1036, "Ptr", 0x04, "Ptr", 0x04) HSIL := DllCall("SendMessage", "Ptr", HLV, "UInt", 0x1002, "Ptr", 2, "Ptr", 0, "UPtr") DllCall("ImageList_GetIconSize", "Ptr", HSIL, "IntP", W, "IntP", H) C := DllCall("ImageList_GetImageCount", "Ptr", HSIL, "Ptr", 0, "Ptr", 0, "Int") HIL := DllCall("ImageList_Create", "Int", W, "Int", H, "UInt", 0x00010001, "Int", C, "Int", C, "UPtr") Loop, %C% { HICO := DllCall("ImageList_GetIcon", "Ptr", HSIL, "Int", A_Index - 1, "UInt", 0, "UPtr") DllCall("ImageList_ReplaceIcon", "Ptr", HIL, "Int", -1, "Ptr", HICO) } DllCall("DestroyWindow", "Ptr", HLV) Return HIL } ; ---------------------------------------------------------------------------------------------------------------------- ; Checks whether an item or subitem shows the 'checked' check box icon ; ---------------------------------------------------------------------------------------------------------------------- LV_IsChecked(HLV, Row, Col) { ; LVM_GETITEMA = 0x1005 Static OffImage := 20 + (A_PtrSize * 2) LV_CreateLVITEM(LVITEM, 0x00000002, Row, Col) Return DllCall("SendMessage", "Ptr", HLV, "UInt", 0x1005, "Ptr", 0, "Ptr", &LVITEM, "UInt") ? NumGet(LVITEM, OffImage, "Int") : False } ; ---------------------------------------------------------------------------------------------------------------------- ; Checks whether the left mouse button was pressed upon a check box icon ; ---------------------------------------------------------------------------------------------------------------------- LV_IsClickOnIcon(HLV, POINTS, ByRef Row, ByRef Col) { ; LVM_SUBITEMHITTEST =0x1039 Col := Row := 0 VarSetCapacity(LVHTI, 24, 0) VarSetCapacity(PTS, 4, 0) NumPut(POINTS, PTS, "Int") NumPut(NumGet(PTS, 0, "Short"), LVHTI, 0, "Int") NumPut(NumGet(PTS, 2, "Short"), LVHTI, 4, "Int") If (DllCall("SendMessage", "Ptr", HLV, "UInt", 0x1039, "Ptr", 0, "Ptr", &LVHTI, "Int") <> -1) { If (NumGet(LVHTI, 8, "UInt") = 2) { ; Flags: LVHT_ONITEMICON = 2 Row := NumGet(LVHTI, 12, "Int") + 1 ; Item Col := NumGet(LVHTI, 16, "Int") + 1 ; SubItem Return True } } Return False } ; ---------------------------------------------------------------------------------------------------------------------- ; Toggles the check box icon (unchecked <> checked) ; ---------------------------------------------------------------------------------------------------------------------- LV_ToggleCheck(HLV, Row, Col) { ; LVM_GETITEMA = 0x1005, LVM_SETITEMA = 0x1006 Static OffImage := 20 + (A_PtrSize * 2) LV_CreateLVITEM(LVITEM, 0x00000002, Row, Col) If DllCall("SendMessage", "Ptr", HLV, "UInt", 0x1005, "Ptr", 0, "Ptr", &LVITEM, "UInt") { NumPut(NumGet(LVITEM, OffImage, "Int") ? 0 : 1, LVITEM, OffImage, "Int") Return DllCall("SendMessage", "Ptr", HLV, "UInt", 0x1006, "Ptr", 0, "Ptr", &LVITEM, "Int") } Return False } ; ---------------------------------------------------------------------------------------------------------------------- ; Sets the check box icon for subitems ; ---------------------------------------------------------------------------------------------------------------------- LV_SetSubItemCB(HLV, Row, Col, Index := 1) { ; LVM_SETITEMA = 0x1006 -> http://msdn.microsoft.com/en-us/library/bb761186(v=vs.85).aspx Static OffImage := 20 + (A_PtrSize * 2) LV_CreateLVITEM(LVITEM, 0x00000002, Row, Col) ; LVIF_IMAGE NumPut(Index - 1, LVITEM, OffImage, "Int") Return DllCall("SendMessage", "Ptr", HLV, "UInt", 0x1006, "Ptr", 0, "Ptr", &LVITEM, "Int") } ; ---------------------------------------------------------------------------------------------------------------------- ; Creates a LVITEM structure filling some fields ; ---------------------------------------------------------------------------------------------------------------------- LV_CreateLVITEM(ByRef LVITEM, Mask := 0, Row := 1, Col := 1) { Static LVITEMSize := 40 + (A_PtrSize * 5) VarSetCapacity(LVITEM, LVITEMSize, 0) NumPut(Mask, LVITEM, 0, "UInt"), NumPut(Row - 1, LVITEM, 4, "Int"), NumPut(Col - 1, LVITEM, 8, "Int") }
声明:站内资源为整理优化好的代码上传分享与学习研究,如果是开源代码基本都会标明出处,方便大家扩展学习路径。请不要恶意搬运,破坏站长辛苦整理维护的劳动成果。本站为爱好者分享站点,所有内容不作为商业行为。如若本站上传内容侵犯了原著者的合法权益,请联系我们进行删除下架。
评论(0)