Buchempfehlung
Windows System Programming
Windows System Programming
Das Kompendium liefert viele interessante Informationen zur Windows-Programmierung auf Englisch. [Mehr Infos...]
FreeBASIC-Chat
Es sind Benutzer im FreeBASIC-Chat online.
(Stand:  )
FreeBASIC bei Twitter
Twitter FreeBASIC-Nachrichten jetzt auch über Twitter erhalten. Follow us!

Tutorial

Lutz Ifers WinAPI Tutorial

von RedakteurMODSeite 10 von 16

Kapitel 3.2: Maus
Kap3.2

Nachdem wir nun wissen, wie wir kontrollieren können, ob der Benutzer eine Taste gedrückt hat, fehlen uns noch die Methoden, um in Erfahrung zu bringen, ob die Maus bewegt wurde, bzw. in unser Fenster geklickt wurde.

''' Lutz Ifers WinAPI-Tutorial
''' Lizenz: WTFPL
'''
''' Kapitel 3.2 - "Maus"

#include "windows.bi"
const ProgrammName = "Maus"

declare function Fenster(byval hWnd as HWND, byval message as UINTEGER,_
    byval wParam as WPARAM, byval lParam as LPARAM) as LRESULT

dim as WNDCLASS wcMeinFenster
with wcMeinFenster
    .style         =  CS_HREDRAW or CS_VREDRAW
    .lpfnWndProc   =  ProcPtr(Fenster)
    .cbClsExtra    =  0
    .cbWndExtra    =  0
    .hInstance     =  GetModuleHandle(NULL)
    .hCursor       =  LoadCursor(NULL, IDC_ARROW)
    .hIcon         =  LoadIcon(NULL, IDI_APPLICATION)
    .hbrBackground =  GetStockObject(WHITE_BRUSH)
    .lpszClassName =  StrPtr(ProgrammName)
    .lpszMenuName  =  NULL
end with
RegisterClass @wcMeinFenster

dim as HWND hMeinFenster = CreateWindow(_
    ProgrammName, "Titelzeile", WS_OVERLAPPEDWINDOW,_
    CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,_
    NULL, NULL, GetModuleHandle(NULL), NULL)

ShowWindow   hMeinFenster, SW_NORMAL
UpdateWindow hMeinFenster

dim as MSG msg
do while getmessage(@msg, NULL, 0, 0) <> 0
    DispatchMessage  @msg
loop
end msg.wParam

In der Callback-Funktion verwenden wir erstmals ein UDT namens POINT. Da dies auch ein Schlüsselwort von FreeBasic ist, gibt es häufiger Probleme, wenn die FreeBasic-Funktion point() verwendet wird und die windows.bi-Headerdatei eingebunden ist. Dies soll uns aber nicht weiter stören, da wir point() sowieso nicht auf Windows-Fenstern benutzen können.

Die Variable für den Device Context definieren wir ausnahmsweise nicht erst im WM_PAINT-Zweig der select case-Anweisung, sondern davor, damit wir die gleiche Variable in einem anderen Zweig verwenden können. Natürlich könnte man auch einfach zwei Variablen nehmen, oder eine C-ähnliche Umgebung mit scope ... end scope erzeugen - aber warum umständlicher als unbedingt notwendig.

function Fenster(byval hWnd as HWND, byval message as UINTEGER,_
    byval wParam as WPARAM, byval lParam as LPARAM) as LRESULT

    static as POINT ptStart, ptEnde
    dim    as HDC   hDC

    select case message
        case WM_DESTROY
            PostQuitMessage 0
            return 0

        case WM_LBUTTONDOWN
            ptStart.x = LOWORD(lParam)
            ptStart.y = HIWORD(lParam)
            hDC = GetDC(hWnd)
                Ellipse hDC, ptStart.x - 5, ptStart.y - 5,_
                    ptStart.x + 5, ptStart.y + 5

            ReleaseDC hWnd, hDC
            return 0

        case WM_LBUTTONUP
            ptEnde.x = LOWORD(lParam)
            ptEnde.y = HIWORD(lParam)
            hDC = GetDC(hWnd)
                Ellipse hDC, ptEnde.x - 5, ptEnde.y - 5,_
                    ptEnde.x + 5, ptEnde.y + 5

            ReleaseDC hWnd, hDC
            return 0

Die Nachrichten WM_LBUTTONDOWN und WM_LBUTTONUP werden uns von Windows geschickt, wenn die linke Maustaste gedrückt bzw. losgelassen wird. Für die rechte Maustaste gelten die Nachrichten WM_RMOUSEBUTTONUP/DOWN. Sowohl die Nachrichten für Tastedrücke, als auch die Nachricht für Mausbewegungen enthalten Informationen über Zustand der Tasten als auch Position der Maus. Um den Unterschied der zwischen beiden Nachrichten besteht zu verdeutlichen, wird beim Klicken und Loslassen (allerdings nicht beim Gedrückthalten) der Maustaste ein Kreis um den Cursor gezeichnet.

        case WM_MOUSEMOVE
            if (wParam and MK_LBUTTON) <> 0 then
                ptEnde.x = LOWORD(lParam)
                ptEnde.y = HIWORD(lParam)
                InvalidateRect hWnd, NULL, TRUE
            end if
            return 0

        case WM_PAINT
            dim as PAINTSTRUCT  ps
            dim as STRING sText = "Maus: "+str(ptEnde.x)+", "+str(ptEnde.y)
            hDC = BeginPaint(hWnd, @ps)
                TextOut hDC, 0, 0, sText, len(sText)
                MoveToEx hDC, ptStart.x, ptStart.y, NULL
                LineTo hDC, ptEnde.x, ptEnde.y
            EndPaint(hWnd, @ps)
            return 0
    end select

    return DefWindowProc( hWnd, message, wParam, lParam )
end function

Bei einer Bewegung der Maus wird der Zweite Punkt (also der Endpunkt der Linie) aktualisiert, und bei WM_PAINT-Nachrichten wird diese Linie neugezeichnet.

Links:

In der MSDN: Externer Link!WM_LBUTTONDOWN, Externer Link!WM_LBUTTONUP, Externer Link!WM_LBUTTONDBLCLK, Externer Link!WM_MOUSEMOVE, Externer Link!GetDC
In der FreeBasic-Referenz: BefehlsreferenzeintragPOINT

 

Gehe zu Seite Gehe zu Seite  1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  
Zusätzliche Informationen und Funktionen
  • Das Tutorial wurde am 17.09.2009 von RedakteurMOD angelegt.
  • Die aktuellste Version wurde am 17.07.2013 von AdministratorSebastian gespeichert.
  Bearbeiten Bearbeiten  

  Versionen Versionen