The MASM Forum

General => The Workshop => Topic started by: PsYcHoCoDe on September 21, 2012, 09:31:21 PM

Title: EM_EXSETSEL problem...
Post by: PsYcHoCoDe on September 21, 2012, 09:31:21 PM
- what i'm trying to actually do: implement search algo (already did it), from a secondary DlgProc (separate dialog, of course), then display the result as a MARKED/SELECTED TEXT in the ascii buffer of the rich edit control using EM_EXSETSEL (this should 'select the defined text, right?)...
- what actually happens: if result is found, the secondary dlgProc closes the dlg, storing the found result's RVA (it's GlobalAlloc'd buff) in a global dword... after that the MAIN dlg proc call the calculation of parameters and actually sending the msg (posted just below is this proc...)...
- result of SendMessageTimeout: returns TRUE (it worked?!), GetLastError: (ERROR_ACCESS_DENIED)... and there's no text actually being selected in the richedit == it actually didn't worked...

- yeah, this is my first meeting with RICHEDIT controls' coding, i'm not really into sophisticated gui stuff usually...

P.S.: yep, i've tryed to load the structure (wParam of msg) with RVA's, tried it with OFFSET's too... nothing happens in both occasions... any ideas, guys?!

MarkFoundString PROC rvaFound:DWORD
LOCAL dwTemp:DWORD
LOCAL rChar:CHARRANGE
    invoke szLen, addr srchString
    mov edx, txtAddr
    mov ecx, rvaFound
    sub ecx, edx ; getting offsets...
    mov rChar.cpMin, ecx
    add eax, ecx
    mov rChar.cpMax, eax
    invoke SendMessageTimeout, hTxt, EM_EXSETSEL, 0, addr rChar, SMTO_NORMAL, 30*1000, addr dwTemp
    ret
MarkFoundString ENDP
Title: Re: EM_EXSETSEL problem...
Post by: MichaelW on September 21, 2012, 09:51:32 PM
If SendMessageTimeout returned true, then the function succeeded and your call to GetLastError is meaningless, because functions that succeed do not necessarily clear the last-error code value. You can test this by using SetLastError to clear the last-error code value immediately before the SendMessageTimeout call.
Title: Re: EM_EXSETSEL problem...
Post by: PsYcHoCoDe on September 21, 2012, 09:56:15 PM
@MichaelW, yes, i know about that, so it's tested... by saying the SendMessageTimeout returns GetLastError, i actually mean that the particular function returns this last error...i always do that, when necessary  :t

P.S: OS = Windows 2009 Embedded (xp-alike), SDK = masm v10 with ml v.10x and updated linker (ms link.exe)...  + i always check everything with immunity dbgr... ;)
Title: Re: EM_EXSETSEL problem...
Post by: qWord on September 22, 2012, 01:06:05 AM
Why are using  SendMessageTimeout()? - AFAICS it makes only sense, if the destination window is created from another thread - otherwise it behaves like SendMessage().
Title: Re: EM_EXSETSEL problem...
Post by: PsYcHoCoDe on September 22, 2012, 01:21:45 AM
@qWord: sometimes hepled me in the past, so i just thought it'ld be kinda 'safer' if i use the timeout... now as u mention it, yeah, it doen't really make much sense, indeed... i just need to get it done somehow, though... maybe i should indeed try this with 'plain' SendMessage?
Title: Re: EM_EXSETSEL problem...
Post by: PsYcHoCoDe on September 22, 2012, 06:16:18 PM
come on, won't someone giva a actual solution to this?! :redface:
Title: Re: EM_EXSETSEL problem...
Post by: sinsi on September 22, 2012, 06:38:45 PM
Well, what are srchString, txtAddr and rvaFound?
Not enough code.
Title: Re: EM_EXSETSEL problem...
Post by: PsYcHoCoDe on September 22, 2012, 06:55:11 PM
@sinsi: srchString is  a pointer, txtAddr & rvaFound too are pointers, mate ;)Allocated , using GlobalAlloc..
Title: Re: EM_EXSETSEL problem...
Post by: sinsi on September 22, 2012, 07:12:34 PM
Pointers to what?
Title: Re: EM_EXSETSEL problem...
Post by: PsYcHoCoDe on September 22, 2012, 07:19:50 PM
srchString is a pointer to default allocated memory. rvaFound is too the same... txtAddr ir allocated using GlobalAlloc...

