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.
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);
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.
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.