[C] HWND finden und PostMessage

_Van

Mitglied
Hallo und guten Abend euch allen,

ich bin neu hier aber trieb hier Account-los eine Weile herum und muss sagen
das man hier echt viel lernen kann. Leider hab ich für mein derzeitige Probleme
keine Lösung finden können (weder hier noch bei MSDN oder Google und IRC
Chat ist z.Z. unerreichbar).

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Wie ihr schon am Titel seht ist mein erstes Problem die HWND von meinem
eigenen Programm (Dosfenster) zu finden. Folgende Möglichkeiten hab ich ausprobiert:

http://www.tutorials.de/forum/c-c/207091-eigenes-konsolenfenster-verstecken.html
Code:
SetConsoleTitle("XYZ");
HWND my_hWnd = FindWindow( NULL, "XYZ" );
if( hWnd != NULL ) printf( "gefunden!\n" ); else printf( "fehlgeschlagen!\n" );

es steht dann immer "fehlgeschlagen!"...

und diese Codeschnipseln (Google) die leider auch nicht funktioniert haben...

Code:
HWND my_hWnd = (HWND)(int)(this.Handle); //bestimmt VB?
HWND my_hWnd = my.HWND; //das auch?

per Mausposition HWND zu bestimmten ist nicht gerade die beste Lösung...
http://www.tutorials.de/forum/c-c/206521-mausposition-ereignisse-erzeugen.html

ich dachte mir man könnte was mit GetCurrentThreadId(); machen aber
bin auch auf keine Lösungen gekommen...

naja, ich wollte euch fragen wie ihr eure HWND findet (wenn ihr das überhaupt tut...)

Wofür ich das brauche?:

Wollte xSound lib ausprobieren (finde leider die IternetAdresse nicht) und zum
Initialisierung der ganzen Sache muss ich folgenden Befehl benutzen

InitDirectSound(hWnd,NULL,NULL,2,44100,16)

Darum steig ich auf http://www.fmod.org/ LIB um.

Aber mich würde trotzdem noch interresieren wie man das Problem lösen würde :)


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Das zweite Problem ist dieser Code hier den ich mit viel Mühe (bin noch ein C Anfänger)
zusammengestellt hab:

Code:
#include <windows.h>
#include <stdio.h>

#define _ATTACH_

WPARAM VK_MY_OP[] = { 'I', 'T', VK_SPACE, 'W', 'O', 'R', 'K', 'S', VK_SPACE, 'O', 'M', 'F', 'G', VK_RETURN };

int main() {
	
	HWND hWnd = FindWindow( NULL, "cmd.exe" );
	
	if( hWnd != NULL )
		{
		
			DWORD			myThread;
			static DWORD	newThread;
			static DWORD	curThread;

			myThread  = GetCurrentThreadId();
			curThread = GetWindowThreadProcessId(GetForegroundWindow(), NULL);
			newThread = GetWindowThreadProcessId(hWnd, NULL);
			
			printf("mT = %i; cT = %i; nT = %i\n\n", myThread, curThread, newThread );
			
			printf("SetFocusSucces = %i;\n", SetFocus( hWnd ) );
			printf("SetActiveSucces = %i;\n", SetActiveWindow( hWnd ) );
			printf("SetEnableSucces = %i;\n\n", EnableWindow( hWnd, TRUE ) );

			UINT scan;
			LPARAM lparam;
			
			#ifdef _ATTACH_
			printf( "a1 = %i\n", AttachThreadInput(myThread, curThread, TRUE) );
			printf( "a2 = %i\n", AttachThreadInput(curThread, newThread, TRUE) );
			printf( "a3 = %i\n", AttachThreadInput(myThread, newThread, TRUE) );
			#endif
			
			int i;
			for( i = 0; VK_MY_OP[i]; i++ )
				{	
					scan = MapVirtualKey( VK_MY_OP[i], 0 );
					lparam = 0x00000001 | (LPARAM)( scan << 16 );
				
					printf( "PostMessage(KeyDown) = %i;\n", PostMessage(hWnd, WM_KEYDOWN, VK_MY_OP[i], lparam) );	// Key down
					
					Sleep(10);
					
					scan = MapVirtualKey( VK_MY_OP[i], 0 );
					lparam = 0xC0000001 | (LPARAM)( scan << 16);
					//lparam = lparam | 0x01000000;
					
					printf( "PostMessage(KeyUp) = %i;\n", PostMessage(hWnd, WM_KEYUP, VK_MY_OP[i], lparam) );     // Key up
					
					printf("space was pressed!\n");
					
					Sleep(500);
				}
			
			#ifdef _ATTACH_
			AttachThreadInput(myThread, curThread, FALSE);
			AttachThreadInput(curThread, newThread, FALSE);
			AttachThreadInput(myThread, newThread, FALSE);
			printf("Deattached Thread Input!\n");
			#endif
		}
		else
		{
			printf("failed to FindWindow()\n");
			getc(stdin);
		}
	


	return 0;

}