P.S: everithin's either dinamically allocated(the usual idea), or statically defined inside the source...  8)
Title: Re: EM_EXSETSEL problem...
Post by: hutch-- on September 22, 2012, 07:56:45 PM
Psycho,

If successful search in a richedit control is what you are after, look in the example code of MASM32, "example06\riched". It works fine.
Title: Re: EM_EXSETSEL problem...
Post by: PsYcHoCoDe on September 22, 2012, 11:42:06 PM
i just tested it with using SendMessage api instead of sendMessageTimeout... it seems the same - LastError == ERROR_ACCESS_DENIED....

@hutch:  of the examples seems that it's actually using offsets, so i didi it that way... alas, still ain't working...

P.S.: eax == 05h and LastError == ERROR_ACCESS_DENIED...

any ideas about that?! (it's being called from the main dialog procedure, that manages the actual richedit controls)...
Title: Re: EM_EXSETSEL problem...
Post by: TouEnMasm on September 23, 2012, 02:11:48 AM

At this time , the ACCESS is only DENIED to your code.
To got an answer post it here.
Title: Re: EM_EXSETSEL problem...
Post by: jj2007 on September 23, 2012, 02:51:47 AM
Psycho,

Your problem can have a dozen different causes. RichEd is an ill-mannered pig, but your chances are good to get an answer because both hutch and myself (and I guess, a few others here) have an awful lot of (bad) experience with RichEd.

However, guessing is not our strong point. Strip your code from anything that you consider valuable and/or confidential, and post the complete source.

Cheers,
jj
Title: Re: EM_EXSETSEL problem...
Post by: PsYcHoCoDe on September 23, 2012, 03:18:37 AM
alas, i pasted ony this piece, cuz almost all of anything else would be considered confidential atm... :/ if it wasn't i would upload somewere the whole thing and post a link... :/

P.S: ye, i wouldn't really mess with richedit items, if i have hadn't do it that way...
Title: Re: EM_EXSETSEL problem...
Post by: jj2007 on September 23, 2012, 03:35:14 AM
Normally in such a case I would construct the simplest setup that shows these symptoms.
Anyway: Have you tried PostMessage?
Title: Re: EM_EXSETSEL problem...
Post by: PsYcHoCoDe on September 23, 2012, 10:50:23 PM
a'right, here's an update... tried to use PostMessage... so it claims that is succeeds (eax == 01) LastError == ERROR_SUCCESS (0)... but still no text is actually being selected inside the richedit box...

MarkFoundString PROC rvaFound:DWORD
LOCAL dwTemp:DWORD
LOCAL rChar:CHARRANGE
int 3
    invoke szLen, addr srchString
    mov edx, txtAddr
    mov ecx, rvaFound
    sub ecx, edx ; getting offsets...
    mov rChar.cpMin, ecx
    add eax, ecx
    mov rChar.cpMax, eax
    ;invoke SendMessage, hTxt, EM_EXSETSEL, 0, addr rChar
    invoke PostMessage, hTxt, EM_EXSETSEL, 0, addr rChar
    ret
MarkFoundString ENDP

:dazzled:

PS: i just tried to eventually work around that, using SendDlgItemMessage like that: invokeSendDlgItemMessage, hWnd, ID_CTEXT, EM_EXSETSEL, 0, addr rChar (instead of postmessage/sendmessage...) -> returns eax == 00000005h/LastError ERROR_ACCESS_DENIED (00000005h)...  :icon_eek: still no text selection marked... hWnd is a GLOBAL variable, containing the MAIN window's handle...
Title: Re: EM_EXSETSEL problem...
Post by: PsYcHoCoDe on September 23, 2012, 11:45:51 PM
What's the probability of that being kinda related to me not bothering to embed a manifest inside the executable?! :icon_rolleyes: i'm going way too short on options on that problem already, so just wild guess...   :redface:
Title: Re: EM_EXSETSEL problem...
Post by: hutch-- on September 23, 2012, 11:58:37 PM
You can test that out by using an external manifest file but I doubt thats the problem. I pointed you at the masm32 example for a reason, it WORKS correctly. If you use a riched 2 or later version, you can search both forwards and backwards with whole word and case options. Just do this the standard Microsoft way and you can do all of these things without having to guess what is happening.
Title: Re: EM_EXSETSEL problem...
Post by: PsYcHoCoDe on September 24, 2012, 12:05:53 AM
i'm using the most primitive/old school/whatever variant - "Riched32.dll", so it's not 2.0 or sth... finally, i may have to give up on the riched32 option and use 2.0 or sth, if it's working... but i still try to preserve backwards compatibility on this...
Title: Re: EM_EXSETSEL problem...
Post by: PsYcHoCoDe on September 24, 2012, 12:17:53 AM
@ hutch-- : btw the example 06 seems to also fail the SendMessage EM_EXSETSEL... return values: eax == 0000000Bh/LastError == ERROR_INVALID_HANDLE... string searched inside the buffer == "asdf"

PS: though the text actually get's selected... ?! ::)
Title: Re: EM_EXSETSEL problem...
Post by: hutch-- on September 24, 2012, 12:43:17 AM
Richedit 1 worked fine in win9x but it is emulated in Win2000 onwards in the later DLL. The series of riched went up to about 3 then it changes to another version that I have avoided as I hear it has problems.

This is the Winhelp on the message EM_EXSETSEL.


The EM_EXSETSEL message selects a range of characters and/or OLE objects in a rich edit control.

EM_EXSETSEL 
wParam = 0;
lParam = (LPARAM) (CHARRANGE FAR *) ichCharRange;


Parameters

ichCharRange

Zero-based index of the character.



Return Values

Returns the zero-based index of the line.


You would check if the LastError value should be applied to a richedit message.
Title: Re: EM_EXSETSEL problem...
Post by: jj2007 on September 24, 2012, 12:51:27 AM
Quote from: PsYcHoCoDe on September 23, 2012, 10:50:23 PM
a'right, here's an update... tried to use PostMessage... so it claims that is succeeds (eax == 01) LastError == ERROR_SUCCESS (0)... but still no text is actually being selected inside the richedit box...

Try something simple like
    ; edit contains "This is a test with Richedit"
    mov rChar.cpMin, 10
    mov rChar.cpMax, 14
with SendMessage, PostMessage, Riched20, ....
Title: Re: EM_EXSETSEL problem...
Post by: PsYcHoCoDe on September 24, 2012, 12:53:04 AM
i've read the official documentationi only wasn't sure about if i should set rva's (inside the memory buffer) or offsets... now i know, it's about offsets, so that calculated correctly... but when using SendMessage, yeah, the getlasterror is the way to check if everything went fine, and it gives me ERROR_ACCESS_DENIED (that applies to SendDlgItemText and PostMessage as well)... i'm sure it's something really tiny, but i still can't think of something, that could be possibly wrong with my current 'setup'... except probably this could be OS specific, since devel environment is Windows Embedded 2009 POSReady, updated to CURRENT... since the last update my 'axe hex editor (v3.0)' stopped actually displaying it's main window... except inside the taskbar... but that seems kinda odd, the updates i applied @ that time were only some stuff about ActiveX rollup (or something similar) and the ms malware remover for september...  :dazzled:
Title: Re: EM_EXSETSEL problem...
Post by: PsYcHoCoDe on September 24, 2012, 01:00:31 AM
@ jj2007: mate, just tried it with static values: cpMin == 04h, cpMax == 08h, using SendDlgItemMessage... again no text's being actually selected, eax == 08h (that would be cpMax i suppose)/LastError == ERROR_ACCESS_DENIED (00000005h)... the last error is actually being set from the SendDlgItemMessage... pretty sure, that plain old SendMessage gives the same result...
Title: Re: EM_EXSETSEL problem...
Post by: PsYcHoCoDe on September 24, 2012, 01:38:52 AM
allright... seems u must EXPLICITLY call SetFocus on the richedit control... how could i work it out, since i actually have to find it in 2 separate richedit's (they can't have the window focus concurrently...)?
Title: Re: EM_EXSETSEL problem...
Post by: TouEnMasm on September 24, 2012, 01:45:50 AM

