Tutorial
Lutz Ifers WinAPI Tutorial
von MOD | Seite 9 von 16 |
Kapitel 3.1: Tastatur
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: TranslateMessage, WM_CHAR, WM_KEYDOWN, WM_KEYUP
In der FreeBasic-Referenz: CASE, LEFT, LEN
Zusätzliche Informationen und Funktionen | |||||||
---|---|---|---|---|---|---|---|
|