[VC++ 6.0 +MFC] Handle eines anderen Fensters

Daniel Toplak

Erfahrenes Mitglied
Ich brauch zunächst beim Click auf ein anders Fenster bzw. eine andere Anwendung die Nachricht, daß darauf geklickt worden ist. Und dann das Handle des jeweiligen Fensters, auf das geklickt worden ist. Ich hab leider keine Ahnung wie ich das anstellen soll, denn ich weiß nicht, wie meine Anwenung Nachrichten von einer anderen empfangen kann.
Ich hoffe mir kann da jemand helfen.

Gruss Homer
 
Die einzige Lösung die mir dazu einfällt ist, dass Du Dir einen Maus-Hook schreibst mit dem Du die Nachrichten der Maus abfangen kannst!
Ein Beispiel findest Du hier!

Mit der Methode WindowFromPos() kannst Du den Zeiger bzw. Handle auf das Fenster an der angegebenen Position herausfinden!

Beispiel für Mousehook gibt's auch bei Codeproject.
 
Zuletzt bearbeitet:
So was in der Art hab ich mir schon gedacht, puh. Aber da ich leider noch nie mit Hook's gearbeitet habe werd ich mir das jetzt wohl auch mal aneignen müssen.
Vielen Dank dafür.

Gruss Homer
 
Also ich hab mir jetzt einen SystemHook geschrieben, der in einer DLL drin ist. Wenn jetzt ein Maus-Click erfolgt, dann wir in der DLL PostMessage() an meine Anwendung eine Nachricht geschickt vom Typ WM_USER+x, die Nachricht kommt auch an und ich kann den LPARAM auch in eine MOUSEHOOKSTRUCT casten. Wenn ich aber jetzt die Werte der Stuct auslese (CPOINT pt), dann bekomm ich z.B. für den Punkt sehr komische Koordinaten.
Hier mal der Beispielcode meiner Funktion in der Anwendung:
Code:
LRESULT CFarbwhlerDlg::processmouse(WPARAM w, LPARAM l)
{
	// hier müsste eingesprungen werden wenn wo geklickt wird

	MOUSEHOOKSTRUCT *mhs = (MOUSEHOOKSTRUCT*) l;
	
	int x = mhs->pt.x;
	int y = mhs->pt.y;
	return 0L;
}
dann steht für x 500
und für y 1235564 drin

ist doch komisch oder. Was ist da falsch?

Gruss Homer

P.S. für den smilie kann ich nix, die Funktion heißt processmouse().
An die Admins man sollte vieleicht innerhalb des CODE-Tags nicht durch smilies ersetzten.
Da ":" + "p" zu :p wird.
 
Zuletzt bearbeitet:
Glaube ich weiss was Du falsch machst!

Du übergibst den Zeiger der MOUSEHOOKSTRUCT in der Hookprocedure in PostMessage! Richtig! Woher willst Du wissen, ob der Zeiger nicht nur temporär verfügbar ist!
Besser wäre es, wenn Du die Mauskoordinaten in HI- und LOBYTE verpackst und dann in LPARAM verschickst!

Beispielsweise so:
Code:
LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
	if(nCode < 0)
		return CallNextHookEx(hMouseHook, nCode, wParam, lParam);

	// Verhindern das eine Nachricht mehrmals verarbeitet wird.
	if(nCode == HC_ACTION)
	{
		MOUSEHOOKSTRUCT *mhs = (MOUSEHOOKSTRUCT*) lParam);
		PostMessage(hMyWnd, WM_MYUSERMSG, 0, MAKELPARAM(mhs->pt.x, mhs->pt.y))
	}

	return CallNextHookEx(hMouseHook, nCode, wParam, lParam);
}

Dann kannst Du nachher in Deiner CFarbwhlerDlg::processmouse() die Koordinaten mit
Code:
xPos = GET_X_LPARAM(lParam); 
yPos = GET_Y_LPARAM(lParam);
Wieder auslesen!

Was willst Du eigentlich machen? Willst Du nur die Farbe unter der aktuellen Mausposition ermitteln? Wenn ja, dann würde es eventuell auch eine andere Möglichkeit geben!
 
Zuletzt bearbeitet:
Dank deiner Hilfe klappt es jetzt, die richtigen Punktkoordinaten kommen in meiner Anwendung an.
Ja du hast ich will die Farbe auslesen, wenn man in der Anwendung auf einen Button klickt sollte so eine Art Pipette als Coursor erscheinen und beim Click auf irgend ein Fenster (z.B. im IE) soll die Farbe in meiner Anwendung zur Verfügung stehen.
Wenn du da ne Andere Möglichkeit hast, bin ich dafür gern offen.

Danke nochmal
Gruss Homer
 
Mein Vorschlag ist dieser! Funktiniert ungefährt so wie der SPY++ bei Visual C++ wenn Du ein Fenster suchst (musst Du Dir mal anschauen)!

Du kannst auch die Maus mit SetCapture() "fangen" so dass die Mauskoordinaten immer an Deine Anwendung geschickt werden!
Leider musst Du Dein Prinzip etwas kehren! Du musst immer die Maustaste gedrückt halten und dort wo Du sie loslässt ist Deine letzte Farbe!

- WM_LBUTTONDOWN Message dort SetCapture aufrufen, Mauszeiger auf Pipette setzten
- WM_MOUSEMOVE bekommt jetzt immer die Koordinaten (Umrechnen auf Desktop-Koordinaten)
- WM_LBUTTONUP Message dort ReleaseCapture aufrufen und Mauszeiger zurücksetzten

Eine etwas andere Bedienung aber Du brauchst keinen Hook!
 
Diese Möglichkeit ist mir vor dem Hook eingefallen. Nur da hab ich das Problem, wenn ich in ein anderes Fenster Klicke erhält das Fenster den Fokus und meine Anwendung verliert ihn. Dadurch kann ich nicht mehr auf Aktivitäten der Maus reagieren.
Oder verstehe ich da was Falsch?
Mir gefällt die Variation mit den Hooks ganz gut. Musste ich ja früher oder später auch mal lernen wie sowas geht. :) :)

Aber trotzdem Danke
Gruss Homer
 
Schau Dir mal den Spy++ in den Tools von Visual C++ an!

Du hälst die ganze Zeit die linke Maustaste und verfährst an die gewünschte Position! Du lässt erst mit Buttonup die Maus wieder "frei"
 
So ich hab das ding jetzt soweit mal fertig. Die Farbe wird an meine Anwendung ohne Probleme übermittelt.
Ich hab jedoch noch ein Problem.
Und zwar möchte ich einen eigenen Cursor, oder einen bestehenden einbinden. Nur dieser Cursor soll eine bestimmte Zeit Systemweit gelten. Ist das Möglich und wenn ja wie.
Ich hoffe da kann mir jemand helfen.

Gruss Homer
 

Neue Beiträge

Zurück