Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ;=======================================================================================
- ; Private Class This class is used internally.
- ;=======================================================================================
- Class Private
- {
- ;=======================================================================================
- ; Private Properties
- ;=======================================================================================
- ; Messages
- Static TB_ADDBUTTONS := 0x0414
- Static TB_ADDSTRING := A_IsUnicode ? 0x044D : 0x041C
- Static TB_AUTOSIZE := 0x0421
- Static TB_BUTTONCOUNT := 0x0418
- Static TB_CHECKBUTTON := 0x0402
- Static TB_COMMANDTOINDEX := 0x0419
- Static TB_CUSTOMIZE := 0x041B
- Static TB_DELETEBUTTON := 0x0416
- Static TB_ENABLEBUTTON := 0x0401
- Static TB_GETBUTTON := 0x0417
- Static TB_GETBUTTONSIZE := 0x043A
- Static TB_GETBUTTONTEXT := A_IsUnicode ? 0x044B : 0x042D
- Static TB_GETEXTENDEDSTYLE := 0x0455
- Static TB_GETHOTITEM := 0x0447
- Static TB_GETIMAGELIST := 0x0431
- Static TB_GETIMAGELISTCOUNT := 0x0462
- Static TB_GETITEMDROPDOWNRECT := 0x0467
- Static TB_GETITEMRECT := 0x041D
- Static TB_GETMAXSIZE := 0x0453
- Static TB_GETPADDING := 0x0456
- Static TB_GETRECT := 0x0433
- Static TB_GETROWS := 0x0428
- Static TB_GETSTATE := 0x0412
- Static TB_GETSTYLE := 0x0439
- Static TB_GETSTRING := A_IsUnicode ? :0x045B 0x045C
- Static TB_GETTEXTROWS := 0x043D
- Static TB_HIDEBUTTON := 0x0404
- Static TB_INDETERMINATE := 0x0405
- Static TB_INSERTBUTTON := A_IsUnicode ? 0x0443 : 0x0415
- Static TB_ISBUTTONCHECKED := 0x040A
- Static TB_ISBUTTONENABLED := 0x0409
- Static TB_ISBUTTONHIDDEN := 0x040C
- Static TB_ISBUTTONHIGHLIGHTED := 0x040E
- Static TB_ISBUTTONINDETERMINATE := 0x040D
- Static TB_ISBUTTONPRESSED := 0x040B
- Static TB_MARKBUTTON := 0x0406
- Static TB_MOVEBUTTON := 0x0452
- Static TB_PRESSBUTTON := 0x0403
- Static TB_SETBUTTONINFO := A_IsUnicode ? 0x0440 : 0x0442
- Static TB_SETBUTTONSIZE := 0x041F
- Static TB_SETBUTTONWIDTH := 0x043B
- Static TB_SETDISABLEDIMAGELIST := 0x0436
- Static TB_SETEXTENDEDSTYLE := 0x0454
- Static TB_SETHOTIMAGELIST := 0x0434
- Static TB_SETHOTITEM := 0x0448
- Static TB_SETHOTITEM2 := 0x045E
- Static TB_SETIMAGELIST := 0x0430
- Static TB_SETINDENT := 0x042F
- Static TB_SETLISTGAP := 0x0460
- Static TB_SETMAXTEXTROWS := 0x043C
- Static TB_SETPADDING := 0x0457
- Static TB_SETPRESSEDIMAGELIST := 0x0468
- Static TB_SETROWS := 0x0427
- Static TB_SETSTATE := 0x0411
- Static TB_SETSTYLE := 0x0438
- ; Styles
- Static TBSTYLE_ALTDRAG := 0x0400
- Static TBSTYLE_CUSTOMERASE := 0x2000
- Static TBSTYLE_FLAT := 0x0800
- Static TBSTYLE_LIST := 0x1000
- Static TBSTYLE_REGISTERDROP := 0x4000
- Static TBSTYLE_TOOLTIPS := 0x0100
- Static TBSTYLE_TRANSPARENT := 0x8000
- Static TBSTYLE_WRAPABLE := 0x0200
- Static TBSTYLE_ADJUSTABLE := 0x20
- Static TBSTYLE_BORDER := 0x800000
- Static TBSTYLE_THICKFRAME := 0x40000
- Static TBSTYLE_TABSTOP := 0x10000
- ; ExStyles
- Static TBSTYLE_EX_DOUBLEBUFFER := 0x80 ; // Double Buffer the toolbar
- Static TBSTYLE_EX_DRAWDDARROWS := 0x01
- Static TBSTYLE_EX_HIDECLIPPEDBUTTONS := 0x10 ; // don't show partially obscured buttons
- Static TBSTYLE_EX_MIXEDBUTTONS := 0x08
- Static TBSTYLE_EX_MULTICOLUMN := 0x02 ; // Intended for internal use; not recommended for use in applications.
- Static TBSTYLE_EX_VERTICAL := 0x04 ; // Intended for internal use; not recommended for use in applications.
- ; Button states
- Static TBSTATE_CHECKED := 0x01
- Static TBSTATE_ELLIPSES := 0x40
- Static TBSTATE_ENABLED := 0x04
- Static TBSTATE_HIDDEN := 0x08
- Static TBSTATE_INDETERMINATE := 0x10
- Static TBSTATE_MARKED := 0x80
- Static TBSTATE_PRESSED := 0x02
- Static TBSTATE_WRAP := 0x20
- ; Button styles
- Static BTNS_BUTTON := 0x00 ; TBSTYLE_BUTTON
- Static BTNS_SEP := 0x01 ; TBSTYLE_SEP
- Static BTNS_CHECK := 0x02 ; TBSTYLE_CHECK
- Static BTNS_GROUP := 0x04 ; TBSTYLE_GROUP
- Static BTNS_CHECKGROUP := 0x06 ; TBSTYLE_CHECKGROUP // (TBSTYLE_GROUP | TBSTYLE_CHECK)
- Static BTNS_DROPDOWN := 0x08 ; TBSTYLE_DROPDOWN
- Static BTNS_AUTOSIZE := 0x10 ; TBSTYLE_AUTOSIZE // automatically calculate the cx of the button
- Static BTNS_NOPREFIX := 0x20 ; TBSTYLE_NOPREFIX // this button should not have accel prefix
- Static BTNS_SHOWTEXT := 0x40 ; // ignored unless TBSTYLE_EX_MIXEDBUTTONS is set
- Static BTNS_WHOLEDROPDOWN := 0x80 ; // draw drop-down arrow, but without split arrow section
- ; TB_GETBITMAPFLAGS
- Static TBBF_LARGE := 0x00000001
- Static TBIF_BYINDEX := 0x80000000 ; // this specifies that the wparam in Get/SetButtonInfo is an index, not id
- Static TBIF_COMMAND := 0x00000020
- Static TBIF_IMAGE := 0x00000001
- Static TBIF_LPARAM := 0x00000010
- Static TBIF_SIZE := 0x00000040
- Static TBIF_STATE := 0x00000004
- Static TBIF_STYLE := 0x00000008
- Static TBIF_TEXT := 0x00000002
- ; Notifications
- Static TBN_BEGINADJUST := -703
- Static TBN_BEGINDRAG := -701
- Static TBN_CUSTHELP := -709
- Static TBN_DELETINGBUTTON := -715
- Static TBN_DRAGOUT := -714
- Static TBN_DRAGOVER := -727
- Static TBN_DROPDOWN := -710
- Static TBN_DUPACCELERATOR := -725
- Static TBN_ENDADJUST := -704
- Static TBN_ENDDRAG := -702
- Static TBN_GETBUTTONINFO := -720 ; A_IsUnicode ? -720 : -700
- Static TBN_GETDISPINFO := A_IsUnicode ? -717 : -716
- Static TBN_GETINFOTIP := A_IsUnicode ? -719 : -718
- Static TBN_GETOBJECT := -712
- Static TBN_HOTITEMCHANGE := -713
- Static TBN_INITCUSTOMIZE := -723
- Static TBN_MAPACCELERATOR := -728
- Static TBN_QUERYDELETE := -707
- Static TBN_QUERYINSERT := -706
- Static TBN_RESET := -705
- Static TBN_RESTORE := -721
- Static TBN_SAVE := -722
- Static TBN_TOOLBARCHANGE := -708
- Static TBN_WRAPACCELERATOR := -726
- Static TBN_WRAPHOTITEM := -724
- ;=======================================================================================
- ; Meta-Functions
- ;
- ; Properties:
- ; tbHwnd: Toolbar's Hwnd.
- ; DefaultBtnInfo: Stores information about button's original structures.
- ; Presets: This is a special object used to save and load buttons
- ; layouts. It has its own methods.
- ;=======================================================================================
- __New(hToolbar)
- {
- this.tbHwnd := hToolbar
- , this.DefaultBtnInfo := []
- , this.Presets := {tbHwnd: hToolbar, Base: Toolbar.tbPresets}
- }
- ;=======================================================================================
- __Delete()
- {
- this.Remove("", Chr(255))
- , this.SetCapacity(0)
- , this.base := ""
- }
- ;=======================================================================================
- ; Private Methods
- ;=======================================================================================
- ; Method: SetButton
- ; Description: Creates buttons and sends specified message to the toolbar.
- ;=======================================================================================
- SendMessage(Button, Options, Message="", Param="")
- {
- If (RegExMatch(Button, "^(\W?)(\w+)[=\s]?(.*)?:(\d+)\(?(.*?)?\)?$", Key))
- {
- idCommand := this.StringToNumber(Key2)
- , iString := Key3, iBitmap := Key4
- , this.Labels[idCommand] := Key2
- , Struct := this.DefineBtnStruct(TBBUTTON, iBitmap, idCommand, iString, Key5 ? Key5 : Options)
- , this.DefaultBtnInfo.Insert(Struct)
- If !(Key1) && (Message)
- {
- SendMessage, Message, Param, &TBBUTTON,, % "ahk_id " this.tbHwnd
- If (ErrorLevel = "FAIL")
- return False
- }
- }
- Else
- {
- Struct := this.BtnSep(TBBUTTON, Options), this.DefaultBtnInfo.Insert(Struct)
- If (Message)
- {
- SendMessage, Message, Param, &TBBUTTON,, % "ahk_id " this.tbHwnd
- If (ErrorLevel = "FAIL")
- return False
- }
- }
- return True
- }
- ;=======================================================================================
- ; Method: DefineBtnStruct
- ; Description: Creates a TBBUTTON structure.
- ; Return: An array with the button structure values.
- ;=======================================================================================
- DefineBtnStruct(ByRef BtnVar, iBitmap=0, idCommand=0, iString="", Options="")
- {
- If Options is Integer
- tbStyle := Options, tbState := this.TBSTATE_ENABLED
- Else
- {
- Loop, Parse, Options, %A_Space%%A_Tab%
- {
- If (this[ "TBSTATE_" A_LoopField ])
- tbState += this[ "TBSTATE_" A_LoopField ]
- Else If (this[ "BTNS_" A_LoopField ] )
- tbStyle += this[ "BTNS_" A_LoopField ]
- Else If (RegExMatch(A_LoopField, "i)W(\d+)-(\d+)", MW))
- {
- Long := this.MakeLong(MW1, MW2)
- SendMessage, this.TB_SETBUTTONWIDTH, 0, Long,, % "ahk_id " this.tbHwnd
- }
- }
- }
- If (iString <> "")
- {
- VarSetCapacity(BTNSTR, (StrPut(iString) * (A_IsUnicode ? 2 : 1), 0))
- , StrPut(iString, &BTNSTR, StrPut(iString) * 2)
- SendMessage, this.TB_ADDSTRING, 0, &BTNSTR,, % "ahk_id " this.tbHwnd
- StrIdx := ErrorLevel
- }
- Else
- StrIdx := -1
- VarSetCapacity(BtnVar, 8 + (A_PtrSize * 3), 0)
- , NumPut(iBitmap-1, BtnVar, 0, "Int")
- , NumPut(idCommand, BtnVar, 4, "Int")
- , NumPut(tbState, BtnVar, 8, "Char")
- , NumPut(tbStyle, BtnVar, 9, "Char")
- , NumPut(StrIdx, BtnVar, 8 + (A_PtrSize * 2), "Ptr")
- return {Icon: iBitmap-1, ID: idCommand, State: tbState
- , Style: tbStyle, Text: iString, Label: this.Labels[idCommand]}
- }
- ;=======================================================================================
- ; Method: DefineBtnInfoStruct
- ; Description: Creates a TBBUTTONINFO structure for a specific member.
- ;=======================================================================================
- DefineBtnInfoStruct(ByRef BtnVar, Member, ByRef Value)
- {
- Static cbSize := 16 + (A_PtrSize * 4)
- VarSetCapacity(BtnVar, cbSize, 0)
- , NumPut(cbSize, BtnVar, 0, "UInt")
- If (this[ "TBIF_" Member] )
- dwMask := this[ "TBIF_" Member ]
- , NumPut(dwMask, BtnVar, 4, "UInt")
- If (dwMask = this.TBIF_COMMAND)
- NumPut(Value, BtnVar, 8, "Int") ; idCommand
- Else If (dwMask = this.TBIF_IMAGE)
- Value := Value-1
- , NumPut(Value, BtnVar, 12, "Int") ; iImage
- Else If (dwMask = this.TBIF_STATE)
- Value := (this[ "TBSTATE_" Value ]) ? this[ "TBSTATE_" Value ] : Value
- , NumPut(Value, BtnVar, 16, "Char") ; fsState
- Else If (dwMask = this.TBIF_STYLE)
- Value := (this[ "BTNS_" Value ]) ? this[ "BTNS_" Value ] : Value
- , NumPut(Value, BtnVar, 17, "Char") ; fsStyle
- Else If (dwMask = this.TBIF_SIZE)
- NumPut(Value, BtnVar, 18, "Short") ; cx
- Else If (dwMask = this.TBIF_TEXT)
- NumPut(&Value, BtnVar, 16 + (A_PtrSize * 2), "UPtr") ; pszText
- }
- ;=======================================================================================
- ; Method: BtnSep
- ; Description: Creates a TBBUTTON structure for a separator.
- ; Return: An array with the button structure values.
- ;=======================================================================================
- BtnSep(ByRef BtnVar, Options="")
- {
- tbStyle := this.BTNS_SEP
- Loop, Parse, Options, %A_Space%%A_Tab%
- {
- If (this[ "TBSTATE_" A_LoopField ])
- tbState += this[ "TBSTATE_" A_LoopField ]
- }
- VarSetCapacity(BtnVar, 8 + (A_PtrSize * 3), 0)
- , NumPut(tbState, BtnVar, 8, "Char")
- , NumPut(tbStyle, BtnVar, 9, "Char")
- return {Icon: -1, ID: "", State: tbState, Style: tbStyle, Text: "", Label: ""}
- }
- ;=======================================================================================
- ; Method: StringToNumber
- ; Description: Returns a number based on a string to be used as Command ID.
- ;=======================================================================================
- StringToNumber(String)
- {
- Loop, Parse, String
- Number += Asc(A_LoopField) + Number + SubStr(Number, -1)
- return SubStr(Number, 1, 4)
- }
- ;=======================================================================================
- ; Method: MakeLong
- ; Description: Creates a LongWord from a LoWord and a HiWord.
- ;=======================================================================================
- MakeLong(LoWord, HiWord)
- {
- return (HiWord << 16) | (LoWord & 0xffff)
- }
- ;=======================================================================================
- ; Method: MakeLong
- ; Description: Extracts LoWord and HiWord from a LongWord.
- ;=======================================================================================
- MakeShort(Long, ByRef LoWord, ByRef HiWord)
- {
- LoWord := Long & 0xffff
- , HiWord := Long >> 16
- }
- }
- }
- WM_NOTIFY(W, L) {
- ; =================================
- ; LV_InCellEdit_WM_NOTIFY from Class_LV_InCellEdit
- ; =================================
- Static LVN_BEGINLABELEDITA := -105
- Static LVN_BEGINLABELEDITW := -175
- Static LVN_ENDLABELEDITA := -106
- Static LVN_ENDLABELEDITW := -176
- Static NM_CLICK := -2
- Static NM_DBLCLICK := -3
- H := NumGet(L + 0, 0, "UPtr")
- M := NumGet(L + (A_PtrSize * 2), 0, "Int")
- If (LV_InCellEdit.Attached.HasKey(H)) {
- ; BeginLabelEdit -------------------------------------------------------------------------------------------------
- If (M = LVN_BEGINLABELEDITW) || (M = LVN_BEGINLABELEDITA) {
- Return LV_InCellEdit.On_LVN_BEGINLABELEDIT(H, L)
- }
- ; EndLabelEdit ---------------------------------------------------------------------------------------------------
- If (M = LVN_ENDLABELEDITW) || (M = LVN_ENDLABELEDITA) {
- Return LV_InCellEdit.On_LVN_ENDLABELEDIT(H, L)
- }
- ; Double click ---------------------------------------------------------------------------------------------------
- If (M = NM_DBLCLICK) {
- LV_InCellEdit.On_NM_DBLCLICK(H, L)
- }
- }
- ; =================================
- ; LV_Colors_WM_NOTIFY from Class_LV_Colors
- ; =================================
- Static NM_CUSTOMDRAW := -12
- Static LVN_COLUMNCLICK := -108
- ; Critical
- If LV_Colors.HasKey(H := NumGet(L + 0, 0, "UPtr")) {
- M := NumGet(L + (A_PtrSize * 2), 0, "Int")
- ; NM_CUSTOMDRAW --------------------------------------------------------------------------------------------------
- If (M = NM_CUSTOMDRAW)
- Return LV_Colors.On_NM_CUSTOMDRAW(H, L)
- ; LVN_COLUMNCLICK ------------------------------------------------------------------------------------------------
- If (LV_Colors[H].NS && (M = LVN_COLUMNCLICK))
- Return 0
- }
- }
- Class LV_InCellEdit {
- ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- ; PRIVATE PROPERTIES ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- Static Attached := {}
- Static Changed := {}
- Static LVSubClassProc := RegisterCallback("LV_InCellEdit_LVSUBCLASSPROC", "", 6)
- Static LVIF_TEXT := 0x0001
- Static LVM_GETITEMTEXT := A_IsUnicode ? 0x1073 : 0x102D ; LVM_GETITEMTEXTW : LVM_GETITEMTEXTA
- Static LVM_SETITEMTEXT := A_IsUnicode ? 0x1074 : 0x102E ; LVM_SETITEMTEXTW : LVM_SETITEMTEXTA
- Static LVM_SETITEM := A_IsUnicode ? 0x104C : 0x1006 ; LVM_SETITEMW : LVM_SETITEMA
- Static NMHDRSize := (2 * A_PtrSize) + 4 + (A_PtrSize - 4) ; Size off NMHDR structure
- Static LVITEMSize := (13 * 4) + (A_PtrSize * 2) + (A_PtrSize - 4) ; Size off LVITEM
- Static ITEMTextP := (5 * 4) + (A_PtrSize - 4) ; Offset of pszText in LVITEM
- Static ITEMTextL := LV_InCellEdit.ITEMTextP + A_PtrSize ; Offset of cchTextMax in LVITEM
- Static OSVersion := LV_InCellEdit.GetOsVersion()
- ; Hotkeys
- Static HK_Esc := 0x801B ; Esc : cancel
- Static HK_Right := 0x8009 ; Tab : next cell
- Static HK_Left := 0x8409 ; Shift+Tab : previous cell
- Static HK_Down := 0x8028 ; Down : lower cell
- Static HK_Up := 0x8026 ; Up : upper cell
- ; Current values
- Static ITEM := -1
- Static SITEM := -1
- Static ITEMTEXT := ""
- Static HWND := 0
- Static HEDIT := 0
- Static Rows := 0
- Static Cols := 0
- Static Cancelled := False
- Static Next := False
- Static DW := 0
- Static EX := 0
- Static EY := 0
- Static EW := 0
- Static EH := 0
- Static LX := 0
- Static LY := 0
- Static LR := 0
- Static LW := 0
- Static SW := 0
- ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- ; META FUNCTIONS ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- __New(P*) {
- Return False ; There is no reason to instantiate this class.
- }
- ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- ; PRIVATE METHODS +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- ; ===================================================================================================================
- ; GetOSVersion
- ; ===================================================================================================================
- GetOsVersion() {
- Return (V := DllCall("Kernel32.dll\GetVersion", "UInt") & 0xFF) . "." . ((V >> 8) & 0xFF)
- }
- ; ===================================================================================================================
- ; Next subItem
- ; ===================================================================================================================
- NextSubItem(H, K) {
- Static LVM_ENSUREVISIBLE := 0x1013
- Static LVM_GETCOLUMNWIDTH := 0x101D
- Static LVM_GETSUBITEMRECT := 0x1038
- Static LVM_SCROLL := 0x1014
- Static WM_LBUTTONDOWN := 0x0201
- Static WM_LBUTTONUP := 0x0202
- Static WM_LBUTTONDBLCLK := 0x0203
- ; OutputDebug, NextSubItem
- ; Find the next subitem
- ITEM := This.ITEM
- SITEM := This.SITEM
- If (K = This.HK_Right) {
- SITEM++
- } Else If (K = This.HK_Left) {
- SITEM--
- If (SITEM = 0) && This.Attached[H].Skip0 {
- SITEM--
- }
- } Else If (K = This.HK_Down) {
- ITEM++
- } Else If (K = This.HK_Up) {
- ITEM--
- }
- IF (K = This.HK_Left) || (K = This.HK_Right) {
- If This.Attached[H].HasKey("Columns") {
- If (SITEM < This.Attached[H].Columns.MinIndex()) {
- SITEM := This.Attached[H].Columns.MaxIndex()
- ITEM--
- } Else If (SITEM > This.Attached[H].Columns.MaxIndex()) {
- SITEM := This.Attached[H].Columns.MinIndex()
- ITEM++
- } Else {
- While !This.Attached[H].Columns.HasKey(SITEM) {
- If (K = This.HK_Right)
- SITEM++
- Else
- SITEM--
- }
- }
- }
- }
- If (SITEM > This.Cols) {
- ITEM++
- SITEM := This.Attached[H].Skip0 ? 1 : 0
- } Else If (SITEM < 0) {
- SITEM := This.Cols
- ITEM--
- }
- If (ITEM > This.Rows) {
- ITEM := 0
- } Else If (ITEM < 0) {
- ITEM := This.Rows
- }
- If (ITEM <> This.ITEM) {
- SendMessage, LVM_ENSUREVISIBLE, ITEM, False, , % "ahk_id " . H
- }
- VarSetCapacity(RECT, 16, 0)
- NumPut(SITEM, RECT, 4, "Int")
- SendMessage, LVM_GETSUBITEMRECT, ITEM, &RECT, , % "ahk_id " . H
- X := NumGet(RECT, 0, "Int")
- Y := NumGet(RECT, 4, "Int")
- If (SITEM = 0) {
- SendMessage, LVM_GETCOLUMNWIDTH, 0, 0, , % "ahk_id " . H
- W := ErrorLevel
- } Else {
- W := NumGet(RECT, 8, "Int") - NumGet(RECT, 0, "Int")
- }
- R := This.LW - (This.DX * 2) - This.SW
- S := 0
- If (X < 0) {
- S := X
- } Else If ((X + W) > R) {
- S := X + W - R + This.DX
- }
- If (S) {
- SendMessage, LVM_SCROLL, S, 0, , % "ahk_id " . H
- }
- Point := (X - S + (This.DX * 2)) + ((Y + (This.DY * 2)) << 16)
- SendMessage, WM_LBUTTONDOWN, 0, Point, , % "ahk_id " . H
- SendMessage, WM_LBUTTONUP, 0, Point, , % "ahk_id " . H
- SendMessage, WM_LBUTTONDBLCLK, 0, Point, , % "ahk_id " . H
- SendMessage, WM_LBUTTONUP, 0, Point, , % "ahk_id " . H
- }
- ; ===================================================================================================================
- ; Register/UnRegister hotkeys
- ; ===================================================================================================================
- RegisterHotkeys(H, Register = True) {
- ; MOD_SHIFT := 0x0004
- If (Register) { ; Register
- DllCall("User32.dll\RegisterHotKey", "Ptr", H, "Int", This.HK_Esc, "UInt", 0, "UInt", 0x1B)
- DllCall("User32.dll\RegisterHotKey", "Ptr", H, "Int", This.HK_Right, "UInt", 0, "UInt", 0x09)
- DllCall("User32.dll\RegisterHotKey", "Ptr", H, "Int", This.HK_Left, "UInt", 4, "UInt", 0x09)
- DllCall("User32.dll\RegisterHotKey", "Ptr", H, "Int", This.HK_Down, "UInt", 0, "UInt", 0x28)
- DllCall("User32.dll\RegisterHotKey", "Ptr", H, "Int", This.HK_Up, "UInt", 0, "UInt", 0x26)
- } Else { ; Unregister
- DllCall("User32.dll\UnregisterHotKey", "Ptr", H, "Int", This.HK_Esc)
- DllCall("User32.dll\UnregisterHotKey", "Ptr", H, "Int", This.HK_Right)
- DllCall("User32.dll\UnregisterHotKey", "Ptr", H, "Int", This.HK_Left)
- DllCall("User32.dll\UnregisterHotKey", "Ptr", H, "Int", This.HK_Down)
- DllCall("User32.dll\UnregisterHotKey", "Ptr", H, "Int", This.HK_Up)
- }
- }
- ; ===================================================================================================================
- ; LVN_BEGINLABELEDIT notification
- ; ===================================================================================================================
- On_LVN_BEGINLABELEDIT(H, L) {
- Static LVM_GETCOLUMNWIDTH := 0x101D
- Static LVM_GETEDITCONTROL := 0x1018
- Static LVM_GETSUBITEMRECT := 0x1038
- Static TBufSize := A_IsUnicode ? 2048 : 1024
- Static Indent := 4 ; indent of the Edit control, 4 seems to be reasonable for XP, Vista, and 7
- ; OutputDebug, % "BEGINLABELEDIT - " . This.Next
- If (This.ITEM = -1) || (This.SITEM = -1)
- Return True
- SendMessage, LVM_GETEDITCONTROL, 0, 0, , % "ahk_id " . H
- This.HEDIT := ErrorLevel
- VarSetCapacity(ITEMTEXT, TBufSize, 0)
- VarSetCapacity(LVITEM, This.LVITEMSize, 0)
- NumPut(This.ITEM, LVITEM, 4, "Int")
- NumPut(This.SITEM, LVITEM, 8, "Int")
- NumPut(&ITEMTEXT, LVITEM, This.ITEMTextP, "Ptr")
- NumPut(1024 + 1, LVITEM, This.ITEMTextL, "Int")
- SendMessage, This.LVM_GETITEMTEXT, This.ITEM, &LVITEM, , % "ahk_id " . H
- This.ITEMTEXT := StrGet(&ITEMTEXT, ErrorLevel)
- ControlSetText, , % This.ITEMTEXT, % "ahk_id " . This.HEDIT
- If (This.SITEM > 0) && (This.Attached[H].Blank) {
- Empty := ""
- NumPut(&Empty, LVITEM, This.ITEMTextP, "Ptr")
- NumPut(0,LVITEM, This.ITEMTextL, "Int")
- SendMessage, This.LVM_SETITEMTEXT, This.ITEM, &LVITEM, , % "ahk_id " . H
- }
- VarSetCapacity(RECT, 16, 0)
- NumPut(This.SITEM, RECT, 4, "Int")
- SendMessage, LVM_GETSUBITEMRECT, This.ITEM, &RECT, , % "ahk_id " . H
- This.EX := NumGet(RECT, 0, "Int") + This.LX + This.DX + Indent
- This.EY := NumGet(RECT, 4, "Int") + This.LY + This.DY
- If (This.OSVersion < 6)
- This.EY -= 1 ; subtract 1 for WinXP
- If (This.SITEM = 0) {
- SendMessage, LVM_GETCOLUMNWIDTH, 0, 0, , % "ahk_id " . H
- This.EW := ErrorLevel
- } Else {
- This.EW := NumGet(RECT, 8, "Int") - NumGet(RECT, 0, "Int")
- }
- This.EW -= Indent
- This.EH := NumGet(RECT, 12, "Int") - NumGet(RECT, 4, "Int")
- ; Register subclass callback
- DllCall("Comctl32.dll\SetWindowSubclass", "Ptr", H, "Ptr", This.LVSubClassProc, "Ptr", H, "Ptr", 0)
- ; Register hotkeys
- If !(This.Next) {
- This.RegisterHotkeys(H)
- }
- This.Cancelled := False
- This.Next := False
- Return False
- }
- ; ===================================================================================================================
- ; LVN_ENDLABELEDIT notification
- ; ===================================================================================================================
- On_LVN_ENDLABELEDIT(H, L) {
- ; OutputDebug, % "ENDLABELEDIT - " . This.Next
- ; Unregister subclass callback
- DllCall("Comctl32.dll\RemoveWindowSubclass", "Ptr", H, "Ptr", This.LVSubClassProc, "Ptr", H)
- ; Unregister hotkeys
- If !(This.Next) {
- This.RegisterHotkeys(H, False)
- }
- ITEMTEXT := This.ITEMTEXT
- If !(This.Cancelled) {
- ControlGetText, ITEMTEXT, , % "ahk_id " . This.HEDIT
- }
- If (ITEMTEXT <> This.ITEMTEXT) {
- If !(This.Changed.HasKey(H))
- This.Changed[H] := []
- This.Changed[H].Insert({Row: This.ITEM + 1, Col: This.SITEM + 1, Txt: ITEMTEXT})
- }
- ; Restore subitem's text if changed or blanked out
- If (ITEMTEXT <> This.ITEMTEXT) || ((This.SITEM > 0) && (This.Attached[H].Blank)) {
- VarSetCapacity(LVITEM, This.LVITEMSize, 0)
- NumPut(This.ITEM, LVITEM, 4, "Int")
- NumPut(This.SITEM, LVITEM, 8, "Int")
- NumPut(&ITEMTEXT, LVITEM, This.ITEMTextP, "Ptr")
- SendMessage, This.LVM_SETITEMTEXT, This.ITEM, &LVITEM, , % "ahk_id " . H
- }
- If !(This.Next) {
- This.ITEM := This.SITEM := -1
- }
- This.Cancelled := False
- This.Next := False
- Return False
- }
- ; ===================================================================================================================
- ; NM_DBLCLICK notification
- ; ===================================================================================================================
- On_NM_DBLCLICK(H, L) {
- Static LVM_EDITLABELA := 0x1017
- Static LVM_EDITLABELW := 0x1076
- Static LVM_EDITLABEL := A_IsUnicode ? LVM_EDITLABELW : LVM_EDITLABELA
- Static LVM_GETCOLUMNWIDTH := 0x101D
- Static LVM_GETSTRINGWIDTHA := 0x1011
- Static LVM_GETSTRINGWIDTHW := 0x1057
- Static LVM_GETSTRINGWIDTH := A_IsUnicode ? LVM_GETSTRINGWIDTHW : LVM_GETSTRINGWIDTHA
- Static LVM_GETSUBITEMRECT := 0x1038
- Static LVM_SCROLL := 0x1014
- Static WS_VSCROLL := 0x200000
- ; OutputDebug, % "NMDBLCLICK - " . This.Next
- This.ITEM := This.SITEM := -1
- ITEM := NumGet(L + This.NMHDRSize, 0, "Int")
- SITEM := NumGet(L + This.NMHDRSize, 4, "Int")
- If This.Attached[H].HasKey("Columns") {
- If !This.Attached[H].Columns.HasKey(SITEM)
- Return False
- }
- If (ITEM >= 0) && (SITEM >= 0) {
- This.ITEM := ITEM
- This.SITEM := SITEM
- If !(This.Next) {
- This.HWND := H
- ControlGet, V, List, Count, , % "ahk_id " . H
- This.Rows := V - 1
- ControlGet, V, List, Count Col, , % "ahk_id " . H
- This.Cols := V - 1
- NumPut(VarSetCapacity(WINDOWINFO, 60, 0), WINDOWINFO)
- DllCall("User32.dll\GetWindowInfo", "Ptr", H, "Ptr", &WINDOWINFO)
- This.DX := NumGet(WINDOWINFO, 20, "Int") - NumGet(WINDOWINFO, 4, "Int")
- This.DY := NumGet(WINDOWINFO, 24, "Int") - NumGet(WINDOWINFO, 8, "Int")
- Styles := NumGet(WINDOWINFO, 36, "UInt")
- SendMessage, LVM_GETSTRINGWIDTH, 0, "WWW", , % "ahk_id " . H
- This.MinW := ErrorLevel
- SendMessage, LVM_GETSTRINGWIDTH, 0, "III", , % "ahk_id " . H
- This.DW := ErrorLevel
- SBW := 0
- If (Styles & WS_VSCROLL)
- SysGet, SBW, 2
- ControlGetPos, LX, LY, LW, , , % "ahk_id " . H
- This.LX := LX
- This.LY := LY
- This.LR := LX + LW - (This.DX * 2) - SBW
- This.LW := LW
- This.SW := SBW
- VarSetCapacity(RECT, 16, 0)
- NumPut(SITEM, RECT, 4, "Int")
- SendMessage, LVM_GETSUBITEMRECT, ITEM, &RECT, , % "ahk_id " . H
- X := NumGet(RECT, 0, "Int")
- If (SITEM = 0) {
- SendMessage, LVM_GETCOLUMNWIDTH, 0, 0, , % "ahk_id " . H
- W := ErrorLevel
- } Else {
- W := NumGet(RECT, 8, "Int") - NumGet(RECT, 0, "Int")
- }
- R := LW - (This.DX * 2) - SBW
- If (X < 0) {
- SendMessage, LVM_SCROLL, X, 0, , % "ahk_id " . H
- } Else If ((X + W) > R) {
- SendMessage, LVM_SCROLL, X + W - R + This.DX, 0, , % "ahk_id " . H
- }
- }
- PostMessage, LVM_EDITLABEL, ITEM, 0, , % "ahk_id " . H
- }
- Return False
- }
- ; ===================================================================================================================
- ; SubClassProc for ListViews
- ; ===================================================================================================================
- SubClassProc(H, M, W, L, I, D) {
- Static EC_LEFTMARGIN := 0x01
- Static EN_SETFOCUS := 0x0100
- Static EN_KILLFOCUS := 0x0200
- Static EN_CHANGE := 0x0300
- Static EN_UPDATE := 0x0400
- Static EM_SETSEL := 0x00B1
- Static EM_SETMARGINS := 0x00D3
- Static WM_COMMAND := 0x0111
- Static WM_HOTKEY := 0x0312
- Static LVM_CANCELEDITLABEL := 0x10B3
- Static LVM_GETSTRINGWIDTHA := 0x1011
- Static LVM_GETSTRINGWIDTHW := 0x1057
- Static LVM_GETSTRINGWIDTH := A_IsUnicode ? LVM_GETSTRINGWIDTHW : LVM_GETSTRINGWIDTHA
- If (H = This.HWND) {
- If (L = This.HEDIT) && (M = WM_COMMAND) {
- N := (W >> 16)
- If (N = EN_UPDATE) || (N = EN_CHANGE) || (N = EN_SETFOCUS) {
- ; OutputDebug, SubClassProc Edit : %N%
- If (N = EN_SETFOCUS)
- SendMessage, EM_SETMARGINS, EC_LEFTMARGIN, 0, , % "ahk_id " . L
- ControlGetText, EDITTEXT, , % "ahk_id " . L
- SendMessage, LVM_GETSTRINGWIDTH, 0, &EDITTEXT, , % "ahk_id " . H
- EW := ErrorLevel + This.DW
- If (EW < This.MinW)
- EW := This.MinW
- EX := This.EX
- EY := This.EY
- EH := This.OSVersion < 6 ? This.EH + 3 : This.EH ; add 3 for WinXP
- If ((EX + EW) > This.LR) {
- EW := This.LR - EX
- }
- ControlMove, , EX, EY, EW, EH, % "ahk_id " . L
- If (N = EN_UPDATE)
- Return 0
- }
- } Else If (M = WM_HOTKEY) {
- ; OutputDebug, SubClassProc Hotkey : %W%
- If (W = This.HK_Esc) {
- This.Cancelled := True
- PostMessage, LVM_CANCELEDITLABEL, 0, 0, , % "ahk_id " . H
- } Else {
- This.Next := True
- SendMessage, LVM_CANCELEDITLABEL, 0, 0, , % "ahk_id " . H
- This.Next := True
- This.NextSubItem(H, W)
- }
- Return False
- }
- }
- Return DllCall("Comctl32.dll\DefSubclassProc", "Ptr", H, "UInt", M, "Ptr", W, "Ptr", L)
- }
- ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- ; PUBLIC INTERFACE ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- ; ===================================================================================================================
- ; METHOD OnMessage Register / unregister LV_InCellEdit message handler for WM_NOTIFY messages
- ; Parameters: DoIt - True / False
- ; Default: True
- ; Return Value: Always True
- ; ===================================================================================================================
- OnMessage(DoIt := True) {
- Static MessageHandler := "LV_InCellEdit_WM_NOTIFY"
- Static WM_NOTIFY := 0x4E
- If (DoIt) {
- OnMessage(WM_NOTIFY, MessageHandler)
- } Else If (MessageHandler = OnMessage(WM_NOTIFY)) {
- OnMessage(WM_NOTIFY, "")
- }
- Return True
- }
- ; ===================================================================================================================
- ; METHOD Attach Register ListView for in-cell editing
- ; Parameters: HWND - ListView's HWND (Integer)
- ; ---------------- Optional:
- ; HiddenCol1 - ListView with hidden first column (Bool)
- ; Values: True / False
- ; Default: False
- ; BlankSubItem - Blank out subitem's text while editing (Bool)
- ; Values: True / False
- ; Default: False
- ; Return values: Always True
- ; ===================================================================================================================
- Attach(HWND, HiddenCol1 := False, BlankSubItem := False) {
- ; Store HWND and options
- This.Attached[HWND] := {Skip0: HiddenCol1, Blank: BlankSubItem}
- Return True
- }
- ; ===================================================================================================================
- ; METHOD Detach Restore ListView's default behavior
- ; Parameters: HWND - ListView's HWND (Integer)
- ; Return values: Always True
- ; ===================================================================================================================
- Detach(HWND) {
- ; Remove HWND
- This.Attached.Remove(HWND, "")
- Return True
- }
- ; ===================================================================================================================
- ; METHOD EditCell Edit the specified cell, if possible.
- ; Parameters: HWND - ListView's HWND (Integer)
- ; Row - 1-based row number (Integer)
- ; Col - 1-based column number (Integer)
- ; Default: 0 - edit the first editable column
- ; Return values: On success: True
- ; On failure: False
- ; ===================================================================================================================
- EditCell(HWND, Row, Col := 0) {
- If !This.Attached.HasKey(HWND)
- Return False
- ControlGet, Rows, List, Count, , % "ahk_id " . HWND
- This.Rows := Rows - 1
- ControlGet, Cols, List, Count Col, , % "ahk_id " . HWND
- This.Cols := Cols - 1
- If (Col = 0) {
- If This.Attached[HWND].HasKey("Columns")
- Col := This.Attached[HWND].Columns.MinIndex() + 1
- ELse If This.Attached[HWND].Skip0
- Col := 2
- Else
- Col := 1
- }
- If (Row < 1) || (Row > Rows) || (Col < 1) || (Col > Cols)
- Return False
- If (Column = 1) && This.Attached[HWND].Skip0
- Col := 2
- If This.Attached[HWND].HasKey("Columns")
- If !This.Attached[HWND].Columns[Col - 1]
- Return False
- VarSetCapacity(LPARAM, 1024, 0)
- NumPut(Row - 1, LPARAM, This.NMHDRSize + 0, "Int")
- NumPut(Col - 1, LPARAM, This.NMHDRSize + 4, "Int")
- This.On_NM_DBLCLICK(HWND, &LPARAM)
- Return True
- }
- ; ===================================================================================================================
- ; METHOD SetColumns Sets the columns you want to edit
- ; Parameters: HWND - ListView's HWND (Integer)
- ; ColArr - Array of 1-based column indices (Array)
- ; If a non-array is passed (e.g. the parameter is omitted),
- ; the ListView will be resetted to edit all columns.
- ; Return values: On success: True
- ; On failure: False
- ; ===================================================================================================================
- SetColumns(HWND, ColArr := "") {
- If !This.Attached.HasKey(HWND)
- Return False
- If !IsObject(ColArr) {
- This.Attached[HWND].Remove("Columns")
- Return True
- }
- ControlGet, Cols, List, Count Col, , % "ahk_id " . HWND
- Indices := []
- For Each, I In ColArr {
- If I Is Not Integer
- Return False
- If (I < 1) || (I > Cols)
- Return False
- Indices[I - 1] := True
- }
- This.Attached[HWND, "Columns"] := Indices
- Return True
- }
- }
- ; ======================================================================================================================
- ; PRIVATE ListView subclassproc
- ; ======================================================================================================================
- LV_InCellEdit_LVSUBCLASSPROC(H, M, W, L, I, D) {
- ; Critical
- Return LV_InCellEdit.SubClassProc(H, M, W, L, I, D)
- }
- ; ======================================================================================================================
- ; PRIVATE ListView notification handler
- ; ======================================================================================================================
- LV_InCellEdit_WM_NOTIFY(W, L) {
- Static LVN_BEGINLABELEDITA := -105
- Static LVN_BEGINLABELEDITW := -175
- Static LVN_ENDLABELEDITA := -106
- Static LVN_ENDLABELEDITW := -176
- Static NM_CLICK := -2
- Static NM_DBLCLICK := -3
- H := NumGet(L + 0, 0, "UPtr")
- M := NumGet(L + (A_PtrSize * 2), 0, "Int")
- If (LV_InCellEdit.Attached.HasKey(H)) {
- ; BeginLabelEdit -------------------------------------------------------------------------------------------------
- If (M = LVN_BEGINLABELEDITW) || (M = LVN_BEGINLABELEDITA) {
- Return LV_InCellEdit.On_LVN_BEGINLABELEDIT(H, L)
- }
- ; EndLabelEdit ---------------------------------------------------------------------------------------------------
- If (M = LVN_ENDLABELEDITW) || (M = LVN_ENDLABELEDITA) {
- Return LV_InCellEdit.On_LVN_ENDLABELEDIT(H, L)
- }
- ; Double click ---------------------------------------------------------------------------------------------------
- If (M = NM_DBLCLICK) {
- LV_InCellEdit.On_NM_DBLCLICK(H, L)
- }
- }
- }
- ;=====================================================================================================================
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement