Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 09.06.2010, 01:50   #1
TwiX
Участник клуба
 
Аватар для TwiX
 
Регистрация: 28.07.2009
Сообщений: 1,510
По умолчанию WH_JOURNALRECORD. Как получить VirtualCode нажатой кнопки? Или как запустить toAscii только с ScanCode?

Сначала хотел спросить чем отличается ScanCode от VirtualCode, но за то время, пока форум был в оффе, я наверно догадался что это: ScanCode - это не табличный код (ASCII), а как бы клавиатурный (т.е. a s d = 30 31 32). (Если не прав, то поправьте пожалуйста)

Краткий обзор хука WH_JOURNALRECORD:
WParam не используется
LParam - указатель на PEVENTMSG
Код:
  PEventMsg = ^TEventMsg;
  {$EXTERNALSYM tagEVENTMSG}
  tagEVENTMSG = packed record
    message: UINT;
    paramL: UINT;
    paramH: UINT;
    time: DWORD;
    hwnd: HWND;
  end;
  TEventMsg = tagEVENTMSG;
  {$EXTERNALSYM EVENTMSG}
  EVENTMSG = tagEVENTMSG;
По экспериментам понял, что paramL и paramH это Hi и Low значения LParam сообщения (сомневался между LParam и WParam).

Т.е. если мне надо получить получить VirtualCode нажатой кнопки, то я должен знать WParam сообщения WM_KeyDown, что невозможно (в моём текущем понимании), т.е. WParam самой функции не используется, а tagEVENTMSG даже не содержит WParam. Как быть?
Чтобы использовать функция toASCII,надо знать сканкод и виртуалкод (сканкод мы можем получить). Тоже непонятно, что делать...

Вот код, получающий сканкод:
Код:
type
  TForm1 = class(TForm)
    Button1: TButton;
    ListBox1: TListBox;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  hook: HHOOK;

implementation

{$R *.dfm}

Function HookProc(Code: Integer; WParam: Word; LParam: Longint): Longint;
  Stdcall;
Var
  Msg: PEVENTMSG;
Begin
  If Code >= 0 Then
  Begin
    Msg := Pointer(LParam);
    if Msg.message=WM_KEYDOWN then
      Form1.ListBox1.Items.Insert(0, IntToStr(Msg.paramH and $ff));
  End;
End;

procedure TForm1.Button1Click(Sender: TObject);
begin
  hook := SetWindowsHookEx(WH_JOURNALRECORD, @HookProc, HInstance, 0);
  Button1.Enabled:=false;
end;

Последний раз редактировалось TwiX; 09.06.2010 в 05:26.
TwiX вне форума Ответить с цитированием
Старый 09.06.2010, 13:37   #2
TwiX
Участник клуба
 
Аватар для TwiX
 
Регистрация: 28.07.2009
Сообщений: 1,510
По умолчанию

Может тогда кто-нибудь знает, как сканкоду получить виртуалкоде хоть в любом регистре?

Добавлено:
Нашёл какую-то функцию, немного доделал. Вот что получилось:
Код:
function ScanToASCII(scancode: DWORD;
PResult: PChar): Integer;
var
  KBLayout: HKL;
  KBState: TKeyboardState;
  vk: UINT;
begin
  KBLayout := GetKeyboardLayout(0);

  if (GetKeyboardState(KBState) = False) then
  begin
    Result := 0;
    exit;
  end;

  vk := MapVirtualKeyEx(scancode, 1, KBLayout);
  Result := ToAscii(vk, scancode, KBState, PResult, 0);
  // Result := ToAsciiEx(vk, scancode, KBState, PResult, 0, KBLayout);  //или так
end;

procedure TForm2.Button1Click(Sender: TObject);
var
  a: char;
  r: integer;
begin
r:=ScanToASCII(36, @a);
if r=1 then
ShowMessage(a);
end;
Для английский букв работает нормально, но если попробовать нажать на кнопку при усской раскладке, то будет иероглиф (36 в функции - это сканкод J). Что делатЬ?

Последний раз редактировалось TwiX; 09.06.2010 в 14:27.
TwiX вне форума Ответить с цитированием
Старый 09.06.2010, 16:54   #3
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,281
По умолчанию

Странно, у меня при использовании вашей же функции ScanToASCII, все нормально отрабатывает
Код:
function HookProc (Code: Integer; WParam: Word; LParam: Longint): Longint; stdcall;
var
  Msg: PEVENTMSG;
  i, j: Integer;
  a: Char;
begin
  if Code >= 0 Then
  begin
    Msg := Pointer(LParam);
    if Msg.message = WM_KEYDOWN then begin
      i := Msg.paramH and $ff;
      j := ScanToASCII (i, @a);

      if j = 1 then
        Form1.ListBox1.Items.Insert (0, IntToStr (i) + ' - "' + a + '"')
      else
        Form1.ListBox1.Items.Insert (0, IntToStr (i));
    end;
  end;
end;
Нажимаю [E/У]. Потом Ctrl+Shift(меняю раскладку). И снова [E/У]. В результате в ListBox1'е имею:
Цитата:
18 - "e"
54
29
18- "у"
Sibedir вне форума Ответить с цитированием
Старый 09.06.2010, 18:02   #4
TwiX
Участник клуба
 
Аватар для TwiX
 
Регистрация: 28.07.2009
Сообщений: 1,510
По умолчанию

Ну что за невезуха...
Вот, что у меня при тех же действиях:
Код:
21 - "í"
18 - "ó"
21 - "y"
18 - "e"
(Жал английские Е и Y)

Добавлено:
Win7, D2010
TwiX вне форума Ответить с цитированием
Старый 09.06.2010, 18:49   #5
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,281
По умолчанию

WinXP, Delphi7
Фиг знает
Sibedir вне форума Ответить с цитированием
Старый 09.06.2010, 19:11   #6
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,281
По умолчанию

Вот, вспомнил. Обсуждалось как то на форуме
http://www.programmersforum.ru/showt...E6%E0%F2%E8%FF
см. пост №8 - GetCharFromVKey.
Sibedir вне форума Ответить с цитированием
Старый 09.06.2010, 23:03   #7
TwiX
Участник клуба
 
Аватар для TwiX
 
Регистрация: 28.07.2009
Сообщений: 1,510
По умолчанию

То же самое... Иероглифы при русских буквах
TwiX вне форума Ответить с цитированием
Старый 09.06.2010, 23:31   #8
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,281
По умолчанию

Да я уже понял вот от сюда
http://www.programmersforum.ru/showthread.php?t=103061
Sibedir вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как запустить вторую форму нажатием кнопки на первой на с#? mr Vi Общие вопросы C/C++ 1 24.05.2010 07:53
Как запустить или скомпоновать? Archivampire Общие вопросы C/C++ 15 07.03.2010 17:52
Как запустить какую - либо программу Windows с помощь кнопки на форме? РЫЖЫЙ :( Общие вопросы Delphi 1 04.11.2007 13:55
Как запустить приложение, дождаться его исполнения и только потом выполнять код? il76 Win Api 6 19.07.2007 14:00
Как запустить exe-шку нажатием кнопки???? Дамир Помощь студентам 3 04.02.2007 19:24