Author Topic: my editor project  (Read 7943 times)

jj2007

  • Member
  • *****
  • Posts: 13872
  • Assembly is fun ;-)
    • MasmBasic
Re: my editor project
« Reply #60 on: October 10, 2022, 10:14:42 AM »
This is what gets selected in RichMasm when I click on the question mark (space after , included):

about       db "My Editor v. ?", 0

It's standard behaviour of the RichEdit control, and probably slightly different for different RichEd20.dll versions. Try the same with Notepad. And don't waste precious time with it, if somebody really wants to select the question mark, he can do it with Shift arrow right.

zedd151

  • Member
  • *****
  • Posts: 1937
Re: my editor project
« Reply #61 on: October 10, 2022, 10:21:28 AM »
This is what gets selected in RichMasm when I click on the question mark (space after , included):

about       db "My Editor v. ?", 0
Yes, qeditor does the same. Thats why I know theres an issue. Normal word selection seems to work ok though (double clicking an actual word), so I might just leave it as-is, and possibly look at it another time.
Regards, zedd.
:tongue:

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 10572
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: my editor project
« Reply #62 on: October 10, 2022, 11:17:10 AM »
Z,

QE does something unusual, when you double click a word, it selects the line and goes to the double click position. It then scans backwards until it finds an unacceptable character, the reverses and scans forward through acceptable characters until it finds another unacceptable character, with the two ends found, it highlites the word between the two. It uses a look up table to determine good and bad characters.

This allow adding an underscore, dollar sign and a period so that common code forms can be selected by double clicking.
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :skrewy:

jj2007

  • Member
  • *****
  • Posts: 13872
  • Assembly is fun ;-)
    • MasmBasic
Re: my editor project
« Reply #63 on: October 10, 2022, 11:57:08 AM »
This allow adding an underscore, dollar sign and a period so that common code forms can be selected by double clicking.

Funny, I've passed the last hour trying to implement exactly that in my editor. I'm almost there ;-)

zedd151

  • Member
  • *****
  • Posts: 1937
Re: my editor project
« Reply #64 on: October 10, 2022, 12:07:17 PM »
QE does something unusual
Since I have been using qeditor since at least 2015, I find nothing unusual about how it works. Everything else is the unusual.  :tongue:  And yes, I am attempting to emulate qeditors word selection function in this editor. I'm almost there but I'm missing something. Not a game changer, it works ok as-is; just not perfectly though.  :biggrin: 
Regards, zedd.
:tongue:

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 10572
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: my editor project
« Reply #65 on: October 10, 2022, 12:24:31 PM »
Z,

Here is the algo out of QE that does work selection.

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

