Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In den vorherigen Abschnitten wurden Mausklicks und Mausbewegungen erläutert. Hier sind einige andere Vorgänge, die mit der Maus ausgeführt werden können.
Ziehen von UI-Elementen
Wenn Ihre Benutzeroberfläche das Ziehen von UI-Elementen unterstützt, gibt es eine andere Funktion, die Sie im Maus-abwärts-Meldungshandler aufrufen sollten: DragDetect. Die DragDetect--Funktion gibt TRUE zurück, wenn der Benutzer eine Mausbewegung initiiert, die als Ziehen interpretiert werden soll. Der folgende Code zeigt, wie diese Funktion verwendet wird.
case WM_LBUTTONDOWN:
{
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
if (DragDetect(m_hwnd, pt))
{
// Start dragging.
}
}
return 0;
Dies ist die Idee: Wenn ein Programm Drag and Drop unterstützt, soll nicht jeder Mausklick als Ziehvorgang interpretiert werden. Andernfalls kann der Benutzer versehentlich etwas ziehen, wenn er einfach darauf klicken wollte (z. B. um es auszuwählen). Aber wenn eine Maus besonders empfindlich ist, kann es schwierig sein, die Maus beim Klicken perfekt zu halten. Daher definiert Windows einen Ziehschwellenwert von ein paar Pixeln. Wenn der Benutzer die Maustaste drückt, wird es nicht als Ziehen betrachtet, es sei denn, die Maus überschreitet diesen Schwellenwert. Die DragDetect-Funktion testet, ob dieser Schwellenwert erreicht ist. Wenn die Funktion TRUE-zurückgibt, können Sie den Mausklick als Ziehvorgang interpretieren. Andernfalls nicht.
Anmerkung
Wenn DragDetectFALSE-zurückgibt, unterdrückt Windows die WM_LBUTTONUP Meldung, wenn der Benutzer die Maustaste loslässt. Rufen Sie daher DragDetect nicht auf, es sei denn, Ihr Programm befindet sich derzeit in einem Modus, der das Ziehen unterstützt. (Wenn z. B. bereits ein ziehbares UI-Element ausgewählt ist.) Am Ende dieses Moduls sehen wir ein längeres Codebeispiel, das die DragDetect--Funktion verwendet.
Zuweisen des Cursors
Manchmal möchten Sie den Cursor möglicherweise auf den Clientbereich oder einen Teil des Clientbereichs beschränken. Die ClipCursor--Funktion schränkt die Bewegung des Cursors auf ein angegebenes Rechteck ein. Dieses Rechteck wird in Bildschirmkoordinaten anstelle von Clientkoordinaten angegeben, sodass der Punkt (0, 0) die obere linke Ecke des Bildschirms bedeutet. Um Clientkoordinaten in Bildschirmkoordinaten zu übersetzen, rufen Sie die Funktion ClientToScreen-auf.
Der folgende Code beschränkt den Cursor auf den Clientbereich des Fensters.
// Get the window client area.
RECT rc;
GetClientRect(m_hwnd, &rc);
// Convert the client area to screen coordinates.
POINT pt = { rc.left, rc.top };
POINT pt2 = { rc.right, rc.bottom };
ClientToScreen(m_hwnd, &pt);
ClientToScreen(m_hwnd, &pt2);
SetRect(&rc, pt.x, pt.y, pt2.x, pt2.y);
// Confine the cursor.
ClipCursor(&rc);
ClipCursor- übernimmt eine RECT- Struktur, aber ClientToScreen- nimmt eine POINT- Struktur. Ein Rechteck wird durch seine oberen linken und unteren rechten Punkte definiert. Sie können den Cursor auf einen beliebigen rechteckigen Bereich beschränken, einschließlich Bereiche außerhalb des Fensters, aber das Eingrenzen des Cursors an den Clientbereich ist eine typische Möglichkeit, die Funktion zu verwenden. Wenn Sie den Cursor vollständig außerhalb Des Fensters einverhängen, wäre das ungewöhnlich, und benutzer würden ihn wahrscheinlich als Fehler wahrnehmen.
Um die Einschränkung zu entfernen, rufen Sie ClipCursor- mit dem Wert NULL-auf.
ClipCursor(NULL);
Mausverfolgungsereignisse: Darauf zeigen und verlassen
Zwei andere Mausnachrichten sind standardmäßig deaktiviert, können jedoch für einige Anwendungen nützlich sein:
- WM_MOUSEHOVER: Der Cursor hat sich für einen festen Zeitraum über den Clientbereich bewegt.
- WM_MOUSELEAVE: Der Cursor hat den Clientbereich verlassen.
Rufen Sie zum Aktivieren dieser Nachrichten die TrackMouseEvent--Funktion auf.
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.hwndTrack = hwnd;
tme.dwFlags = TME_HOVER | TME_LEAVE;
tme.dwHoverTime = HOVER_DEFAULT;
TrackMouseEvent(&tme);
Die TRACKMOUSEEVENT Struktur enthält die Parameter für die Funktion. Das dwFlags Element der Struktur enthält Bitkennzeichnungen, die angeben, welche Nachverfolgungsnachrichten Sie interessieren. Sie können sowohl WM_MOUSEHOVER als auch WM_MOUSELEAVEabrufen, wie hier gezeigt, oder nur eine der beiden. Der dwHoverTime Member gibt an, wie lange die Maus darauf zeigen muss, bevor das System eine Hovermeldung generiert. Dieser Wert wird in Millisekunden angegeben. Die Konstante HOVER_DEFAULT bedeutet, den Systemstandard zu verwenden.
Nachdem Sie eine der angeforderten Nachrichten erhalten haben, wird die TrackMouseEvent-Funktion zurückgesetzt. Sie müssen es erneut aufrufen, um eine weitere Nachverfolgungsnachricht zu erhalten. Sie sollten jedoch warten, bis die nächste Mausbewegungsnachricht ausgeführt wird, bevor Sie TrackMouseEvent- erneut aufrufen. Andernfalls wird Ihr Fenster möglicherweise mit Tracking-Nachrichten überflutet. Wenn z. B. die Maus darauf zeigt, generiert das System weiterhin einen Datenstrom von WM_MOUSEHOVER Nachrichten, während die Maus stationiert ist. Sie möchten nicht, dass eine andere WM_MOUSEHOVER Nachricht angezeigt wird, bis die Maus wieder an eine andere Stelle wechselt und wieder bewegt wird.
Hier ist eine kleine Hilfsklasse, die Sie zum Verwalten von Mausverfolgungsereignissen verwenden können.
class MouseTrackEvents
{
bool m_bMouseTracking;
public:
MouseTrackEvents() : m_bMouseTracking(false)
{
}
void OnMouseMove(HWND hwnd)
{
if (!m_bMouseTracking)
{
// Enable mouse tracking.
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.hwndTrack = hwnd;
tme.dwFlags = TME_HOVER | TME_LEAVE;
tme.dwHoverTime = HOVER_DEFAULT;
TrackMouseEvent(&tme);
m_bMouseTracking = true;
}
}
void Reset(HWND hwnd)
{
m_bMouseTracking = false;
}
};
Das nächste Beispiel zeigt, wie Sie diese Klasse in Ihrer Fensterprozedur verwenden.
LRESULT MainWindow::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_MOUSEMOVE:
mouseTrack.OnMouseMove(m_hwnd); // Start tracking.
// TODO: Handle the mouse-move message.
return 0;
case WM_MOUSELEAVE:
// TODO: Handle the mouse-leave message.
mouseTrack.Reset(m_hwnd);
return 0;
case WM_MOUSEHOVER:
// TODO: Handle the mouse-hover message.
mouseTrack.Reset(m_hwnd);
return 0;
}
return DefWindowProc(m_hwnd, uMsg, wParam, lParam);
}
Mausverfolgungsereignisse erfordern eine zusätzliche Verarbeitung durch das System. Lassen Sie sie daher deaktiviert, wenn Sie sie nicht benötigen.
Zur Vollständigkeit ist hier eine Funktion, die das System für das Standardtimeout für den Hover abfragt.
UINT GetMouseHoverTime()
{
UINT msec;
if (SystemParametersInfo(SPI_GETMOUSEHOVERTIME, 0, &msec, 0))
{
return msec;
}
else
{
return 0;
}
}
Mausrad
Mit der folgenden Funktion wird überprüft, ob ein Mausrad vorhanden ist.
BOOL IsMouseWheelPresent()
{
return (GetSystemMetrics(SM_MOUSEWHEELPRESENT) != 0);
}
Wenn der Benutzer das Mausrad dreht, empfängt das Fenster mit Fokus eine WM_MOUSEWHEEL Nachricht. Der wParam--Parameter dieser Nachricht enthält einen ganzzahligen Wert namens Delta-, der misst, wie weit das Rad gedreht wurde. Das Delta verwendet beliebige Einheiten, wobei 120 Einheiten als Drehung definiert sind, die zum Ausführen einer "Aktion" erforderlich ist. Natürlich hängt die Definition einer Aktion von Ihrem Programm ab. Wenn beispielsweise das Mausrad zum Scrollen von Text verwendet wird, würde jede Drehung um 120 Einheiten eine Textzeile scrollen.For example, if the mouse wheel is used to scroll text, each 120 units of rotation would scroll one line of text.
Das Zeichen des Deltas gibt die Drehrichtung an:
- Positiv: Vorwärts drehen, vom Benutzer weg.
- Negativ: Drehen Sie rückwärts in Richtung des Benutzers.
Der Wert des Deltas wird zusammen mit einigen zusätzlichen Flags in wParam- platziert. Verwenden Sie das GET_WHEEL_DELTA_WPARAM Makro, um den Wert des Deltas abzurufen.
int delta = GET_WHEEL_DELTA_WPARAM(wParam);
Wenn das Mausrad eine hohe Auflösung aufweist, kann der Absolutewert des Deltas kleiner als 120 sein. In diesem Fall ist es sinnvoll, dass die Aktion in kleineren Schritten ausgeführt wird. Beispielsweise könnte Text in Schritten von weniger als einer Zeile scrollen. Andernfalls akkumieren Sie das Gesamtdelta, bis das Rad genug dreht, um die Aktion auszuführen. Speichern Sie das nicht verwendete Delta in einer Variablen, und wenn sich 120 Einheiten ansammeln (entweder positiv oder negativ), führen Sie die Aktion aus.
Nächster