|
Вопрос # 1 066/ вопрос решён / |
|
Здравствуйте, эксперты! Как назначить глобальные "горячие" клавиши? Можно ли использовать сочетания клавиш, используя клавишу "Windows"?
 |
Вопрос задал: alone (статус: Посетитель)
Вопрос отправлен: 1 ноября 2007, 01:13
Состояние вопроса: решён, ответов: 3.
|
Ответ #1. Отвечает эксперт: min@y™
Первый нормальный вопрос за сегодня.
Цитата:
Как назначить глобальные "горячие" клавиши?
Читай хэлп или гугл по поводу функций RegisterHotkey() и UnregisterHotkey(). Вот что говорит SDK:
The RegisterHotKey function defines a hot key for the current thread.
BOOL RegisterHotKey(
HWND hWnd, // window to receive hot-key notification
int id, // identifier of hot key
UINT fsModifiers, // key-modifier flags
UINT vk // virtual-key code
);
Parameters
hWnd
Identifies the window that will receive WM_HOTKEY messages generated by the hot key. If this parameter is NULL, WM_HOTKEY messages are posted to the message queue of the calling thread and must be processed in the message loop.
id
Specifies the identifier of the hot key. No other hot key in the calling thread should have the same identifier. An application must specify a value in the range 0x0000 through 0xBFFF. A shared dynamic-link library (DLL) must specify a value in the range 0xC000 through 0xFFFF (the range returned by the GlobalAddAtom function). To avoid conflicts with hot-key identifiers defined by other shared DLLs, a DLL should use the GlobalAddAtom function to obtain the hot-key identifier.
fsModifiers
Specifies keys that must be pressed in combination with the key specified by the nVirtKey parameter in order to generate the WM_HOTKEY message. The fsModifiers parameter can be a combination of the following values:
Value Meaning
MOD_ALT Either ALT key must be held down.
MOD_CONTROL Either CTRL key must be held down.
MOD_SHIFT Either SHIFT key must be held down.
vk
Specifies the virtual-key code of the hot key.
Вот один из примеров.
 |
