Как я могу установить комбинацию горячих клавиш («win + Key») для вызова приложения? - PullRequest
7 голосов
/ 11 сентября 2010

Мне нужно установить горячую клавишу на уровне операционной системы, которая после установки вызовет все, что я скажу, для вызова. Набор горячих клавиш должен выполняться изнутри моего предпочтения, но приложение не должно быть открыто, чтобы работала горячая клавиша.

Ответы [ 6 ]

14 голосов
/ 17 сентября 2010

Это делает то, что вы хотите.

Во-первых, вам нужна программа, которая работает в фоновом режиме и прослушивает нажатия клавиш и реагирует на них.Например:

program Project1;

uses
  Windows, Messages, ShellAPI;

var
  W: HWND;
  M: MSG;

const
  WM_SETHOTKEY = WM_APP + 1;
  WM_UNSETHOTKEY = WM_APP + 2;
  AppName = 'Rejbrand Hot Key Listener';

const
  FileNames: array[0..1] of string = ('notepad.exe', 'pbrush.exe');

begin

  if FindWindow('STATIC', PChar(AppName)) <> 0 then
    Exit;


  W := CreateWindow('STATIC', PChar(AppName), 0, 0, 0, 100, 100, HWND_MESSAGE, 0, HInstance, nil);

  while GetMessage(M, W, 0, 0) do
    case M.message of
      WM_HOTKEY:
        ShellExecute(0, nil, PChar(FileNames[M.wParam]), nil, nil, SW_SHOWNORMAL);
      WM_SETHOTKEY:
        RegisterHotKey(W, M.wParam, M.lParam shr 16, M.lParam and $FFFF);
      WM_UNSETHOTKEY:
        UnregisterHotKey(W, M.wParam);
    end;

end.

(Чтобы создать эту программу, выберите New / VCL Forms Application, а затем удалите основную форму из проекта. Затем выберите Project / View Source и удалите нонсенс Application.Initialize.Программа должна выглядеть следующим образом.)

Вышеуказанная программа слушает сообщения WM_SETHOTKEY, в которых регистрируется новая горячая клавиша Windows, WM_UNSETHOTKEY, которая удаляет ранее зарегистрированную горячую клавишу, и WM_HOTKEY, отправляемая Windowsкогда конечный пользователь активирует зарегистрированную горячую клавишу.Первые два сообщения определены мной, в этом приложении.

Чтобы зарегистрировать горячую клавишу, отправьте сообщение WM_SETHOTKEY в окно W.wParam сообщения должно быть индексом (в массиве FileNames) запускаемой программы.lParam должен иметь форму $ MMMMKKKK, где $ MMMM - модификаторы ( Ctrl , Alt , Shift ) и $ KKKK - код виртуальной клавишигорячей клавишиЧтобы удалить горячую клавишу, отправьте сообщение WM_UNSETHOTKEY с индексом программы от wParam до W.

Пример использования

Из любого приложения, вы можетеdo (при условии, что Project1.exe работает в фоновом режиме)

const
  WM_SETHOTKEY = WM_APP + 1;
  WM_UNSETHOTKEY = WM_APP + 2;

const
  MODIFIER_ALT = MOD_ALT shl 16;
  MODIFIER_CTRL = MOD_CONTROL shl 16;
  MODIFIER_SHIFT = MOD_SHIFT shl 16;

procedure TForm1.RegisterHotkeys;
var
  w: HWND;
begin
  w := FindWindow('STATIC', 'Rejbrand Hot Key Listener');
  PostMessage(w, WM_UNSETHOTKEY, 0, MODIFIER_CTRL + MODIFIER_ALT + ord('N'));
  PostMessage(w, WM_SETHOTKEY, 1, MODIFIER_CTRL + MODIFIER_ALT + ord('P'));
end;

Теперь, даже если вы закроете эту новую программу, notepad.exe и pbrush.exe запустятся на Ctrl + Alt + N и Ctrl + Alt + P соответственно.

Ещеобсуждение

Обратите внимание, что при компиляции Project1.exe имеет размер всего 20 КБ!Это крошечный для приложения, созданного в Delphi!

Чтобы отменить регистрацию ранее зарегистрированной горячей клавиши, выполните

PostMessage(w, WM_UNSETHOTKEY, N, 0);

, где N, в этом примере, равно = 0 дляблокнот и = 1 для pbrush.

Чтобы выйти из project1.exe, выполните

PostMessage(w, WM_QUIT, 0, 0);

Но, конечно, если вы выйдете из project1.exe, все горячие клавиши не будут зарегистрированы в Windows.

Возможно, вы захотите сделать

procedure TForm1.RegisterHotkeys;
var
  w: HWND;
