Tastendruck an ein externes Programm senden.



  • Hi,

    ich würde gerne ein Programm in c++ für WinXP schreiben das einen bestimmten Tastendruck simuliert und an ein bestimmtes Programm sendet. Hm... ich denk mal anhand des Fensternamens bzw. exe-Namens.

    Es sollte ca. so aussehen.

    [MyProg] ---- (sendet) ----> [H][a][l][l][o]----> (an) ---> [Notepad]

    Wobei Notepad in diesem Fall minimiert in der Taskleiste ist und auch dort bleiben soll.

    Weiss jemand wie das geht? Oder wo ich bzw. wonach ich suchen muss?

    Vielen Dank im vorraus 😉



  • Was soll denn Notepad dann damit anfangen ? Soll der Text dargestellt werden oder was ?

    BTW:

    - FindWindow
    - FindWindowEx
    - SendMessage
    - PostMessage



  • Richtig... so als wenn ich selber in Notepad "Hallo" schreiben würde. Nur tuh ich das nicht sondern das Tool macht es und lässt Notepad dabei im selben zustand wie es ist... also minimiert. 😉

    Danke ich werde mir mal die Funktionen anschauen.



  • Action-Jackson schrieb:

    [...]lässt Notepad dabei im selben zustand wie es ist... also minimiert.[...]

    Jo das ist mit den oben genannten Funktion kein Problem. Du kannst dir über die Spy++ die Klassennamen der Fenster besorgen.
    Was vllt auch noch interessant wäre ist eine Enumeration der Child-Fenster.

    Siehe dazu:

    ➡ EnumChildWindows(...).

    ➡ EnumChildProc(...)



  • Der korrekte Weg ist via "SendInput".



  • Jochen Kalmbach schrieb:

    Der korrekte Weg ist via "SendInput".

    Aber SendInput sendet doch global, so das jede Anwendung davon etwas 'mitbekommt'. Oder kann man den Aufruf spezifizieren ?



  • Danke ich schau mir das gleich alles mal an. Bei SendInput sieht das jedoch etwas komisch aus... da ich der Funktion kein hwnd oder ähnliches vom Notepad Fenster übergeben kann glaub ich.

    Aber ich arbeite mich da gleich mal rein, mal schauen 😉 thx



  • CodeFinder schrieb:

    Jochen Kalmbach schrieb:

    Der korrekte Weg ist via "SendInput".

    Aber SendInput sendet doch global, so das jede Anwendung davon etwas 'mitbekommt'. Oder kann man den Aufruf spezifizieren ?

    Es bekommt natürlich nicht jede Anwendung was mit, sondern nur die mit dem Input-Focus! Eben genaus so, wie wenn Du eine Taste drücken würdest.



  • Jochen Kalmbach schrieb:

    [...]Es bekommt natürlich nicht jede Anwendung was mit, sondern nur die mit dem Input-Focus! Eben genaus so, wie wenn Du eine Taste drücken würdest.

    Dann war dein Post schwachsinnig, denn:

    Richtig... so als wenn ich selber in Notepad "Hallo" schreiben würde. Nur tuh ich das nicht sondern das Tool macht es und lässt Notepad dabei im selben zustand wie es ist... also minimiert.



  • Also ich hab mir mal eine DLL angeschaut die Tastatureingaben an ein bestimmtes Programm sendet.

    Für mein Prog würde das ganze dann so in etwa aussehen:

    char tmp = 'A';
    
        HWND ghAppWnd = FindWindow("Unbenannt - Editor", 0);
        SendMessage(ghAppWnd, 0, 0, (LPARAM)tmp);
    

    Bei SendMessage, an der Stelle wo die 1. null steht stand "WM_KEY".

    Und in dem Programm selber war WM_KEY als Callback definiert... oder wie das heisst. 😉

    Also müsste ich theoretisch eine Callback Funktion in Notepad finden die ich benutzen kann. Ich schau mir gleich mal Spy++ an. Eventuell lässt sich damit was finden.

    😉



  • Action-Jackson schrieb:

    char tmp = 'A';
    
        HWND ghAppWnd = FindWindow("Unbenannt - Editor", 0);
        SendMessage(ghAppWnd, 0, 0, (LPARAM)tmp);
    

    Bei SendMessage, an der Stelle wo die 1. null steht stand "WM_KEY".

    Und in dem Programm selber war WM_KEY als Callback definiert... oder wie das heisst. 😉

    Jo also 0, kann da nicht stehen bleiben, dann passiert nit -> WM_NULL.

    Action-Jackson schrieb:

    Also müsste ich theoretisch eine Callback Funktion in Notepad finden die ich benutzen kann. Ich schau mir gleich mal Spy++ an. Eventuell lässt sich damit was finden.

    Nop. Das geht so nicht. Und mit der Spy findeste auch keine Callback-Funktionen.

    So kannst du es machen:

    #include <Windows.h>
    #include <ioStream>
    #include <String>
    
    using namespace std;
    
    #define STR_DESTCLASSNAME   (string("Edit"))
    #define EBX_DESTWINDOWID    (0x0F)
    
    // Ermittelt den gesamten oder nur einen Teil Textes
    // aus einem Control einer fremden Anwendung:
    inline string& GetCaptionPart(HWND hWnd, long lCharCounts = 0L)
    {
    	static string strReturn;
    	long lLength;
    	if(lCharCounts <= 0L) // den gesamten Text ermitteln
    		lLength = SendMessage(hWnd, WM_GETTEXTLENGTH, 0, 0L);
    	else
    		lLength = lCharCounts;
    
    	PTCHAR pszCaption;
    	pszCaption = new TCHAR[lLength + 1L];
    	SendMessage(hWnd, WM_GETTEXT, lLength, reinterpret_cast<LPARAM>(pszCaption));
    	strReturn = pszCaption;
    	delete [] pszCaption;
    	return (strReturn);
    }
    
    HWND hWndDestEdit = NULL; // Handle zum Edit-Conrol von Notepad
    
    // Enumeriert alle Child-Fenster der Notepad-Anwendung, bis das 
    // gwünschte Steuerelement gefunden wurde:
    BOOL CALLBACK EnumNotepadChilds(HWND hWndChild, LPARAM lParamExtra)
    {
    	cout << ">>>ENTERING: EnumNotepadChilds..." << endl << endl;
    	static int iCounter = 0;
    	cout << "Enum-Counter: " << ++iCounter << endl;
    	cout << "Information ueber aktuelles Fenster:" << endl;
    	cout << "\t- Titel: " << "'" << GetCaptionPart(hWndChild, 0) << "'" << endl;
    	TCHAR szClassName[100];
    	GetClassName(hWndChild, szClassName, 100);
    	if(string(szClassName) == STR_DESTCLASSNAME &&
    	   GetWindowLong(hWndChild, GWL_ID) == EBX_DESTWINDOWID)
    	{
    		hWndDestEdit = hWndChild;
    		cout << "LEAVING: EnumNotepadChilds...Destination-Control found!" << endl << endl;
    		return (FALSE);
    	}
    	cout << "<<<LEAVING: EnumNotepadChilds...Destination-Control NOT found!" << endl << endl;
    	return (TRUE);
    }
    
    // Einspungspunkt des Programms:
    int main()
    {
    	HWND hWndNotepad  = NULL;
    	hWndNotepad = FindWindow("Notepad", NULL);
    	if(hWndNotepad != NULL)
    	{
    		cout << "Notepad gefunden - Beginne Enumeration..." << endl << endl;
    		EnumChildWindows(hWndNotepad, EnumNotepadChilds, reinterpret_cast<LPARAM>(hWndDestEdit));
    		if(hWndDestEdit != NULL)
    		{
    			cout << "Edit-Control in Notepad identifiziert!" << endl;
    			PostMessage(hWndDestEdit, WM_CHAR, static_cast<WPARAM>('H'), 0L);
    			/*
    			Hier kannste du auch andere Nachrichten senden, da gibts viele
    			Möglichkeiten...Achte nur auf die Belegungen für wParam und lParam!
    			*/
    			// Kontrollergebnis:
    			cout << "Der gesamte Text:\n------------------------------\n\n"
    				 << GetCaptionPart(hWndDestEdit, 0) << endl << endl;
    		}
    		else
    			cout << "Edit-Control in Notepad NICHT identifiziert!" << endl;
    	}
    	return (0);
    }
    

    PS: Hab das getestet, funktioniert perfekt und ist sogar sprachunabhängig bzw.
    dokumenten-unabhängig, da Notepad nur an der Klasse identifiziert wird 😉 .
    Meine Güte war das ne Arbeit...hoffe das hat dich weiter gebracht 👍 .



  • LOOOL es funzt perfekt. Mit dem Borland builder hatte ich an 2 Stellen komische Fehlermeldungen.

    Aber mit DevC++ funzt es wunderbar!!

    DANKE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    Eine Frage noch ... wie kommst du auf den Wert hier:

    #define EBX_DESTWINDOWID    (0x0F)
    

    ... also 0x0F?



  • Action-Jackson schrieb:

    [...]
    Eine Frage noch ... wie kommst du auf den Wert hier:

    #define EBX_DESTWINDOWID    (0x0F)
    

    ... also 0x0F?

    Das bekommste mit der Spy heraus...is auch nicht unbedingt nötig, wollte aber auf Nummer sicher gehen 😉 .

    @Jochen: Das war dann wohl ein Schuss in den Ofen 😃 .



  • 🙂 Danke euch allen nochmal!!!



  • Action-Jackson schrieb:

    🙂 Danke euch allen nochmal!!!

    Kein Problem 😉 .


Anmelden zum Antworten