Buchempfehlung
Mikrocomputertechnik mit Controllern der Atmel AVR-RISC-Familie
Mikrocomputertechnik mit Controllern der Atmel AVR-RISC-Familie
Umfassend, aber leicht verständlich führt dieses Buch in die Programmierung von ATMEL AVR Mikrocontrollern ein. [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 9 von 16

Kapitel 3.1: Tastatur
Kap3.1

In diesem Kapitel beschäftigen wir uns mit den Nachichten, die uns Windows schickt, wenn wir eine Taste auf der Tastatur drücken. Das Hauptprogramm ist dieses mal ein wenig anders, in der Nachrichtenschleife gibt es nun zusätzlich den Befehl "TranslateMessage @msg", dessen Bedeutung wir später genauer unter die Lupe nehmen werden. Desweiteren definieren wir ein globales Array namens "Key".

''' Lutz Ifers WinAPI-Tutorial
''' Lizenz: WTFPL
'''
''' Kapitel 3.1 - "Tastatur"

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

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

dim shared as byte Key(255)

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
    TranslateMessage @msg
loop
end msg.wParam

Die Nachrichten WM_KEYDOWN und WM_KEYUP schickt uns Windows immer dann, wenn eine Taste gedrückt bzw. losgelassen wurde. Wenn eine dieser Nachrichten eingetreten ist, setzen wir den Status dieser Taste im Array Key auf TRUE bzw. FALSE. Dadurch ließe sich dieses Array ähnlich der multikey-Funktion von FreeBasic verwenden. Einiziger Unterschied: Die Tastencodes beginnen nicht mit "SC" sondern mit "VK" für "Virtual Key", denn die Werte entsprechen nicht den Ascii-Werten der eingetippten Tasten, sondern den IDs der Tasten.

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

    static as STRING    sText

    select case message
        case WM_DESTROY
            PostQuitMessage 0
            return 0

        case WM_KEYDOWN
            Key(wParam) = TRUE
            InvalidateRect hWnd, NULL, TRUE
            return 0

        case WM_KEYUP
            Key(wParam) = FALSE
            InvalidateRect hWnd, NULL, TRUE
            return 0

Die WM_CHAR Nachricht gibt es eigentlich nicht. Windows schickt uns nur Nachrichten über Niederdrücken und loslassen der Tasten. Allerdings kommt hier der TranslateMessage-Aufruf der Nachrichtenschleife zum Tragen: Diese Funktion fügt nach jeder WM_KEYDOWN-Nachricht eine WM_CHAR-Nachricht ein, die dann als wParam den tatsächlichen ASCII-Wert des Zeichens enthält. Um das zu demonstrieren, sammeln wir mal alle gedrückten Tasten in einem String. Die nicht druckbaren Zeichen TAB(9), LINEFEED(10) und ESC(27) ignorieren wir, ENTER(13) soll den Text zurücksetzen, BACKSPACE(8) soll das letzte Zeichen löschen.

"InvalidateRect" weißt Windows an, das Fenster neuzuzeichnen. Auf diesen Befehl wird an anderer Stelle weiter eingegangen.

        case WM_CHAR
            select case wParam
                case  9, 10, 27
                case 13 :   sText = ""
                case  8 :   if len(sText) > 0 then
                                sText = left(sText, len(sText) - 1)
                            end if
                case else : sText += chr(wParam)
            end select
            InvalidateRect hWnd, NULL, TRUE
            return 0

In der WM_PAINT-Nachricht geben wir zwei Texte aus: Als erstes eine Liste der im Moment gedrückten Tasten, als zweites den eingetippten Text. Hierbei wird deutlich, dass der Keycode zum Beispiel der Taste "A" immer der Selbe ist, also unabhängig von anderen Tasten wie "CTRL", "ALT" oder "SHIFT". Erst in der WM_CHAR-Nachricht wird ein "richtiges" Zeichen daraus.

        case WM_PAINT
            dim as INTEGER      i
            dim as STRING       sTasten = "Gedrückte Tasten: "
            dim as PAINTSTRUCT  ps

            for i = 0 to 255
                if Key(i) = TRUE then sTasten += chr(i, 32)
            next

            dim as HDC hDC = BeginPaint(hWnd, @ps)
                TextOut hDC, 5,  5, sTasten, len(sTasten)
                TextOut hDC, 5, 26, sText, len(sText)
            EndPaint(hWnd, @ps)
            return 0
    end select

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

Links:

In der MSDN: Externer Link!TranslateMessage, Externer Link!WM_CHAR, Externer Link!WM_KEYDOWN, Externer Link!WM_KEYUP
In der FreeBasic-Referenz: BefehlsreferenzeintragCASE, BefehlsreferenzeintragLEFT, BefehlsreferenzeintragLEN

 

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