FAQ VCL
Клавиатура и мышь\Клавиатура

:: Меню ::
:: На главную ::
:: FAQ ::
:: Заметки ::
:: Практика ::
:: Win API ::
:: Проекты ::
:: Скачать ::
:: Секреты ::
:: Ссылки ::

:: Сервис ::
:: Написать ::

:: MVP ::

:: RSS ::

Яндекс.Метрика

Как yзнать текущую (Ru/En) pаскладкy клавиатypы?

// Способ первый
procedure TForm1.Button1Click(Sender: TObject);
var
  AklName: PWideChar;
begin
   GetMem( AklName, SizeOf( Char ) * 3 );
   GetLocaleInfo( LoWord( GetKeyboardLayout( 0 ) ),
                  LOCALE_SABBREVLANGNAME, AklName,
                  SizeOf( AklName ) );
   ShowMessage( AklName );
   FreeMem( AklName );
end;

// Способ второй
procedure TForm1.Button1Click(Sender: TObject);
var
  AklName: PWideChar;
begin
   GetMem( AklName, SizeOf( Char ) * 3 );
   GetLocaleInfo( LoWord( GetKeyboardLayout( 0 ) ),
                  LOCALE_SISO639LANGNAME, AklName,
                  SizeOf( AklName ) );
   ShowMessage( AklName );
   FreeMem( AklName );
end;

// Способ третий
function GetCurrentInputLanguage: string;
var
  LocaleID: cardinal;
  Size: Integer;
  Success: Boolean;
  Layout: HKL;
  SubLanguage, PrimaryLanguage: string;
begin
   Success := False;

   Layout := GetKeyboardLayout(0);
   LocaleID := LoWord(Layout);

   Size := GetLocaleInfo(LocaleID, LOCALE_SISO639LANGNAME, nil, 0);
   SetLength(PrimaryLanguage, Size);
   if GetLocaleInfo(LocaleID, LOCALE_SISO639LANGNAME, @PrimaryLanguage[1], Size) <> 0 then
   begin
      SetLength(PrimaryLanguage, Size - 1);
      Size := GetLocaleInfo(LocaleID, LOCALE_SISO3166CTRYNAME, nil, 0);
      SetLength(SubLanguage, Size);
      if GetLocaleInfo(LocaleID, LOCALE_SISO3166CTRYNAME, @SubLanguage[1], Size) <> 0 then
      begin
         SetLength(SubLanguage, Size - 1);
         Result := Format('%s-%s', [PrimaryLanguage, SubLanguage]);
         Success := True;
      end;
   end;

   if not Success then
      raise Exception.Create('Error retrieving locale information');
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   ShowMessage(GetCurrentInputLanguage);
end;

// Способ четвертый
procedure TForm1.Button2Click(Sender: TObject);

  function GetKBLayoutName: string;
  begin
     SetLength(Result, KL_NAMELENGTH);
     GetKeyboardLayoutName(@Result[1]);
     SetLength(Result, lstrlen(@Result[1]));
  end;

begin
   ShowMessage(GetKBLayoutName);
end;

// Способ пятый
procedure TForm1.Button1Click(Sender: TObject);
var
  Buffer: PWideChar;
begin
   GetMem( Buffer, SizeOf( Char ) * KL_NAMELENGTH );
   GetKeyboardLayoutName( Buffer );
   case ( ( StrToInt( '$' + Buffer ) ) and $03FF ) of
      LANG_ENGLISH: Caption := 'Eng';
      LANG_RUSSIAN: Caption := 'Rus';
   end;
   FreeMem( Buffer );
end;

// Способ шестой
procedure TForm1.Button1Click(Sender: TObject);
var
  KeyboardLayout: HKL;
begin
   //KeyboardLayout := GetKeyboardLayout( GetWindowThreadProcessId( GetForegroundWindow, nil ) );
   KeyboardLayout := GetKeyboardLayout( 0 );
   if KeyboardLayout = 67699721 then
      Caption := 'Eng'
   else
   if KeyboardLayout = 68748313 then
      Caption := 'Rus';
end;


Как отличить нажатие левого Shift, Alt, Control, Win от правого?

// Работает под Win NT/2000, но не работает под Win9x
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
   if (Word(GetKeyState(VK_LSHIFT)) and $8000) <> 0 then
      Caption := 'Левый Shift';
   if (Word(GetKeyState(VK_RSHIFT)) and $8000) <> 0 then
      Caption := 'Правый Shift';

   if (Word(GetKeyState(VK_LWIN)) and $8000) <> 0 then
      Caption := 'Левый Win';
   if (Word(GetKeyState(VK_RWIN)) and $8000) <> 0 then
      Caption := 'Правый Win';

   if (Word(GetKeyState(VK_LCONTROL)) and $8000) <> 0 then
      Caption := 'Левый Control';
   if (Word(GetKeyState(VK_RCONTROL)) and $8000) <> 0 then
      Caption := 'Правый Control';

   if (Word(GetKeyState(VK_LMENU)) and $8000) <> 0 then
      Caption := 'Левый Alt';
   if (Word(GetKeyState(VK_RMENU)) and $8000) <> 0 then
      Caption := 'Правый Alt';
