[Library] Edit v3.0 - Update and Manage any Edit Control

Post your working scripts, libraries and tools for AHK v1.1 and older
User avatar
jballi
Posts: 723
Joined: 29 Sep 2013, 17:34

[Library] Edit v3.0 - Update and Manage any Edit Control

04 Nov 2014, 08:16

Post History
This library was first released on the original AutoHotkey forum. You can find the original post here. New versions of the library will be posted on this forum.

Introduction
The standard Edit Control is a lightweight and surprisingly powerful window control for displaying and editing text. The Edit library was created to help exploit the capabilities of this excellent control.

Edit Library
Key features:
  • Find text. Search for text in the Edit control. Supports RegEx and backward search.
  • Zoom. [v3.0+, Windows 10+] New functions to support zoom, the ability to increase and decrease the size of text in a multiline Edit control.
  • Spell check. The Edit_SpellCheckGUI add-on is a ready-to-go spell check module that can be used on any Edit control. This add-on requires the Fnt and Spell library.
  • Auto-set tab stops. [v1.4+] The Edit_AutoSetTabStop add-on function can be used to automatically set the tab stops for tab-delimited text. This add-on requires the Fnt library.
  • Show selected text. [v3.0+] The Edit_ShowSelectedText function can be used to scroll the lines in the Edit control so that selected text is showing.
Screenshots
A couple of screenshots from the examples:

What's New in Version 3.0
This version is not a reboot. However, there are a lot of changes and there are a large number of possible script breakers. Please read the Release Notes carefully before using. Some key updates:

New functions:
  • Extended Styles. New functions to add or remove extended styles. These functions are only available for Windows 10+.
  • Zoom. The Edit library now supports the Edit control's built-in zoom feature. There is a new function to enable zoom and there are new functions to zoom in, zoom out, and to reset zoom. These functions are only available for Windows 10+.
  • General. There are almost 30 new functions in this version. See the Release Notes for a complete list.
Updates:
  • Flag names. Some functions have been enhanced so that flag or option names (Ex: "Horizontal") can be used instead of integer flag values.
  • Performance. Many functions have been rewritten or enhanced to improve performance.
  • Documentation. The general library documentation has been moved to the _Edit.Doc.ahk file. Natural Docs v2.3 is used to generate HTML documentation from this file and from the function documentation. See the Release Notes for more information.
The Code
The pertinent files are as follows:
  • Project: Edit.zip
    This archive file includes the Edit library, add-on libraries, example scripts, and project documentation.
  • Documentation: Starting with v3.0, the project documentation is included in the project archive file (above).
Compatibility
Starting with v2.0, this project is designed to work on a recent version of AutoHotkey v1.1+. It is not compatible with AutoHotkey v2.0+ (yet).

Issues/Considerations
Most developers will not experience any issues using the Edit library. However, there may be some issues when using the more complex aspects of the Edit control or the Edit library. See the Issues and Considerations section in the Edit library documentation for more information.

References
The following posts were helpful in the creation of this library. Thanks to the original authors. Additional links: There are additional links in the Edit library documentation.

Release Notes
Last edited by jballi on 04 Feb 2024, 21:22, edited 6 times in total.
User avatar
jballi
Posts: 723
Joined: 29 Sep 2013, 17:34

Re: [Library] Edit v1.4 - Update and Manage any Edit Control

04 Nov 2014, 08:17

v1.4
Bug fixes, enhancements, and a few new functions. See the bottom of the first post for the details.
User avatar
jNizM
Posts: 3183
Joined: 30 Sep 2013, 01:33
Contact:

Re: [Library] Edit v1.4 - Update and Manage any Edit Control

04 Nov 2014, 08:21

nice work jballi
but why you dont use github or something?
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
User avatar
joedf
Posts: 8940
Joined: 29 Sep 2013, 17:08
Location: Canada
Contact:

Re: [Library] Edit v1.4 - Update and Manage any Edit Control

04 Nov 2014, 08:27

yes, why not? O__O (peer pressure, Muahahaha!) ;)
Image Image Image Image Image
Windows 10 x64 Professional, Intel i5-8500, NVIDIA GTX 1060 6GB, 2x16GB Kingston FURY Beast - DDR4 3200 MHz | [About Me] | [About the AHK Foundation] | [Courses on AutoHotkey]
[ASPDM - StdLib Distribution] | [Qonsole - Quake-like console emulator] | [LibCon - Autohotkey Console Library]
User avatar
xZomBie
Posts: 256
Joined: 02 Oct 2013, 02:57