Ich weiß das dieser Code völlig unsauber geschrieben ist aber meine Angewohnheit
leider ist "Erst wenn es funktioniert in Teillösungen verteilen" (zumindenst bei
kleinen Programmen...)

Das Ziel ist einfach eine bestimmte Tastatureingabe (definiert in VK_MY_OP[])
zu simulieren. Wie im Beispielcode zu sehen ist wird die "cmd.exe" attacht und
Input an das Programm übergeben. Das klappt problemlos. Jedoch wenn ich
nun z.B. auf den normalen Editor wechsle (HWND hWnd = FindWindow( NULL, "Unbenannt - Editor" );)
dann passiert nichts. Und bei manchen anderen Programmen funktionierts nur
wenn ich vor jedem einzelnen simulierten Input das Programm manuell entfokusiere
(irgendein anderes Fenster anklicke) und dann wieder fokusiere.

SendInput()
und keybd_event() (http://www.tutorials.de/forum/c-c/218748-sendinput.html)
sind auch eine Lösung aber ich will stur bleiben und auf diese Weise das machen
wenn ihr nichts dageben habt ;)


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Ich bin euch sehr dankbar für die Zeit die ihr euch nehmt um mir zu helfen :)

Edit:

Sorry, ich vergass zu sagen:

Mein Compiler ist MinGW + MSYS. Cygwin funktioniert leider bei mir nicht ( er findet gcc befehl nicht ),
 
Zuletzt bearbeitet:
Wenn du machst

Code:
HWND my_hWnd = FindWindow( NULL, "XYZ" );

dann wird das handle in "my_hWnd" gespeichert, also musst du danach auch abfragen:

Code:
if( my_hWnd != NULL ) ...

Zur zweiten Frage:
WPARAM entspricht einem DWORD, also sowas wie ein 64bit int, da kannst du nicht einfach haufenweise Text reinschreiben, weil es dafür keinen bzw. zu viel oder nicht den richtigen Typ von Platz hat.
 
Zuletzt bearbeitet:
Wenn du machst

Code:
HWND my_hWnd = FindWindow( NULL, "XYZ" );

dann wird das handle in "my_hWnd" gespeichert, also musst du danach auch abfragen:

Code:
if( my_hWnd != NULL ) ...

Oh mein Gott....
so ein simpler Fehler...
Danke für den Fund :)
(Gibts aber einen schöneren Weg HWND zu finden?)

Zur zweiten Frage:
WPARAM entspricht einem DWORD, also sowas wie ein 64bit int, da kannst du nicht einfach haufenweise Text reinschreiben, weil es dafür keinen bzw. zu viel oder nicht den richtigen Typ von Platz hat.

Hmm, ich weiß nicht genau was du meinst.
Die sind doch in Arrays angeordnet und klappt auch sehr gut so.
Bei einer normalen Command Shell von Windows (cmd.exe) gehts
wunderbar. Nur bei paar anderen Programmen hackt es teilweise oder
funktioniert garnicht :(
 
Du speicherst einzelne char´s in einem array von DWORD´s, das kann funktionieren, weil rechnerisch

0000000000000000000000000000000000000000010101010

das gleiche ist wie

10101010

aber sobald eine Funktion den Typ der Variable braucht gibt es error, weil WPARAM nun mal nicht char ist, um korrekt aus einem WPARAM ein char zu machen, müsstest du das LOWORD des WPARAM von int nach char konvertieren.

edit:
Wozu überhaupt WPARAM?
Wenn du char´s speichern willst, warum nicht als char?
Dann musst du nur in der PostMessage machen:

Code:
PostMessage(hWnd, WM_KEYUP, (WPARAM)VK_MY_OP[i], lparam)
 
Zuletzt bearbeitet:
So, hab den Code so umgebessert wie du es gesagt hast :)
Leider ist mein Hauptproblem damit noch nicht behoben.
Nach wie vor gehts bei meinen TextEditoren nicht, sondern nur
in der cmd.exe einwandfrei.
 
Zuletzt bearbeitet:
Zurück