Исходя из ТЗ приходится загонять пользователей в жесткие рамки ввода текста... Задача следующего характера, пользователи могут вводить только русские символы, как бы организовать выдачу сообщения, что в данный момент у них раскладка английская или введены цифры? Смотрел по свойствам Edit - OnKeyPress или OnChange, единственное что пришло в голову это туп перебирать все буквы так:
На самом деле, задача сложнее, чем просто отследить, какая на данный момент раскладка. Просто раскладка - это вот так:
if LOWORD(GetKeyboardLayout(GetWindowThreadProcessId(GetForegroundWindow, nil))) = $0419
then { Русская } else { Не русская }
uses ..., ClipBrd;Вот что-то в этом духе...
// Сразу говорю, чтоб не было вопросов, почему здесь не множество, а строка:
// НЕ РАБОТАЕТ Дельфи с множествами из юникодных символов. Если компилятор
// выше, чем D2007, то начнутся проблемы
function CheckSymbol(Ch : Char) : Boolean;
const
StrAlpha : String = 'ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮЁ';
begin
result := (Pos(Ch, StrAlpha) <> 0);
end;
// Пишем свою оконную процедуру для Edit-а, где будем отслеживать Paste
function NewEditProc(MyWnd: HWND; uMsg: UINT; MyWParam: WPARAM; MyLParam: LPARAM): Integer; stdcall;
var
s: String;
i: Integer;
begin
if (uMsg = WM_PASTE) and Clipboard.HasFormat(CF_TEXT) then
begin
s := Clipboard.AsText;
for i := 1 to Length(s) do
if not CheckSymbol(s[i]) then
begin
uMsg := 0; Break // Если хоть один символ попадает под ограничения - отменить Paste полностью
end
end;
result := CallWindowProc(Pointer(GetWindowLong(MyWnd, GWL_USERDATA)),
MyWnd, uMsg, MyWParam, MyLParam);
end;
// При создании формы установим Edit-у новую оконную процедуру
// (ecUpperCase можно не устанавливать, ES_UPPERCASE в любом случае сделает то же самое)
procedure TForm1.FormCreate(Sender: TObject);
begin
SetWindowLong(Edit1.Handle, GWL_STYLE, GetWindowLong(Edit1.Handle, GWL_STYLE) or ES_UPPERCASE);
SetWindowLong(Edit1.Handle, GWL_USERDATA, SetWindowLong(Edit1.Handle, GWL_WNDPROC, LPARAM(@NewEditProc)))
end;
// Ну ладно, Paste мы отследили, там враг не пройдет. А что с печатанием в Эдит?
procedure TForm1.Edit1Change(Sender: TObject);
var
i: integer;
s : TCaption;
begin
s := Edit1.Text;
for i := 1 to Length(s) do
begin
if not CheckSymbol(s[i]) then
begin
ShowMessage('Неверная раскладка / символ');
delete(s, i, 1);
break;
end;
end;
Edit1.Text := s;
Edit1.SelStart := Length(s) + 1;
end;
Огромное спасибо! И отдельное спасибо за Копи-Паст, а то я как-то не подумал об этом )))