Symulowanie wciśnięcia klawisza PrintScreen

0

Próbuję zasymulować operacje wciskania klawiszy na klawiaturze: windows-m printscreen za pomocą winapi. Tak jak zminimalizowanie okien działa jak należy, tak z jakiegoś powodu program nie obsługuje(?) sygnału zrobienia zrzutu ekranu. Tzn. Niby SendInput() zwraca, że zostało wykonanych tyle akcji ile mu przekazałem, jednak schowek nadal jest pusty. Myślałem, że ma na to wpływ uruchomienie aplikacji jako administrator jednak po odpaleniu go z prawami, nadal bez zmian. Jakieś pomysły dlaczego?

Kod symulowania klawiszy:

bool FillInputArrayCell(INPUT & InputCell, UINT Key, UINT KeyState) {
    InputCell.type = INPUT_KEYBOARD;
    InputCell.ki.wVk = Key;
    InputCell.ki.wScan = 0;
    InputCell.ki.dwFlags = KeyState;
    InputCell.ki.time = 0;
    InputCell.ki.dwExtraInfo = GetMessageExtraInfo();

    return true;
}

bool GetPrintScreen() {
    // Tworzymy potrzebne struktury INPUT i je wypełniamy
    const UINT ArraySize = 6;
    INPUT InputArray[ArraySize];

    FillInputArrayCell(InputArray[0],VK_LWIN,0);
    FillInputArrayCell(InputArray[1],0x4D,0);                        // 0x4D == M
    FillInputArrayCell(InputArray[2],0x4D,KEYEVENTF_KEYUP);            // 0x4D == M
    FillInputArrayCell(InputArray[3],VK_LWIN,KEYEVENTF_KEYUP);
    FillInputArrayCell(InputArray[4],VK_SNAPSHOT,0);
    FillInputArrayCell(InputArray[5],VK_SNAPSHOT,KEYEVENTF_KEYUP);

    if(SendInput(ArraySize,InputArray,sizeof(InputArray[0])) != ArraySize) return false;
    return true;
}

Dalej mam ifa który powinien wywalić msgboxa jeśli GetPrintScreen() zwróci false. Ani razu tak się nie stało.

2

Wedlug mnie poniższy kod powinien działać. Działa na wszystkich klawiszach niemalże, to i z PrintScreen powinien. Ponieważ w c/c++ nie piszę i nienawidzę, a jeśli już tłumaczę to na Delphi. Także ten kod poniżej sobie przetłumacz. Ewentualnie przerób po swojemu na c/c++. Zresztą tutaj nie ma poza tablicami specjalnie skomplikowanych i zbyt charakterystycznych konstrukcji języka. Można zawsze pozmieniać to na if'y, chociaż przez uzycie tablic ze stałymi jest najkrócej i najprościej. Ewentualnie może ktoś odpisze, kto ogarnia c/c++. Ja pisuję w WinAPI, ale tylko pod Delphi. A ponieważ do tej pory wątek był bez odpowiedzi, a dotyczył WinAPI i symulacji klawiszy - to postanowiłem tutaj zajrzeć.

procedure KeyDownUp(KeyToSend : Byte; KeyDown : boolean);
const
  DownUp_Flags_Arr : array[boolean] of DWORD = (0, KEYEVENTF_KEYUP);
  Extended_Flags_Arr : array[boolean] of DWORD = (0, KEYEVENTF_EXTENDEDKEY);
var
  Input : TagINPUT;
  KeyExtended : boolean;
begin
  Input.Itype := INPUT_KEYBOARD;
  Input.ki.wVK := KeyToSend;
  Input.ki.wScan := MapVirtualKey(KeyToSend, 0);
  KeyExtended := KeyToSend in
    [VK_CONTROL, VK_LCONTROL, VK_RCONTROL,
    VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT,
    VK_HOME, VK_END, VK_PRIOR, VK_NEXT,
    VK_INSERT, VK_DELETE, VK_MENU];
  Input.ki.dwFlags := DownUp_Flags_Arr[not KeyDown] or Extended_Flags_Arr[KeyExtended];
  Input.ki.time := 0;
  SendInput(1, Input, SizeOf(Input));
end;

EDIT: tak, sprawdziłem, powyższy kod z poniższym wywołaniem działa idealnie i robi printscreeny jak należy. Sprawdzane na Windows 7 Ultimate 64 bit, ale na starszych/nowszych również imo powinno.

  KeyDownUp(VK_SNAPSHOT, True);
  KeyDownUp(VK_SNAPSHOT, False);
1

Zgadza się, działa jak należy, dzięki bardzo.

Przetłumaczony kod:

bool InTab(unsigned char Key) {
    for(unsigned int i=0; i<14; ++i) if(tab[i] == Key) return true;
    return false;
}

void KeyDownUp(unsigned char KeyToSend, bool KeyDown) {
    const DWORD DownUp_Flags_Arr[2] = {0,KEYEVENTF_KEYUP};
    const DWORD Extended_Flags_Arr[2] = {0,KEYEVENTF_EXTENDEDKEY};
    INPUT Input;
    bool KeyExtended;
    Input.type = INPUT_KEYBOARD;
    Input.ki.wVk = KeyToSend;
    Input.ki.wScan = MapVirtualKey(KeyToSend,0);
    KeyExtended = InTab(KeyToSend);
    Input.ki.dwFlags = DownUp_Flags_Arr[!KeyDown] | Extended_Flags_Arr[KeyExtended];
    Input.ki.time = 0;
    SendInput(1,&Input,sizeof(INPUT));
}

Należy sobie tylko dorobić/przerobić tablice z wartościami VK_CONTROL itd

@Edit Mała poprawka kodu

0

Proszę bardzo. Cieszę się, że mogłem pomóc. A tablica, a w Delphi w zasadzie tutaj zbiór dla klawiszy z flagą extended jest dość ważnym elementem. Swego czasu nie mogłem zmusić do działania na przykład klawisz Control. Lewy czy nawet prawy, w większości gier DirectX. Okazało się, że właśnie była konieczność użycia tej flagi. Natomiast pozostałe klawisze wygooglowałem kiedyś w podobnej postaci tego kodu, który później tak przerobiłem by był jak najkrótszy.

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