![]() |
|
|
#1
|
|||
|
|||
|
Здравствуйте. Возникла следующая потребность:
Нужно пользователю сделать выбор горячих клавиш. То есть сам код их уже есть в настройках нужно указать только горячую клавишу. Разъясню на примере: Пользователю нужно, что бы на Tab переходило на новую строку. В настройках уже код этого есть, но там по стандарту стоит enter. Дак вот, пользователь может нажать в настройках допустим на клавишу tab и теперь он может tab'ом переходить между строк. Так называемый key bindings. |
|
#2
|
||||
|
||||
|
Код:
Как сделать так, чтобы при минимизации приложения в Tray его можно было вызвать определённой комбинацией клавиш, например Alt-Shift-F9 ?
//В обработчике события OnCreate
//основной формы создаём горячую клавишу:
if not RegisterHotkey(Handle, 1, MOD_ALT or MOD_SHIFT, VK_F9) then
ShowMessage('Unable to assign Alt-Shift-F9 as hotkey.');
//В событии OnClose удаляем горячую клавишу:
UnRegisterHotkey( Handle, 1 );
//Добавляем обработчик в форму для сообщения
//WM_HOTKEY:
private // в секции объявлений формы
procedure WMHotkey( var msg: TWMHotkey ); message WM_HOTKEY;
procedure TForm1.WMHotkey( var msg: TWMHotkey );
begin
if msg.hotkey = 1 then
begin
if IsIconic( Application.Handle ) then
Application.Restore;
BringToFront;
end;
end;Это пример вставки гарячих клавиш, взял с делфи ворда, дак вот, если ты хочешь, чтоб в даном примере например место alt+shift+f9 поменять на ctrl+shift+f9, то измени строчку Код:
if not RegisterHotkey(Handle, 1, MOD_ALT or MOD_SHIFT, VK_F9) then НА if not RegisterHotkey(Handle, 1, MOD_CTRL or MOD_SHIFT, VK_F9) then // собственно здесь мы и изменяем гарячие клавиши... экспериментируй... |
|
#3
|
|||
|
|||
|
Мне не совсем это надо. Если я в ручную буду перебирать все сочетания, то это не реально. Пользователь может зажать любые клавиши, которые и станут горячими, хоть ENTER, хоть Q+1. Можно ли такое реализовать?
|
|
#4
|
||||
|
||||
|
Почему нереально?
В настройках (или где тебе надо изменять гарячие клавиши) создаешь едит (например), в который пользователь будет вводить 3 клавишу (пример: Alt+Shift (обязательные) + его клавиша (может быть например F2)), и есть глобальная переменная (допустим q: integer), и когда пользователь нажимает "сохранить настройки" пишешь в buttonsaveClick: Код:
q := Edit.Text; ... а потом собственно изменяешь: if not RegisterHotkey(Handle, 1, MOD_CTRL or MOD_SHIFT, q) then Где q - сама клавиша (коды клавиш можешь найти в инете)... |
|
#5
|
|||
|
|||
|
Спасибо, жаль что только через ктрл шифт, думал можно и обычные клавиши устанавливать.
|
|
#6
|
|||
|
|||
|
можно любые. делай через Action's.
|
|
#7
|
|||
|
|||
|
Решил делать первым способом, только возникла проблема. Мне надо сделать так: Когда человек нажимает ctrl+shift+f1, то происходит одно действие, когда ctrl+shift+f2, то другое. Дак вот как определить какую именно клавишу нажал человек и передать это процедуре TForm1.WMHotkey( var msg: TWMHotkey ); ?
|
|
#8
|
||||
|
||||
|
Ты каждой гарячей клавише даешь "номер (id)", дак вот с ним и работай, пример:
Код:
...
// вот, смотри на 2 параметр, вот твой id
if not RegisterHotkey(Handle, 1, MOD_CTRL or MOD_SHIFT, q) then
...
procedure TForm1.WMHotkey( var msg: TWMHotkey );
begin
/// вот внимание:
if msg.hotkey = 1 then // и сдесь...
begin
if IsIconic( Application.Handle ) then
Application.Restore;
BringToFront;
end;
end;Надеюсь понял ![]() |
|
#9
|
|||
|
|||
|
Понял, попробую, спасибо.
Upd. Решил сделать через массив, получилось такое, мне просто надо, что бы было забито от F1 до F9. Код:
procedure TForm1.FormCreate(Sender: TObject); var i:integer; s:string; q:integer; begin script.Clear; for i:=1 to 9 do begin s:='VK_F'+Inttostr(i); q:=Strtoint(s); if not RegisterHotkey(Handle, i, MOD_ALT or MOD_SHIFT, q) then end; end; Когда компилю выдаёт еррор, но не в привычной форме, т.е. внизу, а еррор типа как в ексе виндоуса: Project1.exe raised expection class EConvertError with messgae "VK_F1' is not a valid integer value' Последний раз редактировалось Мяфк, 06.10.2010 в 09:58. |
|
#10
|
||||
|
||||
|
Правильно. Ты пытаешься текст 'VK_F1' перевести в число.
Вообще VK_F1 и т.п. это константы целого типа. И VK_F1 = 112 и далее +1 до VK_F24 = 135 Приведённый выше код это пример использования ГЛОБАЛЬНЫХ горячих клавиш, т.е. твоя программа будет отлавливать их даже если у тебя активно окно совсем другой программы. И если будут использоваться популярные сочетания горячих клавиш, то когда включена данная программа, эти же сочетания не будут работать в других программах, твоя программа будет их просто перехватывать. Если тебе не нужен глобальный перехват горячих клавиш, то используй события: OnKeyPress (Клавиша нажата) OnKeyDown (Клавиша зажата) OnKeyUp (Клавиша отпущена) Обычно 2 последних события используются для обработки модификационных клавиш (Alt, Ctrl, Shift) Приведу код использования из моей курсовой :Код:
procedure TForm1.OnKeyPress(Sender: TObject; var Key: Char);
begin
// Обработчик нажатий клавиш
case Key of
'0': B_0Click(Sender); // Если нажат символ 0, вызываем процедуру B_0Click и т.п.
'1': B_1Click(Sender);
'2': B_2Click(Sender);
'3': B_3Click(Sender);
'4': B_4Click(Sender);
'5': B_5Click(Sender);
'6': B_6Click(Sender);
'7': B_7Click(Sender);
'8': B_8Click(Sender);
'9': B_9Click(Sender);
#13: B_EnterClick(Sender); // клавиша Enter (код 13)
end;
end;
procedure TForm2.OnKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
// Обработчик нажатий клавиш с Shift, Ctrl, Alt
if ssAlt in Shift then // если зажата клавиша Alt
Begin
FlagF := true;
E_2ndF.Text := '2ndF';
if chr(Key) = 'M' then // И если нажат символ M
B_MemAddClick(Sender);
end;
if ssShift in Shift then // если зажата клавиша Shift
if chr(Key) = 'M' then
B_MemShowClick(Sender);
if ssCtrl in Shift then // если зажата клавиша Ctrl
if chr(Key) = 'M' then
B_MemClearClick(Sender);
end;
procedure TForm2.OnKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
if not(ssAlt in Shift) then // если отпущена клавиша Alt
Begin
FlagF := false;
E_2ndF.Text := '';
end;
end;Последний раз редактировалось Sky.NET, 06.10.2010 в 13:13. |
|
#11
|
|||
|
|||
|
Спасибо, но проблема. Сделал такой код под себя:
Код:
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
var i:integer;
var e1,e2:Tedit;
begin
For i := 1 to 9 Do
Begin
e1 := FindComponent('LabeledEdit'+IntToStr(I)+'.text') As TEdit;
e2 := FindComponent('edit'+IntToStr(i)+'.text') As TEdit;
if ssAlt in Shift then
if chr(Key) = e2.text then
script.lines.add (e1.Text);
end;
end; |
|
#12
|
||||
|
||||
|
Должен быть активен объект с ссылкой на эту процедуру в событии. Можешь задать ссылки на эту процедуру для всех объектов.
|
|
#13
|
|||
|
|||
|
Не понял какой именно объект rich edit что ли?
|
|
#14
|
||||
|
||||
|
Любой объект. Ведь ты по умолчанию используешь объект Form, а если ты нажимаешь на кнопку, или вводишь значение в Edit, то они становятся активными...
Sorry, не так выразился Наводится на них фокус. И если у этого объекта есть событие по нажатию клавиш, то процедура сработает. Чтобы сработало везде, нужно всем объектам, которые могут иметь фокус, сделать ссылку на процедуру в событии. P.S. Возможно можно сделать, чтобы объекты перенимали события от формы как дочерние, но можно ли вообще так сделать я не знаю. P.P.S. А кстати, хороший вопрос А действительно, можно ли так сделать?Последний раз редактировалось Sky.NET, 08.10.2010 в 18:24. |
|
#15
|
|||
|
|||
|
Сделал я у рич едита событие, других фокусов нету. Но всё равно не срабатывает, пытался и с альтом и с контром
|