Description:
A collection of functions for interacting with Edit controls.
Compatiblity:
AHK v1.0.46 minimum, tested on v1.0.47.04.
Works with standard Edit controls, should work with rich-edit controls and partially Scintilla. Edit_SelectLine() and Edit_DeleteLine() don't work with Scintilla, since EM_LINELENGTH doesn't seem to work.
When named Edit.ahk, it should be Lib-compatible.
Documentation:
See the comments.
;************************ ; Edit Control Functions ;************************ ; ; Standard parameters: ; Control, WinTitle If WinTitle is not specified, 'Control' may be the ; unique ID (hwnd) of the control. If "A" is specified ; in Control, the control with input focus is used. ; ; Standard/default return value: ; true on success, otherwise false. Edit_Standard_Params(ByRef Control, ByRef WinTitle) { ; Helper function. if (Control="A" && WinTitle="") { ; Control is "A", use focused control. ControlGetFocus, Control, A WinTitle = A } else if (Control+0!="" && WinTitle="") { ; Control is numeric, assume its a ahk_id. WinTitle := "ahk_id " . Control Control = } } ; Returns true if text is selected, otherwise false. ; Edit_TextIsSelected(Control="", WinTitle="") { Edit_Standard_Params(Control, WinTitle) return Edit_GetSelection(start, end, Control, WinTitle) and (start!=end) } ; Gets the start and end offset of the current selection. ; Edit_GetSelection(ByRef start, ByRef end, Control="", WinTitle="") { Edit_Standard_Params(Control, WinTitle) VarSetCapacity(start, 4), VarSetCapacity(end, 4) SendMessage, 0xB0, &start, &end, %Control%, %WinTitle% ; EM_GETSEL if (ErrorLevel="FAIL") return false start := NumGet(start), end := NumGet(end) return true } ; Selects text in a text box, given absolute character positions (starting at 0.) ; ; start: Starting character offset, or -1 to deselect. ; end: Ending character offset, or -1 for "end of text." ; Edit_Select(start=0, end=-1, Control="", WinTitle="") { Edit_Standard_Params(Control, WinTitle) SendMessage, 0xB1, start, end, %Control%, %WinTitle% ; EM_SETSEL return (ErrorLevel != "FAIL") } ; Selects a line of text. ; ; line: One-based line number, or 0 to select the current line. ; include_newline: Whether to also select the line terminator (`r`n). ; Edit_SelectLine(line=0, include_newline=false, Control="", WinTitle="") { Edit_Standard_Params(Control, WinTitle) ControlGet, hwnd, Hwnd,, %Control%, %WinTitle% if (!WinExist("ahk_id " hwnd)) return false if (line<1) ControlGet, line, CurrentLine SendMessage, 0xBB, line-1, 0 ; EM_LINEINDEX offset := ErrorLevel SendMessage, 0xC1, offset, 0 ; EM_LINELENGTH lineLen := ErrorLevel if (include_newline) { WinGetClass, class lineLen += (class="Edit") ? 2 : 1 ; `r`n : `n } ; Select the line. SendMessage, 0xB1, offset, offset+lineLen ; EM_SETSEL return (ErrorLevel != "FAIL") } ; Deletes a line of text. ; ; line: One-based line number, or 0 to delete current line. ; Edit_DeleteLine(line=0, Control="", WinTitle="") { Edit_Standard_Params(Control, WinTitle) ; Select the line. if (Edit_SelectLine(line, true, Control, WinTitle)) { ; Delete it. ControlSend, %Control%, {Delete}, %WinTitle% return true } return false }Example: (Simple, but useful)
; Delete word left/right. ^BS:: Send % Edit_TextIsSelected("A") ? "{Delete}" : "^+{Left}{Delete}" ^Delete:: Send % Edit_TextIsSelected("A") ? "{Delete}" : "^+{Right}{Delete}"
Related: Hotkeys that affect only Edit controls (scroll down to "Example.")