Re: [Library] Edit v1.4 - Update and Manage any Edit Control

05 Nov 2014, 01:36

This really should be on GitHub just in case the DropBox got deleted or something...
(Add more pressure!! :twisted: )
Godly Cheese

Re: [Library] Edit v1.4 - Update and Manage any Edit Control

14 Nov 2014, 14:19

Heyo, I love your spell check function.

I just wanted to point out that it could use some streamlining, where GUIs aren't shown if there are no potential corrections. I made a few small changes:

A) Removed "Spell check complete." dialogue.
B) Moved your "Render & Position" section to inside the else component of "if Spell_Spell(hSpell,l_RegExOut)" so the main GUI is only displayed if it registers a spelling error.
User avatar
jballi
Posts: 723
Joined: 29 Sep 2013, 17:34

Re: [Library] Edit v1.4 - Update and Manage any Edit Control

14 Nov 2014, 18:01

Godly Cheese wrote:Heyo, I love your spell check function.
Thanks for giving it a try.
Godly Cheese wrote:I just wanted to point out that it could use some streamlining, where GUIs aren't shown if there are no potential corrections. I made a few small changes:

A) Removed "Spell check complete." dialogue.
B) Moved your "Render & Position" section to inside the else component of "if Spell_Spell(hSpell,l_RegExOut)" so the main GUI is only displayed if it registers a spelling error.
I've gone back and forth on this one. At one time the function was written to only show the "Spell Check" window if there was an spell check hit. While developing this function over the years, I came across a few problem that I tried to solve with the current design.
  • Speed. I'm fairly certain that you are not running into this problem. Most people won't. When checking a very large document and/or if using poorly designed or overly complex dictionary, the spell check process can take a while. 5 seconds or more is not unheard of. The Spell Check window serves as makeshift progress dialog in these cases. I've thought of using some sort progress window instead but anything that needs to be updated regularly will slow down the Spell Check process.
  • End of task. For long Spell Check events, having some sort "end of task" task dialog is a must. Without it, users (myself included) would be asking, "Is it done yet? Can I start working or other stuff?" This "Spell check complete" dialog also doubles as the "Continue checking the remainder of the document?" dialog when the spell check is performed on selected text.
  • Ownership. When displaying a dialog such as the "Continue checking the remainder of the document?" dialog, defining ownership is easy if running the Spell Check on your own GUI. However, ownership is not so clear cut when performing a Spell Check on some random Edit control. This is one of reasons the Spell Check window is always shown so that ownership of stuff (other windows, dialogs, etc.) can be attached to it.
