Wysyłanie do okna aplikacji skrótu klawiszowego Ctrl+V

0

Witam.

Wiem jak dzięki sendmessage mogę symulować wciśnięcie jednego klawisza w danym oknie. Niestety, ale potrzebuję zrobić ctrl + v i nie potrafię tego w żaden sposób uczynić. Ktoś wie jak to zrobić poprawnie?
Dzięki.

1

A może być wysłany komunikat WM_PASTE ? Jak nie to jest to zabawa tego typu:

hWin:= FindWindow(nil, 'To jest tytuł apki');
SendMessage(hWin, WM_KEYDOWN, VK_CONTROL, 0);
SendMessage(hWin, WM_KEYDOWN, Ord('V'), 0);
SendMessage(hWin, WM_KEYUP, Ord('V'), 0);
SendMessage(hWin, WM_KEYUP, VK_CONTROL, 0); 
0

a to nie jest tak że ctrl+v jest funkcją systemową i standardowo wkleja dane ze schowka do aktywnej kontrolki w aktywnym oknie?

1

Można też spróbować z SendInput.

0
kAzek napisał(a):

A może być wysłany komunikat WM_PASTE ? Jak nie to jest to zabawa tego typu:

hWin:= FindWindow(nil, 'To jest tytuł apki');
SendMessage(hWin, WM_KEYDOWN, VK_CONTROL, 0);
SendMessage(hWin, WM_KEYDOWN, Ord('V'), 0);
SendMessage(hWin, WM_KEYUP, Ord('V'), 0);
SendMessage(hWin, WM_KEYUP, VK_CONTROL, 0); 

W moim przypadku to nie działa. Za przykład podałem ctrl + v, ale chodzi o różne inne np. ctrl + f, h itp. co w tym przypadku nie ma znaczenia i tak. Nie chce działać niestety. Tak jakby jakiś problem był z controlem.

var
  okno: HWND;
  inputArray: array[0..3] of TInput;
begin
  okno := FindWindow('Program1', nil );

  // TODO: Either exit if notepad isn't focused, or set focus to notepad

  FillChar(inputArray, length(inputArray) * sizeof(TInput), 0);

  inputArray[0].Itype := INPUT_KEYBOARD;
  inputArray[0].ki.wVk := VK_LCONTROL;
  inputArray[1].Itype := INPUT_KEYBOARD;
  inputArray[1].ki.wVk := VkKeyScan('H');
  inputArray[2].Itype := INPUT_KEYBOARD;
  inputArray[2].ki.wVk := VkKeyScan('H');
  inputArray[2].ki.dwFlags := KEYEVENTF_KEYUP;
  inputArray[3].Itype := INPUT_KEYBOARD;
  inputArray[3].ki.wVk := VK_LCONTROL;
  inputArray[3].ki.dwFlags := KEYEVENTF_KEYUP;

  SendInput(length(inputArray), inputArray[0], sizeof(TInput));

// kombinatoryka SendMessage(okno, Tinput[0], sizeof(TInput), 0);

end;

Taki kod działa dobrze, tylko niestety nie wiem jak zrobić by działał również, gdy okno jest w tle, lub po prostu zminimalizowane.

1
DroniC napisał(a):

Taki kod działa dobrze, tylko niestety nie wiem jak zrobić by działał również, gdy okno jest w tle, lub po prostu zminimalizowane.

Pamiętaj, że SendInput udaje, że to ty wciskasz klawisze na klawiaturze lub machasz myszką i klikasz. A skoro tak, to cały w ten sposób wygenerowany input będzie leciał do aktualnie sfokusowanego okna oraz do procesów, które mają zarejestrowane hooki na klawiaturę/mysz. Jeśli okno tego docelowego programu nie ma fokusu lub jest zminimalizowane, system nie dostarczy do niego komunikatów inputu.

Dlatego @kAzek wcześniej podał najlepsze rozwiązanie, czyli wysłanie wyspecjalizowanych komunikatów do okna, takich jak WM_PASTE. Problem jednak polega tutaj na tym, że okno docelowe może nie obsłużyć tego komunikatu i przez to też się z tą apką nie dogadasz.


Dlatego też dokładnie sprawdź czy poprawnie wysyłasz komunikat do okna — czy masz prawidłowy uchwyt okna, jaka była odpowiedź SendMessage itd., czyli za każdym razem gdy korzystasz z funkcji Win32 API, po prostu sprawdzaj rezultaty i upewnij się, że nie wystąpił żaden błąd.

Jeśli to nic nie da, to okno tego programu będziesz musiał najpierw aktywować, zanim wyślesz dane inputu. Do tego są specjalne funkcje systemowe, np. IsWindowVisible, IsIconic, SetForegroundWindow, SetActiveWindow, SetFocus itd. Najpierw sprawdź gdzie to okno jest, jeśli jest zminimalizowane to je przywróć, później przesuń je na pierwszy plan i ostatecznie aktywuj, dając mu fokus. Na koniec wyślij input np. za pomocą SendInput. Każdy z tych kroków może się nie udać, więc sprawdzaj rezultaty.

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