Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Edit Control Functions


  • Please log in to reply
6 replies to this topic
Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
Edit.ahk
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.")

corrupt
  • Members
  • 2558 posts
  • Last active: Nov 01 2014 03:23 PM
  • Joined: 29 Dec 2004
Cool, Thanks :) . Feel free to grab any code from here also for your collection if you'd like, if anything there seems useful.

jballi
  • Members
  • 1029 posts
  • Last active:
  • Joined: 01 Oct 2005
I know this is an old post but I just discovered it. These functions should a lot more reliable than than trying to manipulate text by sending a bunch of keys. Thanks for sharing. 8)

I noticed there were no functions for copy/paste/etc. so I wrote a few that can be incorporated into the Edit.ahk script. These functions haven't gone through hard core testing but they should do the job. Please feel free to rename, modify, and/or ignore.

; Returns true if text is copied to the clipboard, otherwise false.
;
Edit_CopySelected(Control="",WinTitle="")
    {
    Edit_Standard_Params(Control,WinTitle)
    if Edit_TextIsSelected(Control,WinTitle)
        {
        SendMessage 0x301,0,0,%Control%, %WinTitle%  ; WM_COPY
        return true
        }

    return false
    }


; Returns true if text is copied to the clipboard, otherwise false.
;
Edit_CutSelected(Control="",WinTitle="")
    {
    Edit_Standard_Params(Control,WinTitle)
    if Edit_TextIsSelected(Control,WinTitle)
        {
        SendMessage 0x300,0,0,%Control%,%WinTitle%  ; WM_CUT
        return true
        }

    return false
    }



; Returns true if text is pasted from the clipboard, otherwise false.
;
Edit_Paste(Control="",WinTitle="")
    {
    Edit_Standard_Params(Control,WinTitle)
    if StrLen(Clipboard)
        {
        SendMessage 0x302,0,0,%Control%,%WinTitle%  ; WM_PASTE
        return true
        }

    return false
    }



; Returns true if selected text is cleared (deleted), otherwise false.
; Note: Undo can be used to reverse this action.
;
Edit_Clear(Control="",WinTitle="")
    {
    Edit_Standard_Params(Control,WinTitle)
    if Edit_TextIsSelected(Control,WinTitle)
        {
        SendMessage 0x303,0,0,%Control%,%WinTitle%  ; WM_CLEAR
        return true
        }

    return false
    }



; Returns true if undo action was successful, otherwise false.
;
Edit_Undo(Control="",WinTitle="")
    {
    Edit_Standard_Params(Control,WinTitle)
    SendMessage 0x304,0,0,%Control%,%WinTitle%  ; WM_UNDO
    return ErrorLevel
    }
Them be my thougths...

Footbaggin
  • Members
  • 18 posts
  • Last active: Dec 30 2011 02:37 AM
  • Joined: 30 Dec 2011
I'm making a program which searches for user-specified text in files within a directory and displays that text in a GUI edit box.

I can't figure out how to get the program to display the results in the edit box with the searched-for text highlighted. I need it to work so that the first instance of the searched-for word(s) is automatically highlighted and then pressing a hotkey advances to the next instance (and so on).

Can you please provide an example script of how to code a simple "find text in an edit box, set selection on said text"?

Additionally, can you provide some idea of how to get the selection to advance to the next instance of the string? Thank you so much!

Below is the program thus far:

#Include C:\Program Files (x86)\AutoHotkey\Lib\Edit.ahk

Gui, Add, Text, x32 y20 w420 h20 , Transcript searcher
Gui, Add, Edit, x32 y220 w380 h20 vWord, 
Gui, Add, Edit, x460 y20 w370 h420 vResultWindow hwndResultWindowHwnd,
Gui, Add, Button, x322 y290 w90 h30 gSearch, Search
Gui, Add, Button, x32 y430 w100 h20 gSelect, Select Folder
Gui, Add, Edit, x32 y400 w380 h20 vDirectory,
Gui, Add, Text, x32 y200 w120 h20 , Word or phrase
Gui, Add, Text, x32 y120 w120 h20 , Character
Gui, Add, Edit, x32 y140 w160 h20 vCharName, 
Gui, Add, Text, x250 y120 w120 h20 , Date
Gui, Add, Edit, x250 y140 w150 h20 vDate,
Gui, Show, x1904 y144 h473 w870, New GUI Window

IniRead, DirRecall, Config.ini, Config, Folder
GuiControl,, Directory, %DirRecall%

Return

Select:
FileSelectFolder, SelectFolder,, 3
Loop, %SelectFolder%\*.txt, 0, 
{
	Filename = %A_LoopFileFullPath%
	;FileAppend, %Filename%`n, data.txt
	
}
Gui, Submit, NoHide
GuiControl,, Directory, %SelectFolder%
IniWrite, %SelectFolder%, Config.ini, Config, Folder
Return



Search:
Gui, Submit, NoHide
Result := ""
Loop, %Directory%\*.txt, 0,
{
   if (InStr(A_LoopFileName, CharName) && InStr(A_LoopFileName, Date))
   {
      FileRead, Contents, %A_LoopFileFullPath%
      If Contents contains %Word%
         Result .= Contents . "`n"
   }
}
GuiControl,, ResultWindow, %result%

return
GuiClose:
ExitApp


  • Guests
  • Last active:
  • Joined: --
@Footbaggin: Did you see the new edit library by jballi here:
<!-- m -->http://www.autohotke... ... it library<!-- m -->

Footbaggin
  • Members
  • 18 posts
  • Last active: Dec 30 2011 02:37 AM
  • Joined: 30 Dec 2011
Yeah, that's the one I'm using. I can't get Edit_FindText or Edit_SetSel to work at all, let alone correctly. I think I need to see examples with explanation of syntax.

  • Guests
  • Last active:
  • Joined: --
Footbaggin, i found the problem in your script, check your thread.

for clarity, here is a very simple example (using Sendmessage directly, without these nice functions wrapped around)
Gui, Add, Edit, w300 h400 vResultWindow HwndMyEditHwnd , 0123456789abcdefghijklmnopqrstuvwxyz
Gui,Show
SendMessage, 0x0B1, 1, 9, , ahk_id %MyEditHwnd%  ; EM_SETSEL