Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Problem calling SendMessage passing FindText structure

0 views
Skip to first unread message

jbhan

unread,
Feb 19, 2004, 4:01:08 PM2/19/04
to
Hi,

I am trying to use SendMessage to find text in a certain window using the FindText structure as parameter.
But I keep on getting a "Object reference not set to instance of an object " when the Sendmessage gets executed.
The same code in vb works just fine!
Can anyone help me out please with what I might be doing wrong.

Since I am calling the api from an addin for Outlook and the SendMessage is taking a handle to an Outlook window, I don't think there is a problem with send message across process boundaries as both are running in the same process.
Any pointers in the right direction would be great. Its been really hard getting any working examples for a combination of SendMessage and Findtext structure parameters in c#.
I could post my code and declarations if need be.

Thanks,
jbhan.

Mattias Sjögren

unread,
Feb 19, 2004, 4:10:55 PM2/19/04
to

>I could post my code and declarations if need be.

Please do

Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.

jbhan

unread,
Feb 19, 2004, 4:51:08 PM2/19/04
to
I have tried a variety of combinations for the FindText structure parameters. Here is one of them..everytime I get the same "Object reference..." error..
The SendMessageLong works fine and returns me the number of lines of text in the window ( I have commented it out here)

These declarartions are in the file named RichEdit.cs

[StructLayout(LayoutKind.Sequential, Pack=4)]

public struct FindText
{
public CHARRANGE chrg;
[MarshalAs(UnmanagedType.LPTStr)]
public String lpstrText;
}

[StructLayout(LayoutKind.Sequential, Pack=4)]
public struct CHARRANGE
{
public long cpMin;
public long cpMax;
}


[DllImport("User32.dll",CharSet = CharSet.Auto) ]

public static extern IntPtr SendMessage(IntPtr hwnd, int wMsg,int wParam, IntPtr lParam);

[DllImport("User32.dll", EntryPoint="SendMessage", CharSet=CharSet.Auto)]
public static extern IntPtr SendMessageLong(IntPtr hwnd,long wMsg,long wParam,long lParam);


This function is in RichTextWrapper.cs

public long FindTextW(string sText,ERECFindTypeOptions eOptions,long lStart,long lEnd)
{

RichEdit.CHARRANGE tCR = new RichEdit.CHARRANGE();
RichEdit.FindText tEx= new RichEdit.FindText();
IntPtr res = IntPtr.Zero;
IntPtr lPtr =IntPtr.Zero;


sText = "Martin\0";//+ Convert.ToChar(0);

tCR.cpMax =-1;
tCR.cpMin =0;

try
{

tEx.lpstrText= sText;
tEx.chrg = tCR;
lPtr = Marshal.AllocHGlobal(Marshal.SizeOf(tEx));
Marshal.StructureToPtr(tEx,lPtr,true);
res= RichEdit.SendMessage((IntPtr)m_hWnd,(int)RichEdit.EM_FINDTEXT,0, lPtr);
}
catch(Exception ex1)
{
MessageBox.Show(ex1.Message);
}

Marshal.FreeHGlobal(lPtr);

//res = RichEdit.SendMessageLong((IntPtr)m_hWnd,(int)RichEdit.EM_GETLINECOUNT, 0,0);
return (long)res;
}

Mattias Sjögren

unread,
Feb 20, 2004, 4:57:17 PM2/20/04
to

Change all your 'long' to 'int'.

You can also save some work by changing the lParam parameter type on
SendMessage to ref FINDTEXT and pass the tEx variable directly.

jbhan

unread,
Feb 20, 2004, 9:26:06 PM2/20/04
to
Thanks a ton! needed to specify the CHARRANGE memebers variables as int instead of long and passed the FindText structure by reference.It worked like a charm!

But now I have another problem, there is a piece of code in Vb and I don't know how to specify its equivalent in c#. This is specifically for the string member variable of the FindText structure.

//VB Code

Dim tCR As CHARRANGE
Dim lR As Long
Dim b() As Byte

tCR.cpMin = lStart
tCR.cpMax = lEnd

b = StrConv(sText, vbFromUnicode)
ReDim Preserve b(0 To UBound(b) + 1) As Byte
b(UBound(b)) = 0
tEx1.lpstrText = VarPtr(b(0))
LSet tEx1.chrg = tCR
lR = SendMessage(m_hWnd, EM_FINDTEXTEX, eOptions, tEx1)

The following is my version in C# ...which always returns me 0.

Byte [] bytes;

ASCIIEncoding ascii = new ASCIIEncoding();
int byteCount = ascii.GetByteCount(sText.ToCharArray());
bytes = new Byte[byteCount];
bytes = ascii.GetBytes(sText);
bytes[bytes.GetUpperBound(0)] = 0; // to remove the null character at the end of the string.

GCHandle gc = GCHandle.Alloc(bytes[0],GCHandleType.Pinned);
tEx.lpstrText = gc.AddrOfPinnedObject(); // lpstrText is an Intptr in the Findtext structure.
gc.Free();

tEx.chrg = new CHARRANGE();
tEx.chrg.cpMax =(int)lEnd;
tEx.chrg.cpMin =(int)lStart;

res= SendMessage((int)m_hWnd,EM_FINDTEXT ,(int)eOptions, ref tEx);
//res is always 0

How do I pass the pointer to an array of bytes as a value for the FindText structure's string member variable?

Thanks,
jbhan

Mattias Sjögren

unread,
Feb 23, 2004, 10:26:36 AM2/23/04
to

You shouldn't have to do any of that in C# (and not in the VB code
either). Just keep the lpstrText member as a string and it should
work.

Mattias Sjögren

unread,
Feb 24, 2004, 5:56:47 PM2/24/04
to

>How can I make FindText work for HTML text?

HTML in a Rich Text Box? Well I don't know why it doesn't work in this
case, sorry.

0 new messages