- 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
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.
@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... ;)
Why are using SendMessageTimeout()? - AFAICS it makes only sense, if the destination window is created from another thread - otherwise it behaves like SendMessage().
@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?
come on, won't someone giva a actual solution to this?! :redface:
Well, what are srchString, txtAddr and rvaFound?
Not enough code.
@sinsi: srchString is a pointer, txtAddr & rvaFound too are pointers, mate ;)Allocated , using GlobalAlloc..
Pointers to what?
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)
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.
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)...
At this time , the ACCESS is only DENIED to your code.
To got an answer post it here.
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
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...
Normally in such a case I would construct the simplest setup that shows these symptoms.
Anyway: Have you tried PostMessage?
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...
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:
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.
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...
@ 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... ?! ::)
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.
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, ....
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:
@ 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...
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...)?
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.
@ 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?
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.
@ 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?
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.
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
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.
screen resolution dependency would be quite a problem about that... :redface:
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.
@ ToutEnMasm : thanks, mate, i'll keep that in mind while developing this... the middle position's actually kinda better for the application actually :t
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.
@ jj2007 : thank u, mate, i'll checkit out right away in the morning and i'll report... :t
@ 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?
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
@ 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)
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