Symulacja wciśnięcia klawisza strzałki.

0

Witam.
Próbuję napisać program w Delphi, w którym będę mógł w Excelu przesunąć zaznaczenie jednej komórki do komórki poniżej. Zaznaczam, że docelowo nie będzie to Excel ale tabela w innej aplikacji.- jeśli zadziała w Excelu, to tam również. W sposób:

keybd_event (vk_Down, 0, 0, 0);
keybd_event (vk_Down, 0, KEYEVENTF_KEYUP, 0);

Powyższy kod przesuwa focus ale nie w dół tylko na pierwszą kolumnę w tym wierszu, czyli tak jakbym wcisnął klawisz HOME.

Jakieś sugestie ?

0

Nawet kilka jeśli wytłumaczysz co chcesz zrobić? Otwierasz Excela w swojej apce i po nim chcesz nawigować? Moze chcesz nawigować po Excelu apka zamiast robić macro ? Opisałeś tak ze ciezko cos powiedzieć

0

Nie mam możliwości testować tego na docelowej aplikacji. Dlatego testuję to na Excelu. Okno mojej aplikacji wyświetla się w rogu na ekranie. Na pierwszym planie aktywnym oknem jest Excel. Podświetlona jest komórka A5 a ja potrzebuję zasymulować klik strzałki w dół, żeby podświetlić komórkę A6. Tyle w temacie. Nie.mam możliwości przechwycić okna tej aplikacji i wysyłać do niej komunikatów.
Nie pytajcie dlaczego tak to robię. Po prostu tam ma to wyglądać.

0
Sowinsky napisał(a):
keybd_event (vk_Down, 0, 0, 0);
keybd_event (vk_Down, 0, KEYEVENTF_KEYUP, 0);

Powyższy kod przesuwa focus ale nie w dół tylko na pierwszą kolumnę w tym wierszu, czyli tak jakbym wcisnął klawisz HOME.
Jakieś sugestie ?

Chrzani Waść.

unit KeyEventForm;

interface uses
  Windows,
  Messages,
  SysUtils,
  Classes,
  Graphics,
  Controls,
  Forms,
  Dialogs,
  StdCtrls,
  ExtCtrls;

type
  TArrowUp=class(TForm)
    BtnStart:TButton;
    Timer:TTimer;
    LCountDown:TLabel;
    procedure BtnStartClick(Sender:TObject);
    procedure TimerTimer(Sender:TObject);
  end;

var ArrowUp: TArrowUp;

implementation

{$R *.DFM}

procedure TArrowUp.BtnStartClick(Sender:TObject);
begin
  Timer.Tag:=30;
  LCountDown.Caption:=IntToStr(Timer.Tag);
  Timer.Enabled:=true;
end;

procedure TArrowUp.TimerTimer(Sender:TObject);
var Key:Integer;
begin
  Key:=0;
  Timer.Tag:=Timer.Tag-1;
  LCountDown.Caption:=IntToStr(Timer.Tag);
  if Timer.Tag<=0 then Timer.Enabled:=false
  else if Timer.Tag<=5 then Key:=VK_UP
  else if Timer.Tag<=10 then Key:=VK_LEFT
  else if Timer.Tag<=15 then Key:=VK_DOWN
  else if Timer.Tag<=20 then Key:=VK_RIGHT;
  if Key>0 then
  begin
    keybd_event(Key,0,0,0);
    keybd_event(Key,0,KEYEVENTF_KEYUP,0);
  end;
end;

end.

dfm:

object ArrowUp: TArrowUp
  Left = 257
  Top = 124
  BorderStyle = bsToolWindow
  Caption = 'Arrow up'
  ClientHeight = 41
  ClientWidth = 178
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  FormStyle = fsStayOnTop
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object LCountDown: TLabel
    Left = 91
    Top = 12
    Width = 9
    Height = 19
    Caption = '0'
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -16
    Font.Name = 'Arial'
    Font.Style = [fsBold]
    ParentFont = False
  end
  object BtnStart: TButton
    Left = 8
    Top = 8
    Width = 75
    Height = 25
    Caption = 'Start'
    TabOrder = 0
    OnClick = BtnStartClick
  end
  object Timer: TTimer
    Tag = 10
    Enabled = False
    Interval = 250
    OnTimer = TimerTimer
    Left = 128
    Top = 8
  end
end
0

@Sowinsky: spróbuj z funkcją SendInput, przykłady znajdziesz w sieci.

0

Wystarczyło najpierw VK_DOWN przypisać do zmiennej Key, a potem zmienną Key użyć w komendach

keybd_event(Key,0,0,0);
keybd_event(Key,0,KEYEVENTF_KEYUP,0);

Czym to się różni, nie mam zielonego pojęcia.

Dziękuję Waść za pomoc.

0

Niczym się to nie różni — jedno i drugie daje dokładnie to samo. Na pewno jedyną wprowadzoną w kodzie zmianą było wrzucenie VK_DOWN do zmiennej? W jednym ze swoich projektów (Free Pascal) używałem takiej funkcji:

procedure BroadcastShortcut(AKey: UInt16; AShift: TShiftState);
begin
  if ssShift in AShift then Windows.keybd_event(VK_SHIFT,   MapVirtualKey(VK_SHIFT,   0), 0, 0);
  if ssAlt   in AShift then Windows.keybd_event(VK_MENU,    MapVirtualKey(VK_MENU,    0), 0, 0);
  if ssCtrl  in AShift then Windows.keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), 0, 0);

  Windows.keybd_event(AKey, MapVirtualKey(AKey, 0), 0, 0);
  Windows.Sleep(100);
  Windows.keybd_event(AKey, MapVirtualKey(AKey, 0), KEYEVENTF_KEYUP, 0);

  if ssCtrl  in AShift then Windows.keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), KEYEVENTF_KEYUP, 0);
  if ssAlt   in AShift then Windows.keybd_event(VK_MENU,    MapVirtualKey(VK_MENU,    0), KEYEVENTF_KEYUP, 0);
  if ssShift in AShift then Windows.keybd_event(VK_SHIFT,   MapVirtualKey(VK_SHIFT,   0), KEYEVENTF_KEYUP, 0);
end;

Nie było żadnych problemów z wysyłaniem klawiszy i całych skrótów — ani w WinXP, ani w Win7, ani w Win10. Tzn. były, bo np. OBS nie zdążał złapać skrótu zanim został on ”wyciśnięty”, więc dodałem Sleep i po problemie.

0

Wcześniej użyłem

keybd_event (vk_Down, 0, 0, 0);
keybd_event (vk_Down, 0, KEYEVENTF_KEYUP, 0);

a teraz

Key:=VK_DOWN;
if Key>0 then
begin
  keybd_event(Key,0,0,0);
  keybd_event(Key,0,KEYEVENTF_KEYUP,0);
end;

Teraz działa, a wcześniej działało jak opisałem powyżej.

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