March 28, 2024, 05:50:16 PM

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


Rich edit control secrets

Started by Andy, July 27, 2020, 04:09:20 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Andy

I have been taking my own notes as I've gone along writing my editor program.

These are snippets of code examples (in no particular order) of what I have found - you might find different results...

Quite a lot of the commands are documented but there is more to it.

Hopefully I will find time to write a "guide to rich edit controls" soon as a help file, but I thought it would be good to share these snippets with you.

Please keep them in mind, it will save a lot of hair pulling should you attempt to work with rich edit controls.

The snippets are attached (not meant to be compiled - just read).

Thanks,
Andy.
Day after day, day after day, we struck nor breath nor motion, as idle as a painted ship upon a painted ocean.

billhsln

Great information.  Will be very useful on RichEdits.

Thank you,
Bill
When all else fails, get a bigger hammer.

Andy

Thanks Bill,

I always like to share with you all, who help me no end - otherwise I would still be trying to work out why a + b always equals c ;D

Andy.
 
Day after day, day after day, we struck nor breath nor motion, as idle as a painted ship upon a painted ocean.

Andy

September 23, 2020, 05:04:47 AM #3 Last Edit: September 23, 2020, 05:37:20 AM by Andy
Another secret found (or re-discovered)...

Clint showed me how to load a file extremely quickly, but this left a problem for me.

TABS.

I was squashing out tabs on loading a file & replacing each tab with X number of spaces - but this was part of the old slow load file process.

I lost this using Clint's load file code, and it left me with a problem, the code on screen looked untidy, and it was all due to tabs.

I did some reading up and found that

EM_SETTABSTOPS was what I needed.

Now playing around with this command at first didn't seem to do anything for me, until I made a change to the text in the rich edit (purely by accident).

Suddenly, the code was tabbed correctly, all nice and neat.

So this is one way to ensure tabbing is correct:

TabSpacing = 3
Tabss = (TabSpacing * 4)

These two variable as just type INT.

