Mausnachrichten

Einführung

Um in einem Programm eine Interaktion mit dem Benutzer realisieren zu können, dann ist wohl die Einbindung der Maus unumgänglich. Ihre Implementierung stützt sich ausschließlich auf das Nachrichtenkonzept. So werden folgende Standardnachrichten an das Programm gesandt:

Umgang mit Mausnachrichten:

Mausnachricht verursachendes Ereignis
WM_MOUSEMOVE - Maus wird bewegt
WM_LBUTTONDOWN - Linke Maustaste wird gedrückt
WM_LBUTTONUP - Linke Maustaste wird losgelassen
WM_RBUTTONDOWN - Rechte Maustaste wird gedrückt
WM_RBUTTONUP - Rechte Maustaste wird losgelassen
WM_MBUTTONDOWN - Mittlere Maustaste wird gedrückt
WM_MBUTTONUP - Mittlere Maustaste wird losgelassen

Wie bereits erwähnt, werden gleichzeitig auch zwei 32-Bit-Parameter ('lParam' und 'wParam') mitgesandt, welche bei allen sieben Nachrichten die gleiche Bedeutung haben. Zum einen sollte bei der Behandlung der Nachrichten bekannt sein, wo sich die Maus gegenwärtig befindet. Außerdem wird übermittelt, welche zusätzlichen Tasten ("Strg", "Shift" und Maustasten) gedrückt worden sind. Um al diese Informationen auf zwei Parameter verteilen zu können, spaltet man einen der Parameter ('lParam') in zwei 16-Bit-Werte auf, die jeweils die X- und die Y-Koordinate enthält. Zu diesem Zweck bietet Windows die Makros 'LOWORD' und 'HIWORD' an. Die jeweiligen Koordinaten können dann wie folgt ermittelt werden:

signed int xPos = LOWORD(lParam);	//X-Koordinate
signed int yPos = HIWORD(lParam);	//Y-Koordinate

Die Koordinaten sind relativ zum Fensterursprung (linke obere Ecke), d.h. wenn sie negativ sind, befinden sie sich außerhalb des Fensters. Wenn man dies nicht anders erwünscht, befinden sich die Koordinaten immer innerhalb des Fensters, welches die Nachricht behandelt.

Der Parameter 'wParam' besteht aus einer Kombination von Konstanten, die jeweils angeben ob eine weitere Taste gedrückt ist oder nicht. Dazu sind folgende Konstanten definiert:

Konstante gedrückte Taste Wert
MK_CONTROL - "Strg"-Taste 0x0008
MK_LBUTTON - Linke Maustaste 0x0001
MK_MBUTTON - Mittlere Maustaste 0x0010
MK_RBUTTON - Rechte Maustaste 0x0002
MK_SHIFT - "Shift"-Taste 0x0004

Bei jede der Konstanten ist ein Bit gesetzt, d.h. jedes Bit (bzw. die ersten fünf) beschreibt den Status einer Taste. Sind n Tasten gedrückt, so sind auch n von fünf Bits gesetzt. hat Ist Beispielsweise die linke und die rechte Maustaste gedrückt so wäre der Wert von 'wParam' wie folgt:

wParam = MK_LBUTTON | MK_RBUTTON;

Es ist jedoch unmöglich den Parameter auf jede mögliche Kombination von gesetzten Bits zu überprüfen. Außerdem ist es eventuell wünschenswert zu ermitteln, ob eine Taste überhaupt gedrückt ist, egal ob weitere Tasten gleichzeitig gedrückt werden oder nicht. Soll überprüft werden, ob die linke Maustaste gedrückt ist, dann wäre folgende Anweisung weniger sinnvoll:

if (wParam == MK_LBUTTON) 
{
	/* --- Behandlung ---
	...
	*/
}

Die Bedingung wäre nämlich überhaupt nur dann erfüllt, wenn nur die linke Maustaste gedrückt wird. Um zu überprüfen ob alleine das Bit gesetzt ist oder nicht, welches den Status ser gewünschten Taste angibt setzt man einfach alle anderen auf 0. Dies erreicht man mit folgender Anweisung:

WPARAM Param = wParam & MK_LBUTTON;	//Alle Bits außer das der linken Taste werden auf 0 gesetzt

