Чтобы ответить на ваш измененный вопрос, и ваш последний комментарий о не-буквенных символах по-прежнему не работает правильно:
Ваше обнаружение верхнего / нижнего регистра не удается для любого символа, кроме a .. z
. Если вы посмотрите на документацию для System.UpCase()
, в ней говорится, что Значения символов, не входящие в диапазон a..z, не затронуты. Поэтому, если вы передадите ему <
, вы получите то же самое * 1008. *. Ваш код будет интерпретировать это как символ верхнего регистра, хотя это не так.
Вам было сказано в комментарии отправить ключи (на самом деле символы) с dwFlags
KEYEVENTF_UNICODE
. Вы, кажется, приняли это только частично, а также ошибочно.
Обратите внимание, что в документации MSDN написано:
wVk: ... Если член dwFlags указывает KEYEVENTF_UNICODE, wVk должно быть 0 .
wScan: ... Если dwFlags указывает KEYEVENTF_UNICODE, wScan указывает символ Unicode
и далее для флага KEYEVENTF_UNICODE
:
Если указано, система синтезирует нажатие клавиши VK_PACKET. Параметр wVk должен быть нулевым. Этот флаг можно комбинировать только с флагом KEYEVENTF_KEYUP.
Ergo, вам не нужно обнаруживать и отдельно обрабатывать символы верхнего и нижнего регистра. Вы просто устанавливаете wScan
на порядковый номер символа UTF-16, который вы хотите отправить. Поэтому ваши не-буквенные символы также корректно работают со следующим кодом, измененным из вашего:
function TForm3.PrintOutLine(sLine: string): boolean;
var
i: integer;
KeyInputsL: array [0..1] of TInput;
begin
Memo1.SetFocus;
i:= 1;
while (i<=Length(sLine)) do begin
ZeroMemory(@KeyInputsL,sizeof(KeyInputsL));
KeyInputsL[0].Itype := INPUT_KEYBOARD;
// KeyInputsL[0].ki.wVk := vk; // don't use wVk with KEYEVENTF_UNICODE
KeyInputsL[0].ki.wScan := ord(sLine[i]); // instead use wScan
KeyInputsL[0].ki.dwFlags := KEYEVENTF_UNICODE;
KeyInputsL[1].Itype := INPUT_KEYBOARD;
// KeyInputsL[1].ki.wVk := vk;
KeyInputsL[1].ki.wScan := ord(sLine[i]);
KeyInputsL[1].ki.dwFlags := KEYEVENTF_UNICODE or KEYEVENTF_KEYUP;
SendInput(2, KeyInputsL[0], SizeOf(TInput));
Application.ProcessMessages;
Sleep(80);
inc(i);
end;
SendEnter;
Form3.SetFocus;
Result:= True;
end;
Вышеприведенный ответ отвечает на ваш фактический вопрос, но не учитывает суррогатные пары кодовых точек UTF-16. Для этого показан полный код (на С ++)
Кроме того, это не часть вашего вопроса, но я не могу обойтись без комментариев: Application.ProcessMessages
и Sleep()
- неправильный способ отправки одного символа за раз. Вместо этого используйте таймер, чтобы инициировать отправку каждого символа.