ekranowa klawiatura numeryczna

0

Witam

Piszę sobie klawiaturę ekranową i mam prawie wszystko. Prawie, bo nie mogę
przeskoczyć klawiatury numerycznej, a konkretnie obsługi NumLocka. Wygląda
to tak, że
(klawiatura sprzętowa)

  1. NumLock wyłączony - działają klawisze sterujące (strzałki, home, end,
    itp)
  2. NumLock włączony - działają cyfry
    (klawiatura programowa)
  3. NumLock wyłączony - działają cyfry
  4. NumLock włączony - działają cyfry

Niezależnie, czy NumLock włączam/wyłączam programowo czy przyciskając
przycisk na klawiaturze.

Trochę kodu:
włączanie/wyłączanie NumLock

keybd_event(VK_NUMLOCK, MapvirtualKey(VK_NUMLOCK, 0), KEYEVENTF_EXTENDEDKEY, 0);
keybd_event(VK_NUMLOCK, MapvirtualKey(VK_NUMLOCK, 0), KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP, 0);

naciskanie np. Num7

keybd_event(VK_NUMPAD7, MapvirtualKey(VK_NUMPAD7, 0), 0, 0);
keybd_event(VK_NUMPAD7, MapvirtualKey(VK_NUMPAD7, 0), KEYEVENTF_KEYUP, 0);

Dodatkowo zrobiłem sobie prosty test - dodałem memo do formy oraz kod

procedure TForm1.FormKeyDown(Sender: TObject; var Key: word; Shift:
TShiftState);
  function keyname: string;
  begin
    SetLength(Result, 128);
    SetLength(Result, GetKeynameText(FLastMsg.lparam, @Result[1],
Length(Result)));
  end;
  function Scancode: byte;
  begin
    Result := LoByte(HiWord(FLastMsg.lparam));
  end;
  function specialkey: string;
  begin
    if (FLastMsg.lparam and $1000000) <> 0 then
      Result := 'yes'
    else
      Result := 'no';
  end;
begin
  //FLastMsg.lParam := Key;
  mmo1.Lines.add(format('key: <%s>; scancode: %d; specialkey: %s; lparam:
%d',
    [Keyname, scancode, specialkey, FLastMsg.lparam]));
  key := 0;
end;

procedure TForm1.AppOnMessage(var Msg: TMsg; var Handled: boolean);
begin
  case msg.message of
    WM_KEYFIRST..WM_KEYLAST:
      FLastMsg := Msg;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Application.OnMessage := AppOnMessage;
end;

w rezultacie przy naciśnięciu klawisza w memo mam nazwę klawisza, scancode,
czy jest klawiszem specjalnym i cały lparam przesyłany do app przy
naciśnięciu klawisza.

Dla klawiatury sprzętowej mam coś takiego:

//włączenie CapsLock
key: <Num Lock>; scancode: 69; specialkey: yes; lparam: 21299201
//naciskam Num7 i dostaję '7'
key: <Num 7>; scancode: 71; specialkey: no; lparam: 4653057
//wyłączenie CapsLock
key: <Num Lock>; scancode: 69; specialkey: yes; lparam: 21299201
//naciskam Num7 i dostaję 'Home'
key: <Num 7>; scancode: 71; specialkey: no; lparam: 4653057

Dla tych samych operacji ale przez keybd_event

//włączenie CapsLock
key: <Num Lock>; scancode: 69; specialkey: yes; lparam: 21299201
//naciskam Num7 i dostaję '7'
key: <Num 7>; scancode: 71; specialkey: no; lparam: 4653057
//wyłączenie CapsLock
key: <Num Lock>; scancode: 69; specialkey: yes; lparam: 21299201
//naciskam Num7 i dostaję '7'
key: <Num 7>; scancode: 71; specialkey: no; lparam: 4653057

i aby było ciekawiej:

//keybd_event - włączenie CapsLock
key: <Num Lock>; scancode: 69; specialkey: yes; lparam: 21299201
//klawiatury sprzętowej - naciskam Num7 i dostaję '7'
key: <Num 7>; scancode: 71; specialkey: no; lparam: 4653057
//keybd_event - wyłączenie CapsLock
key: <Num Lock>; scancode: 69; specialkey: yes; lparam: 21299201
//klawiatury sprzętowej - naciskam Num7 i dostaję 'Home'
key: <Num 7>; scancode: 71; specialkey: no; lparam: 4653057

Może coś robię źle, może gdzieś ktoś widzi jakiś błąd. Przyznam, że walczę
z tym już trochę czasu, przeszukałem googla i nic :/.

Dla CapsLock'a identyczny kod działa poprawnie, dla CTRL/SHIFT/PALT/LALT +
litera też jest OK, jedynie NumLock.

A druga sprawa to czy jest może jakaś funkcja, która zwróci mi, biorąc pod
uwagę stan klawiszy takich jak Shift, CapsLock, Alt, to co ma się
wyświetlić na ekranie. Tzn jak mam wciśnięty Shift i 'a' to da mi 'A', a
jak mam RAlt i 'a' to da mi 'ą'. Można to zrobić na piechotkę, ale przecież
windows wie, co za znak wyświetlić więc gdzieś powinno coś takiego być.

--
Pozdrawiam Misiekd


1 użytkowników online, w tym zalogowanych: 0, gości: 1