Witam,

jestem w trakcie pisania prostego keybindera do gry (na użytek własny). Niby wszystko działa poprawnie, ale w jednej drobnej rzeczy pojawia się problem.

System jest taki, że obiekt Timer, co 10 ms sprawdza stany wszystkich zbindowanych klawiszy, jeżeli wykryje, że któryś jest wciśnięty to wysyła komendę przypisaną temu klawiszowi do funkcji PutText. Funkcja ta rozbija łańcuch na pojedyncze znaki i wywołuje dla każdego funkcję SendKey.

Funkcja SendKey wysyła łańcuch, literka po literce, na ekran gry. Ponieważ robię to za pomocą funkcji keybd_event (która korzysta z mapy klawiszy wirtualnych), nie da się wysłać bezpośrednio np. wykrzyknika, tylko trzeba zasymulować najpierw wciśnięcie shifta, potem klawisza '1', w wyniku czego powstanie wykrzyknik (SHIFT + 1 = !)

Gdy do funkcji SendKey dociera łańcuch zawierający znaki specjalne z shiftem (!, @, #, $, %, :, {, }, itd.) trzeba najpierw zamienić na odpowiadające im na klawiaturze znaki bez shifta. Oto fragment kodu:

// Globalne obiekty przechowujące znaki specjalne z shiftem i odpowiadające im znaki zwykłe
String shift_0 = "!@#$%^&*(){}|:\"<>?_+";
String shift_1 = "1234567890[]\\;',./-=";

[...]

// Fragment funkcji Send Key

	} else if ( shift_0.Pos(c) ) { // Warunek sprawdzający, czy dany znak jest znakiem specjalnym z shiftem, np. !, @, #, $, %, ^, & ('c' to argument przekazany do funkcji - znak, który ma pojawić się na ekranie)

		for (unsigned short i = 1; i <= shift_0.Length(); i++) {
			if ( (char)c == shift_0[i] ) {

				c = shift_1[i];

				keybd_event(VK_SHIFT, 0, 0, 0);
				keybd_event(TextToShortCut(c), 0, 0, 0);
				keybd_event(TextToShortCut(c), 0, KEYEVENTF_KEYUP, 0);
				keybd_event(VK_SHIFT, 0, KEYEVENTF_KEYUP, 0);

			}
		}

Długie wyjaśnienie sprowadza się w zasadzie do prostego problemu: funkcja zamienia poprawnie wszystkie znaki, oprócz znaku zapytania. Zamiast "?" na ekranie pojawia się tylko "/".

Wygląda na to jaby znak "/" nie "podnosił się" przy zasymulowaniu naciśnięcia Shifta, bo taka instrukcja:

keybd_event(VK_SHIFT, 0, 0, 0);
keybd_event(TextToShortCut('/'), 0, 0, 0); 
keybd_event(TextToShortCut('/'), 0, KEYEVENTF_KEYUP, 0);
keybd_event(VK_SHIFT, 0, KEYEVENTF_KEYUP, 0);

również skutkuje wyświetleniem znaku "/". Jeżeli zamiast funkcji TextToShortCut('/'), umieścić funkcję MapVirtualKey(0x2F, 2) problem jest taki sam. (0x2F to znak "/" w tablicy ASCII).

Proszę o pomoc, bo próbowałem już różnych sposobów i nie mogę sobie z tym poradzić.