end;


Как заставить дополнительную клавиатуру всегда работать в режиме цифр?

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

procedure TForm1.AppOnMessage(var Msg: TMsg; var Handled: Boolean);
var
  ccode: Word;
begin
   case Msg.Message of
      WM_KEYDOWN, WM_KEYUP:
      begin
         if ( GetKeyState( VK_NUMLOCK ) >= 0 ) // NumLock не включен
              and ( ( Msg.lparam and  $1000000 ) = 0 )
         then
         begin
            ccode := 0;
            case Msg.wparam of
               VK_HOME   : ccode := VK_NUMPAD7;
               VK_UP     : ccode := VK_NUMPAD8;
               VK_PRIOR  : ccode := VK_NUMPAD9;
               VK_LEFT   : ccode := VK_NUMPAD4;
               VK_CLEAR  : ccode := VK_NUMPAD5;
               VK_RIGHT  : ccode := VK_NUMPAD6;
               VK_END    : ccode := VK_NUMPAD1;
               VK_DOWN   : ccode := VK_NUMPAD2;
               VK_NEXT   : ccode := VK_NUMPAD3;
               VK_INSERT : ccode := VK_NUMPAD0;
               VK_DELETE : ccode := VK_DECIMAL;
            end;
            if ccode <> 0 then Msg.Wparam := ccode;
         end;
      end;
   end;
end;


Как определить время задержки перед началом автоповтора ввода символа?

procedure TForm1.Button1Click(Sender: TObject);
var
  KeyboardDelay: integer;
begin
   SystemParametersInfo( SPI_GETKEYBOARDDELAY, 0, @KeyboardDelay, 0 );
   ShowMessage( IntToStr( KeyboardDelay ) );
end;


Как определить частоту автоповтора символа?

procedure TForm1.Button1Click(Sender: TObject);
var
  KeyboardSpeed: integer;
begin
   SystemParametersInfo( SPI_GETKEYBOARDSPEED, 0, @KeyboardSpeed, 0 );
   ShowMessage( IntToStr( KeyboardSpeed ) );
end;


Как отловить изменение раскладки клавиатуры?

type
  TForm1 = class(TForm)
  private
    { Private declarations }
  public
    { Public declarations }
    procedure DoMessageEvent( var Msg: TMsg ); message WM_INPUTLANGCHANGEREQUEST {или WM_INPUTLANGCHANGE};
  end;

procedure TForm1.DoMessageEvent(var Msg: TMsg);
begin
   ShowMessage( 'Произошло изменение раскладки клавиатуры' );
end;

// Примечание: чтобы перехватить это сообщение в MDI форме, придется использовать хук.


Как получить время мерцания каретки?

procedure TForm1.Button1Click(Sender: TObject);
begin
   Caption := Format( 'Время мерцания каретки: %d ms', [GetCaretBlinkTime] );
end;


Как установить время мерцания каретки?

procedure TForm1.Button1Click(Sender: TObject);
begin
   SetCaretBlinkTime( 2000 );
end;


Как перехватить нажатие клавиш в Windows, даже если приложение неактивно?

// Timer1.Interval = 100
procedure TForm1.Timer1Timer(Sender: TObject);
begin
   if GetAsyncKeyState( VK_RETURN ) <> 0 then
      ShowMessage( 'Вы нажали на Enter' );
   if GetAsyncKeyState( VK_SPACE ) <> 0 then
      ShowMessage( 'Вы нажали на Space' );
   if GetAsyncKeyState( VK_ESCAPE ) <> 0 then
      ShowMessage( 'Вы нажали на Escape' );
end;


Как определить нажатие Shift, Control, Alt?

// Способ первый
function CtrlDown: Boolean;
var
  State: TKeyboardState;
begin
   GetKeyboardState( State );
   Result := ( ( State[VK_CONTROL] and 128 ) <> 0 );
end;

function ShiftDown: Boolean;
var
  State: TKeyboardState;
begin
   GetKeyboardState( State );
   Result := ( ( State[VK_SHIFT] and 128 ) <> 0 );
end;

function AltDown: Boolean;
var
  State: TKeyboardState;
begin
   GetKeyboardState( State );
   Result := ( ( State[VK_MENU] and 128 ) <> 0 );
end;

// Способ второй
function CtrlDown: Boolean;
begin
   Result := ( GetAsyncKeyState( VK_CONTROL ) shr 16 ) and 1 = 1;
end;

function ShiftDown: Boolean;
begin
   Result := ( GetAsyncKeyState( VK_SHIFT ) shr 16 ) and 1 = 1;
end;

function AltDown: Boolean;
begin
   Result := ( GetAsyncKeyState( VK_MENU ) shr 16 ) and 1 = 1;
end;

При использовании материала - ссылка на сайт обязательна