Die WinAPI Plattform

Tutorials

Tutorial Nummer 10

(10.) Bewegungen der Maus

In dem letzten Tutorial habe ich dir gezeigt, wie man auf das Drücken von Maustasten reagiert. In diesem Tutorial werden wir auf die Bewegung der Maus reagieren. Wir schreiben ein Programm, in dem man bei gedrückter Maustaste ein Rechteck zeichnet. Und solange die Maustaste noch gedrückt ist, ändert sich bei Bewegung der Maus auch entsprechend das Rechteck. Man zieht also das Rechteck in die gewünschte Form.

#include <windows.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   PSTR szCmdLine, int iCmdShow)
{
   MSG         msg;
   HWND        hWnd;
   WNDCLASS    wc;
   char        szAppName[] = "Beweungen der Maus";
   
   wc.cbClsExtra         = 0;
   wc.cbWndExtra         = 0;
   wc.hbrBackground      = (HBRUSH)GetStockObject(WHITE_BRUSH);
   wc.hCursor            = LoadCursor(NULL, IDC_ARROW);
   wc.hIcon              = LoadIcon(NULL, IDI_APPLICATION);
   wc.hInstance          = hInstance;
   wc.lpfnWndProc        = WndProc;
   wc.lpszClassName      = szAppName;
   wc.lpszMenuName       = NULL;
   wc.style              = CS_VREDRAW | CS_HREDRAW;
   
   RegisterClass(&wc);
   
   hWnd = CreateWindow(  szAppName,
                         szAppName,
                         WS_OVERLAPPEDWINDOW,
                         CW_USEDEFAULT,
                         CW_USEDEFAULT,
                         CW_USEDEFAULT,
                         CW_USEDEFAULT,
                         NULL,
                         NULL,
                         hInstance,
                         NULL);
                         
   ShowWindow(hWnd, iCmdShow);
   UpdateWindow(hWnd);
   
   while (GetMessage(&msg, NULL, 0, 0))
   {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
   }
   
   return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

Diesmal brauchen wir zwei POINT Strukturen. Eine für den Startpunkt, also wo die Maustaste gedrückt wurde, und die andere für den Endpunkt des Rechtecks, also meistens die aktuelle Cursorposition. In der WM_CREATE Nachricht belegen wir die Strukturen mit -1 vor. Dies hat den Effekt, dass das Rechteck außerhalb des Anwendungsbereiches gezeichnet werden müsste, aber da Windows dies nicht zuläßt, wird nichts gezeichnet (Clipping).

   static POINT start;
   static POINT ende;
   
   switch (message)
   {
   case WM_CREATE:
      {
         start.x = -1;
         start.y = -1;
         ende.x  = -1;
         ende.y  = -1;
         return 0;
      }

In der WM_LBUTTONDOWN Nachricht speichern wir die Koordinaten als Startpunkt.

   case WM_LBUTTONDOWN:
      {
         start.x = LOWORD(lParam);
         start.y = HIWORD(lParam);
         return 0;
      }

Die WM_MOUSEMOVE Nachricht wird immer dann zum Programm geschickt, wenn isch der Mauszeiger auf dem Anwendungsbereich des Fensters bewegt.

   case WM_MOUSEMOVE:
      {

Im wParam der Nachricht WM_MOUSEMOVE ist der Maustasten Status gespeichert, also ob eine Maustaste gedrückt ist oder nicht. Wir prüfen mit einer und-Verknüpfung, ob linke Maustaste gedrückt ist (Analog funktioniert das auch mit MK_RBUTTON, das MK steht für Maus Key). Wenn dem so war, dann soll unser Rechteck neugezeichnet werden (da es entweder vergrößert oder verkleinert worden ist). Dazu speichern wir die neuen Koordinaten, die in lParam mit übergeben wurden, und beauftragen Windows uns eine WM_PAINT Nachricht zu schicken.

         if (wParam & MK_LBUTTON)
         {
            ende.x = LOWORD(lParam);
            ende.y = HIWORD(lParam);
            InvalidateRect(hWnd, NULL, TRUE);
         }
         return 0;
      }

In der WM_PAINT Nachricht zeichnen wir ganz gewöhnlich das Rechteck mit der Rectangle Funktion. Als Parameter übergeben wir den Gerätekontext und die Start- und Endkoordinaten.

   case WM_PAINT:
      {
         PAINTSTRUCT    ps;
         HDC            hDC;
         
         hDC = BeginPaint(hWnd, &ps);
         {
            Rectangle(hDC, start.x, start.y, ende.x, ende.y);
         }
         EndPaint(hWnd, &ps);
         return 0;
      }
   case WM_DESTROY:
      {
         PostQuitMessage(0);
         return 0;
      }
   }
   
   return DefWindowProc(hWnd, message, wParam, lParam);
}

In diesem Tutorial hast du gelernt auch auf die Bewegung der Maus zu regieren. Wenn du meinst, dass irgend eine Stelle in diesem Tutorial ungenau ist, oder etwas nicht erklärt wird, dann schreibe mir einfach eine E-Mail.

webmaster@win-api.de