I just wanted to give you the reasons why the function works the way it does but it doesn't mean that you shouldn't make changes that work better for you. Go for it! If you read those last three words real fast out loud, it sounds like 'Go fart!' You can fart if you want to (that's none of my business), but that shouldn't stop you from making the changes that you need to.

If you have any other change recommendations or any requests, please let me know. It's good to hear from someone who is actually using the library.
Godly Cheese

Re: [Library] Edit v1.4 - Update and Manage any Edit Control

15 Nov 2014, 20:57

Ah, that makes sense; especially for Hotkey/manual spell checking.

The script I'm using your library for is something I created to aid line-for-line Japanese to Engilsh translations. Since there are no green/red squigglies like in MS Word, I've opted to force a spell check when the user changes lines (which consist of 20~ English words.) Changing lines takes a few milliseconds anyway, so there's no noticeable delay attributed to the spell check; when the next line loads you're good to go.



I did sift through your documentation a bit and found that Spell_AddCustom() doesn't load the new words into the active dictionary.

Your solution to this was adding a normal Spell_Add() with the same fields after any calls. I may be misunderstanding your documentation/didn't test thoroughly, but isn't the purpose of a Custom Dictionary to allow you to have multiple sets of different words that will or will not conditionally trigger the spell check? If those words are simply added to the main dictionary with Spell_Add() then doesn't that defeat the purpose of having multiple custom dictionaries?

To bypass this problem I altered your Edit_SpellCheckGUI() function to return True if Spell_AddCustom() was successfully run, so I could selectively uninitialize -> initialize SpellInit and load the updated Custom Dictionary.

My script allows users to create multiple profiles for different translation projects, where common terms like names can be added, so my goal was to create separate custom dictionaries to match those profiles.


You might want to consider auto-updating when Spell_AddCustom() is run.
User avatar
jballi
Posts: 723
Joined: 29 Sep 2013, 17:34

Re: [Library] Edit v1.4 - Update and Manage any Edit Control

16 Nov 2014, 21:10

I read this a few times and I still can't be sure if/where the problem is without further clarification or without taking a peek at your code. Also, there may be some confusion as to what the Edit_SpellCheckGUI function does versus what the Spell library functions do. I will give it a shot.
Godly Cheese wrote:I did sift through your documentation a bit and found that Spell_AddCustom() doesn't load the new words into the active dictionary.

Your solution to this was adding a normal Spell_Add() with the same fields after any calls. I may be misunderstanding your documentation/didn't test thoroughly, but isn't the purpose of a Custom Dictionary to allow you to have multiple sets of different words that will or will not conditionally trigger the spell check? If those words are simply added to the main dictionary with Spell_Add() then doesn't that defeat the purpose of having multiple custom dictionaries?
For any project that uses the custom dictionary piece of the Spell library, properly managing the use of one or custom dictionaries is a multi-step process.

There is one and only one spell object that can be used at time. It is created and loaded with words from a primary Hunspell dictionary via the Spell_Init function.

A custom dictionary is just a list of words that have been loaded to a text file, one word per line. Words from a custom dictionary are initially added to the active spell object via the Spell_InitCustom function. This function was separated from the Spell_Init function to allow more than one custom dictionary to be loaded to the active spell object.

As long as the developer understands the rules, the "purpose" of custom dictionaries is up to the developer. The functions that control the actions of custom dictionaries were purposely broken into multiple pieces to allow the developer to determine what action occurs when.

I originally envisioned custom dictionaries to be a list of words that were broken down into logical groups. The primary (and many times the only) custom dictionary would be for the standard use -- users add words not found in main dictionary as they find them. Secondary custom dictionaries might include key words in a programming language (Ex: AutoHotkey), HTML colors, etc. The developer could load whatever custom dictionary is needed for the particular spell check task.

For the Edit_SpellCheckGUI function, any number of custom dictionaries can be loaded on startup, but only one custom dictionary can be specified when the function is called and it is to that custom dictionary, that words are added when the Add button is pressed.
Godly Cheese wrote:To bypass this problem I altered your Edit_SpellCheckGUI() function to return True if Spell_AddCustom() was successfully run, so I could selectively uninitialize -> initialize SpellInit and load the updated Custom Dictionary.

My script allows users to create multiple profiles for different translation projects, where common terms like names can be added, so my goal was to create separate custom dictionaries to match those profiles.
For the Edit_SpellCheckGUI function, custom words are added when the Add button is pressed. The function first adds the word to the specified custom dictionary file with the Spell_AddCustom function. The word is then added to the active spell object with the Spell_Add function. There is no reason to re-initialize the spell object because the new word has already been loaded to the active spell object.

Again, without further clarification or without taking a look at your code, I can't be sure but it appears that the time to re-initialize the spell object is when the profile changes, not when a new word is added.

I hope that this was helpful but something tells me that stuff was lost in translation. If I missed something, please ask again.
-_+
Posts: 70
Joined: 06 Dec 2014, 12:43

Re: [Library] Edit v1.4 - Update and Manage any Edit Control

10 Jan 2015, 21:23

jballi, could you make your example Spell Checks work with RichEdit controls?
User avatar
Soft
Posts: 174
Joined: 07 Jan 2015, 13:18
Location: Seoul
Contact:

Re: [Library] Edit v1.4 - Update and Manage any Edit Control

10 Jan 2015, 21:38

interesting!
AutoHotkey & AutoHotkey_H v1.1.22.07
User avatar
jballi
Posts: 723
Joined: 29 Sep 2013, 17:34

Re: [Library] Edit v1.4 - Update and Manage any Edit Control

11 Jan 2015, 06:12

-_+ wrote:jballi, could you make your example Spell Checks work with RichEdit controls?
Yes, but...

The standard Edit control and the RichEdit control are similar in that they are both "Edit" controls and they share several messages between them. Other than that, they are completely different controls.

For a project that deals exclusively with the standard Edit control, it wouldn't make sense to create an example that works with the RichEdit control. In addition, it's probably not an easy thing to do. I say "probably" because I've spent a total of 38 minutes looking into the RichEdit control. It's a powerful control but for some reason, it's never been a priority for me to use it. That could change in the future.

On the other hand, creating a RichEdit example for the Spell v2.0 project does make sense. It's on my list of things to do but like I said, it's low on the priority list. If someone wants to create an example for that project, I would be very happy publish it along with the project. In the mean time, it's on the list.
-_+
Posts: 70
Joined: 06 Dec 2014, 12:43

Re: [Library] Edit v1.4 - Update and Manage any Edit Control

11 Jan 2015, 09:16

jballi, ok.
Another few questions:
1. does this lib allow to easily get a true line number of a char/caret position?
When a file contains long lines and 'wrap words' feature is turned on - the long line gets cut into smaller ones and each smaller line is then regarded as a separate line, while I need to get it's index as if 'wrap words' feature is off.
2. seems like using Edit_IsWordWrap() to detect 'word wrap' state in an edit is useless: irregardless of that setting's state in notepad.exe that function always returns 'true' and thus it's useless.
User avatar
jballi
Posts: 723
Joined: 29 Sep 2013, 17:34

Re: [Library] Edit v1.4 - Update and Manage any Edit Control

11 Jan 2015, 14:52

-_+ wrote:2. seems like using Edit_IsWordWrap() to detect 'word wrap' state in an edit is useless: irregardless of that setting's state in notepad.exe that function always returns 'true' and thus it's useless.
Thanks for reporting the problem.

I first found this problem when I tried to write this function years back. The function sat dormant for a long time for this very reason. I recently dug up and reworked the function and thought I solved the problem. It seems to work correctly on Edit controls created by AutoHotkey. Obviously I did not retest it with Notepad. Notepad is a unique program that uses some unique combinations of styles. I will make a note of this in the documentation.
-_+ wrote:1. does this lib allow to easily get a true line number of a char/caret position?
When a file contains long lines and 'wrap words' feature is turned on - the long line gets cut into smaller ones and each smaller line is then regarded as a separate line, while I need to get it's index as if 'wrap words' feature is off.
Interesting requirement.

First of all, even with word wrap turned off, the Edit control will break up very long lines (>1024 characters if I remember correctly) into multiple lines. So in theory, this problem could occur with or without knowing the status of the Word Wrap.

This problem can be resolved by counting all of the characters of each line until the desired character position is found. It's not pretty but it should give you the information you need. The following snippet is an example of how to accomplish this task.

Code: Select all

/*
    Note: This example assumes that character position is known and it is stored
    in a variable called CharPos.  The result is a zero-index line number.
*/
Text:=Edit_GetText(hEdit)
    ;-- Note: Only collect/recollect the text from the Edit control if the text
    ;   has changed.

;-- Calculate the "true" line.  Your term, not mine.
LinePos:=-1  ;-- Start at -1 so that the result will be a zero-index value
Loop Parse,Text,`n,`r
    {
    LinePos+=StrLen(A_LoopField)+2
        ;-- Note: The "+2" is for the CR+LF that the Edit control counts for
        ;   every line.

    ;-- Is the CharPos within the current line?
    if (LinePos>CharPos)
        {
        TrueLineIdx:=A_Index-1
        Break
        }
    }

return
I hope this helps.
user12223

Re: [Library] Edit v1.4 - Update and Manage any Edit Control

11 Jan 2015, 19:58

Could I set the margin between line and line ?
User avatar
jballi
Posts: 723
Joined: 29 Sep 2013, 17:34

Re: [Library] Edit v1.4 - Update and Manage any Edit Control

11 Jan 2015, 21:18

user12223 wrote:Could I set the margin between line and line ?
The ability control the vertical space between the lines of text in the document (like double spacing) is not one of the options of the standard Edit control. Sorry. However, I'm fairly certain that vertical spacing is a standard feature of the RichEdit control.
-_+
Posts: 70
Joined: 06 Dec 2014, 12:43

Re: [Library] Edit v1.4 - Update and Manage any Edit Control

12 Jan 2015, 05:46

jballi wrote:Thanks for reporting the problem.

I first found this problem when I tried to write this function years back. The function sat dormant for a long time for this very reason. I recently dug up and reworked the function and thought I solved the problem. It seems to work correctly on Edit controls created by AutoHotkey. Obviously I did not retest it with Notepad. Notepad is a unique program that uses some unique combinations of styles. I will make a note of this in the documentation.
I mentioned notepad as an example. This issue is also reproducible (yet with the opposite result) with Notepad++ and another text editor.
jballi wrote:Interesting requirement.

First of all, even with word wrap turned off, the Edit control will break up very long lines (>1024 characters if I remember correctly) into multiple lines. So in theory, this problem could occur with or without knowing the status of the Word Wrap.

This problem can be resolved by counting all of the characters of each line until the desired character position is found. It's not pretty but it should give you the information you need. The following snippet is an example of how to accomplish this task.

I hope this helps.
I haven't yet tested it (will test when I'll get home), and I hope it helps, but I thought the only reliable way to get true line index is to count the number of line breaks between the caret and the start of the file.
User avatar
jballi
Posts: 723
Joined: 29 Sep 2013, 17:34

