Отправляет email-рассылки с помощью сервиса Sendsay

Web-Мастеринг - с нуля до профи

  Все выпуски  

нет.


Информационный Канал Subscribe.Ru


Познавательное программирование



Выпуск 3


Здраствуйте, Уважаемые подписчики!


Предисловие.


В прошлом номере я обращался к вам с просьбой о рекомендации содержания этого выпуска, но так и не получил ни одного отзыва, что совсем неудивительно - вас, подписчиков, слишком мало и вы по своей природе пассивны.
Ну да ладно. Раз вы незахотели выбрать, то я выбрал сам. Выбрал то, что большинству из вас наверняка сейчас непонадобится, тем не менее я решил рассказать, чем я заменил драйвер для своей мультимедийной клавиатуры.
История проблемы следующая. С приобретением нового компьютера я купил себе клавиатуру Genius KB21E, к которой прилагался CD с драйверами.
В целом драйвер был достаточно надёжным и удобным, но:
1) у него были только две Soft-клавиши, т.е. клавиши, события на которые можно поставить самому, этого мало, так как всего дополнительных мультимедийных клавиш у неё около 20.
2) у него были 5 кнопок для управления CDPlayer'ом. Но так как я CDAudio не слушаю, а предпочитаю MP3, то эти 5 клавиш просто "сидели без дела".
3) у клавы есть колёсико. При движении им вверх-вниз имитируется нажатия стрелок вверх-вниз на уровне самой клавиатуры. Так вот при нажатии на это колёсико вылезает Task Manager, чтобы переходить с одного приложения на другое. Мне такая возможность не нужна - я всегда использую для этого ALT+TAB. Мне понадобилось заменить нажатие на колёсико имитацией нажатия клавиши ENTER.
Все эти проблемы я смог решить созданием своей программы для обработки мультимедийных клавиш. Сделал я это на основе уже разобранной ранее здесь программы KeyLogger.
Сейчас я очень доволен этим, так как могу без проблем управлять WinAmp'ом, набирая этот текст или играя в Counter Strike, а стандартный драйвер удалил давно. :)
Замечу, что созданная мной программа, исполняя функции драйвера, сама драйвером является весьма условно. Потому слово "драйвер" в данном тексте я буду использовать в кавычках. Назвал я всё это Universal Extended Keyboard Driver. Универсальный "драйвер" потому, что вы сами можете подстроить его под любую (!) мультимедийную клавиатуру.

Описание работы.


Изначально я делал эту программу под Windows98, но затем я полностью перешёл на Windows2000 и возникли некоторые проблемы совместимости. К примеру, Windows98 предоставлял мне полный доступ к обработке клавиш, а Windows2000 половину "стандартных" (т.е. присутствующих на всех мультимедийных клавиатурах) взял на себя, тем самым мне не пришлось реализовывать в "драйвере" регулировку звука и работу browser-клавиш.
Так же в Windows2000 пришлось динамическим способом загружать HOOKLIB.DLL и использовать её функции.
Опытным путём было обнаружено, что мульти-клавиши тоже выдают событие Системе. Это событие ловит мой keylogger (в исправленном варианте). Также было установлено, что каждая мульти-клавиша имеет (естесственно) свой уникальный код, который содержится в высшем слове параметра .LParam, т.е. в M.HiLParam.
Код для каждой клавиши также был получен опытным путём.
В качестве приятной фичи могу назвать возможность управления WinAmp'ом.
Кстати, функции работы с ним я взял из открытого компонента Ивана Спиридонова - TWinAmpControl.
Ещё я использовал модуль TrayIcon.pas, чтобы выводить иконку в системный Tray.
Больше никаких принципиальных отличий от KeyLogger'а нет.

Плюсы.