Only one window could have the focus.If you want to write two differents richedit and you have need of setfocus with riched32.dll,invoke setfocus and then send message to the richedit.The two functions must used the same handle.
Title: Re: EM_EXSETSEL problem...
Post by: PsYcHoCoDe on September 24, 2012, 01:49:07 AM
@ ToutEnMasm : cool, mate, that's quite similar to what i had in mind, since i've two riched's that must have 'concurrent' view... it's something similar to a hex editor, but still not exactly... damn, what a mess for a first richedit project...  :t

P.S.: btw what riched window message could i use to scroll it down to the found position?
Title: Re: EM_EXSETSEL problem...
Post by: TouEnMasm on September 24, 2012, 01:57:30 AM

You made a scroll  with a richedit giving it the style  XX_scroll something.
Use msdn or any help file to have the exact name of the style to use.The style can be up-down  or left-right.
Title: Re: EM_EXSETSEL problem...
Post by: PsYcHoCoDe on September 24, 2012, 02:00:52 AM
@ ToutEnMasm : styles are both ES_AUTOVSCROLL/ES_AUTOVHORIZONTAL and WS_VSCROLL/WS_HSCROLL currently... and it still doesn't seem to do the AUTO part...  :icon_rolleyes:

P.S.: no problem to paste the whole rsrc.rc, if needed?
Title: Re: EM_EXSETSEL problem...
Post by: TouEnMasm on September 24, 2012, 02:05:08 AM

