Advertisement
Guest User

TBBUTTONINFO AHK

a guest
Oct 1st, 2017
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ;=======================================================================================
  2. ; Private Class This class is used internally.
  3. ;=======================================================================================
  4. Class Private
  5. {
  6. ;=======================================================================================
  7. ; Private Properties
  8. ;=======================================================================================
  9. ; Messages
  10. Static TB_ADDBUTTONS := 0x0414
  11. Static TB_ADDSTRING := A_IsUnicode ? 0x044D : 0x041C
  12. Static TB_AUTOSIZE := 0x0421
  13. Static TB_BUTTONCOUNT := 0x0418
  14. Static TB_CHECKBUTTON := 0x0402
  15. Static TB_COMMANDTOINDEX := 0x0419
  16. Static TB_CUSTOMIZE := 0x041B
  17. Static TB_DELETEBUTTON := 0x0416
  18. Static TB_ENABLEBUTTON := 0x0401
  19. Static TB_GETBUTTON := 0x0417
  20. Static TB_GETBUTTONSIZE := 0x043A
  21. Static TB_GETBUTTONTEXT := A_IsUnicode ? 0x044B : 0x042D
  22. Static TB_GETEXTENDEDSTYLE := 0x0455
  23. Static TB_GETHOTITEM := 0x0447
  24. Static TB_GETIMAGELIST := 0x0431
  25. Static TB_GETIMAGELISTCOUNT := 0x0462
  26. Static TB_GETITEMDROPDOWNRECT := 0x0467
  27. Static TB_GETITEMRECT := 0x041D
  28. Static TB_GETMAXSIZE := 0x0453
  29. Static TB_GETPADDING := 0x0456
  30. Static TB_GETRECT := 0x0433
  31. Static TB_GETROWS := 0x0428
  32. Static TB_GETSTATE := 0x0412
  33. Static TB_GETSTYLE := 0x0439
  34. Static TB_GETSTRING := A_IsUnicode ? :0x045B 0x045C
  35. Static TB_GETTEXTROWS := 0x043D
  36. Static TB_HIDEBUTTON := 0x0404
  37. Static TB_INDETERMINATE := 0x0405
  38. Static TB_INSERTBUTTON := A_IsUnicode ? 0x0443 : 0x0415
  39. Static TB_ISBUTTONCHECKED := 0x040A
  40. Static TB_ISBUTTONENABLED := 0x0409
  41. Static TB_ISBUTTONHIDDEN := 0x040C
  42. Static TB_ISBUTTONHIGHLIGHTED := 0x040E
  43. Static TB_ISBUTTONINDETERMINATE := 0x040D
  44. Static TB_ISBUTTONPRESSED := 0x040B
  45. Static TB_MARKBUTTON := 0x0406
  46. Static TB_MOVEBUTTON := 0x0452
  47. Static TB_PRESSBUTTON := 0x0403
  48. Static TB_SETBUTTONINFO := A_IsUnicode ? 0x0440 : 0x0442
  49. Static TB_SETBUTTONSIZE := 0x041F
  50. Static TB_SETBUTTONWIDTH := 0x043B
  51. Static TB_SETDISABLEDIMAGELIST := 0x0436
  52. Static TB_SETEXTENDEDSTYLE := 0x0454
  53. Static TB_SETHOTIMAGELIST := 0x0434
  54. Static TB_SETHOTITEM := 0x0448
  55. Static TB_SETHOTITEM2 := 0x045E
  56. Static TB_SETIMAGELIST := 0x0430
  57. Static TB_SETINDENT := 0x042F
  58. Static TB_SETLISTGAP := 0x0460
  59. Static TB_SETMAXTEXTROWS := 0x043C
  60. Static TB_SETPADDING := 0x0457
  61. Static TB_SETPRESSEDIMAGELIST := 0x0468
  62. Static TB_SETROWS := 0x0427
  63. Static TB_SETSTATE := 0x0411
  64. Static TB_SETSTYLE := 0x0438
  65. ; Styles
  66. Static TBSTYLE_ALTDRAG := 0x0400
  67. Static TBSTYLE_CUSTOMERASE := 0x2000
  68. Static TBSTYLE_FLAT := 0x0800
  69. Static TBSTYLE_LIST := 0x1000
  70. Static TBSTYLE_REGISTERDROP := 0x4000
  71. Static TBSTYLE_TOOLTIPS := 0x0100
  72. Static TBSTYLE_TRANSPARENT := 0x8000
  73. Static TBSTYLE_WRAPABLE := 0x0200
  74. Static TBSTYLE_ADJUSTABLE := 0x20
  75. Static TBSTYLE_BORDER := 0x800000
  76. Static TBSTYLE_THICKFRAME := 0x40000
  77. Static TBSTYLE_TABSTOP := 0x10000
  78. ; ExStyles
  79. Static TBSTYLE_EX_DOUBLEBUFFER := 0x80 ; // Double Buffer the toolbar
  80. Static TBSTYLE_EX_DRAWDDARROWS := 0x01
  81. Static TBSTYLE_EX_HIDECLIPPEDBUTTONS := 0x10 ; // don't show partially obscured buttons
  82. Static TBSTYLE_EX_MIXEDBUTTONS := 0x08
  83. Static TBSTYLE_EX_MULTICOLUMN := 0x02 ; // Intended for internal use; not recommended for use in applications.
  84. Static TBSTYLE_EX_VERTICAL := 0x04 ; // Intended for internal use; not recommended for use in applications.
  85. ; Button states
  86. Static TBSTATE_CHECKED := 0x01
  87. Static TBSTATE_ELLIPSES := 0x40
  88. Static TBSTATE_ENABLED := 0x04
  89. Static TBSTATE_HIDDEN := 0x08
  90. Static TBSTATE_INDETERMINATE := 0x10
  91. Static TBSTATE_MARKED := 0x80
  92. Static TBSTATE_PRESSED := 0x02
  93. Static TBSTATE_WRAP := 0x20
  94. ; Button styles
  95. Static BTNS_BUTTON := 0x00 ; TBSTYLE_BUTTON
  96. Static BTNS_SEP := 0x01 ; TBSTYLE_SEP
  97. Static BTNS_CHECK := 0x02 ; TBSTYLE_CHECK
  98. Static BTNS_GROUP := 0x04 ; TBSTYLE_GROUP
  99. Static BTNS_CHECKGROUP := 0x06 ; TBSTYLE_CHECKGROUP // (TBSTYLE_GROUP | TBSTYLE_CHECK)
  100. Static BTNS_DROPDOWN := 0x08 ; TBSTYLE_DROPDOWN
  101. Static BTNS_AUTOSIZE := 0x10 ; TBSTYLE_AUTOSIZE // automatically calculate the cx of the button
  102. Static BTNS_NOPREFIX := 0x20 ; TBSTYLE_NOPREFIX // this button should not have accel prefix
  103. Static BTNS_SHOWTEXT := 0x40 ; // ignored unless TBSTYLE_EX_MIXEDBUTTONS is set
  104. Static BTNS_WHOLEDROPDOWN := 0x80 ; // draw drop-down arrow, but without split arrow section
  105. ; TB_GETBITMAPFLAGS
  106. Static TBBF_LARGE := 0x00000001
  107. Static TBIF_BYINDEX := 0x80000000 ; // this specifies that the wparam in Get/SetButtonInfo is an index, not id
  108. Static TBIF_COMMAND := 0x00000020
  109. Static TBIF_IMAGE := 0x00000001
  110. Static TBIF_LPARAM := 0x00000010
  111. Static TBIF_SIZE := 0x00000040
  112. Static TBIF_STATE := 0x00000004
  113. Static TBIF_STYLE := 0x00000008
  114. Static TBIF_TEXT := 0x00000002
  115. ; Notifications
  116. Static TBN_BEGINADJUST := -703
  117. Static TBN_BEGINDRAG := -701
  118. Static TBN_CUSTHELP := -709
  119. Static TBN_DELETINGBUTTON := -715
  120. Static TBN_DRAGOUT := -714
  121. Static TBN_DRAGOVER := -727
  122. Static TBN_DROPDOWN := -710
  123. Static TBN_DUPACCELERATOR := -725
  124. Static TBN_ENDADJUST := -704
  125. Static TBN_ENDDRAG := -702
  126. Static TBN_GETBUTTONINFO := -720 ; A_IsUnicode ? -720 : -700
  127. Static TBN_GETDISPINFO := A_IsUnicode ? -717 : -716
  128. Static TBN_GETINFOTIP := A_IsUnicode ? -719 : -718
  129. Static TBN_GETOBJECT := -712
  130. Static TBN_HOTITEMCHANGE := -713
  131. Static TBN_INITCUSTOMIZE := -723
  132. Static TBN_MAPACCELERATOR := -728
  133. Static TBN_QUERYDELETE := -707
  134. Static TBN_QUERYINSERT := -706
  135. Static TBN_RESET := -705
  136. Static TBN_RESTORE := -721
  137. Static TBN_SAVE := -722
  138. Static TBN_TOOLBARCHANGE := -708
  139. Static TBN_WRAPACCELERATOR := -726
  140. Static TBN_WRAPHOTITEM := -724
  141. ;=======================================================================================
  142. ; Meta-Functions
  143. ;
  144. ; Properties:
  145. ; tbHwnd: Toolbar's Hwnd.
  146. ; DefaultBtnInfo: Stores information about button's original structures.
  147. ; Presets: This is a special object used to save and load buttons
  148. ; layouts. It has its own methods.
  149. ;=======================================================================================
  150. __New(hToolbar)
  151. {
  152. this.tbHwnd := hToolbar
  153. , this.DefaultBtnInfo := []
  154. , this.Presets := {tbHwnd: hToolbar, Base: Toolbar.tbPresets}
  155. }
  156. ;=======================================================================================
  157. __Delete()
  158. {
  159. this.Remove("", Chr(255))
  160. , this.SetCapacity(0)
  161. , this.base := ""
  162. }
  163. ;=======================================================================================
  164. ; Private Methods
  165. ;=======================================================================================
  166. ; Method: SetButton
  167. ; Description: Creates buttons and sends specified message to the toolbar.
  168. ;=======================================================================================
  169. SendMessage(Button, Options, Message="", Param="")
  170. {
  171. If (RegExMatch(Button, "^(\W?)(\w+)[=\s]?(.*)?:(\d+)\(?(.*?)?\)?$", Key))
  172. {
  173. idCommand := this.StringToNumber(Key2)
  174. , iString := Key3, iBitmap := Key4
  175. , this.Labels[idCommand] := Key2
  176. , Struct := this.DefineBtnStruct(TBBUTTON, iBitmap, idCommand, iString, Key5 ? Key5 : Options)
  177. , this.DefaultBtnInfo.Insert(Struct)
  178. If !(Key1) && (Message)
  179. {
  180. SendMessage, Message, Param, &TBBUTTON,, % "ahk_id " this.tbHwnd
  181. If (ErrorLevel = "FAIL")
  182. return False
  183. }
  184. }
  185. Else
  186. {
  187. Struct := this.BtnSep(TBBUTTON, Options), this.DefaultBtnInfo.Insert(Struct)
  188. If (Message)
  189. {
  190. SendMessage, Message, Param, &TBBUTTON,, % "ahk_id " this.tbHwnd
  191. If (ErrorLevel = "FAIL")
  192. return False
  193. }
  194. }
  195. return True
  196. }
  197. ;=======================================================================================
  198. ; Method: DefineBtnStruct
  199. ; Description: Creates a TBBUTTON structure.
  200. ; Return: An array with the button structure values.
  201. ;=======================================================================================
  202. DefineBtnStruct(ByRef BtnVar, iBitmap=0, idCommand=0, iString="", Options="")
  203. {
  204. If Options is Integer
  205. tbStyle := Options, tbState := this.TBSTATE_ENABLED
  206. Else
  207. {
  208. Loop, Parse, Options, %A_Space%%A_Tab%
  209. {
  210. If (this[ "TBSTATE_" A_LoopField ])
  211. tbState += this[ "TBSTATE_" A_LoopField ]
  212. Else If (this[ "BTNS_" A_LoopField ] )
  213. tbStyle += this[ "BTNS_" A_LoopField ]
  214. Else If (RegExMatch(A_LoopField, "i)W(\d+)-(\d+)", MW))
  215. {
  216. Long := this.MakeLong(MW1, MW2)
  217. SendMessage, this.TB_SETBUTTONWIDTH, 0, Long,, % "ahk_id " this.tbHwnd
  218. }
  219. }
  220. }
  221. If (iString <> "")
  222. {
  223. VarSetCapacity(BTNSTR, (StrPut(iString) * (A_IsUnicode ? 2 : 1), 0))
  224. , StrPut(iString, &BTNSTR, StrPut(iString) * 2)
  225. SendMessage, this.TB_ADDSTRING, 0, &BTNSTR,, % "ahk_id " this.tbHwnd
  226. StrIdx := ErrorLevel
  227. }
  228. Else
  229. StrIdx := -1
  230. VarSetCapacity(BtnVar, 8 + (A_PtrSize * 3), 0)
  231. , NumPut(iBitmap-1, BtnVar, 0, "Int")
  232. , NumPut(idCommand, BtnVar, 4, "Int")
  233. , NumPut(tbState, BtnVar, 8, "Char")
  234. , NumPut(tbStyle, BtnVar, 9, "Char")
  235. , NumPut(StrIdx, BtnVar, 8 + (A_PtrSize * 2), "Ptr")
  236. return {Icon: iBitmap-1, ID: idCommand, State: tbState
  237. , Style: tbStyle, Text: iString, Label: this.Labels[idCommand]}
  238. }
  239. ;=======================================================================================
  240. ; Method: DefineBtnInfoStruct
  241. ; Description: Creates a TBBUTTONINFO structure for a specific member.
  242. ;=======================================================================================
  243. DefineBtnInfoStruct(ByRef BtnVar, Member, ByRef Value)
  244. {
  245. Static cbSize := 16 + (A_PtrSize * 4)
  246. VarSetCapacity(BtnVar, cbSize, 0)
  247. , NumPut(cbSize, BtnVar, 0, "UInt")
  248. If (this[ "TBIF_" Member] )
  249. dwMask := this[ "TBIF_" Member ]
  250. , NumPut(dwMask, BtnVar, 4, "UInt")
  251. If (dwMask = this.TBIF_COMMAND)
  252. NumPut(Value, BtnVar, 8, "Int") ; idCommand
  253. Else If (dwMask = this.TBIF_IMAGE)
  254. Value := Value-1
  255. , NumPut(Value, BtnVar, 12, "Int") ; iImage
  256. Else If (dwMask = this.TBIF_STATE)
  257. Value := (this[ "TBSTATE_" Value ]) ? this[ "TBSTATE_" Value ] : Value
  258. , NumPut(Value, BtnVar, 16, "Char") ; fsState
  259. Else If (dwMask = this.TBIF_STYLE)
  260. Value := (this[ "BTNS_" Value ]) ? this[ "BTNS_" Value ] : Value
  261. , NumPut(Value, BtnVar, 17, "Char") ; fsStyle
  262. Else If (dwMask = this.TBIF_SIZE)
  263. NumPut(Value, BtnVar, 18, "Short") ; cx
  264. Else If (dwMask = this.TBIF_TEXT)
  265. NumPut(&Value, BtnVar, 16 + (A_PtrSize * 2), "UPtr") ; pszText
  266. }
  267. ;=======================================================================================
  268. ; Method: BtnSep
  269. ; Description: Creates a TBBUTTON structure for a separator.
  270. ; Return: An array with the button structure values.
  271. ;=======================================================================================
  272. BtnSep(ByRef BtnVar, Options="")
  273. {
  274. tbStyle := this.BTNS_SEP
  275. Loop, Parse, Options, %A_Space%%A_Tab%
  276. {
  277. If (this[ "TBSTATE_" A_LoopField ])
  278. tbState += this[ "TBSTATE_" A_LoopField ]
  279. }
  280. VarSetCapacity(BtnVar, 8 + (A_PtrSize * 3), 0)
  281. , NumPut(tbState, BtnVar, 8, "Char")
  282. , NumPut(tbStyle, BtnVar, 9, "Char")
  283. return {Icon: -1, ID: "", State: tbState, Style: tbStyle, Text: "", Label: ""}
  284. }
  285. ;=======================================================================================
  286. ; Method: StringToNumber
  287. ; Description: Returns a number based on a string to be used as Command ID.
  288. ;=======================================================================================
  289. StringToNumber(String)
  290. {
  291. Loop, Parse, String
  292. Number += Asc(A_LoopField) + Number + SubStr(Number, -1)
  293. return SubStr(Number, 1, 4)
  294. }
  295. ;=======================================================================================
  296. ; Method: MakeLong
  297. ; Description: Creates a LongWord from a LoWord and a HiWord.
  298. ;=======================================================================================
  299. MakeLong(LoWord, HiWord)
  300. {
  301. return (HiWord << 16) | (LoWord & 0xffff)
  302. }
  303. ;=======================================================================================
  304. ; Method: MakeLong
  305. ; Description: Extracts LoWord and HiWord from a LongWord.
  306. ;=======================================================================================
  307. MakeShort(Long, ByRef LoWord, ByRef HiWord)
  308. {
  309. LoWord := Long & 0xffff
  310. , HiWord := Long >> 16
  311. }
  312. }
  313. }
  314.  
  315. WM_NOTIFY(W, L) {
  316.     ; =================================
  317.     ;       LV_InCellEdit_WM_NOTIFY from Class_LV_InCellEdit
  318.     ; =================================
  319.     Static LVN_BEGINLABELEDITA := -105
  320.     Static LVN_BEGINLABELEDITW := -175
  321.     Static LVN_ENDLABELEDITA := -106
  322.     Static LVN_ENDLABELEDITW := -176
  323.     Static NM_CLICK := -2
  324.     Static NM_DBLCLICK := -3
  325.     H := NumGet(L + 0, 0, "UPtr")
  326.     M := NumGet(L + (A_PtrSize * 2), 0, "Int")
  327.     If (LV_InCellEdit.Attached.HasKey(H)) {
  328.         ; BeginLabelEdit -------------------------------------------------------------------------------------------------
  329.         If (M = LVN_BEGINLABELEDITW) || (M = LVN_BEGINLABELEDITA) {
  330.             Return LV_InCellEdit.On_LVN_BEGINLABELEDIT(H, L)
  331.         }
  332.         ; EndLabelEdit ---------------------------------------------------------------------------------------------------
  333.         If (M = LVN_ENDLABELEDITW) || (M = LVN_ENDLABELEDITA) {
  334.             Return LV_InCellEdit.On_LVN_ENDLABELEDIT(H, L)
  335.         }
  336.         ; Double click ---------------------------------------------------------------------------------------------------
  337.         If (M = NM_DBLCLICK) {
  338.             LV_InCellEdit.On_NM_DBLCLICK(H, L)
  339.         }
  340.     }
  341.    
  342.  ; =================================
  343.     ;       LV_Colors_WM_NOTIFY from Class_LV_Colors
  344.     ; =================================
  345.     Static NM_CUSTOMDRAW := -12
  346.     Static LVN_COLUMNCLICK := -108
  347.     ; Critical
  348.     If LV_Colors.HasKey(H := NumGet(L + 0, 0, "UPtr")) {
  349.         M := NumGet(L + (A_PtrSize * 2), 0, "Int")
  350.         ; NM_CUSTOMDRAW --------------------------------------------------------------------------------------------------
  351.         If (M = NM_CUSTOMDRAW)
  352.             Return LV_Colors.On_NM_CUSTOMDRAW(H, L)
  353.         ; LVN_COLUMNCLICK ------------------------------------------------------------------------------------------------
  354.         If (LV_Colors[H].NS && (M = LVN_COLUMNCLICK))
  355.             Return 0
  356.     }
  357. }
  358.  
  359.  
  360. Class LV_InCellEdit {
  361. ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  362. ; PRIVATE PROPERTIES ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  363. ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  364.    Static Attached := {}
  365.    Static Changed := {}
  366.    Static LVSubClassProc := RegisterCallback("LV_InCellEdit_LVSUBCLASSPROC", "", 6)
  367.    Static LVIF_TEXT := 0x0001
  368.    Static LVM_GETITEMTEXT := A_IsUnicode ? 0x1073 : 0x102D ; LVM_GETITEMTEXTW : LVM_GETITEMTEXTA
  369.    Static LVM_SETITEMTEXT := A_IsUnicode ? 0x1074 : 0x102E ; LVM_SETITEMTEXTW : LVM_SETITEMTEXTA
  370.    Static LVM_SETITEM := A_IsUnicode ? 0x104C : 0x1006 ; LVM_SETITEMW : LVM_SETITEMA
  371.    Static NMHDRSize := (2 * A_PtrSize) + 4 + (A_PtrSize - 4) ; Size off NMHDR structure
  372.    Static LVITEMSize := (13 * 4) + (A_PtrSize * 2) + (A_PtrSize - 4) ; Size off LVITEM
  373.    Static ITEMTextP := (5 * 4) + (A_PtrSize - 4) ; Offset of pszText in LVITEM
  374.    Static ITEMTextL := LV_InCellEdit.ITEMTextP + A_PtrSize ; Offset of cchTextMax in LVITEM
  375.    Static OSVersion := LV_InCellEdit.GetOsVersion()
  376. ; Hotkeys
  377.    Static HK_Esc := 0x801B ; Esc : cancel
  378.    Static HK_Right := 0x8009 ; Tab : next cell
  379.    Static HK_Left := 0x8409 ; Shift+Tab : previous cell
  380.    Static HK_Down := 0x8028 ; Down : lower cell
  381.    Static HK_Up := 0x8026 ; Up : upper cell
  382. ; Current values
  383.    Static ITEM := -1
  384.    Static SITEM := -1
  385.    Static ITEMTEXT := ""
  386.    Static HWND := 0
  387.    Static HEDIT := 0
  388.    Static Rows := 0
  389.    Static Cols := 0
  390.    Static Cancelled := False
  391.    Static Next := False
  392.    Static DW := 0
  393.    Static EX := 0
  394.    Static EY := 0
  395.    Static EW := 0
  396.    Static EH := 0
  397.    Static LX := 0
  398.    Static LY := 0
  399.    Static LR := 0
  400.    Static LW := 0
  401.    Static SW := 0
  402. ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  403. ; META FUNCTIONS ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  404. ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  405.    __New(P*) {
  406.       Return False ; There is no reason to instantiate this class.
  407.    }
  408. ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  409. ; PRIVATE METHODS +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  410. ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  411. ; ===================================================================================================================
  412. ; GetOSVersion
  413. ; ===================================================================================================================
  414.    GetOsVersion() {
  415.       Return (V := DllCall("Kernel32.dll\GetVersion", "UInt") & 0xFF) . "." . ((V >> 8) & 0xFF)
  416.    }
  417. ; ===================================================================================================================
  418. ; Next subItem
  419. ; ===================================================================================================================
  420.    NextSubItem(H, K) {
  421.       Static LVM_ENSUREVISIBLE := 0x1013
  422.       Static LVM_GETCOLUMNWIDTH := 0x101D
  423.       Static LVM_GETSUBITEMRECT := 0x1038
  424.       Static LVM_SCROLL := 0x1014
  425.       Static WM_LBUTTONDOWN := 0x0201
  426.       Static WM_LBUTTONUP := 0x0202
  427.       Static WM_LBUTTONDBLCLK := 0x0203
  428. ; OutputDebug, NextSubItem
  429. ; Find the next subitem
  430.       ITEM := This.ITEM
  431.       SITEM := This.SITEM
  432.       If (K = This.HK_Right) {
  433.          SITEM++
  434.       } Else If (K = This.HK_Left) {
  435.          SITEM--
  436.          If (SITEM = 0) && This.Attached[H].Skip0 {
  437.             SITEM--
  438.          }
  439.       } Else If (K = This.HK_Down) {
  440.          ITEM++
  441.       } Else If (K = This.HK_Up) {
  442.          ITEM--
  443.       }
  444.       IF (K = This.HK_Left) || (K = This.HK_Right) {
  445.          If This.Attached[H].HasKey("Columns") {
  446.             If (SITEM < This.Attached[H].Columns.MinIndex()) {
  447.                SITEM := This.Attached[H].Columns.MaxIndex()
  448.                ITEM--
  449.             } Else If (SITEM > This.Attached[H].Columns.MaxIndex()) {
  450.                SITEM := This.Attached[H].Columns.MinIndex()
  451.                ITEM++
  452.             } Else {
  453.                While !This.Attached[H].Columns.HasKey(SITEM) {
  454.                   If (K = This.HK_Right)
  455.                      SITEM++
  456.                   Else
  457.                      SITEM--
  458.                }
  459.             }
  460.          }
  461.       }
  462.       If (SITEM > This.Cols) {
  463.          ITEM++
  464.          SITEM := This.Attached[H].Skip0 ? 1 : 0
  465.       } Else If (SITEM < 0) {
  466.          SITEM := This.Cols
  467.          ITEM--
  468.       }
  469.       If (ITEM > This.Rows) {
  470.          ITEM := 0
  471.       } Else If (ITEM < 0) {
  472.          ITEM := This.Rows
  473.       }
  474.       If (ITEM <> This.ITEM) {
  475.          SendMessage, LVM_ENSUREVISIBLE, ITEM, False, , % "ahk_id " . H
  476.       }
  477.       VarSetCapacity(RECT, 16, 0)
  478.       NumPut(SITEM, RECT, 4, "Int")
  479.       SendMessage, LVM_GETSUBITEMRECT, ITEM, &RECT, , % "ahk_id " . H
  480.       X := NumGet(RECT, 0, "Int")
  481.       Y := NumGet(RECT, 4, "Int")
  482.       If (SITEM = 0) {
  483.          SendMessage, LVM_GETCOLUMNWIDTH, 0, 0, , % "ahk_id " . H
  484.          W := ErrorLevel
  485.       } Else {
  486.          W := NumGet(RECT, 8, "Int") - NumGet(RECT, 0, "Int")
  487.       }
  488.       R := This.LW - (This.DX * 2) - This.SW
  489.       S := 0
  490.       If (X < 0) {
  491.          S := X
  492.       } Else If ((X + W) > R) {
  493.          S := X + W - R + This.DX
  494.       }
  495.       If (S) {
  496.          SendMessage, LVM_SCROLL, S, 0, , % "ahk_id " . H
  497.       }
  498.       Point := (X - S + (This.DX * 2)) + ((Y + (This.DY * 2)) << 16)
  499.       SendMessage, WM_LBUTTONDOWN, 0, Point, , % "ahk_id " . H
  500.       SendMessage, WM_LBUTTONUP, 0, Point, , % "ahk_id " . H
  501.       SendMessage, WM_LBUTTONDBLCLK, 0, Point, , % "ahk_id " . H
  502.       SendMessage, WM_LBUTTONUP, 0, Point, , % "ahk_id " . H
  503.    }
  504. ; ===================================================================================================================
  505. ; Register/UnRegister hotkeys
  506. ; ===================================================================================================================
  507.    RegisterHotkeys(H, Register = True) {
  508. ; MOD_SHIFT := 0x0004
  509.       If (Register) { ; Register
  510.          DllCall("User32.dll\RegisterHotKey", "Ptr", H, "Int", This.HK_Esc, "UInt", 0, "UInt", 0x1B)
  511.          DllCall("User32.dll\RegisterHotKey", "Ptr", H, "Int", This.HK_Right, "UInt", 0, "UInt", 0x09)
  512.          DllCall("User32.dll\RegisterHotKey", "Ptr", H, "Int", This.HK_Left, "UInt", 4, "UInt", 0x09)
  513.          DllCall("User32.dll\RegisterHotKey", "Ptr", H, "Int", This.HK_Down, "UInt", 0, "UInt", 0x28)
  514.          DllCall("User32.dll\RegisterHotKey", "Ptr", H, "Int", This.HK_Up, "UInt", 0, "UInt", 0x26)
  515.       } Else { ; Unregister
  516.          DllCall("User32.dll\UnregisterHotKey", "Ptr", H, "Int", This.HK_Esc)
  517.          DllCall("User32.dll\UnregisterHotKey", "Ptr", H, "Int", This.HK_Right)
  518.          DllCall("User32.dll\UnregisterHotKey", "Ptr", H, "Int", This.HK_Left)
  519.          DllCall("User32.dll\UnregisterHotKey", "Ptr", H, "Int", This.HK_Down)
  520.          DllCall("User32.dll\UnregisterHotKey", "Ptr", H, "Int", This.HK_Up)
  521.       }
  522.    }
  523. ; ===================================================================================================================
  524. ; LVN_BEGINLABELEDIT notification
  525. ; ===================================================================================================================
  526.    On_LVN_BEGINLABELEDIT(H, L) {
  527.       Static LVM_GETCOLUMNWIDTH := 0x101D
  528.       Static LVM_GETEDITCONTROL := 0x1018
  529.       Static LVM_GETSUBITEMRECT := 0x1038
  530.       Static TBufSize := A_IsUnicode ? 2048 : 1024
  531.       Static Indent := 4 ; indent of the Edit control, 4 seems to be reasonable for XP, Vista, and 7
  532. ; OutputDebug, % "BEGINLABELEDIT - " . This.Next
  533.       If (This.ITEM = -1) || (This.SITEM = -1)
  534.          Return True
  535.       SendMessage, LVM_GETEDITCONTROL, 0, 0, , % "ahk_id " . H
  536.       This.HEDIT := ErrorLevel
  537.       VarSetCapacity(ITEMTEXT, TBufSize, 0)
  538.       VarSetCapacity(LVITEM, This.LVITEMSize, 0)
  539.       NumPut(This.ITEM, LVITEM, 4, "Int")
  540.       NumPut(This.SITEM, LVITEM, 8, "Int")
  541.       NumPut(&ITEMTEXT, LVITEM, This.ITEMTextP, "Ptr")
  542.       NumPut(1024 + 1, LVITEM, This.ITEMTextL, "Int")
  543.       SendMessage, This.LVM_GETITEMTEXT, This.ITEM, &LVITEM, , % "ahk_id " . H
  544.       This.ITEMTEXT := StrGet(&ITEMTEXT, ErrorLevel)
  545.       ControlSetText, , % This.ITEMTEXT, % "ahk_id " . This.HEDIT
  546.       If (This.SITEM > 0) && (This.Attached[H].Blank) {
  547.          Empty := ""
  548.          NumPut(&Empty, LVITEM, This.ITEMTextP, "Ptr")
  549.          NumPut(0,LVITEM, This.ITEMTextL, "Int")
  550.          SendMessage, This.LVM_SETITEMTEXT, This.ITEM, &LVITEM, , % "ahk_id " . H
  551.       }
  552.       VarSetCapacity(RECT, 16, 0)
  553.       NumPut(This.SITEM, RECT, 4, "Int")
  554.       SendMessage, LVM_GETSUBITEMRECT, This.ITEM, &RECT, , % "ahk_id " . H
  555.       This.EX := NumGet(RECT, 0, "Int") + This.LX + This.DX + Indent
  556.       This.EY := NumGet(RECT, 4, "Int") + This.LY + This.DY
  557.       If (This.OSVersion < 6)
  558.          This.EY -= 1 ; subtract 1 for WinXP
  559.       If (This.SITEM = 0) {
  560.          SendMessage, LVM_GETCOLUMNWIDTH, 0, 0, , % "ahk_id " . H
  561.          This.EW := ErrorLevel
  562.       } Else {
  563.          This.EW := NumGet(RECT, 8, "Int") - NumGet(RECT, 0, "Int")
  564.       }
  565.       This.EW -= Indent
  566.       This.EH := NumGet(RECT, 12, "Int") - NumGet(RECT, 4, "Int")
  567. ; Register subclass callback
  568.       DllCall("Comctl32.dll\SetWindowSubclass", "Ptr", H, "Ptr", This.LVSubClassProc, "Ptr", H, "Ptr", 0)
  569. ; Register hotkeys
  570.       If !(This.Next) {
  571.          This.RegisterHotkeys(H)
  572.       }
  573.       This.Cancelled := False
  574.       This.Next := False
  575.       Return False
  576.    }
  577. ; ===================================================================================================================
  578. ; LVN_ENDLABELEDIT notification
  579. ; ===================================================================================================================
  580.    On_LVN_ENDLABELEDIT(H, L) {
  581. ; OutputDebug, % "ENDLABELEDIT - " . This.Next
  582. ; Unregister subclass callback
  583.       DllCall("Comctl32.dll\RemoveWindowSubclass", "Ptr", H, "Ptr", This.LVSubClassProc, "Ptr", H)
  584. ; Unregister hotkeys
  585.       If !(This.Next) {
  586.          This.RegisterHotkeys(H, False)
  587.       }
  588.       ITEMTEXT := This.ITEMTEXT
  589.       If !(This.Cancelled) {
  590.          ControlGetText, ITEMTEXT, , % "ahk_id " . This.HEDIT
  591.       }
  592.       If (ITEMTEXT <> This.ITEMTEXT) {
  593.          If !(This.Changed.HasKey(H))
  594.             This.Changed[H] := []
  595.          This.Changed[H].Insert({Row: This.ITEM + 1, Col: This.SITEM + 1, Txt: ITEMTEXT})
  596.       }
  597. ; Restore subitem's text if changed or blanked out
  598.       If (ITEMTEXT <> This.ITEMTEXT) || ((This.SITEM > 0) && (This.Attached[H].Blank)) {
  599.          VarSetCapacity(LVITEM, This.LVITEMSize, 0)
  600.          NumPut(This.ITEM, LVITEM, 4, "Int")
  601.          NumPut(This.SITEM, LVITEM, 8, "Int")
  602.          NumPut(&ITEMTEXT, LVITEM, This.ITEMTextP, "Ptr")
  603.          SendMessage, This.LVM_SETITEMTEXT, This.ITEM, &LVITEM, , % "ahk_id " . H
  604.       }
  605.       If !(This.Next) {
  606.          This.ITEM := This.SITEM := -1
  607.       }
  608.       This.Cancelled := False
  609.       This.Next := False
  610.       Return False
  611.    }
  612. ; ===================================================================================================================
  613. ; NM_DBLCLICK notification
  614. ; ===================================================================================================================
  615.    On_NM_DBLCLICK(H, L) {
  616.       Static LVM_EDITLABELA := 0x1017
  617.       Static LVM_EDITLABELW := 0x1076
  618.       Static LVM_EDITLABEL := A_IsUnicode ? LVM_EDITLABELW : LVM_EDITLABELA
  619.       Static LVM_GETCOLUMNWIDTH := 0x101D
  620.       Static LVM_GETSTRINGWIDTHA := 0x1011
  621.       Static LVM_GETSTRINGWIDTHW := 0x1057
  622.       Static LVM_GETSTRINGWIDTH := A_IsUnicode ? LVM_GETSTRINGWIDTHW : LVM_GETSTRINGWIDTHA
  623.       Static LVM_GETSUBITEMRECT := 0x1038
  624.       Static LVM_SCROLL := 0x1014
  625.       Static WS_VSCROLL := 0x200000
  626. ; OutputDebug, % "NMDBLCLICK - " . This.Next
  627.       This.ITEM := This.SITEM := -1
  628.       ITEM := NumGet(L + This.NMHDRSize, 0, "Int")
  629.       SITEM := NumGet(L + This.NMHDRSize, 4, "Int")
  630.       If This.Attached[H].HasKey("Columns") {
  631.          If !This.Attached[H].Columns.HasKey(SITEM)
  632.             Return False
  633.       }
  634.       If (ITEM >= 0) && (SITEM >= 0) {
  635.          This.ITEM := ITEM
  636.          This.SITEM := SITEM
  637.          If !(This.Next) {
  638.             This.HWND := H
  639.             ControlGet, V, List, Count, , % "ahk_id " . H
  640.             This.Rows := V - 1
  641.             ControlGet, V, List, Count Col, , % "ahk_id " . H
  642.             This.Cols := V - 1
  643.             NumPut(VarSetCapacity(WINDOWINFO, 60, 0), WINDOWINFO)
  644.             DllCall("User32.dll\GetWindowInfo", "Ptr", H, "Ptr", &WINDOWINFO)
  645.             This.DX := NumGet(WINDOWINFO, 20, "Int") - NumGet(WINDOWINFO, 4, "Int")
  646.             This.DY := NumGet(WINDOWINFO, 24, "Int") - NumGet(WINDOWINFO, 8, "Int")
  647.             Styles := NumGet(WINDOWINFO, 36, "UInt")
  648.             SendMessage, LVM_GETSTRINGWIDTH, 0, "WWW", , % "ahk_id " . H
  649.             This.MinW := ErrorLevel
  650.             SendMessage, LVM_GETSTRINGWIDTH, 0, "III", , % "ahk_id " . H
  651.             This.DW := ErrorLevel
  652.             SBW := 0
  653.             If (Styles & WS_VSCROLL)
  654.                SysGet, SBW, 2
  655.             ControlGetPos, LX, LY, LW, , , % "ahk_id " . H
  656.             This.LX := LX
  657.             This.LY := LY
  658.             This.LR := LX + LW - (This.DX * 2) - SBW
  659.             This.LW := LW
  660.             This.SW := SBW
  661.             VarSetCapacity(RECT, 16, 0)
  662.             NumPut(SITEM, RECT, 4, "Int")
  663.             SendMessage, LVM_GETSUBITEMRECT, ITEM, &RECT, , % "ahk_id " . H
  664.             X := NumGet(RECT, 0, "Int")
  665.             If (SITEM = 0) {
  666.                SendMessage, LVM_GETCOLUMNWIDTH, 0, 0, , % "ahk_id " . H
  667.                W := ErrorLevel
  668.             } Else {
  669.                W := NumGet(RECT, 8, "Int") - NumGet(RECT, 0, "Int")
  670.             }
  671.             R := LW - (This.DX * 2) - SBW
  672.             If (X < 0) {
  673.                SendMessage, LVM_SCROLL, X, 0, , % "ahk_id " . H
  674.             } Else If ((X + W) > R) {
  675.                SendMessage, LVM_SCROLL, X + W - R + This.DX, 0, , % "ahk_id " . H
  676.             }
  677.          }
  678.          PostMessage, LVM_EDITLABEL, ITEM, 0, , % "ahk_id " . H
  679.       }
  680.       Return False
  681.    }
  682. ; ===================================================================================================================
  683. ; SubClassProc for ListViews
  684. ; ===================================================================================================================
  685.    SubClassProc(H, M, W, L, I, D) {
  686.       Static EC_LEFTMARGIN := 0x01
  687.       Static EN_SETFOCUS := 0x0100
  688.       Static EN_KILLFOCUS := 0x0200
  689.       Static EN_CHANGE := 0x0300
  690.       Static EN_UPDATE := 0x0400
  691.       Static EM_SETSEL := 0x00B1
  692.       Static EM_SETMARGINS := 0x00D3
  693.       Static WM_COMMAND := 0x0111
  694.       Static WM_HOTKEY := 0x0312
  695.       Static LVM_CANCELEDITLABEL := 0x10B3
  696.       Static LVM_GETSTRINGWIDTHA := 0x1011
  697.       Static LVM_GETSTRINGWIDTHW := 0x1057
  698.       Static LVM_GETSTRINGWIDTH := A_IsUnicode ? LVM_GETSTRINGWIDTHW : LVM_GETSTRINGWIDTHA
  699.       If (H = This.HWND) {
  700.          If (L = This.HEDIT) && (M = WM_COMMAND) {
  701.             N := (W >> 16)
  702.             If (N = EN_UPDATE) || (N = EN_CHANGE) || (N = EN_SETFOCUS) {
  703. ; OutputDebug, SubClassProc Edit : %N%
  704.                If (N = EN_SETFOCUS)
  705.                   SendMessage, EM_SETMARGINS, EC_LEFTMARGIN, 0, , % "ahk_id " . L
  706.                ControlGetText, EDITTEXT, , % "ahk_id " . L
  707.                SendMessage, LVM_GETSTRINGWIDTH, 0, &EDITTEXT, , % "ahk_id " . H
  708.                EW := ErrorLevel + This.DW
  709.                If (EW < This.MinW)
  710.                   EW := This.MinW
  711.                EX := This.EX
  712.                EY := This.EY
  713.                EH := This.OSVersion < 6 ? This.EH + 3 : This.EH ; add 3 for WinXP
  714.                If ((EX + EW) > This.LR) {
  715.                   EW := This.LR - EX
  716.                }
  717.                ControlMove, , EX, EY, EW, EH, % "ahk_id " . L
  718.                If (N = EN_UPDATE)
  719.                   Return 0
  720.             }
  721.          } Else If (M = WM_HOTKEY) {
  722. ; OutputDebug, SubClassProc Hotkey : %W%
  723.             If (W = This.HK_Esc) {
  724.                This.Cancelled := True
  725.                PostMessage, LVM_CANCELEDITLABEL, 0, 0, , % "ahk_id " . H
  726.             } Else {
  727.                This.Next := True
  728.                SendMessage, LVM_CANCELEDITLABEL, 0, 0, , % "ahk_id " . H
  729.                This.Next := True
  730.                This.NextSubItem(H, W)
  731.             }
  732.             Return False
  733.          }
  734.       }
  735.       Return DllCall("Comctl32.dll\DefSubclassProc", "Ptr", H, "UInt", M, "Ptr", W, "Ptr", L)
  736.    }
  737. ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  738. ; PUBLIC INTERFACE ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  739. ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  740. ; ===================================================================================================================
  741. ; METHOD OnMessage Register / unregister LV_InCellEdit message handler for WM_NOTIFY messages
  742. ; Parameters: DoIt - True / False
  743. ; Default: True
  744. ; Return Value: Always True
  745. ; ===================================================================================================================
  746.    OnMessage(DoIt := True) {
  747.       Static MessageHandler := "LV_InCellEdit_WM_NOTIFY"
  748.       Static WM_NOTIFY := 0x4E
  749.       If (DoIt) {
  750.          OnMessage(WM_NOTIFY, MessageHandler)
  751.       } Else If (MessageHandler = OnMessage(WM_NOTIFY)) {
  752.          OnMessage(WM_NOTIFY, "")
  753.       }
  754.       Return True
  755.    }
  756. ; ===================================================================================================================
  757. ; METHOD Attach Register ListView for in-cell editing
  758. ; Parameters: HWND - ListView's HWND (Integer)
  759. ; ---------------- Optional:
  760. ; HiddenCol1 - ListView with hidden first column (Bool)
  761. ; Values: True / False
  762. ; Default: False
  763. ; BlankSubItem - Blank out subitem's text while editing (Bool)
  764. ; Values: True / False
  765. ; Default: False
  766. ; Return values: Always True
  767. ; ===================================================================================================================
  768.    Attach(HWND, HiddenCol1 := False, BlankSubItem := False) {
  769. ; Store HWND and options
  770.       This.Attached[HWND] := {Skip0: HiddenCol1, Blank: BlankSubItem}
  771.       Return True
  772.    }
  773. ; ===================================================================================================================
  774. ; METHOD Detach Restore ListView's default behavior
  775. ; Parameters: HWND - ListView's HWND (Integer)
  776. ; Return values: Always True
  777. ; ===================================================================================================================
  778.    Detach(HWND) {
  779. ; Remove HWND
  780.       This.Attached.Remove(HWND, "")
  781.       Return True
  782.    }
  783. ; ===================================================================================================================
  784. ; METHOD EditCell Edit the specified cell, if possible.
  785. ; Parameters: HWND - ListView's HWND (Integer)
  786. ; Row - 1-based row number (Integer)
  787. ; Col - 1-based column number (Integer)
  788. ; Default: 0 - edit the first editable column
  789. ; Return values: On success: True
  790. ; On failure: False
  791. ; ===================================================================================================================
  792.    EditCell(HWND, Row, Col := 0) {
  793.       If !This.Attached.HasKey(HWND)
  794.          Return False
  795.       ControlGet, Rows, List, Count, , % "ahk_id " . HWND
  796.       This.Rows := Rows - 1
  797.       ControlGet, Cols, List, Count Col, , % "ahk_id " . HWND
  798.       This.Cols := Cols - 1
  799.       If (Col = 0) {
  800.          If This.Attached[HWND].HasKey("Columns")
  801.             Col := This.Attached[HWND].Columns.MinIndex() + 1
  802.          ELse If This.Attached[HWND].Skip0
  803.             Col := 2
  804.          Else
  805.             Col := 1
  806.       }
  807.       If (Row < 1) || (Row > Rows) || (Col < 1) || (Col > Cols)
  808.          Return False
  809.       If (Column = 1) && This.Attached[HWND].Skip0
  810.          Col := 2
  811.       If This.Attached[HWND].HasKey("Columns")
  812.          If !This.Attached[HWND].Columns[Col - 1]
  813.             Return False
  814.       VarSetCapacity(LPARAM, 1024, 0)
  815.       NumPut(Row - 1, LPARAM, This.NMHDRSize + 0, "Int")
  816.       NumPut(Col - 1, LPARAM, This.NMHDRSize + 4, "Int")
  817.       This.On_NM_DBLCLICK(HWND, &LPARAM)
  818.       Return True
  819.    }
  820. ; ===================================================================================================================
  821. ; METHOD SetColumns Sets the columns you want to edit
  822. ; Parameters: HWND - ListView's HWND (Integer)
  823. ; ColArr - Array of 1-based column indices (Array)
  824. ; If a non-array is passed (e.g. the parameter is omitted),
  825. ; the ListView will be resetted to edit all columns.
  826. ; Return values: On success: True
  827. ; On failure: False
  828. ; ===================================================================================================================
  829.    SetColumns(HWND, ColArr := "") {
  830.       If !This.Attached.HasKey(HWND)
  831.          Return False
  832.       If !IsObject(ColArr) {
  833.          This.Attached[HWND].Remove("Columns")
  834.          Return True
  835.       }
  836.       ControlGet, Cols, List, Count Col, , % "ahk_id " . HWND
  837.       Indices := []
  838.       For Each, I In ColArr {
  839.          If I Is Not Integer
  840.             Return False
  841.          If (I < 1) || (I > Cols)
  842.             Return False
  843.          Indices[I - 1] := True
  844.       }
  845.       This.Attached[HWND, "Columns"] := Indices
  846.       Return True
  847.    }
  848. }
  849. ; ======================================================================================================================
  850. ; PRIVATE ListView subclassproc
  851. ; ======================================================================================================================
  852. LV_InCellEdit_LVSUBCLASSPROC(H, M, W, L, I, D) {
  853. ; Critical
  854.    Return LV_InCellEdit.SubClassProc(H, M, W, L, I, D)
  855. }
  856. ; ======================================================================================================================
  857. ; PRIVATE ListView notification handler
  858. ; ======================================================================================================================
  859. LV_InCellEdit_WM_NOTIFY(W, L) {
  860.    Static LVN_BEGINLABELEDITA := -105
  861.    Static LVN_BEGINLABELEDITW := -175
  862.    Static LVN_ENDLABELEDITA := -106
  863.    Static LVN_ENDLABELEDITW := -176
  864.    Static NM_CLICK := -2
  865.    Static NM_DBLCLICK := -3
  866.    H := NumGet(L + 0, 0, "UPtr")
  867.    M := NumGet(L + (A_PtrSize * 2), 0, "Int")
  868.    If (LV_InCellEdit.Attached.HasKey(H)) {
  869. ; BeginLabelEdit -------------------------------------------------------------------------------------------------
  870.       If (M = LVN_BEGINLABELEDITW) || (M = LVN_BEGINLABELEDITA) {
  871.          Return LV_InCellEdit.On_LVN_BEGINLABELEDIT(H, L)
  872.       }
  873. ; EndLabelEdit ---------------------------------------------------------------------------------------------------
  874.       If (M = LVN_ENDLABELEDITW) || (M = LVN_ENDLABELEDITA) {
  875.          Return LV_InCellEdit.On_LVN_ENDLABELEDIT(H, L)
  876.       }
  877. ; Double click ---------------------------------------------------------------------------------------------------
  878.       If (M = NM_DBLCLICK) {
  879.          LV_InCellEdit.On_NM_DBLCLICK(H, L)
  880.       }
  881.    }
  882. }
  883. ;=====================================================================================================================
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement