Die WinAPI Plattform

Tutorials

(10.) Bewegungen der Mouse

In dem letzten Tutorial habe ich dir gezeigt, wie man auf das Drücken von Mousetasten reagiert. In diesem Tutorial werden wir auf die Bewegung der Mouse reagieren. Wir schreiben ein Programm, in dem man bei gedrückter Mousetaste ein Rechteck zeichnet. Und solange die Mousetaste noch gedrückt ist, ändert sich bei Bewegung der Mouse 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 Mouse";
   
   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 Mousetaste 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 Mousezeiger auf dem Anwendungsbereich des Fensters bewegt.

   case WM_MOUSEMOVE:
      {

Im wParam der Nachricht WM_MOUSEMOVE ist der Mousetasten Status gespeichert, also ob eine Mousetaste gedrückt ist oder nicht. Wir prüfen mit einer und-Verknüpfung, ob linke Mousetaste gedrückt ist (Analog funktioniert das auch mit MK_RBUTTON, das MK steht für Mouse 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 Mouse 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