Ответ отправил: min@y™ (статус: Доктор наук)
Время отправки: 1 ноября 2007, 08:29
Оценка за ответ: 5
|
Ответ #2. Отвечает эксперт: Feniks
Здравствуйте, Гадлевский Олег Вячеславович!
Держите примеры с разных сайтов:
1. http://forum.sources.ru
2. http://www.swissdelphicenter.ch
3. рассылка "Мастера DELPHI. Новости мира компонент, FAQ, статьи..."
4. http://forum.vingrad.ru
Приложение: Переключить в обычный режим-
-
- unit Unit1;
- interface
- uses
- Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,StdCtrls;
-
- type
- TForm1 = class(TForm)
- procedure FormActivate(Sender: TObject);
- procedure FormDestroy(Sender: TObject);
- private
- procedure WMHotKey(var Message: TMessage); message WM_HOTKEY;
- end;
-
- var
- Form1: TForm1;
- implementation
-
- {$R *.DFM}
- procedure Tform1.WMHotKey(var Message: TMessage);
- begin
- application.Restore;
- application.bringtofront;
-
- end;
-
- procedure TForm1.FormActivate(Sender: TObject);
- begin
- RegisterHotKey(form1.Handle,123,mod_control,vk_f7);
- end;
-
- procedure TForm1.FormDestroy(Sender: TObject);
- begin
- UnregisterHotKey(Handle, 123)
- end;
-
- end.
- // =======================================================
-
-
-
- {
- The following example demonstrates registering hotkeys with the
- system to globally trap keys.
-
- Das Folgende Beispiel zeigt, wie man Hotkeys registrieren und
- darauf reagieren kann, wenn sie gedruckt werden. (systemweit)
- }
-
- unit Unit1;
-
- interface
-
- uses
- Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
- Dialogs;
-
- type
- TForm1 = class(TForm)
- procedure FormCreate(Sender: TObject);
- procedure FormDestroy(Sender: TObject);
- private
- { Private declarations }
- id1, id2, id3, id4: Integer;
- procedure WMHotKey(var Msg: TWMHotKey); message WM_HOTKEY;
- public
- { Public declarations }
- end;
-
- var
- Form1: TForm1;
-
- implementation
-
- {$R *.dfm}
-
- // Trap Hotkey Messages
- procedure TForm1.WMHotKey(var Msg: TWMHotKey);
- begin
- if Msg.HotKey = id1 then
- ShowMessage('Ctrl + A pressed !');
- if Msg.HotKey = id2 then
- ShowMessage('Ctrl + Alt + R pressed !');
- if Msg.HotKey = id3 then
- ShowMessage('Win + F4 pressed !');
- if Msg.HotKey = id4 then
- ShowMessage('Print Screen pressed !');
- end;
-
- procedure TForm1.FormCreate(Sender: TObject);
- // Different Constants from Windows.pas
- const
- MOD_ALT = 1;
- MOD_CONTROL = 2;
- MOD_SHIFT = 4;
- MOD_WIN = 8;
- VK_A = $41;
- VK_R = $52;
- VK_F4 = $73;
- begin
- // Register Hotkey Ctrl + A
- id1 := GlobalAddAtom('Hotkey1');
- RegisterHotKey(Handle, id1, MOD_CONTROL, VK_A);
-
- // Register Hotkey Ctrl + Alt + R
- id2 := GlobalAddAtom('Hotkey2');
- RegisterHotKey(Handle, id2, MOD_CONTROL + MOD_Alt, VK_R);
-
- // Register Hotkey Win + F4
- id3 := GlobalAddAtom('Hotkey3');
- RegisterHotKey(Handle, id3, MOD_WIN, VK_F4);
-
- // Globally trap the Windows system key "PrintScreen"
- id4 := GlobalAddAtom('Hotkey4');
- RegisterHotKey(Handle, id4, 0, VK_SNAPSHOT);
- end;
-
- // Unregister the Hotkeys
- procedure TForm1.FormDestroy(Sender: TObject);
- begin
- UnRegisterHotKey(Handle, id1);
- GlobalDeleteAtom(id1);
- UnRegisterHotKey(Handle, id2);
- GlobalDeleteAtom(id2);
- UnRegisterHotKey(Handle, id3);
- GlobalDeleteAtom(id3);
- UnRegisterHotKey(Handle, id4);
- GlobalDeleteAtom(id4);
- end;
-
- end.
-
- {
- RegisterHotKey fails if the keystrokes specified for the hot key have
- already been registered by another hot key.
-
- Windows NT4 and Windows 2000/XP: The F12 key is reserved for use by the
- debugger at all times, so it should not be registered as a hot key. Even
- when you are not debugging an application, F12 is reserved in case a
- kernel-mode debugger or a just-in-time debugger is resident.
- }
- // =======================================================
-
-
-
- type
- TForm1 = class(TForm)
- procedure FormCreate(Sender: TObject);
- procedure FormDestroy(Sender: TObject);
- protected
- procedure hotykey(var msg:TMessage); message WM_HOTKEY;
- end;
-
- var
- Form1: TForm1;
- id,id2:Integer;
-
- implementation
-
- {$R *.DFM}
-
- procedure TForm1.hotykey(var msg:TMessage);
- begin
- if (msg.LParamLo=MOD_CONTROL) and (msg.LParamHi=81) then
- begin
-
- end;
- if (msg.LParamLo=MOD_CONTROL) and (msg.LParamHi=82) then
- begin
-
- end;
- end;
-
- procedure TForm1.FormCreate(Sender: TObject);
- begin
- id:=GlobalAddAtom('hotkey');
- RegisterHotKey(handle,id,mod_control,81);
- id2:=GlobalAddAtom('hotkey2');
- RegisterHotKey(handle,id2,mod_control,82);
- end;
-
- procedure TForm1.FormDestroy(Sender: TObject);
- begin
- UnRegisterHotKey(handle,id);
- UnRegisterHotKey(handle,id2);
- end;
- // =======================================================
-
-
-
-
-
-
-
- If not RegisterHotkey
- (Handle, 1, MOD_ALT or MOD_SHIFT, VK_F9) Then
- ShowMessage('Unable to assign Alt-Shift-F9 as hotkey.');
-
-
-
- UnRegisterHotkey( Handle, 1 );
-
-
- //WM_HOTKEY:
-
-
- 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;
 |
Ответ отправил: Feniks (статус: Бакалавр)
Время отправки: 1 ноября 2007, 10:26
Оценка за ответ: 5
|
Ответ #3. Отвечает эксперт: Вадим К
Здравствуйте, Гадлевский Олег Вячеславович!
Добавлю.
Некоторые клавиши нельзя перехватывать. Это относиться Ctrl+Alt+Del. также не рекомендовано перехватывать F12. Эта клавиша зарезервирована за системой для отладчика ядра, хотя его на компьютерах обычных пользователей нет.
 |
