我正在为键盘开发一个钩子,并使用SetWindowsHookEx,并在TStringList中添加每一个击键。为了操作TStringList中的击键,我总是使用'.Text‘属性。例如,要添加类型化击键,我使用:
KeyStrokes.Text:= KeyStrokes.Text + AChr;
如果检测到一个backspace,则尝试使用以下方法删除StringList中的最后一个字符:
KeyStrokes.Text :=拷贝(KeyStrokes.Text,1,长度(KeyStrokes.Text)- 1);
当我使用相同的‘TMemo’属性在一个.Text中添加时,所有这些都是有效的。但是,自从我输入TStringList时,在保存的Log.txt文件(使用.SaveToFile属性)中,我得到的日志如下:
H
E
我
我
O
而不是“你好”。我尝试了‘..Append’,'.Add‘属性,并且总是一样的。当然,删除最后一封信的后置空间不再起作用.如何正确地输入键盘?在TStringList中甚至可以这样做吗?
发布于 2013-09-05 22:50:32
TStringList似乎不是工作的合适工具,至少如果要使用Text属性,则不是这样。正如您从文档中了解到的,读取Text属性会将列表中的所有项与换行连接起来。写入该属性将在每行中断处拆分新值,并在列表中为每个项创建一个单独的条目。
如果您试图跟踪击键,您不希望您的数据结构通过插入和删除看起来像击键但不代表真正击键的内容来默默地咀嚼数据。(特别是,请注意,读取Text属性将在结果末尾附加一个断行。这会影响到您的后台逻辑。)
使用普通的旧字符串来跟踪字符串输入的当前状态。
发布于 2013-09-05 22:54:08
TStringList将行中断保存到文件中的唯一方法是,当调用SaveToFile()时,TStringList中有多个字符串。原因是因为读取Text属性在结束时插入了一个隐式断行符,在写回Text之前没有删除它。因此,每次击键都会在列表中作为一个新字符串结束。
就像其他人说的那样,TStringList一开始就是这个工作的错误工具。使用简单的String代替:
KeyStrokes: String;
...
KeyStrokes := KeyStrokes + AChr;
...
Delete(KeyStrokes, Length(KeyStrokes), 1);发布于 2013-09-06 19:41:29
使用普通的字符串似乎要实际得多。在一条评论中,你担心失去了一些功能,说:“我正在执行行中断时,检测进入”。通过添加sLineBreak (行尾标记的常量),您可以轻松地通过普通字符串来支持这一点。在Windows上,这等于#13#10 (回车和行提要)。唯一需要注意的是,当您使用backspace删除EOL时,您需要删除正确的字符数: Windows为2个,Linux/MAC为1个。Length(sLineBreak)会告诉你有多少。
您可能需要考虑的另一个选项是TStringBuilder类。它的设计是为了建立字符串块-餐,所以可以套用你的目的。
最后,如果您真的想使用TStringList,可以单独操作字符串(即不使用Text属性):
FInputData: TStrings;
FInputData := TStringList.Create;
FInputData.Add(''); { Important to always have at least 1 string }
{ When adding a character "Ch" }
FInputData[FInputData.Count-1] := FInputData[FInputData.Count-1] + Ch;
{ When detecting the Enter Key }
FInputData.Add('');
{ When detecting Backspace }
S := FInputData[FInputData.Count-1];
if (S <> '') then
begin
{ Delete last character on current line }
Delete(S, Length(S), 1);
FInputData[FInputData.Count-1] := S;
end
else if (S = '') and (FInputData.Count > 1) then
begin
{ Go back to previous line if current is empty, but don't delete if
there's nothing left. (Remember: always have at least 1 string) }
FInputData.Delete(FInputData.Count-1);
end;
{ To write the current data }
Writeln(FInputData.Text);https://stackoverflow.com/questions/18646907
复制相似问题