To see them you need to have, a long horizontal text to view the horizontal scrool bar and many lines to see the vertical scrooll bar.If not needed,not shown.
Title: Re: EM_EXSETSEL problem...
Post by: PsYcHoCoDe on September 24, 2012, 02:09:42 AM
yes, mate, i got them... want to think of some way to do it actually automatically scroll down to the found string's line, u know... so that i can think figure out how my algo should go further...

P.S: anyway, i stillg have to develop/extend the search algorithm, etc further... that was just the 'basic' stuff... thank u very much for the help, guys!  :t
Title: Re: EM_EXSETSEL problem...
Post by: TouEnMasm on September 24, 2012, 02:20:11 AM
Quote
want to think of some way to do it actually automatically scroll down
Study a help file,you will find a fonction who allow to show the found line at the desired position on the screen.UP screen to down screen.The code isn't to easy to write.Result depend of the screen resolution.

Title: Re: EM_EXSETSEL problem...
Post by: PsYcHoCoDe on September 24, 2012, 02:21:43 AM
screen resolution dependency would be quite a problem about that...  :redface:
Title: Re: EM_EXSETSEL problem...
Post by: TouEnMasm on September 24, 2012, 02:43:22 AM

The difference with various screen resolution isn't very important but he is.
The line could appear one line upper or down than you want,that all.
The midle position on the screen is the better for me.
Title: Re: EM_EXSETSEL problem...
Post by: PsYcHoCoDe on September 24, 2012, 02:46:50 AM
@ ToutEnMasm : thanks, mate, i'll keep that in mind while developing this... the middle position's actually kinda better for the application actually  :t
Title: Re: EM_EXSETSEL problem...
Post by: jj2007 on September 24, 2012, 02:54:37 AM
Quote from: PsYcHoCoDe on September 24, 2012, 01:49:07 AM
P.S.: btw what riched window message could i use to scroll it down to the found position?

Something like this should do the job:
xor edi, edi
.Repeat
invoke SendMessage, hRE, EM_GETFIRSTVISIBLELINE, 0, 0
sub eax, esi  ; compare to some desired line count
.Break .if !Sign?
invoke SendMessage, hRE, EM_SCROLL, SB_LINEDOWN, 0
inc edi
.Until edi>99 ; break if limit exceeded (e.g. bottom of doc)


SetFocus is not required. RichMasm sets the selection while the user scrolls down the listbox showing the search results, so obviously the listbox has the focus.
Title: Re: EM_EXSETSEL problem...
Post by: PsYcHoCoDe on September 24, 2012, 04:04:16 AM
@ jj2007 : thank u, mate, i'll checkit out right away in the morning and i'll report...  :t
Title: Re: EM_EXSETSEL problem...
Post by: PsYcHoCoDe on September 25, 2012, 01:47:45 AM
@ jj2007 : well, i finally ended up with an algo to calculate new lines from the start and just use EM_LINESCROLL to set the 'current' line...  8) btw is there a 'trustworthy way' to get on which line is actually placed the currently marked up selection? sinds the custom algo tends to have some... erm... bug actually :P what i mean is basically i.e. : get the index with EM_EXGETSEL and eventually using some message to get the actual line number, @which the selection is?
Title: Re: EM_EXSETSEL problem...
Post by: jj2007 on September 25, 2012, 03:54:47 AM
Quote from: PsYcHoCoDe on September 25, 2012, 01:47:45 AMbtw is there a 'trustworthy way' to get on which line is actually placed the currently marked up selection?

Sure, it's EM_EXLINEFROMCHAR
Title: Re: EM_EXSETSEL problem...
Post by: PsYcHoCoDe on September 25, 2012, 05:01:55 AM
@ jj2007 : it's kinda strange, but the offset that does the EM_EXLINEFROMCHAR tends to be kinda pretty the same, as the home brew algo... seems like i'll have to look fer sth somewhere earlier as a defect... :/ the buffer's like 32 BYTES long string (CR - converted to 'C' (if ain't terminators of a 32 bytes string len), LF - converted to 'L' (again, if they're not secondary terminators), zeroes - replaced with SPACE (020h))... each line's fixed len 32 bytes long...  :icon_eek:

P.S.: While the actual selection using EM_EXSETSEL's perfectly correct...  somehow it offsets some quite lines PAST each iteration... though the first (find first actually' correct)
Title: Re: EM_EXSETSEL problem...
Post by: PsYcHoCoDe on September 25, 2012, 05:16:21 AM
here's the actual code... both the initial variant, the secondary variant of an algo (the initial's actually kinda stupid, cuz i thought to do it another way, whatever...) and the EX_LINEFROMCHAR option...

QuoteCOMMENT %
GetLineCountToFoundString PROC uses ecx esi edi edx dwInitRVA:DWORD, dwRVA:DWORD ; returns ZeroBased index...
    xor ecx, ecx ; line count
    xor edx, edx ; byte count
    mov esi, dwInitRVA
    mov edi, dwRVA
@count_lpy:
    cmp esi, edi
    jge @out_of_loop
    lodsb
    inc edx
    cmp edx, 32
    jz @go_count_line
    jmp @count_lpy
@go_count_line:
    cmp word ptr [esi], 0A0Dh
    jz @fix_esi
    xor edx, edx
    inc edx
    inc esi
    inc ecx
    jmp @count_lpy
@fix_esi:
    add esi, 02h
    inc ecx
    xor edx, edx
    jmp @count_lpy
@out_of_loop:
    xchg eax, ecx
    ret
GetLineCountToFoundString ENDP
%

GetLineCountToFoundString PROC uses ecx esi edi dwBaseRVA:DWORD, dwTargRVA:DWORD
    xor ecx, ecx
    mov esi, dwBaseRVA
    mov edi, dwTargRVA
@calc_lpy:
    add esi, 32
    cmp word ptr [esi], 0A0Dh
    jz @count_CRLF
    inc ecx
@check_if_done:
    cmp esi, edi
    jge @out_of_loop
    jmp @calc_lpy
@count_CRLF:
    add esi, 02h
    inc ecx
    jmp @check_if_done
@out_of_loop:
    xchg eax, ecx
    dec eax
    ret
GetLineCountToFoundString ENDP

FindNextString PROC
LOCAL currChar:CHARRANGE
LOCAL fdText:FINDTEXT
LOCAL scrLines:DWORD
LOCAL lenSz:DWORD
int 3
    lea edi, currChar
    xor eax, eax
    mov ecx, sizeof currChar/04h
    rep stosd
   
    invoke szLen, addr srchString
    mov lenSz, eax
   
    invoke SendDlgItemMessage, hWnd, ID_CTEXT, EM_EXGETSEL, 0, addr currChar
    lea ebx, fdText
ASSUME EBX:PTR FINDTEXT
    mov eax, currChar.cpMin
    add eax, lenSz
    mov [ebx].chrg.cpMin, eax
    mov eax, -1
    mov [ebx].chrg.cpMax, eax
    lea eax, srchString
    mov [ebx].lpstrText, eax
    invoke SendDlgItemMessage, hWnd, ID_CTEXT, EM_FINDTEXT, FR_DOWN, addr fdText
    cmp eax, 0FFFFFFFFh
    jz @not_found
    mov [ebx].chrg.cpMin, eax
    mov [ebx].chrg.cpMax, eax
    mov eax, lenSz
    add [ebx].chrg.cpMax, eax
    invoke SendDlgItemMessage, hWnd, ID_CTEXT, EM_EXSETSEL, 0, addr [ebx].chrg

    invoke SendDlgItemMessage, hWnd, ID_CTEXT, EM_EXLINEFROMCHAR, 0, [ebx].chrg.cpMin
    mov scrLines, eax

    ;mov ecx, txtAddr
    ;mov eax, [ebx].chrg.cpMin
    ;add eax, ecx
    ;invoke GetLineCountToFoundString, ecx, eax
    ;mov scrLines, eax
   
    invoke SendDlgItemMessage, hWnd, ID_CTEXT, EM_LINESCROLL, 0, scrLines
ASSUME EBX:PTR NOTHING
    ret
@not_found:
    xor eax, eax
    ret
FindNextString ENDP