The times by 4 is based on a font size on 10 (I'm sure there will be a question from me about this at some point), every 4 equals a space length.

Now with the "Tabss" variable set, if we make a change after loading our text into a rich edit control, the command goes to work and the job is done.

SENDMESSAGE(rHandle,EM_SETSEL,0,0+1)
CONTROLCMD w1,1,@RTGETSELTEXT,ClipText
CONTROLCMD w1,1,@RTREPLACESEL,CLipText
SENDMESSAGE(rHandle,EM_SETTABSTOPS,1,&Tabss)

Here I'm just replacing the first character with itself - and it works.

rHandle is just a handle to my rich edit control.
ClipText is just an ISTRING.

Andy.
Day after day, day after day, we struck nor breath nor motion, as idle as a painted ship upon a painted ocean.

Andy

October 04, 2020, 10:45:12 PM #4 Last Edit: October 05, 2020, 12:08:40 AM by Andy
Here is another useful tip - line spacing.

The focus for me at the moment was to change the font name / size from a non-changeable font to one that could be chosen by a user.

I was working with (up till now) the "Courier New" font, and sizes 10, 11 & 12.

And all seemed well - until I tried changing to a different font.

Then my edit position calculations went seriously wrong, but what was causing that? and how could I fix it?

More to the point for me, without knowing "where I am" in the rich edit I could not auto complete key words!

With a lot of work, research and testing I found the answer - line spacing.

I needed to find the line spacing of two lines, but how?

Attached is the answer.

How it works:

1. Create a window with a rich edit control in it.
2. Add to the rich edit control two lines of text.
3. Get the first line position by setting a selection.
4. Set focus to the rich edit (which causes a carot position on screen).
5. Store that carot's Y (down) position.
6. Repeat the above for the second line.
7. Calculate the difference - and that's the line spacing answer.

This one is very useful!

How I use it:
I placed the code in a sub routine, which is called after the font preference is set.

The sub routine does the above, and then closes the window, the line spacing value is saved in a global variable.

Once I have this value, I know how big (the height of the rich edit) needs to be.
It also tells me how many lines per page I have.
It fixes my edit position calculation.
I can now change to any font / size.

See attached.

Andy.
Day after day, day after day, we struck nor breath nor motion, as idle as a painted ship upon a painted ocean.

Andy

November 24, 2020, 02:11:18 AM #5 Last Edit: November 24, 2020, 09:10:33 PM by Andy
Thought this would be useful to those of you who are interested in this subject.

Detecting Ctrl + key presses.

I sent Bill a copy of my latest editor code for a test, as always he was very precise in what he tested - which is a major help.

He noted that Ctrl + Z wasn't working, and at that point I didn't expect it to as it was on my "to do" list.

So I decided to have a look and get these key presses working - please remember my rich edit is sub classed.

Step 1.

In the rich edit sub class handler I have this:

CASE WM_KEYDOWN
    IF wParam = 17 'Ctrl Key
        CtrlDown = 1 'A global variable
    ENDIF


I'm setting the global variable CtrlDown to 1 when the Ctrl key is pressed.


Step 2.

Detect when the Ctrl key has been pressed (CtrlDown = 1) and the letter "Z" is typed.

We have to detect what value wParam is (i.e. what letter has been typed).

CASE WM_CHAR
    IF CtrlDown '<--- Control key is down
        PRINT wParam '<--- I print to my console screen to see what this is
    ENDIF

Now you would think (as I did) wParam would have a value of 90 ("Z"'s ASCII number) - wrong!

I found out that with the Ctrl key pressed down & pressing "Z" it gives you a different value.

It's actually 26 not 90.

Armed with this I then did Step 3.


Step 3.
CASE WM_CHAR
    IF CtrlDown and wParam = 26

        "Do my undo code here" 'Ctrl + Z - Undo

    ENDIF

But that wasn't quite right yet, we have to stop the rich edit from doing what it's programmed to do.

So Step 4 was to amend CASE WM_KEYDOWN.

CASE WM_KEYDOWN
    IF wParam = 17 'Ctrl Key
        CtrlDown = 1 'A global variable
    ENDIF

    'Stop the rich edit from doing what it's programmed to do.
    IF CtrlDown = 1 (AND wParam = 67 OR wParam = 86 OR wParam = 88 OR wParam = 89 OR wParam = 90 OR wParam = 65) 'Ctrl + C / V etc...
        RETURN 0
    ENDIF


Finally, step 5, setting the global variable back to zero when the Ctrl key is released.

CASE WM_KEYUP
    IF wParam = 17 'Ctrl Key
        CtrlDown = 0
    ENDIF

Finally, here they are all together for you:

CASE WM_KEYUP
    IF wParam = 17 'Ctrl Key
        CtrlDown = 0
    ENDIF

CASE WM_KEYDOWN
    IF wParam = 17 'Ctrl Key
        CtrlDown = 1 'A global variable
    ENDIF

    IF CtrlDown = 1 AND (wParam = 67 OR wParam = 86 OR wParam = 88 OR wParam = 89 OR wParam = 90 OR wParam = 65) 'Ctrl + C / V etc...
        RETURN 0
    ENDIF

CASE WM_CHAR
    IF CtrlDown and wParam = 26 'Ctrl + Z - Undo
        "Do your undo here"
    ENDIF

Here are the basic (Ctrl + ) codes for you:

1  = A 
24 = X
25 = Y
26 = Z

Hope this helps someone.

Andy.
:)
Day after day, day after day, we struck nor breath nor motion, as idle as a painted ship upon a painted ocean.

billhsln

Shouldn't:

IF CtrlDown = 1 AND wParam = 67 OR wParam = 86 OR wParam = 88 OR wParam = 89 OR wParam = 90 OR wParam = 65 'Ctrl + C / V etc...
be

IF CtrlDown = 1 AND (wParam = 67 OR wParam = 86 OR wParam = 88 OR wParam = 89 OR wParam = 90 OR wParam = 65) 'Ctrl + C / V etc...
Otherwise, if wParam is 67 for any reason this code would be processed.  You are specifically looking for Control codes, then you need the parens.

Bill
When all else fails, get a bigger hammer.

Andy

Bill,

Of course you are right, that's what happens when you are tiered.

I will correct it,

Thanks,
Andy.
 
Day after day, day after day, we struck nor breath nor motion, as idle as a painted ship upon a painted ocean.

Andy

December 15, 2020, 11:06:17 PM #8 Last Edit: December 16, 2020, 12:22:04 AM by Andy
Hi,

This really is a hidden one for all of us using IWB - Hex strings.

I had the editor source code (all 21,000 lines of it - yes it's that big) loaded into my actual editor program, all good so far...

I was simply scrolling away, looking at the code etc and by accident I pressed the Enter key, it didn't matter as it only inserted a blank line.

When I came to exit the editor, it asked me quite correctly if I wanted to save the file, thought what the heck, so I clicked "Yes"...

Then I went back to the IWB editor and re-compiled the program and got several errors!

They were all lines that had say 0x200, or 0x something in.

It seems that the compiler does not like a hex string in upper case.
These lines were being saved as 0X200 not 0x200 etc.

So I have amended the save file routine to check for a hex string in a line and make sure that part of the line is saved as lower case.

FOR a = 0 to CONTROLCMD(w1,RichEdit,@RTGETLINECOUNT) - 1
    CONTROLCMD(w1,RichEdit,@RTGETLINE,a,line$,512)
    INT HexPos = 0
    IF INSTR(UCASE$(line$),"0X")
      HexPos = instr(ucase$(line$),"0X")
    ENDIF
    'Lines with 0x in must be saved as lower case!
    IF HexPos
      INT b1 = HexPos
      INT HexLen = 0
      DO
            b1 ++
            Letter = MID$(line$,b1,1)
            Del = INSTR(CheckLetter2,Letter)
            IF !Del
              HexLen ++
            ENDIF
      UNTIL Del OR b1 = len(line$)
      REPLACE$(line$,HexPos,HexLen+1,LCASE$(MID$(line$,HexPos,HexLen+1))) '<--- Save as lower case!
    ENDIF

    IF INSTR(line$,chr$(13)) 'Line has CHR$(13) + CHR$(10)
      WRITE file1,MID$(line$,1,INSTR(line$,CHR$(13))-1)
      GOTO NextLine
    ENDIF
    IF INSTR(line$,CHR$(10)) 'Line has CHR$(13)
      WRITE file1,MID$(line$,1,INSTR(line$,CHR$(10))-1)
      GOTO NextLine
    ENDIF
    IF !INSTR(line$,CHR$(13)) AND !INSTR(line$,CHR$(10)) 'Line does not have CHR$(13) or CHR$(10)
      WRITE file1,line$
    ENDIF
    LABEL NextLine
NEXT a

The string "Checkletter2" is defined as:

ISTRING CheckLetter2[50] =  CHR$(34) + "' ,-+()[]=:<>&|" + CHR$(9) + CHR$(13)  + CHR$(0) + CHR$(10) + "."

You may need to be aware of this.

Thanks,
Andy.
:)
Day after day, day after day, we struck nor breath nor motion, as idle as a painted ship upon a painted ocean.