Please help me understand

B

Beringer

I am trying to access some functionality of the underlying RichTextBox
control and am getting all mixed up with conversions of types. I know my
basic issue is not completely understanding reference types in C#. I would
be much obliged if someone could "educate" me some.

Since I need to use the SendMessage of User32.dll I defined the following:
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr
wParam, IntPtr lParam);

Then I'm trying to create the equivalent code in C# for the following
callback function:
DWORD EditStreamCallback(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG
*pcb);by defining the following delegate:public delegate UInt32
EditStreamCallback(IntPtr dwCookie, IntPtr pbBuff, Int32 cb, IntPtr
pcb);That seems to work well (at least for the compiler).I then "translated"
the following typedef:typedef struct _editstream {
DWORD_PTR dwCookie;
DWORD dwError;
EDITSTREAMCALLBACK pfnCallback;
} EDITSTREAMinto the following structure:private struct EDITSTREAM {public
IntPtr dwCookie;public UInt32 dwError;public EditStreamCallback
pfnCallback;}So with all the definitions out of the way I thought I could do
something like this:...FileStream fs = new FileStream(Filename,
FileMode.Open);int format = SF_RTF;EDITSTREAM es = new
EDITSTREAM();es.dwCookie = (IntPtr)fs;es.pfnCallback = new
EditStreamCallback(StreamIn);SendMessage(this.Handle, EM_STREAMIN,
(IntPtr)format, (IntPtr)es);...but now the complier isn't happy and I get
"Cannot convert type 'x' to System.IntPtr" errors where I try to cast to
IntPtr.It was my understanding the "new" creates a reference type (i.e.
memory address, e.g. pointer) So, why can't I cast to IntPtr here?It is
interesting to note that there is no error on the cast of "format".Now on
the flip side I have the following code:static UInt32 StreamIn(IntPtr
dwCookie, IntPtr pbBuff, Int32 cb, IntPtr pcb){ UInt32 result = 0;
FileStream fs = (FileStream)dwCookie; pcb = cb; try { pcb =
fs.Read((byte[])pbBuff, 0, cb); } catch (Exception e) { pcb = 0;
result = 1; } return result;}This is the call back function delegate
used above. I get compile time errors at the attempted unboxing of dwCookie
and pbBuff. Also there is an error at pcb = cb ("cannot implictly convert
int to IntPtr")I know I am asking alot here but I am really stuck and since
I'm trying to learn C# on my own I could really use some help.Thank you in
advance,Eric
 
M

Morten Wennevik

Eric,

Please format your message so that it can be read easily.
Don't write everything as a single line, especially code.
Put in line breaks and empty lines in between so the reader gets a chance
to breathe (and space after punctuation as well).

I'm not sure what the answer would be but I notice you don't tell the
compiler where to find the external function (no [DllImport...]).
It may be that you have done so in your original code. Without it you
are sure to get into trouble.

[DllImport("User32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr
wParam, IntPtr lParam);

Something like this would be much better:
<Eric's Message>

I am trying to access some functionality of the underlying RichTextBox
control and am getting all mixed up with conversions of types. I know my
basic issue is not completely understanding reference types in C#. I would
be much obliged if someone could "educate" me some.

Since I need to use the SendMessage of User32.dll I defined the following:

private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr
wParam, IntPtr lParam);

Then I'm trying to create the equivalent code in C# for the following
callback function:

DWORD EditStreamCallback(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG
*pcb);

by defining the following delegate:

public delegate UInt32 EditStreamCallback(IntPtr dwCookie, IntPtr pbBuff,
Int32 cb, IntPtr pcb);

That seems to work well (at least for the compiler).
I then "translated" the following typedef:

typedef struct _editstream {
DWORD_PTR dwCookie;
DWORD dwError;
EDITSTREAMCALLBACK pfnCallback;
} EDITSTREAM

into the following structure:

private struct EDITSTREAM {
public IntPtr dwCookie;
public UInt32 dwError;
public EditStreamCallback pfnCallback;
}

So with all the definitions out of the way I thought I could do something
like this:...

FileStream fs = new FileStream(Filename, FileMode.Open);
int format = SF_RTF;EDITSTREAM es = new EDITSTREAM();
es.dwCookie = (IntPtr)fs;
es.pfnCallback = new EditStreamCallback(StreamIn);
SendMessage(this.Handle, EM_STREAMIN, (IntPtr)format, (IntPtr)es);

....but now the complier isn't happy and I get "Cannot convert type 'x' to
System.IntPtr" errors where I try to cast to IntPtr. It was my
understanding the "new" creates a reference type (i.e. memory address,
e.g. pointer) So, why can't I cast to IntPtr here? It is interesting to
note that there is no error on the cast of "format". Now on the flip side
I have the following code:

static UInt32 StreamIn(IntPtr dwCookie, IntPtr pbBuff, Int32 cb, IntPtr
pcb){
UInt32 result = 0;
FileStream fs = (FileStream)dwCookie;
pcb = cb;
try
{
pcb = fs.Read((byte[])pbBuff, 0, cb);
}
catch (Exception e)
{
pcb = 0;
result = 1;
}
return result;
}

This is the call back function delegate used above. I get compile time
errors at the attempted unboxing of dwCookie and pbBuff. Also there is an
error at pcb = cb ("cannot implictly convert int to IntPtr") I know I am
asking alot here but I am really stuck and since I'm trying to learn C# on
my own I could really use some help. Thank you in advance,

Eric
 
B

Beringer

If I could I would use C++ Managed Extension. I have to use C#.
Eric
benben said:
Why don't you just use C++ Managed Extension and save all the
hassals???????

ben
I am trying to access some functionality of the underlying RichTextBox
control and am getting all mixed up with conversions of types. I know my
basic issue is not completely understanding reference types in C#. I would
be much obliged if someone could "educate" me some.

Since I need to use the SendMessage of User32.dll I defined the
following:
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr
wParam, IntPtr lParam);

