News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Selecting Text [Still need help]

Started by chemicalNova, May 26, 2005, 12:08:36 PM

Previous topic - Next topic

chemicalNova

Howdy all,

I'm attempting to select some text inside a richtextbox. The word I want to select, is the word the user just typed. I'm wondering if there are MASM functions like "InStr" and "InStrRev"? If I had these, I could easily do it, but my ASM skills just aren't up to scratch it in this area.

I know how to use EM_SETSEL, but I need the starting and ending positiong of the word, which require Instr or InStrRev.

Ta in advance,

chem

pbrennick

chemicalNova,
Hii, in the masm32 library you will find instring.asm

hth,
Paul

ToutEnMasm

Hello,
It's not so easy to find the world you just Type.When you have got the line , you have also to find what is around the world and what are the limits of a world.That's would be a , a \ ,a space a tab ....
Use getsel to give the line,terminated by zero,and then analyze the line starting at the end , and look for words breaks with lodsb.
                              ToutEnMasm

hutch--

chem,

have a look at the richedit sample in the example code in MASM32. It does all of this stuff and if you need more, just ask.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

chemicalNova

Quote from: pbrennick on May 26, 2005, 12:28:23 PM
chemicalNova,
Hii, in the masm32 library you will find instring.asm

hth,
Paul

Is there any way to reverse this function? I'm wanting to search backwards from the current cursor position. I'm tired now, but could I just:

1) Change the counter default value to the length of the source
2) Change the Pre_Scan label to decrease instead of increase
?

Sorry, for the life of me I can't figure these simple things out. I'll look at your replies in the morning. Thanks again all! :)

chem

hutch--

chem,

Not really, the instring function in the MASM32 library is dedicated for forward search and to do a reverse search would mean writing an algo to do it. If you are just processing simple text as user entry, you probably don't need anything complicated, tell us a bit more about what you are doing and there may be a simpler way to do it.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

chemicalNova

I'm trying to create a sort of Syntax Highlighting feature, but just to create some words bold, some underline, etc..

I know how to do it, because I've used the API in VB and C to create something similar, but they had functions like InStrRev to use, so I could select the last typed word, and make it bold.

I'm using LockWindowUpdate to not update the RichTextBox while highlighting.

Thanks hutch and everyone else for your help,

chem

hutch--

chem,

About the only thing I have done that dores anything even vaguely similar is the F1 help in QE which grabs the line after determining the current location of the caret then it scans backwards to find the first unacceptable character then scans back forward toi locate the next unacceptable character.


This is a TEST of word selection


Think in terms of the caret being located somewhere in the word "TEST", scan backwards to find the space before it then scan forward to get the next space after it and you have the start location and lebgth of the word you want.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

chemicalNova

I just need to know how to scan backwards. I can use InString to scan forwards once I now how to scan backwards.

To select the word, I'll use this:

startpos = space_before_word_pos
endpos = space_after_word_pos
SelStart = startpos
WordLength = endpos - startpos

I can't figure out how to scan backwards  :(

