After I receive the Caret (x,y) position using GetCaretPos
I want to SendMessage()
of EM_CHARFROMPOS
.
The problem is that the lParam
should be of type IntPtr
, and the result of GetCaretPos
is a point.
How do I cast the point to an IntPtr correctly?
Asked
Active
Viewed 145 times
0

Tal XD
- 45
- 6
-
You need a pointer to unmanaged memory. So use : https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.marshal.structuretoptr?view=netcore-3.1 – jdweng Apr 28 '20 at 15:21
-
The return value of `GetCaretPos` is a [POINT](https://learn.microsoft.com/en-us/previous-versions/dd162805(v=vs.85)). That's binary compatible with a [POINTL](https://learn.microsoft.com/en-us/previous-versions/dd162807(v=vs.85)), so you can pass a pointer to it unmodified, if you are targeting a Rich Edit control. For a standard Edit control, you're going to have to truncate the `x` and `y` fields to 16-bit unsigned values, and binary OR them together into a 32-bit value. You can pass a zero-extended value of pointer size as the `lParam` when targeting a standard Edit control. – IInspectable Apr 28 '20 at 15:29
-
How do I do that? @IInspectable – Tal XD Apr 28 '20 at 15:31
-
That generally involves to stop being a managed-only developer. Apart from that it seems irrational to avoid UI Automation for what you're trying to do. – IInspectable Apr 28 '20 at 15:49
-
I need it for google chorme, which doesn't support UI Automation. @IInspectable – Tal XD Apr 28 '20 at 17:11
-
Google Chrome doesn't use native Windows controls either, so that's not going to work anyway. – IInspectable Apr 28 '20 at 17:37
1 Answers
1
The code must be different if you target a Rich edit control vs an Edit control, but you can get inspiration from .NET's code (and you can define multiple versions of SendMessage that suit your needs):
For a text box: https://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/TextBoxBase.cs,1754
...
var pt = (IntPtr)MAKELONG(pt.X, pt.Y);
SendMessage(handle, EM_CHARFROMPOS, 0, pt);
...
public static int MAKELONG(int low, int high) {
return (high << 16) | (low & 0xffff);
}
[DllImport("user32", CharSet=CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
For a rich text box: https://referencesource.microsoft.com/#system.windows.forms/winforms/Managed/System/WinForms/RichTextBox.cs,2323
...
var pt = new POINT(pt.X, pt.Y);
SendMessage(handle, EM_CHARFROMPOS, 0, pt);
...
[StructLayout(LayoutKind.Sequential)]
public class POINT
{
public int x;
public int y;
}
[DllImport("user32", CharSet=CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, POINT lParam);

Simon Mourier
- 132,049
- 21
- 248
- 298