Then I'm trying to create the equivalent code in C# for the following
callback function:
DWORD EditStreamCallback(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG
*pcb);by defining the following delegate:public delegate UInt32
EditStreamCallback(IntPtr dwCookie, IntPtr pbBuff, Int32 cb, IntPtr
pcb);That seems to work well (at least for the compiler).I then "translated"
the following typedef:typedef struct _editstream {
DWORD_PTR dwCookie;
DWORD dwError;
EDITSTREAMCALLBACK pfnCallback;
} EDITSTREAMinto the following structure:private struct EDITSTREAM
{public
IntPtr dwCookie;public UInt32 dwError;public EditStreamCallback
pfnCallback;}So with all the definitions out of the way I thought I could do
something like this:...FileStream fs = new FileStream(Filename,
FileMode.Open);int format = SF_RTF;EDITSTREAM es = new
EDITSTREAM();es.dwCookie = (IntPtr)fs;es.pfnCallback = new
EditStreamCallback(StreamIn);SendMessage(this.Handle, EM_STREAMIN,
(IntPtr)format, (IntPtr)es);...but now the complier isn't happy and I get
"Cannot convert type 'x' to System.IntPtr" errors where I try to cast to
IntPtr.It was my understanding the "new" creates a reference type (i.e.
memory address, e.g. pointer) So, why can't I cast to IntPtr here?It is
interesting to note that there is no error on the cast of "format".Now on
the flip side I have the following code:static UInt32 StreamIn(IntPtr
dwCookie, IntPtr pbBuff, Int32 cb, IntPtr pcb){ UInt32 result = 0;
FileStream fs = (FileStream)dwCookie; pcb = cb; try { pcb =
fs.Read((byte[])pbBuff, 0, cb); } catch (Exception e) { pcb = 0;
result = 1; } return result;}This is the call back function
delegate
used above. I get compile time errors at the attempted unboxing of dwCookie
and pbBuff. Also there is an error at pcb = cb ("cannot implictly
convert
int to IntPtr")I know I am asking alot here but I am really stuck and since
I'm trying to learn C# on my own I could really use some help.Thank you
in
advance,Eric
 
B

Beringer

Morten,
Sorry about the formatting issues.
When I created the message in Outlook express it looked as though I had
formated it nicely.
The formating got messed up after I sent the message. I appreciate you
effort in clarifying it.

I did include [DllImport("User32.dll")] in my code, just didn't include it
in the message.

After reading benben's comments I'm wondering if what I want to do is
possible in C#.

Thanks,
Eric
 
B

Bob Grommes

Eric,

You probably need to create a text message rather than an HTML message.
Even then you will still be fighting word wrap, but it should be a lot more
universally readable to everyone else, especially if you try to keep line
lengths under 75 characters.

You may want to get a copy of ".NET and COM - The Complete Interoperability
Guide" by Adam Nathan (SAMS) -- a terrific resource for P/Invoke and all
other forms of Interop.

Also, try www.pinvoke.net for ideas and inspiration.

--Bob
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top