- совместимость с Windows98 (однако некоторые функции, например регулировку звука, вам придётся делать самим в отличии от Windows2000).
- уникальность программы: перед тем как сделать её, я обшарил часть интернета в поиске аналога, но я его не нашёл. Так что пожалуй, моя программа единственная в своём роде. И ценна она не тем, что универсальна, а тем что предоставляет гибкий (из-за открытости исходников) инструмент для полного использования всех преимуществ мультимедийных клавиатур.
Собственно больше оправданий существований моего "драйвера" я сказать не могу. Но пожалуй эта программа - один большой плюс уже потому, что она есть!

Исходные коды.


Все файлы исходников:
- Исходники: http://newff.narod.ru/pascal/uekd.rar
- Модуль TrayIcon.pas: http://newff.narod.ru/pascal/trayicon.rar
Внимание! Чтобы воссоздать программу одного файла Main.pas недостаточно - скачайте вышеприведённые архивы.

Файл Main.pas программы extkey.exe

unit Main;

{ Файл Main.pas программы Universal Extended Keyboard Driver }
{ (c) 2003 Nabatnikov Ivan (urisff@inbox.ru) }
{ http://newff.narod.ru }

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, TrayIcon,
Menus, ShellApi;

const
wm_Key_Event=wm_User+134; //Общее событие
WAPath='d:\work\winamp\winamp.exe'; //У меня здесь лежит WinAmp. Замените это на то, где он у Вас...

type
TMF = class(TForm)
PM: TPopupMenu; //Только один компонент на форме
mnAbout: TMenuItem;
space: TMenuItem;
mnClose: TMenuItem;
procedure FormCreate(Sender: TObject);
procedure FormPaint(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure mnCloseClick(Sender: TObject);
procedure mnAboutClick(Sender: TObject);
private
procedure wm_KeyEvent(var M: TMessage); message wm_Key_Event; //процедура обработки события
end;

var
MF: TMF;
hlib: HMODULE=0; //Идентификатор библиотеки hooklib.dll
WAHandle: THandle; //Идентификатор WinAmp
TI: TTrayNotifyIcon; //Иконка в System Tray
//Описываем функцию и процедуру как переменные
SetHook: function: boolean;
UnHook: procedure;

implementation

{$R *.DFM}

function WaFind: boolean;
begin
//Ищем WinAmp в памяти по известному классу
WAHandle:=FindWindow(PChar('Winamp v1.x'),0);
//проверка на результативность
If WAHandle<>INVALID_HANDLE_VALUE then Result:=true else Result:=false;
end;

function WaExec: boolean;
//Запуск WinAmp с определённым классом
begin
If ShellExecuteA(0,0,WAPath,PChar('/CLASS="Winamp v1.x"'),PChar(ExtractFilePath(WAPath)),SW_MINIMIZE)>32 then Result:=true else Result:=false;
WaFind; //Получаем WAHandle
end;


//Процедуры для работы с включенным WinAmp'ом
//были взяты из открытого компонента Ивана Спиридонова TWinAmpControl.

procedure WaMsg(Msg: UINT; wParam: WPARAM; lParam: LPARAM);
begin SendMessage(WAHandle,Msg,wParam,lParam); end;

procedure WaPlay;
begin WaFind; WaMsg(WM_COMMAND,40045,0); end;

procedure WaPause;
begin WaFind; WaMsg(WM_COMMAND,40046,0); end;

procedure WaPrev;
begin WaFind; WaMsg(WM_COMMAND,40044,0); end;

procedure WaNext;
begin WaFind; WaMsg(WM_COMMAND,40048,0); end;

procedure WaClose;
begin WaFind; WaMsg(WM_COMMAND,40001,0); end;



procedure TMF.FormCreate(Sender: TObject);
begin
//Открываем библиотеку hooklib.dll
hlib:=LoadLibrary(PChar(ExtractFilePath(Application.ExeName)+'hooklib.dll'));
If hlib=0 then //Если не была открыта
begin
//Выдаём ошибку
ShowMessage('File not found or invalid: '+ExtractFilePath(Application.ExeName)+'hooklib.dll');
//И выходим
Halt(1);
end;

//Загружаем функцию и процедуру
@SetHook:=GetProcAddress(hlib,'SetHook');
@UnHook:=GetProcAddress(hlib,'UnHook');

If not SetHook then ShowMessage('Failed to set hook'); //Устанавливаем и проверяем ловушку

TI:=TTrayNotifyIcon.Create(TI); //Помещаем иконку в Tray
TI.Hint:='Keyboard Driver'; //Всплывающая подсказка
TI.Icon:=Application.Icon; //Присваиваем иконку самой программы как иконку в Tray
TI.IconVisible:=true; //Показываем её
TI.PopupMenu:=PM; //Приделываем к ней меню
end;

procedure TMF.FormPaint(Sender: TObject);
begin
MF.Hide; //Когда форма начинает отображаться, скрываем её.
end;

procedure TMF.FormClose(Sender: TObject; var Action: TCloseAction);
begin
UnHook; //При выходе снимаем ловушку (на всякий случай)
end;

function Exec(const FileName, Params, DefaultDir: string; ShowCmd: Integer): THandle;
//Функция для быстрого запуска приложения
var
zFileName, zParams, zDir: array[0..79] of Char;
begin
Result:=ShellExecute(Application.MainForm.Handle,nil,
StrPCopy(zFileName, FileName), StrPCopy(zParams, Params),
StrPCopy(zDir, DefaultDir), ShowCmd);
end;


procedure TMF.wm_KeyEvent(var M: TMessage);
//Наше событие
begin
//Истинные уникальные коды для мультимедийных клавиш находятся в
//высшем слове параметра m.lparam, т.е. в m.lparamhi

//Обрабатываем эти кнопки
case m.lparamhi of
//Если нажали [Media]...
365: WaExec; //Запускаем WinAmp
//Если нажали [Play]...
290: WaPlay; //Посылаем Play в WinAmo
//Если нажали [Prev]...
272: WaPrev; //Возвращаемся на предыдущую песню
//Если нажали [Next]...
281: WaNext; //Идём на следующую песню
//А бесполезную и редкоиспользуемую кнопку [Stop]...
292: WaPause; //Обрабатываем как кнопку Pause
//Кнопка [Calculator]...
289: Exec('calc','','c:',1); //Запускает калькулятор, как ни странно
//Кнопка [My Computer]...
363: Exec('explorer.exe','/e,/root,::{20D04FE0-3AEA-1069-A2D8-08002B30309D}','c:',1); //Запускает "Мой компьютер"
//При нажатии на колёсико (Wheel)...
291: begin keybd_event(13,0,0,0); keybd_event(13,0,2,0); end; //Имитируем нажатие Enter - удобно в оболочках (теперь у нас ТРИ Enter'а на клавиатуре)
//Кнопка [Excel]...
276: Exec('excel','','c:',1); //Запускает Excel
//Кнопка [Word]...
275: Exec('winword','','c:',1); //Запускает Word
end;
end;

procedure TMF.mnCloseClick(Sender: TObject);
//Пункт меню Close
begin
Application.Terminate;
end;

procedure TMF.mnAboutClick(Sender: TObject);
//Пункт меню About...
begin
ShowMessage(
'Universal Extended Keyboard Driver'+#13+
'Version 1.1 (2K edition)'+#13+#13+
'Programmer: Nabatnikov Ivan'+#13+
'urisff@inbox.ru'+#13+
'http://newff.narod.ru'+#13+#13+
'Lipetsk, 2003'+#13);
end;

end.

Уважаемые подписчики! Возможно кому-то приводимые здесь материалы очень интересны и вы можете отправить этому человеку приглашение на подписку:
Отправить приглашение подписаться.

Все вопросы и пожелания ко мне, т.е. ведущему рассылки, прошу слать на e-mail: urisff@inbox.ru
Перепубликация допускается только с моего разрешения.
В случае, если вы будете использовать приведённые в этой рассылке коды, не забудьте сделать ссылку на мой сайт.

Ведущий рассылки:
Иван (urisff@inbox.ru)
http://newff.narod.ru/


http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться
Убрать рекламу

В избранное