Erst mal Integer(@p); ist falsch. Der benötigte typ ist LPARAM nicht Integer. Wenn du deine Anwendung für 64 bit Kompilierst geht das ganz gewaltig in die Hose. Mein tipp: Benutz den typen der verlangt wird, nicht den von dem du denkst das er richtig sein könnte
Das ist aber nicht der fehler. Wenn man mal in die Dokumentation schaut:
Link
lParam
The coordinates of a point in the control's client area. The coordinates are in screen units and are relative to the upper-left corner of the control's client area.
Rich edit controls: A pointer to a POINTL structure that contains the horizontal and vertical coordinates.
Edit controls: The LOWORD contains the horizontal coordinate. The HIWORD contains the vertical coordinate.
Es handelt sich bei TMemo um ein EditControl, also ist ein Pointer auf eine TPoint struktur eh komplett falsch, was du wirklich willst ist einen LongInt zusammengebaut aus der X-Koordinate als unteres WORD und der Y Koordinate als oberes WORD. Zum erstellen des LParams gibt es die Funktion MakeLParam in der Windows Unit, welche die X und Y Koordinate zu einem Longword zusammenfügt.
Außerdem, zu dem Rückgabewert, der ist nicht nur ein Integer, sondern ein LPRESULT, dessen oberes WORD die Zeile und dessen unteres WORD den tatsächlichen Index (nicht die spalte) angibt:
Edit controls: The LOWORD specifies the zero-based index of the character nearest the specified point. This index is relative to the beginning of the control, not the beginning of the line. If the specified point is beyond the last character in the edit control, the return value indicates the last character in the control. The HIWORD specifies the zero-based index of the line that contains the character. For single-line edit controls, this value is zero. The index indicates the line delimiter if the specified point is beyond the last visible character in a line.
Bei mir funktioniert das hier super:
Code: Alles auswählen
i := LOWORD(SendMessage(Memo1.Handle, EM_CHARFROMPOS, 0, MakeLParam(X, Y)));
Gibt den Index des Characters über dem der Cursor hovert
PS: Das ist alles natürlich windows only. Wenn du es cross plattform haben willst würde ich dir Empfehlen TSynEdit zu nehmen, das kann sowas (umrechnen von Koordinaten zu Character positionen und umgekehrt) von haus aus
PPS: ich hab grade mal das ganze mit Perform angeschaut, und mit Perform scheint auch das nicht zu funktionieren, was wenn man da mal in die Doc schaut:
Link auch nicht verwunderlich ist. Perform führt nicht die Message auf Systemebene aus, Perform tut so als wäre die Message aufgetreten und ruft den Handler auf. Wird also innerhalb von der LCL behandelt, somit fällt der WinAPI call weg der dir das ergebnis gibt. Also musst du wohl SendMessage benutzen. (Was ja auch sinn ergibt, SendMessage ist ein Windows konzept, also macht es keinen Sinn das auf der Cross Platform abstraktionsebene der LCL zu implementieren)
PPPS: Wenn man nach "delphi EM_CHARFROMPOS" googlet (bzw. habe ge duckduckgo'ed) ist das ersten Ergebnis das hier:
Link was die frage beantworetet. (Bei WinAPI fragen lohnt es sich nach delphi zu googlen)