Tutorial
Lutz Ifers WinAPI Tutorial
von MOD | Seite 6 von 16 |
Kapitel 2.3: Textausgabe
In diesem Kapitel lernen wir zwei Methoden kennen, um Text auf unserem Fenster darzustellen. Dazu definieren wir als erstes mal einen längeren Text, um die verschieden Möglichkeiten, die sich uns bieten, zu demonstrieren.
''' Lutz Ifers WinAPI-Tutorial
''' Lizenz: WTFPL
'''
''' Kapitel 2.3 - "Textausgabe"
#include "windows.bi"
const ProgrammName = "Textausgabe"
const sText = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, "+_
"sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut en"+_
"im ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut al"+_
"iquip ex ea commodo consequat."+chr(13,10)+"Duis aute irure dolor in rep"+_
"rehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatu"+_
"r."+chr(13,10)+"Excepteur sint occaecat cupidatat non proident, sunt in "+_
"culpa qui officia deserunt mollit anim id est laborum."+chr(13,10,13,10)+_
"Lorem ipsum dolor sit amet, consectetur adipisicing elit, "+_
"sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut en"+_
"im ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut al"+_
"iquip ex ea commodo consequat."+chr(13,10)+"Duis aute irure dolor in rep"+_
"rehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatu"+_
"r."+chr(13,10)+"Excepteur sint occaecat cupidatat non proident, sunt in "+_
"culpa qui officia deserunt mollit anim id est laborum."
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
Die WM_SIZE Nachricht ist für uns neu. Sie wird immer dann an das Fenster geschickt, sobald sich die Größe des Fensters ändert. (Das Erstellen des Fensters gilt hier auch als Größenänderung.) Was ebenfalls neu ist, ist dass wir uns um lParam kümmern. Dieser Wert enthält codiert (namentlich: zwei SHORT-Werte in einem INTEGER) die Breite und Höhe des Fensters, die wir in ein UDT namens rect speichern. Dieses UDT besteht schlicht aus den vier INTEGER-Werten top, left, right und bottom.
function Fenster(byval hWnd as HWND, byval message as UINTEGER,_
byval wParam as WPARAM, byval lParam as LPARAM) as LRESULT
static as RECT rect
select case message
case WM_DESTROY
PostQuitMessage 0
return 0
case WM_SIZE
rect.right = LOWORD(lParam)
rect.bottom = HIWORD(lParam)
return 0
Die beiden Textausgabebefehle arbeiten pixelgenau. Um das zu demonstrieren, definieren wir einen Brush, mit dem wir den Bereich der Textausgabe einrahmen. Die Deklaration des ersten Befehls, den wir hier betrachten wollen lautet:
declare function TextOut(hDC as HDC, x as INTEGER, y as INTEGER, sText as STRING, lText as INTEGER) as BOOL
Theoretisch ist bei der Verwendung von Strings ja die Längenangabe überflüssig. Da die Funktion allerdings eigentlich mit zStrings arbeitet, war die Angabe der Länge notwendig. Als zweites betrachten wir die Funktion DrawText, die statt zwei INTEGERN eine RECT-Struktur für die Positionierung verwendet, und den Text innerhalb dieses Rechtecks formatieren kann. Dies geschieht wie üblich durch eine Kombination von Flags, die wir uns noch genauer ansehen werden. Die Deklaration der Funktion lautet:
declare function DrawText(hDC as HDC, sText as STRING, lText as INTEGER, pRect as RECT PTR, flags as BOOL) as INTEGER
Um einige Formatierungen zu demonstrieren, lassen wir die Überschrift zentriert (DT_CENTER), und den Text einmal so wie er ist, einmal ohne Zeilenumbrüche(DT_SINGLELINE) und einmal an ganzen Wörtern umgebrochen(DT_WORDBREAK) darstellen. Weitere Formatierungsmöglichkeiten finden sich in der MSDN.
case WM_PAINT
const sUeberschrift = "Überschrift"
dim as PAINTSTRUCT pnt
dim as RECT textrect
dim as HDC hDC = BeginPaint(hWnd, @pnt)
SelectObject hDC, GetStockObject(LTGRAY_BRUSH)
TextOut hDC, 10, 10, sUeberschrift, len(sUeberschrift)
with textrect
.top = 30
.left = 0
.right = rect.right
.bottom = 50
end with
Rectangle hDC, textrect.left, textrect.top, textrect.right, textrect.bottom
DrawText hDC, sUeberschrift, len(sUeberschrift), @textrect, DT_CENTER
with textrect
.top = 60
.left = 10
.right = rect.right - 10
.bottom = 120
end with
Rectangle hDC, textrect.left-1, textrect.top-1, textrect.right+1, textrect.bottom+1
DrawText hDC, sText, len(sText), @textrect, 0
with textrect
.top = 130
.left = 10
.right = rect.right - 10
.bottom = 170
end with
Rectangle hDC, textrect.left-1, textrect.top-1, textrect.right+1, textrect.bottom+1
DrawText hDC, sText, len(sText), @textrect, DT_SINGLELINE
with textrect
.top = 180
.left = 10
.right = rect.right - 10
.bottom = rect.bottom - 10
end with
Rectangle hDC, textrect.left-1, textrect.top-1, textrect.right+1, textrect.bottom+1
DrawText hDC, sText, len(sText), @textrect, DT_WORDBREAK
EndPaint(hWnd, @pnt)
return 0
end select
return DefWindowProc(hWnd, message, wParam, lParam)
end function
Links:
In der MSDN: RECT, WM_SIZE, TextOut, DrawText
In der FreeBasic-Referenz: HIWORD, LOWORD, CONST, STATIC
Zusätzliche Informationen und Funktionen | |||||||
---|---|---|---|---|---|---|---|
|