begin
  w := FindWindow('STATIC', 'Rejbrand Hot Key Listener');
  if w = 0 then
    MessageBox('Error: Rejbrand Hot Key Listener not running!');
  PostMessage(w, WM_UNSETHOTKEY, 0, MODIFIER_CTRL + MODIFIER_ALT + ord('N'));
  PostMessage(w, WM_SETHOTKEY, 1, MODIFIER_CTRL + MODIFIER_ALT + ord('P'));
end;

или даже запустить project1.exe, если не можете найти окно.

4 голосов
/ 15 сентября 2010

Вам нужен экземпляр приложения, который прослушивает горячую клавишу или, вернее, сообщение, которое будет отправлено системой, если горячая клавиша нажата (после регистрации с помощью RegisterHotKey). Так что либо ваше приложение слушает само по себе и активируется / выходит вперед, либо у вас есть прослушиватель горячих клавиш, который запускает второе приложение.

Хотя оболочка Windows (explorer.exe) позволяет определять сочетания клавиш для запуска программы, невозможно использовать клавишу Win (также не под Windows 7), поскольку Интерфейс ISHellLink поддерживает только Alt , Ctrl и Shift с помощью метода SetHotKey . Вероятно, поэтому существуют приложения типа WinKey .

4 голосов
/ 11 сентября 2010

Я думаю, что вы ищете функцию RegisterHotKey .

3 голосов
/ 16 сентября 2010

Использование ключа Windows противоречит рекомендациям Microsoft по взаимодействию с пользователем. См. ответ mghie на "THotkey с поддержкой win-key" для хорошего комментария по этому поводу.

И если вы посмотрите на запись MSDN для RegisterHotKey , вы увидите, что, хотя они допускают значение MOD_WIN, они конкретно заявляют:

"Сочетания клавиш с клавишей WINDOWS зарезервированы для использования операционной системой. "

Windows допускает сочетания клавиш для программ. Вы можете добавить ярлык на странице свойств исполняемого файла. Это именно то, что вы хотите сделать в своей программе. На странице свойств они позволяют вам установить Ctrl , Shift и Alt , а также комбинации из трех клавиш с другой клавишей в качестве ярлыка. , Но когда вы попытаетесь использовать ключ Windows, он не позволит вам его использовать и вместо этого предложит Crtl + Alt .

Вы можете использовать RegisterHotKey , поскольку Александр первым ответил на это. Вот пример Delphi о том, как это сделать.

Но я настоятельно рекомендую вам не использовать Windows Key для ваших ярлыков.

3 голосов
/ 15 сентября 2010

Ярлык (файл .LNK), который находится на рабочем столе или в иерархии меню «Пуск», может иметь назначенную ему «горячую клавишу» (горячую клавишу).[1,2]

Диалог свойств, по крайней мере, под XP, не позволяет Win сочетаний клавиш, но вы можете создать их программно.JCL имеет функцию ShellLinkCreate() для создания ярлыков.Обратите внимание, что после создания ярлыка программно, Explorer не будет автоматически выбирать горячую клавишу, которую вы установили.Очевидно, что вы можете перезапустить Проводник (что можно сделать чисто, не выходя из системы [3,4]), или вы можете просто обзвонить SHChangeNotify для файла .lnk или, возможно, передать WM_SETTINGCHANGE сообщение.

[1] Запуск программы с помощью сочетания клавиш
[2] Как создать сочетание клавиш для программы в Windows XP
[3] Скрытый трюк для выхода из проводника Windows с помощью диалогового окна выключения в Windows XP
[4] Скрытый трюк для выхода из проводника Windows с помощью меню «Пуск» в Windows Vista иСервер 2008

1 голос
/ 11 сентября 2010

Это будет сделано (uses ComObj, ActiveX, ShlObj):

procedure TForm1.Button1Click(Sender: TObject);
var
  IObject: IUnknown;
  ISLink: IShellLink;
  IPFile: IPersistFile;
const
  HOTKEY_CONTROL = 512;
  HOTKEY_ALT = 1024;
begin
  // Creates a shell link (*.lnk) to C:\WINDOWS\notepad.exe in the directory of this exe;
  // the link has keyboard shortcut CTRL+ALT+N.
  IObject := CreateComObject(CLSID_ShellLink);
  ISLink := IObject as IShellLink;
  IPFile := IObject as IPersistFile;
  ISLink.SetPath('C:\WINDOWS\notepad.exe');
  ISLink.SetHotkey(Ord('N') + HOTKEY_CONTROL + HOTKEY_ALT);
  IPFile.Save(PChar(ExtractFilePath(Application.ExeName) + 'Shortcut to Notepad.lnk'), false);
end;

Но, если вы хотите запустить другое приложение из своего приложения, просто используйте ShellExecute (uses ShellAPI):

procedure TForm1.Button2Click(Sender: TObject);
begin
  ShellExecute(Handle, nil, 'C:\WINDOWS\notepad.exe', nil, nil, SW_SHOWNORMAL);
end;

Конечно, используя TActionList или TMainMenu, вы можете назначить любое сочетание клавиш для любой функции или процедуры Delphi.

...