Re: [Library] Edit v1.4 - Update and Manage any Edit Control

12 Jan 2015, 07:54

-_+ wrote:I mentioned notepad as an example. This issue is also reproducible (yet with the opposite result) with Notepad++ and another text editor.
Most editors outside of Notepad don't count because they don't use the standard Edit control. Notepad++ for example, uses the Scintilla control.
User avatar
jballi
Posts: 723
Joined: 29 Sep 2013, 17:34

Re: [Library] Edit v1.4 - Update and Manage any Edit Control

12 Jan 2015, 11:37

Thanks to a bug report by -_+, I've done some additional testing and it appears that the conditions tested by the Edit_IsWordWrap function are not good enough indicator of whether Word Wrap is enabled or not. Apparently there are many combinations of styles and other factors that determine whether or not Word Wrap is enabled or not. The function only tests for a few of these conditions and therefore cannot be considered reliable. I have updated the Issues/Considerations section of the first post with this information.
User avatar
jballi
Posts: 723
Joined: 29 Sep 2013, 17:34

Re: [Library] Edit v1.4 - Update and Manage any Edit Control

16 Jan 2015, 11:29

The following is an updated version of the Edit_IsWordWrap function that I'm working on. I'm still testing it but it seems to work correctly. There is one exception (so far) and I've noted it in the documentation. If anyone has the time/opportunity, please give it a try. Let me know if you find any problems. If no one finds any problems, I will include it (less the debug code) in the next release.