Ответ отправил: Вадим К (статус: Академик)
Время отправки: 1 ноября 2007, 11:32
|
Мини-форум вопроса
Всего сообщений: 3; последнее сообщение — 2 ноября 2007, 08:23; участников в обсуждении: 2.
|
min@y™ (статус: Доктор наук), 1 ноября 2007, 08:37 [#1]:
Да, про клавишу Windows, кстати, есть такой примерчик. Недавно я наткнулся на прогу с исходниками, которая служит для показа меню вставки спецсимволов в любое поле редактирования любого окна любой программы. Называется она SpecChar. Написана на Delphi, но на чистом WinAPI. Вот что у неё там в Readme.txt:
Цитата:
Вставка спец.символов
Поместите ярлык в Автозагрузку.
Меню вызывается Win+C.
Там тоже используются функции RegisterHotkey() и UnregisterHotkey(). Найди её и скачай (или могу прислать) и изучи сорцы.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
alone (статус: Посетитель), 1 ноября 2007, 22:29 [#2]:
Пришлите пожалуйста программу с исходным кодом, заранее благодарен
|
|
min@y™ (статус: Доктор наук), 2 ноября 2007, 08:23 [#3]:
Файл SpecChar.dpr:
program SpecChar;
uses
Windows,
Messages,
BaseUtils;
{$R WindowsXP.res}
var
Menu: HMENU;
Wnd, ForeWnd: HWND;
MenuDisplay: Boolean;
Terminated: Boolean = False;
function WindowProc(Wnd: HWND; Msg: UINT; WParam, LParam: Longint): Longint; stdcall;
var
P: TPoint;
begin
case Msg of
WM_HOTKEY:
if MenuDisplay then
EndMenu
else
begin
GetCursorPos(P);
ForeWnd := GetForegroundWindow;
SetForegroundWindow(Wnd);
MenuDisplay := True;
try
TrackPopupMenu(Menu, TPM_CENTERALIGN, P.X, P.Y, 0, Wnd, nil);
finally
MenuDisplay := False;
SetForegroundWindow(ForeWnd);
end;
end;
WM_COMMAND:
begin
SetClipboard(CF_UNICODETEXT, WParam, 4);
// Paste
SetForegroundWindow(ForeWnd);
keybd_event(VK_CONTROL, 0, 0, 0);
keybd_event(Ord('V'), 0, 0, 0);
keybd_event(Ord('V'), 0, KEYEVENTF_KEYUP, 0);
keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);
end;
end;
Result := DefWindowProc(Wnd, Msg, WParam, LParam);
end;
procedure Init;
procedure InitError(const Text: string; Code: Integer);
begin
MessageBox(0, PChar(Text), 'Special characters', MB_ICONERROR);
Halt(Code);
end;
var
Mutex: THandle;
F: file;
UnicodeSign: WideChar;
Chars: array[0..255] of WideChar;
I, Count: Integer;
NewCol: Boolean;
begin
Mutex := CreateMutex(nil, True, 'SpecChar_Running');
if WaitForSingleObject(Mutex, 0) <> WAIT_OBJECT_0 then
InitError('Already running', 1);
AssignFile(F, 'Chars.ini');
FileMode := 0;
{$I-}
Reset(F, 2);
if IOResult <> 0 then
InitError('Ini-file miss', 2);
BlockRead(F, UnicodeSign, 1);
if (IOResult <> 0) or (UnicodeSign <> #$FEFF) then
InitError('Ini-file is not Unicode', 3);
BlockRead(F, Chars, Length(Chars), Count);
if Count = 0 then
InitError('Ini-file is empty', 4);
CloseFile(F);
{$I+}
Menu := CreatePopupMenu;
NewCol := False;
for I := 0 to Count - 1 do
case Chars[I] of
'|': AppendMenuW(Menu, MF_SEPARATOR, 0, nil);
#10, #13: NewCol := True;
else
AppendMenuW(Menu, Ord(NewCol) * MF_MENUBARBREAK, Ord(Chars[I]), Pointer(
WideString(Chars[I])));
NewCol := False;
end;
end;
var
Cls: WNDCLASS = (lpfnWndProc: @WindowProc; lpszClassName: 'AppWin');
Msg: TMsg;
begin
Init;
Cls.hInstance := HInstance;
Windows.RegisterClass(Cls);
Wnd := CreateWindow(Cls.lpszClassName, '', WS_POPUP, 0, 0, 0, 0, 0, 0,
HInstance, nil);
RegisterHotKey(Wnd, 0, MOD_WIN, Ord('C'));
repeat
GetMessage(Msg, 0, 0, 0);
DispatchMessage(Msg);
until Terminated;
UnregisterHotKey(Wnd, 0);
DestroyMenu(Menu);
DestroyWindow(Wnd);
end.
Файл BaseUtils.pas:
unit BaseUtils;
interface
uses
Windows;
procedure SetClipboard(Format: Cardinal; const Buffer; Size: Integer);
implementation
procedure SetClipboard(Format: Cardinal; const Buffer; Size: Integer);
var
Data: THandle;
DataPtr: Pointer;
begin
OpenClipboard(0);
EmptyClipboard;
OpenClipboard(0);
try
Data := GlobalAlloc(GMEM_MOVEABLE + GMEM_DDESHARE, Size);
try
DataPtr := GlobalLock(Data);
try
Move(Buffer, DataPtr^, Size);
SetClipboardData(Format, Data);
finally
GlobalUnlock(Data);
end;
except
GlobalFree(Data);
raise;
end;
finally
CloseClipboard;
end;
end;
end.
Файл chars.ini:
–—«»•·¶§|¹²³
±≈≠≥≤÷√∆∞|½¼¾
°µ‰Ω|?¥|©®™
Копирайтов автор не проставил, так что неизвестен.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
31 января 2011, 20:02: Статус вопроса изменён на решённый (изменил модератор Ерёмин А.А.): Автоматическая обработка (2 и более ответов с оценкой 5)
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|