News:

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

FindText and ReplaceText bug??

Started by jj2007, February 03, 2009, 11:01:49 PM

Previous topic - Next topic

jj2007

After lots of crashes, my friend Olly told me that FindText and ReplaceText do strange things with the stack. When returning from these two functions, the stack is just a little bit (a dword) too low. Is that a bug in these functions, or a bug in my code?? With the add esp, 4, it works perfectly.




.data?
hFR dd ?
frs FINDREPLACE <>

.code
FindOnly: ; Find
xor eax, eax

FindReplace proc ; Replace
  m2m frs.lStructSize, sizeof FINDREPLACE
  m2m frs.hwndOwner, hWin
  m2m frs.Flags, FR_DOWN
  m2m frs.lpstrReplaceWith, offset BufRepl
  m2m frs.lpstrFindWhat, offset BufFind
  m2m frs.wFindWhatLen, sizeof BufFind
  m2m frs.wReplaceWithLen, sizeof BufRepl
  push offset frs ; one longword
  .if eax
call ReplaceText
  .else
call FindText
  .endif
  add esp, 4 ; strange things happening here
  ret
FindReplace endp

donkey

I would imagine the FindText and ReplaceText functions are STDCALL which would mean that the ADD ESP,xxxx is not required, as a matter of fact it would unbalance the stack and throw an error. If add esp,4 is required perhaps you are supplying too many parameters in the call or something else is distorting the stack.
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

GregL

jj,

The problem seems to be with the m2m macro and the WORD sized structure members. It messes up the stack before you even call FindText or ReplaceText.


jj2007

Quote from: Greg on February 04, 2009, 01:24:48 AM
jj,

The problem seems to be with the m2m macro and the WORD sized structure members. It messes up the stack before you even call FindText or ReplaceText.


Thanxalot, Greg. I fixed this one using
m2m MACRO M1, M2
  pushd M2
  pop dword ptr M1
ENDM


But now I have another problem: The Tab key is not working as expected. I tried this one but no effect:

.Repeat
invoke GetMessage, addr msg, NULL, 0, 0
.break .if eax==0
invoke TranslateAccelerator, hWin, hAccT, addr msg
.if eax==0 ; not an accelerator
.if hFR
invoke IsDialogMessage, hFR, addr msg
.endif
.if eax==0
invoke TranslateMessage, addr msg
invoke DispatchMessage, addr msg
.endif
.endif
.Until 0


hFR is a valid handle to the Find dialog. Any ideas?

donkey

Try this one, worked for me when I used MASM

.WHILE TRUE
invoke GetMessage, ADDR msg,NULL,0,0
.BREAK .IF (!eax)
invoke IsDialogMessage, hMainDlg, ADDR msg
.IF eax ==FALSE
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.ENDIF
.ENDW
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

jj2007

hanks, Edgar. I tried this and a bunch of other combinations nut no success. This seems conformant with the SDK:

.Repeat
invoke GetMessage, addr msg, NULL, 0, 0
.break .if eax==0
.if hFR
invoke IsDialogMessage, hFR, addr msg
.if eax
or eax, -1 ; flag 0, was processed
.endif
inc eax ; 0 if message was processed, 1 if not
.endif
.if eax
invoke TranslateAccelerator, hWin, hAccT, addr msg
.if eax==0
invoke TranslateMessage, addr msg
invoke DispatchMessage, addr msg
.endif
.endif
.Until 0



BOOL IsDialogMessage(

    HWND hDlg,   // handle of dialog box
    LPMSG lpMsg   // address of structure with message
   );

Return Values

If the message has been processed, the return value is nonzero.
If the message has not been processed, the return value is zero.

MichaelW

I think a layout like this meets all of the requirements:

  msgLoop:

    invoke GetMessage, ADDR msg, 0, 0, 0
    .IF eax != 0
      invoke TranslateAccelerator, hDlg, hAccel, ADDR msg
      .IF eax == 0
        invoke IsDialogMessage, hDlg, ADDR msg
        .IF eax == 0
          invoke TranslateMessage, ADDR msg
          invoke DispatchMessage, ADDR msg
        .ENDIF
      .ENDIF
      jmp msgLoop
    .ENDIF
eschew obfuscation

jj2007

Quote from: MichaelW on February 04, 2009, 08:09:08 AM
I think a layout like this meets all of the requirements:
Looks good but doesn't work. Thanks anyway, Michael and others :thumbu

donkey

Maybe a dumb question but did you set the WS_TABSTOP style on your controls ?
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

jj2007

Quote from: donkey on February 04, 2009, 11:22:27 AM
Maybe a dumb question but did you set the WS_TABSTOP style on your controls ?

Windows set them for me - it's a standard Find/Replace box. I attach the full project; extract all somewhere, then launch TinyRTF.exe

Everything seems to work fine, but it's a nagging experience to hit Tab in a Replace box, and nothing happens... grateful for a solution!

[attachment deleted by admin]

Mark Jones

Quote from: Win32 Programmer's ReferenceBecause the IsDialogMessage function performs all necessary translating and dispatching of messages, a message processed by IsDialogMessage must not be passed to the TranslateMessage or DispatchMessage function.

(Although I've seen this done quite a bit in practice, think some of the RadASM templates do this.)
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

jj2007

#11
Yep, that's correct, but it wasn't the cause of the problem.

.Repeat
invoke GetMessage, addr msg, 0, 0, 0
.break .if eax==0
invoke IsDialogMessage, hFR, addr msg
.if eax==0
invoke TranslateAccelerator, hWin, hAccT, addr msg
.if eax==0
invoke TranslateMessage, addr msg
invoke DispatchMessage, addr msg
.endif
.endif
.Until 0


This part was correct. Note the hFR, not hWin, for IsDialogMessage - we are getting messages for a modeless dialog that are not meant for the main window hWin.

Now the solution of the puzzle:
    mov hFR, eax ; this line I had forgotten - sorry...

Attached the "final" version. At 5632 bytes this is a pretty handy editor. UPX says it's not compressible. Hmmm...
IMHO it has everything a newbie needs to start working with Masm32 - but if you are missing any important functions, I am willing to negotiate adding half a kByte ;-)

EDIT: I decided to use up most of the negotiable kByte for making it compatible with the \masm32\examples folder...

[attachment deleted by admin]

herge


Hi there!

In C:\masm32\examples\poasm\riched
there is a file called richedit.asm
Use qeditor to Open it.
Follow instructions inside richedit.asm at
top of file.
You will be rocking and rolling in under a
minute!

Regards herge
// Herge born  Brussels, Belgium May 22, 1907
// Died March 3, 1983
// Cartoonist of Tintin and Snowy

jj2007

Hi Herge,

RichEd is a dll aimed at working with Rich Text Files. That is what my editor does. Try opening an RTF file with Pelle's example  :bg

PBrennick

JJ,
I have not looked at the example in POASM but I am certain I know why it will not. There needs to be code added to handle RTF. In other words, the control needs to know what you want to do. Something like this:

    .if szRTF == 1
      invoke  SendMessage, hWndEdit, EM_STREAMIN, SF_RTF, addr editstream ; Load and decode RTF
    .else
      invoke  SendMessage, hWndEdit, EM_STREAMIN, SF_TEXT, addr editstream ; Load straight text
    .endif


Chances are he is just using SF_TEXT. I use the filter specification in the open dialog to set the value of szRTF. I use this in a mini wordprocessor that I wrote in '93. Actually, Ewayne and I both wrote one as a little, private competition. They both worked well but mine handled WordWrap properly.

Paul
The GeneSys Project is available from:
The Repository or My crappy website