Nun ist es ein leichtes den Status abzufragen. Man brauch nur überprüfen ob der modifizierte Parameter der Konstanten der gewünschten Taste entspricht. Ist dies der Fall, dann ist die Taste gedrückt, im anderen Fall ist dieser Parameter dann 0, weil alle Bits auf 0 gesetzt sind und die Taste ist nicht gedrückt. Die logischste Realisierung wäre:

if ((wParam & MK_LBUTTON) == MK_LBUTTON) 
{
	/* --- Behandlung ---
	...
	*/
}

Es reicht allerdings aus zu überprüfen, ob der modifizierte Parameter ungleich 0 ist:

if (wParam & MK_LBUTTON)		//entspricht if ((wParam & MK_LBUTTON) != 0)
{
	/* --- Behandlung ---
	...
	*/
}

Soweit zu den Parametern. Nun sollen die Nachrichten in die Fensterprozedur eingebunden werden.

Die Nachrichten in der Fensterprozedur

Greifen wir noch einmal auf den Rahmencode der Fensterprozedur zurück und erweitern diesen, um die bisher bekannten Nachrichten, wobei wir uns zunächst auf die Nachrichten, welche mit der linken Maustaste einher gehen, konzentrieren:

//Implementierung der Fensterprozedur
LRESULT CALLBACK WndProc(HWND hWnd, UINT uiMessage, WPARAM wParam, LPARAM lParam)
{
	//Variablen für WM_PAINT-Zweig
	PAINTSTRUCT ps;
	RECT rc;

	//Grafikobjekte
	HDC hDC;					//Gerätekontext
	
	//Variablen für Mausnachrichten
	static bool bLButtonDown = false;
	static signed int X1, X2, Y1, Y2;

	switch (uiMessage)
	{
	case WM_PAINT:
		//Koordinaten des Anwendungsbereiches ermitteln
		GetClientRect(hWnd, &rc);

		//Zeichenvorgang beginnen
		HDC hDC = BeginPaint(hWnd, &ps);
		
		/* --- Zeichenoperationen ---
		...
		*/
		
		//Zeichenvorgang beenden
		EndPaint(hWnd, &ps);
		
		return 0;
	case WM_CLOSE:
		DestroyWindow(hWnd);
		return 0;
	case WM_LBUTTONDOWN:
		//Koordinaten für den ersten Punkt ermitteln (zweiten Punkt initialisieren)
		X1 = X2 = LOWORD(lParam);
		Y1 = Y2 = HIWORD(lParam);
		
		//linke Maustaste gedrückt
		bLButtonDown = true;
		
		return 0;
	case WM_LBUTTONUP:
		//Koordinaten für den zweiten Punkt ermitteln
		X2 = LOWORD(lParam);
		Y2 = HIWORD(lParam);
		
		//linke Maustaste nicht mehr gedrückt
		bLButtonDown = false;
		
		return 0;

	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	default:
		break;
	}
	return DefWindowProc(hWnd, uiMessage, wParam, lParam);
}

Hier wird beim Drücken der linken Maustaste die Position des Mauszeigers in den Variablen 'X1' und 'Y1'  festgehalten. Außerdem wird der Status der linken Maustaste in der Variablen 'bLButtonDown' gespeichert. Die Variablen müssen statisch sein, da sie nach der Behandlung der Nachricht 'WM_LBUTTONDOWN' noch in der Funktion erhalten bleiben sollen, um bei späteren Behandlungen z.B. bei der Behandlung der 'WM_LBUTTONUP'-Nachricht noch gültige Werte zu besitzen. Bei der Behandlung der letzteren Nachricht werden nämlich erneut die Koordinaten gespeichert. An dieser Stelle könnte man dann beispielsweise eine entsprechende Figur zeichnen.

Zusammenfassung

Hier sollte die Behandlung der Mausnachrichten deutlich geworden sein. Das beinhaltet unter anderem die Bestimmung der Mausposition und des Status der Aktions- und Maustasten.

In der nächsten Lektion

Die Behandlung der Mausnachrichten soll im nächsten Kapitel an einem Beispiel genauer erläutert werden. So sollen wie bereits angesprochen Figuren durch, das Drücken und Loslassen der linken Maustaste an der gewünschten Stelle auf dem Bildschirm erscheinen.

 

Zurück Nach oben Weiter