我正在使用Delphi使用您自己的SQL(使用Devart UniDac)开发DBLookupComboBox组件,而无需外部ListSource,ListField,KeyField。一切都工作得很好,但为了更好的用户界面,我需要一个小细节。
我总是根据用户的输入留下所选文字。输入字符时,可以;但是,当键入移动键(VK_LEFT,VK_RIGHT,组合等)时,过程并不酷,因为SelStart / SelLength将光标放在文本的末尾(sellength),我希望光标在左侧(在SelStart),旁边输入的最后一个字母。
组件(使用TFrame,TEdit等)。
用户输入BIAN,我的组件找到第一个人并使用SelStart / SelLength突出显示。
用户输入的VK_LEFT,我的组件应该显示:
但是要表明:
答案 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 键按下直到插入符号到达所需的左侧位置。