【问题标题】:Mouse Coordinates To Caret Position in Firemonkey TMemo ComponentFiremonkey TMemo 组件中插入符号位置的鼠标坐标
【发布时间】:2013-08-14 06:22:05
【问题描述】:

在 Firemonkeys 上处理鼠标/拖放事件 TMemo 组件提供鼠标光标坐标。有没有办法根据鼠标坐标计算 CaretPosition?

我想将一个文本拖到一个 TMemo 中,这个文本应该插入到当前的 MouseCoordinates。

【问题讨论】:

  • 哎哟!框架不是为你实现的吗?如果没有,那将是令人失望的。

标签: delphi mouse coordinates firemonkey tmemo


【解决方案1】:

尝试拨打GetPointPosition

不幸的是,这似乎已从 XE3 中的 TMemo 中删除。作为一种快速而肮脏的解决方法,您可以尝试以下方法:

function GetPointPosition(Memo: TMemo; Pt: TPointF; RoundToWord: Boolean = False): TCaretPosition;
var
  I, LPos: Integer;
  Rgn: TRegion;
begin
  Result.Line := -1;
  Result.Pos := -1;
  for I := 0 to Memo.Lines.Count - 1 do
  begin
    if Memo.Lines.Objects[I] is TTextLayout then
    begin
      LPos := TTextLayout(Memo.Lines.Objects[I]).PositionAtPoint(Pt, RoundToWord);
      if LPos >= 0 then
      begin
        if LPos > 0 then
        begin
          Rgn := TTextLayout(Memo.Lines.Objects[I]).RegionForRange(TTextRange.Create(LPos, 1), RoundToWord);
          if (Length(Rgn) > 0) and (Rgn[0].Top > Pt.Y) then
            Dec(LPos);
        end;
        Result.Line := I;
        Result.Pos := LPos;
        Break;
      end;
    end;
  end;
end;

【讨论】:

  • FMX.Memo.TMemo.GetPointPosition 似乎仅在 XE2 中可用。它在 XE4 中是否被移动或丢弃?
  • 是的,XE3 中好像已经去掉了。
  • GetPointPositionTMemoLines 的成员函数,在 FMX.Memo.pas 中定义。不幸的是,这是一个私有类型。 lines' member in TMemo` 定义为TStrings,但创建为TMemoLines。目前看来,没有实用的方法来使用这个功能。
【解决方案2】:

使用 RTTI 在 XE10 中适用的解决方案:

procedure TMyForm.MemoMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Single);
var Obj: IControl;   
    af: TPointf;
    cp: TCaretPosition;
    aName: string;
    LVar: TStyledMemo;
    LClass: TRttiInstanceType;
    aLines: TObject;
    aMethod: TRttiMethod;
    aValue: TValue;
    pointValue, boolValue: TValue;
begin
   af := TPointF.Create(Panel1.Position.X + X, panel4.Height + Y);
   Obj := ObjectAtPoint(ClientToScreen(af));

   if Assigned(Obj) then
   begin
       LVar := TStyledMemo(Obj);
       LClass := LContext.GetType(TStyledMemo) as TRttiInstanceType;
       aLines := LClass.GetField('FLineObjects').GetValue(LVar).AsObject;

       af := TPointF.Create(X,Y);
       pointValue := TValue.From<TPointF>(af);  
       boolValue := TValue.From<Boolean>(false);

       LClass := LContext.GetType(aLines.ClassType) as TRttiInstanceType;
       aMethod := LClass.GetMethod('GetPointPosition');
       aValue := aMethod.Invoke(aLines, [pointValue, boolValue]);

       cp := aValue.AsType<TCaretPosition>;
   end;
end;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多