So sorry :(

chem

hutch--

 :bg

chem,

You have to get your hands dirty and code some assembler to do what you need. The string you want to work on will have an adress so you load it into a register and scan in either direction by adding or subtracting from that address.

This is not a complete algo but its basically how you do a two way scan.


    mov esi, lpstring
  @@:
    cmp BYTE PTR [esi], 32      ; space character and lower
    jle nxt
    sub esi, 1                  ; sub means scan backwards
    jmp @B

nxt:
    mov edi, esi                ; store current location in EDI
    add esi, 1                  ; start back on last scanned character
  @@:
    cmp BYTE PTR [esi], 32
    jle lpout
    add esi, 1                  ; add means scan forwards
    jmp @B

  lpout:
    ; EDI holds start pos
    ; ESI holds end pos
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

chemicalNova

Sorry for the late reply hutch, I've had my keyboard stolen by my brothers GF for a while..  :red

Thanks for the above. So, basically, if I have a string inside a 32 bit register, adding numbers to it (using add), then using BYTE PTR would return the letter in the string based on how much I have added? So, if reg = "hello world!" and I used, add reg,4, BYTE PTR would return "o"? Seems kinda strange if this is the case, but ok  :green2

Also, @B. Does this mean the last label (above?)? I'll give it a try. I'll keep at it, I may even figure it out myself yet!

I feel stupid though.

Thanks again for all the help! :green2

chem

Phil

QuoteThanks for the above. So, basically, if I have a string inside a 32 bit register, adding numbers to it (using add), then using BYTE PTR would return the letter in the string based on how much I have added? So, if reg = "hello world!" and I used, add reg,4, BYTE PTR would return "o"? Seems kinda strange if this is the case, but ok
The register would actually contain a pointer to the string and you would increment by 1 as you processed characters in the forward direction. Decrement by 1 and you go in reverse.

In Hutch's code above the @B is refering the @@: that immediately preceeds the @B (Backward) reference. You'll also see @F that refers to the next @@: label following the @F reference. Checkout the help menu in the MASM32 Editor (qeditor.exe) that came with your MASM32 installation for some great help with the assembler, opcodes, libraries, and lots of other things.

hutch--

chem,

I would find a solution to the "missing keyboard" problem, put locktite in her hair gel or fine chopped fibreglass in her washing basket.

Now a couple of things, a 32 bit register ONLY holds 4 bytes so it does not contain the string, what it contains is the ADDRESS of the string, literally WHERE its at in memory. Adding or subtracting from the register changes where the BYTE you are testing is located in memory.

The expression "BYTE PTR" is a DWORD address of a BYTE, literally it tells you WHERE the BYTE is in memory.

Now the distinction you need to keep in mind with addressing is between WHERE something is and what VALUE it has at the address. Think of it this way, you can have a normal integer "5" written at an address so the address will be a DWORD which is generally a large number but the value AT that address is still "5".
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

chemicalNova

Does this kinda look right?

ReColorText proc uses edi esi hWinH:HWND,hRich:HWND
;this will recolor the text
LOCAL buffer1[128]:BYTE
LOCAL tl:DWORD
LOCAL lpstring:DWORD
LOCAL var1:DWORD
LOCAL var2:DWORD
LOCAL thePos:DWORD
LOCAL theStart:DWORD
LOCAL theEnd:DWORD


;invoke LockWindowUpdate,hRich
invoke SendMessage,hRich,WM_GETTEXTLENGTH,0,0
mov tl,eax
inc tl ;add 1 more because of option base 0
invoke GetWindowText,hRich,lpstring,tl
invoke SendMessage,hRich,EM_EXGETSEL,var1,var2
mov esi,lpstring
add esi,var1
@@:
cmp BYTE PTR [esi],32
jle nxt
sub esi,1 ;go backwards..
jmp @B

nxt:
mov edi, esi ;store this position in edi
add esi, 1

@@:
cmp BYTE PTR [esi],32
jle finish
add esi,1 ;go forwards
jmp @B

finish:

mov theStart,edi
mov theEnd,esi

invoke SendMessage,hRich,EM_SETSEL,theStart,theEnd

;invoke LockWindowUpdate,0
ret
ReColorText endp

It crashes, and the only reason I could think of, is the way I get the RichTextBoxes text, and I don't check if the position is the end of the string, or the very start (which probably results in negative numbers).

edit: Ta hutch, *writes down the above suggestions* :green2 . Ta for the explanation aswell, its better coming from a person than from a manual; I find anyway.

chem

chemicalNova

Well, I've made little progress. This doesn't work, but it doesn't crash. It seems to be the basic idea..

ReColorText proc uses edi esi hWinH:HWND,hRich:HWND
;this will recolor the text
LOCAL tl:DWORD
LOCAL lpstring:DWORD
LOCAL rect:RECT
LOCAL thePos:DWORD
LOCAL theStart:DWORD
LOCAL theEnd:DWORD
LOCAL theChar:CHARRANGE


;invoke LockWindowUpdate,hRich
invoke SendMessage,hRich,WM_GETTEXTLENGTH,0,0
mov tl,eax
inc tl ;add 1 more because of option base 0
invoke GetWindowText,hRich,lpstring,tl
invoke SendMessage,hRich,EM_POSFROMCHAR,ADDR rect,ecx
mov esi,lpstring
add esi,ecx
@@:
cmp BYTE PTR [esi],32
jle nxt
sub esi,1 ;go backwards..
jmp @B

nxt:
mov edi, esi ;store this position in edi
add esi, 1

@@:
cmp BYTE PTR [esi],32
jle finish
add esi,1 ;go forwards
jmp @B

finish:

mov theChar.cpMin,edi
mov theChar.cpMax,esi

invoke SendMessage,hRich,EM_EXSETSEL,0,ADDR theChar

;invoke LockWindowUpdate,0
ret
ReColorText endp

It doesn't work, but it doesn't crash. Can anyone fix this so it highlights the word? I don't get why it won't..

Ta in advance,

chem