select_word proc edit:DWORD

    LOCAL ln    :DWORD
    LOCAL ll    :DWORD
    LOCAL ci    :DWORD
    LOCAL os    :DWORD
    LOCAL mn    :DWORD
    LOCAL mx    :DWORD
    LOCAL cr    :CHARRANGE
    LOCAL cn    :CHARRANGE
    LOCAL buf[4096]:BYTE
    LOCAL pbuf  :DWORD

    ;;;; invoke SleepEx,100,0

    invoke SendMessage,edit,WM_KEYDOWN,VK_LEFT,0

    invoke SendMessage,edit,EM_EXGETSEL,0,ADDR cr               ; get current selection
    mov eax, cr.cpMin
    mov mn, eax

    mov ln, rv(SendMessage,edit,EM_EXLINEFROMCHAR,0,cr.cpMin)   ; zero-based index of the line
    mov ll, rv(SendMessage,edit,EM_LINELENGTH,cr.cpMin,0)       ; get the line length
    mov ci, rv(SendMessage,edit,EM_LINEINDEX,ln,0)              ; get 1st char offset from beginning

    mov eax, cr.cpMin                                           ; offset on line of current caret location
    sub eax, ci
    mov os, eax
    mov eax, ci
    mov cr.cpMin, eax
    add eax, ll
    mov cr.cpMax, eax

    invoke SendMessage,edit,EM_HIDESELECTION,1,0
    invoke SendMessage,edit,EM_EXSETSEL,0,ADDR cr               ; set selection
    invoke SendMessage,edit,EM_GETSELTEXT,0,ADDR buf            ; get selected text

    xor ecx, ecx                                                ; zero ECX + EDX
    xor edx, edx

    push esi
    lea esi, buf                                                ; load buffer address
    add esi, os                                                 ; add offset to ESI
  lbl0:
    movzx eax, BYTE PTR [esi]                                   ; scan backwards
    cmp BYTE PTR [chtbl+eax], 1                                 ; testing if acceptable character
    jne lbl1
    add ecx, 1                                                  ; count characters read backwards
    sub esi, 1
    jmp lbl0

  lbl1:
    add esi, 1                                                  ; correct for last char being non acceptable

  lbl2:
    movzx eax, BYTE PTR [esi]                                   ; scan forwards until next unacceptable character
    cmp BYTE PTR [chtbl+eax], 1
    jne lbl3
    add edx, 1                                                  ; count characters read forward
    add esi, 1
    jmp lbl2

  lbl3:
    pop esi

    sub ecx, 1
    sub mn, ecx
    mov eax, mn
    mov cr.cpMin, eax
    mov cr.cpMax, eax
    add cr.cpMax, edx


  ; |||||||||||||||||||||||||||||||||||||||||||
  ; zero the selection to the first cpMin value
  ; |||||||||||||||||||||||||||||||||||||||||||

    add eax, edx
    mov cn.cpMin, eax
    mov cn.cpMax, eax

    invoke SendMessage,edit,EM_EXSETSEL,0,ADDR cn

  ; |||||||||||||||||||||||||||||||||||||||||||


    invoke SendMessage,edit,EM_HIDESELECTION,0,0
    invoke SendMessage,edit,EM_EXSETSEL,0,ADDR cr               ; set selection

  quit:
    xor eax, eax
    ret

    align 16
    chtbl:
    ; -----------------------------------------
    ; upper and lower case, numbers and "_" "." "$"
    ; -----------------------------------------
      db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
      db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
      db 0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0
      db 1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
      db 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
      db 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1
      db 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
      db 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0
      db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
      db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
      db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
      db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
      db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
      db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
      db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
      db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

      ; ¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤

select_word endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤


It is called from here.

      case WM_KEYDOWN
        switch wParam
          case VK_F1
            invoke SendMessage,hEdit,EM_EXGETSEL,0,ADDR cr
            mov eax, cr.cpMax
            sub eax, cr.cpMin
            .if eax > 256
              fn MessageBox,hWnd,"Selection is too large","Sorry ....",MB_OK
              ret
            .endif

            invoke select_word,hWin
            invoke SendMessage,hEdit,EM_EXGETSEL,0,ADDR cr
            mov eax, cr.cpMin
            .if eax != cr.cpMax                             ; if the algo selects a word
              mov pbuf, ptr$(buffer)
              invoke SendMessage,hEdit,EM_GETSELTEXT,0,pbuf

              mov pMem, ptr$(buf)
              invoke get_app_path,pMem
              mov pMem, cat$(pMem,"qehlp.bin")
              .if rv(exist,pMem)
                mov hMem, InputFile(pMem)
                invoke SetWindowText,rv(GetDlgItem,hWin,101),hMem
                invoke WinHelp,hWnd,hMem,HELP_PARTIALKEY,pbuf
                free hMem
              .endif

              xor eax, eax
              ret
            .endif
        endsw
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :skrewy:

zedd151

  • Member
  • *****
  • Posts: 1937
Re: my editor project
« Reply #66 on: October 10, 2022, 12:28:43 PM »
It's almost 8:30 PM here. I've not done much with the editor today. Between fiddling with the word selection and a couple of other things, I basically wasted that time. At any rate I'll leave that code, as well as my funky tab replacement code as is for the foreseeable future so that I can continue and try to finish this project. I have at least another hour and a half to work on the editor. Need to get the command line functions into code.  :smiley:  Which means that the code up until then is basically finished. Then I can add the search and replace code and a few more custom formatting functions.  :biggrin:
« Last Edit: October 11, 2022, 12:21:08 AM by zedd151 »
Regards, zedd.
:tongue:

zedd151

  • Member
  • *****
  • Posts: 1937
Re: my editor project
« Reply #67 on: October 10, 2022, 12:35:01 PM »
@ hutch.  :biggrin:
I've been waiting for you to share that. Thank you.  :eusa_dance:  That is one the most useful functions in qeditor.

I thought it'd never happen though.
Now I am going to get some work done after all with the editor.
Regards, zedd.
:tongue:

zedd151

  • Member
  • *****
  • Posts: 1937
Re: my editor project
« Reply #68 on: October 10, 2022, 12:41:48 PM »
Quote from: hutch
It is called from here.
      case WM_KEYDOWN

        switch wParam
          case VK_F1
That looks like its for F1 help (Win32.hlp)

Shouldnt it be in WM_LBUTTONDBLCLK??
Quote
invoke select_word, hWin
should'nt that be "invoke select_word, hEdit"?
Are you playing tricks on me?  :biggrin:   
Edit to add:
I made the necessary changes  :cool:

« Last Edit: October 10, 2022, 04:06:07 PM by zedd151 »
Regards, zedd.
:tongue:

zedd151

  • Member
  • *****
  • Posts: 1937
Re: select_word failure!
« Reply #69 on: October 10, 2022, 01:41:37 PM »
Having some issues with the 'select_word' function hutch posted above. Not quite working as expected.
I'll take another look at it in the morning.

Attachment removed. Issue addressed below.
« Last Edit: October 11, 2022, 12:08:44 AM by zedd151 »
Regards, zedd.
:tongue:

zedd151

  • Member
  • *****
  • Posts: 1937
Re: select_word_success
« Reply #70 on: October 10, 2022, 03:25:32 PM »
YaY! I did a bit of exploring the function in olly... and experimenting
Works now.
Code: [Select]
      .if uMsg == WM_LBUTTONDBLCLK
        invoke select_word, hCtl
        invoke SendMessage,hCtl,EM_EXGETSEL,0,ADDR cr
        mov eax, cr.cpMax
        sub eax, cr.cpMin
        cmp eax, 0
        jz xxoo
        xor eax, eax
        ret
      xxoo:

Turns out that if you let CallWindowProc run after processing the selection, the (processed) selection gets interfered with. So return 0, if text is selected.

Also tweaked the select_word function where selection was set with another CHARRANGE; then set with the CHARRANGE where the manipulations were done, so I removed the seemingly useless part and the CHARRANGE struct that went with it.   :tongue:
Code: [Select]
select_word proc edit:DWORD


    LOCAL ln    :DWORD
    LOCAL ll    :DWORD
    LOCAL ci    :DWORD
    LOCAL os    :DWORD
    LOCAL mn    :DWORD
    LOCAL mx    :DWORD
    LOCAL cr    :CHARRANGE
    LOCAL buf[4096]:BYTE
    LOCAL pbuf  :DWORD


    ;;;; invoke SleepEx,100,0


    invoke SendMessage,edit,WM_KEYDOWN,VK_LEFT,0


    invoke SendMessage,edit,EM_EXGETSEL,0,ADDR cr               ; get current selection
    mov eax, cr.cpMin
    mov mn, eax


    mov ln, rv(SendMessage,edit,EM_EXLINEFROMCHAR,0,cr.cpMin)   ; zero-based index of the line
    mov ll, rv(SendMessage,edit,EM_LINELENGTH,cr.cpMin,0)       ; get the line length
    mov ci, rv(SendMessage,edit,EM_LINEINDEX,ln,0)              ; get 1st char offset from beginning


    mov eax, cr.cpMin                                           ; offset on line of current caret location
    sub eax, ci
    mov os, eax
    mov eax, ci
    mov cr.cpMin, eax
    add eax, ll
    mov cr.cpMax, eax


    invoke SendMessage,edit,EM_HIDESELECTION,1,0
    invoke SendMessage,edit,EM_EXSETSEL,0,ADDR cr               ; set selection
    invoke SendMessage,edit,EM_GETSELTEXT,0,ADDR buf            ; get selected text


    xor ecx, ecx                                                ; zero ECX + EDX
    xor edx, edx


    push esi
    lea esi, buf                                                ; load buffer address
    add esi, os                                                 ; add offset to ESI
  lbl0:
    movzx eax, BYTE PTR [esi]                                   ; scan backwards
    cmp BYTE PTR [chtbl+eax], 1                                 ; testing if acceptable character
    jne lbl1
    add ecx, 1                                                  ; count characters read backwards
    sub esi, 1
    jmp lbl0


  lbl1:
    add esi, 1                                                  ; correct for last char being non acceptable


  lbl2:
    movzx eax, BYTE PTR [esi]                                   ; scan forwards until next unacceptable character
    cmp BYTE PTR [chtbl+eax], 1
    jne lbl3
    add edx, 1                                                  ; count characters read forward
    add esi, 1
    jmp lbl2


  lbl3:
    pop esi


    sub ecx, 1
    sub mn, ecx
    mov eax, mn
    mov cr.cpMin, eax
    mov cr.cpMax, eax
    add cr.cpMax, edx
    invoke SendMessage,edit,EM_HIDESELECTION,0,0
    invoke SendMessage,edit,EM_EXSETSEL,0,ADDR cr               ; set selection


  quit:
    xor eax, eax
    ret
I'm glad this little fiasco is done with. And thank you very much again, hutch.
Obviously I couldn't wait until morning, I spent at least an hour and a half trying to figure out why known good code didn't seem to work. It's now almost midnight here. Sleep is overrated anyway. At least I had the chance to hone my troubleshooting skills.


Attachment removed as it is no longer needed. The working code now will be incorporated into my editor project
« Last Edit: October 11, 2022, 12:11:10 AM by zedd151 »
Regards, zedd.
:tongue:

NoCforMe

  • Member
  • *****
  • Posts: 1106
Re: my editor project
« Reply #71 on: October 10, 2022, 04:18:05 PM »
Apologies if you already know this, but I sense some confusion on your part regarding the use of CallWindowProc(). You found that not calling it solved your problem. That makes sense.

The basic rule is this: if you handle a message yourself, do not call CallWindowProc(). Otherwise, if you don't handle the message, call it; this makes the standard control code work on whatever message is being handled. But if you handle the message and then call this function, it may undo what you just did (or do something else unwanted).

zedd151

  • Member
  • *****
  • Posts: 1937
Re: my editor project
« Reply #72 on: October 10, 2022, 04:22:26 PM »
No apologies needed, but I did figure that out apparently. Otherwise I would not have gotten it running.  :biggrin:
Deductive logic I believe. Or at least a happy accident.  :tongue:  Under most circumstances I had never had to bypass CallWindowProc, or not that I remember anyway. But I new that the selection was modified but not showing in the rich edit control. In time I figured it out. It's what troubleshooting is all about.   :biggrin:  And that rhymes.
Regards, zedd.
:tongue:

jj2007

  • Member
  • *****
  • Posts: 13872
  • Assembly is fun ;-)
    • MasmBasic
Re: my editor project
« Reply #73 on: October 10, 2022, 08:46:38 PM »
The basic rule is this: if you handle a message yourself, do not call CallWindowProc(). Otherwise, if you don't handle the message, call it; this makes the standard control code work

The Micros*t language is, e.g. for WM_CHAR:

    Return Values
    An application should return zero if it processes this message.

Which means, translated to English:

Code: [Select]
    xor eax, eax
    ret

i.e. do not CallWindowProc, instead return directly. Do not let the OS handle the message.

To save some space, I often use

Code: [Select]
    xor eax, eax
    jmp ReturnEax
...
    invoke CallWindowProc, ...
...
ReturnEax:
    ret

You may think "it's just a ret", but in reality ret is a macro that handles also the uses esi edi ebx stuff, so it can cost several bytes more. Put an int 3 in front, then launch your debugger :cool:

jj2007

  • Member
  • *****
  • Posts: 13872
  • Assembly is fun ;-)
    • MasmBasic
Re: select_word failure!
« Reply #74 on: October 10, 2022, 09:29:31 PM »
Having some issues with the 'select_word' function hutch posted above. Not quite working as expected.

Alternative code here: Better word selection