Author Topic: select_word procedure 32->64 bit conversion  (Read 592 times)

zedd151

  • Member
  • *****
  • Posts: 1929
select_word procedure 32->64 bit conversion
« on: October 12, 2022, 03:09:14 AM »
I am having a little difficulty in converting hutch's "select_word" procedure from 32 bit to 64. I know it is a register/variable size issue somewhere just hard to track it down. I'll have to install x64dbg to look at it there.
I know that CHARRANGE members are still dword and have adjusted register and variable usage accordingly. I'll look at it in x64dbg and post the 64 bit conversion of that code once I find the error.  :tongue:
« Last Edit: October 12, 2022, 05:25:31 AM by zedd151 »
Regards, zedd.
:tongue:

zedd151

  • Member
  • *****
  • Posts: 1929
Re: select_word procedure 32->64 bit conversion
« Reply #1 on: October 12, 2022, 03:45:34 AM »
btw, I forgot about edx->rdx used r11 instead.  :tongue: 
Heres what I came up with: (removed the unnecessary bits)
Code: [Select]
select_word_64 proc edit:QWORD
    LOCAL ln    :dword
    LOCAL ll    :dword
    LOCAL ci    :dword
    LOCAL os    :dword
    LOCAL mn    :dword
    LOCAL cr    :CHARRANGE
    LOCAL buf[4096]:BYTE
    LOCAL pbuf  :QWORD
    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
    invoke SendMessage,edit,EM_EXLINEFROMCHAR,0,cr.cpMin        ; zero-based index of the line
    mov ln, eax
    invoke SendMessage,edit,EM_LINELENGTH,cr.cpMin,0
    mov ll, eax                                                 ; get the line length
    invoke SendMessage,edit,EM_LINEINDEX,ln,0
    mov ci, eax                                                 ; 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_EXSETSEL,0,ADDR cr               ; set selection
    invoke SendMessage,edit,EM_GETSELTEXT,0,ADDR buf            ; get selected text
    xor r10, r10                                                ; zero r10 + r11
    xor r11, r11
    lea r12, buf                                                ; load buffer address
    xor rax, rax
    mov eax, os
    add r12, rax                                                 ; add offset to r12
  lbl0:
    movzx eax, BYTE PTR [r12]                                   ; scan backwards
    cmp BYTE PTR [chtbl+eax], 1                                 ; testing if acceptable character
    jne lbl1
    add r10, 1                                                  ; count characters read backwards
    sub r12, 1
    jmp lbl0
  lbl1:
    add r12, 1                                                  ; correct for last char being non acceptable
  lbl2:
    movzx eax, BYTE PTR [r12]                                   ; scan forwards until next unacceptable character
    cmp BYTE PTR [chtbl+eax], 1
    jne lbl3
    add r11, 1                                                  ; count characters read forward
    add r12, 1
    jmp lbl2
  lbl3:
    sub r10, 1
    mov rax, r10
    sub mn, eax
    mov eax, mn
    mov cr.cpMin, eax
    mov cr.cpMax, eax
    mov rax, r11
    add cr.cpMax, eax
    invoke SendMessage,edit,EM_EXSETSEL,0,ADDR cr               ; set selection
  quit:
    xor rax, rax
    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_64 endp