Code: Select all

;-----------------------------
;
; Function: Edit_IsWordWrap
;
; Description:
;
;   Returns TRUE if word wrap is enabled on the edit control.
;
; Remarks:
;
;   This function can be tricked into into returning TRUE, i.e. Word Wrap is
;   enabled, by hiding the horizontal scroll bar after the edit control has been
;   created.  Although this situation is rare, it is a possiblity.  One way to
;   ensure that the function always returns FALSE correctly (i.e. Word Wrap is
;   not enabled) is to always include the ES_AUTOHSCROLL style (0x80 or -Wrap)
;   when the WS_HSCROLL style (0x100000) is also included.
;
;-------------------------------------------------------------------------------
Edit_IsWordWrap(hEdit)
    {
    Static Dummy8256

          ;-- Styles
          ,ES_LEFT       :=0x0
          ,ES_CENTER     :=0x1
          ,ES_RIGHT      :=0x2
          ,ES_MULTILINE  :=0x4
          ,ES_AUTOHSCROLL:=0x80
          ,WS_HSCROLL    :=0x100000

          ;-- Message
          ,EM_GETWORDBREAKPROC:=0xD1


    ;-- Get style
    l_Style:=Edit_GetStyle(hEdit)

    ;---------------------------------------------------------------------------
    ;
    ;   Note: The following tests must be performed in the current order.  All
    ;   tests assume that conditions from previous tests have been met.
    ;
    ;---------------------------------------------------------------------------

    ;-- FALSE if not multiline
    ;   Background: Word wrap is only a feature of the multiline edit control.
    if not (l_Style & ES_MULTILINE)
        {
        outputdebug Not a multiline Edit control.  Return FALSE
        Return False
        }

    ;-- TRUE if ES_CENTER or ES_RIGHT style is set.
    ;   Background: ES_AUTOHSCROLL is ignored by a multiline edit control that
    ;   is not left-aligned.  Centered and right-aligned multiline edit controls
    ;   cannot be horizontally scrolled.
    if (l_Style & (ES_CENTER|ES_RIGHT))
        {
        outputdebug ES_CENTER or ES_RIGHT style found.  Return TRUE
        Return TRUE
        }

    ;-- FALSE if ES_AUTOHSCROLL style is set
    if (l_Style & ES_AUTOHSCROLL)
        {
        outputdebug ES_AUTOHSCROLL style found.  Return FALSE
        Return False
        }

    ;-- FALSE if WS_HSCROLL style
    ;   Background: ES_AUTOHSCROLL is automatically applied to a left-aligned,
    ;   multiline edit control that has a WS_HSCROLL style.
    if (l_Style & WS_HSCROLL)
        {
        outputdebug ES_LEFT and WS_HSCROLL styles found.  Return FALSE
        Return False
        }

    ;-- Otherwise, TRUE
    outputdebug No conflicting or definitive styles found.  Return TRUE
    Return True
    }

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: No registered users and 116 guests