Delphi - 使用selstart和sellength,但是光标在左边(selstart位置)而不是end(sellength position)

时间:2016-04-30 01:02:12

标签: delphi position cursor edit right-to-left

我正在使用Delphi使用您自己的SQL(使用Devart UniDac)开发DBLookupComboBox组件,而无需外部ListSource,ListField,KeyField。一切都工作得很好,但为了更好的用户界面,我需要一个小细节。

我总是根据用户的输入留下所选文字。输入字符时,可以;但是,当键入移动键(VK_LEFT,VK_RIGHT,组合等)时,过程并不酷,因为SelStart / SelLength将光标放在文本的末尾(sellength),我希望光标在左侧(在SelStart),旁边输入的最后一个字母。

组件(使用TFrame,TEdit等)。

enter image description here

用户输入BIAN,我的组件找到第一个人并使用SelStart / SelLength突出显示。

enter image description here

用户输入的VK_LEFT,我的组件应该显示:

enter image description here

但是要表明:

enter image description here

1 个答案:

答案 0 :(得分:3)

不幸的是,SelStart / SelLength属性不支持您要求的内容。 Despite what MSDN documentation claims,插入符号始终位于选择的右侧。

但是,您可以使用简单的技巧将插入符号放在选择的左侧:

procedure SelectText(Edit: TCustomEdit; iFirst, iLast: Integer);
var
  bState: TKeyboardState;
  bNewState: TKeyboardState;
  i: Integer;
begin
  if iFirst <= iLast then begin
    {
    Edit.SelStart := iFirst;
    Edit.SelLength := iLast - iFirst;
    }
    SendMessage(Edit.Handle, EM_SETSEL, iFirst, iLast);
  end else
  begin
    //Edit.SelStart := iFirst;
    SendMessage(Edit.Handle, EM_SETSEL, iFirst, iFirst);
    if GetKeyboardState(bState) then
    begin
      bNewState := bState;
      bNewState[VK_SHIFT] := bNewState[VK_SHIFT] or 128;
      if SetKeyboardState(bNewState) then
      begin
        repeat
          SendMessage(Edit.Handle, WM_KEYDOWN, VK_LEFT, 0);
          Dec(iFirst);
        until iFirst = iLast;
        SendMessage(Edit.Handle, WM_KEYUP, VK_LEFT, 0);
        SetKeyboardState(bState);
      end;
    end;
  end;
end;

可替换地:

procedure SelectText(Edit: TEdit; iFirst, iLength: Integer);
var
  bState: TKeyboardState;
  bNewState: TKeyboardState;
  i: Integer;
begin
  if iLength >= 0 then begin
    {
    Edit.SelStart := iFirst;
    Edit.SelLength := iLength;
    }
    SendMessage(Edit.Handle, EM_SETSEL, iFirst, iFirst + iLength);
  end else
  begin
    //Edit.SelStart := iFirst;
    SendMessage(Edit.Handle, EM_SETSEL, iFirst, iFirst);
    if GetKeyboardState(bState) then
    begin
      bNewState := bState;
      bNewState[VK_SHIFT] := bNewState[VK_SHIFT] or 128;
      if SetKeyboardState(bNewState) then
      begin
        repeat
          SendMessage(Edit.Handle, WM_KEYDOWN, VK_LEFT, 0);
          Inc(iLength);
        until iLength = 0;
        SendMessage(Edit.Handle, WM_KEYUP, VK_LEFT, 0);
        SetKeyboardState(bState);
      end;
    end;
  end;
end;

取决于您是要使用绝对开始/结束位置,还是开始位置和长度来定义选择。

基本上,这段代码正在做的是如果结束位置低于起始位置,代码将插入符号放在起始右侧位置,然后模拟 Shift + Left 键按下直到插入符号到达所需的左侧位置。