EditProc proc hWin:QWORD, uMsg:QWORD, wParam:QWORD, lParam:QWORD
    .switch uMsg
      .case WM_LBUTTONDBLCLK
        invoke select_word_64, hEdit
        xor rax, rax
        ret
    .endsw
    invoke CallWindowProc, lpEditProc, hWin, uMsg, wParam, lParam
    ret(
EditProc endp
It werks now. using r10, r11 and r12 to replace ecx, edx and esi respectively.
Had to use "/LARGEADDRESSAWARE:NO" as polink & link were complaing about 'chtbl' and recommended that LARGEADDRESSAWARE:NO be used.
I don't know if I will get used to programming 64 bit code. I try though. I'm sure hutch's 64 bit version looks more elegant than this certainly.
I have removed the example attachment as it has served its purpose. The code for "select_word, 64 bit" is above.
« Last Edit: October 13, 2022, 07:02:15 AM by zedd151 »
Regards, zedd.
:tongue:

zedd151

  • Member
  • *****
  • Posts: 1929
Re: select_word procedure 32->64 bit conversion
« Reply #2 on: October 13, 2022, 02:51:27 AM »
Well my 64 bit adventures didn't last very long. Now back to my regularly scheduled Masm32 project.  :biggrin:
Regards, zedd.
:tongue:

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 10281
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: select_word procedure 32->64 bit conversion
« Reply #3 on: October 13, 2022, 09:43:38 AM »
Z,

Just load the table "chtbl" into a register, in 64 bit you have enough to do this.

    lea r10, chtbl
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :skrewy:

zedd151

  • Member
  • *****
  • Posts: 1929
Re: select_word procedure 32->64 bit conversion
« Reply #4 on: October 13, 2022, 09:55:09 AM »
Z,

Just load the table "chtbl" into a register, in 64 bit you have enough to do this.

    lea r10, chtbl

I hadn't thought of trying that. I did move chtbl into the data section with the same result. Thanks
Regards, zedd.
:tongue:

NoCforMe

  • Member
  • *****
  • Posts: 1043
Re: RichEdit character selection
« Reply #5 on: October 13, 2022, 12:42:44 PM »
Since we're discussing character selection in edit controls, let me throw this into the mix.

After creating and using my own editor, which also uses a RichEdit control, I'm finding some things I really do not like about those controls. Chief among them is some weirdness concerning character selection. Specifically, what happens when you're selecting text at the end of a line.

Compare the two images below. In both I'm selecting text ("EDI") at the end of a line; ain't nothing past that text but a carriage return/line feed pair. But for some strange reason. RichEdit lets you select one character past the end of line, which ends up including a space after the last character. Which means that any searches on this string will only succeed if that text is at the end of line as well. (So does that makes this a feature instead of a bug? I don't think so.)

And sometimes it's difficult to select just that text and not that extra space at the end. Compare to a regular (non-RichEdit) edit control, where the end of line is the end of line and that's that. Obviously the team that created this control made some compromises, and this is one of them.

zedd151

  • Member
  • *****
  • Posts: 1929
Re: RichEdit character selection
« Reply #6 on: October 13, 2022, 12:55:06 PM »
Chief among them is some weirdness concerning character selection. Specifically, what happens when you're selecting text at the end of a line.
Yes, also that it selects a word and the trailing space after it. Thats why the need for a custom word selection function similar to that in the second post. That one is table based for allowing or disallowing certain characters and may be changed depending on your particular needs.
Regards, zedd.
:tongue:

NoCforMe

  • Member
  • *****
  • Posts: 1043
Re: select_word procedure 32->64 bit conversion
« Reply #7 on: October 13, 2022, 01:08:49 PM »
Except that you cannot change the selection behavior of the RichEdit control itself; that's built into it, and you're stuck with its results. How is a "custom word selection function" going to change anything?

Also, I was showing that it pretends that there's a trailing space after EOL when there really isn't one.

zedd151

  • Member
  • *****
  • Posts: 1929
Re: select_word procedure 32->64 bit conversion
« Reply #8 on: October 13, 2022, 01:18:29 PM »
Except that you cannot change the selection behavior of the RichEdit control itself
But you can bypass it. That is what that function does. That is why you don't let CallWindowProc get called and return 0 instead. Just try it. You will see the difference. Easier still, just select a word in qeditor anywhere on a line of text. qeditor uses the same exact function according to hutch.
Regards, zedd.
:tongue:

NoCforMe

  • Member
  • *****
  • Posts: 1043
Re: select_word procedure 32->64 bit conversion
« Reply #9 on: October 13, 2022, 01:27:33 PM »
OK, I think I see what you're doing: you're selecting a "word" (however you define that--more below) starting at the current selection point.

You find a "word" by searching for the next word delimiter, meaning any non-word character, after the current selection point. That could be a space, or any number of punctuation characters (or the end-of-line). Everything up to the delimiter is part of the word.

zedd151

  • Member
  • *****
  • Posts: 1929
Re: select_word procedure 32->64 bit conversion
« Reply #10 on: October 13, 2022, 01:32:14 PM »
Yes exactly, and it bypasses the default word selection function of the rich edit control. That's hutches table and algorithm btw. He made it that way for a purpose. It can be changed also, if there are other specific needs.
I'll look for the 32 bit version and post link to it, if you wanna try it out.
Regards, zedd.
:tongue:

zedd151

  • Member
  • *****
  • Posts: 1929
Re: select_word procedure 32->64 bit conversion
« Reply #11 on: October 13, 2022, 01:33:58 PM »
http://masm32.com/board/index.php?topic=10411.msg114603#msg114603
Hutch's word selection code 32 bit...


But his example is wrong.
Should be the handle of the richedit control passed.
And in left button double click message handler in the richedit WNDPROC
The other is for F1 help (win32.hlp) he obviously copied the wrong portion of code to post there.


Trying to post on an iPad is an exercise in futility. Word correction interferes with asm specific words. Lol
Regards, zedd.
:tongue:

NoCforMe

  • Member
  • *****
  • Posts: 1043
Re: select_word procedure 32->64 bit conversion
« Reply #12 on: October 13, 2022, 01:41:13 PM »
I'll look for the 32 bit version and post link to it, if you wanna try it out.

Thanks, but don't bother. I can see what's going on there and could code it myself when I want to. Right now it's not any kind of priority; I just go by whatever selections I've made in the text.

The table of delimiter characters is pretty kewl, gotta admit.

zedd151

  • Member
  • *****
  • Posts: 1929
Re: select_word procedure 32->64 bit conversion
« Reply #13 on: October 13, 2022, 01:41:58 PM »
Ok.  :azn:  Incidentally the code I previously used was very close, but I missed something. It didn't work quite as expected. That's why hutch offered up his code.
Regards, zedd.
:tongue: