Od jakiegoś czasu pracuję nad pewnym narzędziem. Jego zadaniem jest gromadzenie i generowanie różnych danych widocznych w jego głównym oknie, a także renderowanie wybranych informacji w oknie podglądu. Czyli program ma dwa okna – główne z kontrolkami i drugie z podglądem dynamicznie wyrenderowanych danych.
Ważną jego funkcją jest informowanie innych programów o zmianie zawartości tego drugiego okienka. Jeśli zawartość okna zmieni się, mój program symuluje określony skrót klawiszowy, który zewnętrzne programy muszą odebrać. Jest to wygodne i funkcjonalne rozwiązanie, dlatego że mój program może współpracować z dowolnym zewnętrznym programem (którego autorem nie jestem), a nawet z wieloma jednocześnie.
Do symulowania wciskania kombinacji klawiszy używam poniższej procedury. Skorzystałem z keybd_event
, bo oczywiście importu funkcji SendInput
, typów danych i flag brakuje w module Windows. :/
procedure BroadcastShortCut(AKey: UInt16; AShift: TShiftState);
begin
if ssShift in AShift then keybd_event(VK_SHIFT, MapVirtualKey(VK_SHIFT, 0), 0, 0);
if ssAlt in AShift then keybd_event(VK_MENU, MapVirtualKey(VK_MENU, 0), 0, 0);
if ssCtrl in AShift then keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), 0, 0);
keybd_event(AKey, MapVirtualKey(AKey, 0), 0, 0);
keybd_event(AKey, MapVirtualKey(AKey, 0), KEYEVENTF_KEYUP, 0);
if ssCtrl in AShift then keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), KEYEVENTF_KEYUP, 0);
if ssAlt in AShift then keybd_event(VK_MENU, MapVirtualKey(VK_MENU, 0), KEYEVENTF_KEYUP, 0);
if ssShift in AShift then keybd_event(VK_SHIFT, MapVirtualKey(VK_SHIFT, 0), KEYEVENTF_KEYUP, 0);
end;
Przetestowałem program w połączeniu z odtwarzaczem WinAMP, który posiada obsługę globalnych klawiszy – bez problemu mogę swoim programem np. przełączać utwory w tym odtwarzaczu. Tu jest wszystko w porządku.
Ale jest problem – program OBS nie reaguje na zasymulowane skróty klawiaturowe. Tzn. reaguje, ale tylko wtedy, gdy okno mojego programu jest nieaktywne i użytkownik swoimi palcami wstuka zadaną kombinację na klawiaturze. No nie może tak być – użytkownik ma obsługiwać mój program, więc jego okno siłą rzeczy musi być aktywne, natomiast zewnętrzne programy powinny działać w tle.
Przechodząc do sedna – w jaki sposób inaczej rozgłosić w systemie dany skrót klawiszowy, tak aby dowolne zewnętrzne programy mogły na ten skrót reagować?