Created
July 10, 2012 15:21
-
-
Save maul-esel/3084017 to your computer and use it in GitHub Desktop.
LVX 1.05.0
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Title: LVX Library | |
Row colouring and cell editing functions for ListView controls. | |
Remarks: | |
Cell editing code adapted from Michas <http://www.autohotkey.com/forum/viewtopic.php?t=19929>; | |
row colouring by evl <http://www.autohotkey.com/forum/viewtopic.php?t=9266>. | |
Many thanks to them for providing the code base of these functions! | |
License: | |
- Version 1.04 by Titan <http://www.autohotkey.net/~Titan/#lvx> | |
- zlib License <http://www.autohotkey.net/~Titan/zlib.txt> | |
- Version 1.05.0-alpha by maul.esel (Unicode and 64bit corrections) | |
*/ | |
/* | |
Function: LVX_Setup | |
Initalization function for the LVX library. Must be called before all other functions. | |
Parameters: | |
name - associated variable name (or Hwnd) of ListView control to setup for colouring and cell editing. | |
*/ | |
LVX_Setup(name) { | |
global lvx ; data storage | |
PtrSize := A_PtrSize ? A_PtrSize : 4, PtrType := A_PtrSize ? "Ptr" : "UInt" | |
If name is xdigit | |
h = %name% | |
Else GuiControlGet, h, Hwnd, %name% | |
VarSetCapacity(lvx, PtrSize + 255 * 9, 0) ; TODO (?) | |
NumPut(h + 0, lvx, 0, PtrType) ; store HWND in data storage | |
OnMessage(0x4e, "WM_NOTIFY") | |
LVX_SetEditHotkeys() ; initialize default hotkeys | |
} | |
/* | |
Function: LVX_CellEdit | |
Makes the specified cell editable with an Edit control overlay. | |
Parameters: | |
r - (optional) row number (default: 1) | |
c - (optional) column (default: 1) | |
set - (optional) true to automatically set the cell to the new user-input value (default: true) | |
Remarks: | |
The Edit control may be slightly larger than its corresponding row, | |
depending on the current font setting. | |
*/ | |
LVX_CellEdit(set = true) { | |
global lvx, lvxb | |
static i := 1, e, h, k := "Enter|Esc|NumpadEnter", LVIR_LABEL := 2 | |
PtrSize := A_PtrSize ? A_PtrSize : 4, PtrType := A_PtrSize ? "Ptr" : "UInt" | |
If i | |
{ | |
Gui, %A_Gui%:Add, Edit, Hwndh ve Hide r1 | |
;make row resize to fit this height.. then back | |
h += i := 0 | |
} | |
If r < 1 | |
r = %A_EventInfo% | |
If !LV_GetNext() | |
Return | |
If !(A_Gui or r) | |
Return | |
l := NumGet(lvx) ; TODO | |
SendMessage, 4135, , , , ahk_id %l% ; LVM_GETTOPINDEX | |
vti = %ErrorLevel% | |
bw := 0, by := 0, bpw := 0 | |
VarSetCapacity(xy, 16, 0) | |
ControlGetPos, bx, t, , , , ahk_id %l% | |
SendMessage, 4136, , , , ahk_id %l% ; LVM_GETCOUNTPERPAGE | |
Loop, %ErrorLevel% { | |
cr = %A_Index% | |
NumPut(cr - 1, xy, 4, "UInt"), NumPut(LVIR_LABEL, xy, 0, "UInt") | |
SendMessage, 4152, vti + cr - 1, &xy, , ahk_id %l% ; LVM_GETSUBITEMRECT | |
by := NumGet(xy, 4, "UInt") | |
If (LV_GetNext() - vti == cr) | |
Break | |
} | |
by += t + 1 | |
cr-- | |
VarSetCapacity(xy, 16, 0) | |
CoordMode, Mouse, Relative | |
MouseGetPos, mx | |
Loop, % LV_GetCount("Col") { | |
cc = %A_Index% | |
NumPut(cc - 1, xy, 4, "UInt"), NumPut(LVIR_LABEL, xy, 0, "UInt") | |
SendMessage, 4152, cr, &xy, , ahk_id %l% ; LVM_GETSUBITEMRECT | |
bx += bw := NumGet(xy, 8, "UInt") - NumGet(xy, 0, "UInt") | |
If !bpw | |
bpw := NumGet(xy, 0, "UInt") | |
If (mx <= bx) | |
Break | |
} | |
bx -= bw - bpw - 2 | |
LV_GetText(t, cr + 1, cc) | |
GuiControl, , e, %t% | |
ControlMove, , bx, by, bw, , ahk_id %h% | |
GuiControl, Show, e | |
GuiControl, Focus, e | |
sizeof_GUITHREADINFO := 6 * PtrSize + 24 | |
VarSetCapacity(g, sizeof_GUITHREADINFO, 0) | |
NumPut(sizeof_GUITHREADINFO, g, 0, "UInt") ; GUITHREADINFO::cbSize | |
LVX_SetEditHotkeys(~1, h) | |
Loop { | |
DllCall("GetGUIThreadInfo", "UInt", 0, PtrType, &g) | |
If (lvxb or NumGet(g, 8 + PtrSize, PtrType) != h) | |
Break | |
Sleep, 100 | |
} | |
GuiControlGet, t, , e | |
If (set and lvxb != 2) | |
LVX_SetText(t, cr + 1, cc) | |
GuiControl, Hide, e | |
Return, lvxb == 2 ? "" : t | |
} | |
/* | |
Function: LVX_SetText | |
Set the text of a specified cell. | |
Parameters: | |
text - new text content of cell | |
row - (optional) row number | |
col - (optional) column number | |
*/ | |
LVX_SetText(text, row = 1, col = 1) { | |
global lvx | |
PtrSize := A_PtrSize ? A_PtrSize : 4, PtrType := A_PtrSize ? "Ptr" : "UInt", sizeof_LVITEM := 52 + 2 * PtrSize | |
LVM_GETITEMTEXT := 0x1000 + (A_IsUnicode ? 115 : 45), LVM_SETITEMTEXT := 0x1000 + (A_IsUnicode ? 116 : 46) | |
l := NumGet(lvx, 0, PtrType) ; get HWND from data storage | |
row-- ; zero-based index | |
VarSetCapacity(d, sizeof_LVITEM, 0) | |
SendMessage, LVM_GETITEMTEXT, row, &d, , ahk_id %l% ; initialize item structure (first item in the row) | |
NumPut(col - 1, d, 8, "Int") ; adjust column index | |
NumPut(&text, d, 20, PtrType) ; set text | |
SendMessage, LVM_SETITEMTEXT, row, &d, , ahk_id %l% | |
} | |
/* | |
Function: LVX_SetEditHotkeys | |
Change accept/cancel hotkeys in cell editing mode. | |
Parameters: | |
enter - comma seperated list of hotkey names/modifiers that will save | |
the current input text and close editing mode | |
esc - same as above but will ignore text entry (i.e. to cancel) | |
Remarks: | |
The default hotkeys are Enter and Esc (Escape) respectively, | |
and such will be used if either parameter is blank or omitted. | |
*/ | |
LVX_SetEditHotkeys(enter = "Enter,NumpadEnter", esc = "Esc") { | |
global lvx, lvxb | |
static h1, h0 | |
If (enter == ~1) { | |
If esc > 0 | |
{ | |
lvxb = 0 | |
Hotkey, IfWinNotActive, ahk_id %esc% | |
} | |
Loop, Parse, h1, `, | |
Hotkey, %A_LoopField%, _lvxb | |
Loop, Parse, h0, `, | |
Hotkey, %A_LoopField%, _lvxc | |
Hotkey, IfWinActive | |
Return | |
} | |
If enter != | |
h1 = %enter% | |
If esc != | |
h0 = %esc% | |
} | |
_lvxc: ; these labels are for internal use: | |
lvxb++ | |
_lvxb: | |
lvxb++ | |
LVX_SetEditHotkeys(~1, -1) | |
Return | |
/* | |
Function: LVX_SetColour | |
Set the background and/or text colour of a specific row on a ListView control. | |
Parameters: | |
index - row index (1-based) | |
back - (optional) background row colour, must be hex code in RGB format (default: 0xffffff) | |
text - (optional) similar to above, except for font colour (default: 0x000000) | |
Remarks: | |
Sorting will not affect coloured rows. | |
*/ | |
LVX_SetColour(index, back = 0xffffff, text = 0x000000) { | |
global lvx | |
PtrType := A_PtrSize ? "Ptr" : "UInt" | |
a := (index - 1) * 9 + 5 ; TODO | |
NumPut(LVX_RevBGR(text) + 0, lvx, a) ; TODO | |
If !back | |
back = 0x010101 ; since we can't use null | |
NumPut(LVX_RevBGR(back) + 0, lvx, a + 4) ; TODO | |
h := NumGet(lvx, 0, PtrType) ; get HWND from data storage | |
WinSet, Redraw, , ahk_id %h% | |
} | |
/* | |
Function: LVX_RevBGR | |
Helper function for internal use. Converts RGB to BGR. | |
Parameters: | |
i - BGR hex code | |
*/ | |
LVX_RevBGR(i) { | |
Return, (i & 0xff) << 16 | (i & 0xffff) >> 8 << 8 | i >> 16 | |
} | |
/* | |
Function: LVX_Notify | |
Handler for WM_NOTIFY events on ListView controls. Do not use this function. | |
*/ | |
LVX_Notify(wParam, lParam, msg) { | |
global lvx | |
PtrSize := A_PtrSize ? A_PtrSize : 4, PtrType := A_PtrSize ? "Ptr" : "UInt" | |
, LVIF_TEXT := 1 | |
If (NumGet(lParam + 0, 0, PtrType) == NumGet(lvx, 0, PtrType) and NumGet(lParam + 0, 2 * PtrSize, "Int") == -12) { ; TODO: adjust -12 for unicode | |
st := NumGet(lParam + 0, 4 + 2 * PtrSize, "UInt") ; get mask item from NMLVDISPINFO->LVITEM structure | |
If (st == LVIF_TEXT) | |
Return, 0x20 ;? | |
Else If (st == 0x10001) { ; TODO: ? | |
a := NumGet(lParam + 36) * 9 + 9 ; get length of item text + 1 and multiply by 9 (?) TODO (36) | |
If NumGet(lvx, a) | |
NumPut(NumGet(lvx, a - 4), lParam + 48), NumPut(NumGet(lvx, a), lParam + 52) | |
} | |
} | |
} | |
WM_NOTIFY(wParam, lParam, msg, hwnd) { | |
; if you have your own WM_NOTIFY function you will need to merge the following four lines: | |
global lvx | |
PtrType := A_PtrSize ? "Ptr" : "UInt" | |
If (NumGet(lParam + 0, 0, PtrType) == NumGet(lvx, 0, PtrType)) | |
Return, LVX_Notify(wParam, lParam, msg) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment