I am attempting to write a basic richedit  control object.
The problem I am having is that the params being passed to the fnCallback method by RichEdit dont seem to be correct, and the ReadFile function is failing with an ERROR_INVALID_HANDLE.

THis is the code I am using:

Method RichEditCtl.DiskStreamIn, uses esi, pFileName:Pointer
LOCAL ess:EDITSTREAM
LOCAL BytesRead:dword

    SetObject esi

    invoke CreateFile,pFileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING, \
      FILE_ATTRIBUTE_NORMAL,0



    mov .hFile, eax
    m2m ess.dwCookie, .hFile
    mov ess.dwError, 0
    m2m ess.pfnCallback, $MethodAddr(esi::RichEditCtl.StreamIn)

    invoke SendMessage,.hREdit,EM_STREAMIN,SF_TEXT,addr ess
invoke SendMessage,.hREdit,EM_SETMODIFY,FALSE,0
invoke CloseHandle,.hFile
MethodEnd


and the callback method is:

Method RichEditCtl.StreamIn, uses esi, hFile:Handle, pBuffer:Pointer, NumBytes:dword, pBytesRead:dword
    mov eax, hFile          ;<-------These moves added for debugging purposes only
    mov ecx, pBuffer      ;<-------These moves added for debugging purposes only
    mov edx, NumBytes  ;<-------These moves added for debugging purposes only
    mov esi, pBytesRead;<-------These moves added for debugging purposes only
int 3;<---------remove after debugging
    invoke ReadFile,hFile,pBuffer,NumBytes,pBytesRead,NULL
xor eax,1

MethodEnd


I checked the values entered into the EDITSTREAM struct with olydebug, and they seem to be correct.But looking at the register values after breaking to oly in the callback, it seems that the value being passed as hFile,  is an address on the stack, and a dump of the stack at that location doesn't match the file handle in the EDITSTREAM STRUCT.

That would account for the ERROR_INVALID_HANDLE failure, but I don't understand where the data is apparantly getting corrupted. ANy Ideas?

Thanks,
Rags
Posted on 2006-04-25 11:04:09 by rags
Hi Rags
I guess that the problem is that you are using a method for the callback while it is a procedure expected. The difference is that a method has a hidden parameter called “Self??? that points to the object instance. The method macro hides this parameter for more clarity of the code, but in your case it is messing the parameters of the StreamIn callback.

I used a RichEdit control to implement the DebugCenter_ChildText object. I got the way to intercept the messages using a Message Interceptor. This is another possible approach that perhaps can help.

Regards,

Biterider
Posted on 2006-04-25 13:29:40 by Biterider
BiteRider,
Looking at the code for the Debug_Center Child text object, in the Childtxt.OnCreate method, I've noticed there are 3 params after the init in the creation of the REdtIptor object.Here is your code I'm refering to:
 mov .pEdtIptor, $New(REdtIptor, Init, esi, .hEdit, offset szREdtIptorProp)


In the help file, in the listing for the MsgInterceptor object, there are only 2 params for Init listed,
arg1-pointer to owner object and arg2-handle to the intercepted window.
Is this an error in documentation?
Thanks,
Rags
Posted on 2006-04-26 01:15:28 by rags
Rags
You are right. In the last releace, a third parameter was added to add a property name to attach the object instance pointer to the intercepted window. In previous versions, this was done using evertime the same name, which sometimes coduced to collisions. Now you can specify your own name and intercept a window with nore than an interceptor object.
The documentation doesn't mention the 3th parameter. I will add it. Thanks.  ;)

Biterider
Posted on 2006-04-26 01:37:27 by Biterider
BiteRider,
I got it working by using a proc for the callback.Thanks for the help! :)
Rags
Posted on 2006-04-26 07:58:53 by rags