http://www.pronix.de -> Tutorials -> Win32-Programmierung -> 6. GDI, Textausgabe und Malen und Zeichnen -> 6.3 Text ausgeben

6.3 Text ausgeben

Um Ihnen das Thema ein wenig schmackhafter zu machen, folgt hier ein einfaches Listing, womit ein einfacher Text in einem neu erstellten Fenster ge"schrieben" wird (richtig wäre wohl gezeichnet).

Ausgabe eines Textes mit GDI
Ausgabe eines Textes mit GDI

Hierzu das WIN32-Listing:

#include <windows.h>
#include <string.h>

LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg,
                          WPARAM wParam, LPARAM lParam );

LPCSTR MainClassName = "Device Context";

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   PSTR szCmdLine, int iCmdShow)
{
    WNDCLASSEX wc;
    HWND hWnd;
    MSG wmsg;

    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = 0;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = LoadIcon(GetModuleHandle(NULL), IDI_APPLICATION);
    wc.hCursor       = LoadCursor(NULL, IDC_CROSS);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName  = MainClassName;
    wc.lpszClassName = MainClassName;
    wc.hIconSm       = LoadIcon(GetModuleHandle(NULL), IDI_APPLICATION);

    if(!RegisterClassEx(&wc))
    {
        MessageBox(NULL, "Windows Registrations Fehler", "Error!",
                   MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    hWnd = CreateWindowEx(WS_EX_CLIENTEDGE, MainClassName,
                          "Gerätekontext Beispiel",
                          WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          300, 200, NULL, NULL, hInstance, NULL);
                          
    if(hWnd == NULL)
    {
        if(MessageBox(NULL, "Fehler beim Erstellen des Fensters!",
                      "Error!", MB_ICONEXCLAMATION | MB_OK) == IDOK)
        return 0;
    }
    
    while(GetMessage(&wmsg, NULL, 0, 0))
    {
        TranslateMessage(&wmsg);
        DispatchMessage(&wmsg);
    }
    return wmsg.wParam;
}


LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg,
                          WPARAM wParam, LPARAM lParam )
{
    PAINTSTRUCT ps;
    HDC hDC;
    char szPuffer[] = "Ein Teststring";
    
    switch( uMsg )
    {
        case WM_PAINT :
            hDC = BeginPaint(hWnd, &ps);
            TextOut(hDC, 0, 0, szPuffer, sizeof(szPuffer)-1);
            EndPaint(hWnd, &ps);
            return 0;
        case WM_DESTROY :
            PostQuitMessage(0);
            break;
        default :
            return( DefWindowProc( hWnd, uMsg, wParam, lParam ));
    }
    return( 0L );
}

Außer der Nachrichtenbehandlung von WM_PAINT enthält dieses Listing nichts Neues. Daher soll auch gleich damit begonnen werden.

    PAINTSTRUCT ps;
    HDC hDC;
    char szPuffer[] = "Ein Teststring";
    
    switch( uMsg )
    {
        case WM_PAINT :
            hDC = BeginPaint(hWnd, &ps);
            TextOut(hDC, 0, 0, szPuffer, sizeof(szPuffer)-1);
            EndPaint(hWnd, &ps);
            return 0;

Mit der Funktion BeginPaint() initialisieren Sie den Zeichenprozess im Fenster. Dabei wird ein Speicher für den Gerätekontext angefordert und zurückgegeben. Der erste Parameter der Funktion ist der Handle des zu zeichnenden Fensters. Der zweite Parameter ist ein Zeiger auf die Windows-Struktur PAINTSTRUCT. In dieser Struktur befinden sich Informationen über den Aktualisierungsbereich des Fensters hWnd.

War die Funktion erfolgreich, wird der Handle (HDC) des Gerätekontextes zurückgegeben, der zum Zeichnen des Fensters verwendet werden soll.

In der nächsten Zeile können Sie nun mit der Funktion TextOut() einen String in den allozierten Gerätekontext schreiben. Der erste Parameter ist dabei der Gerätekontext selbst. Mit dem zweiten und dritten Parameter geben Sie die logische x bzw. y Position des Referenzpunktes für die Ausrichtung des Strings an. Der vierte Parameter ist der auszugebende String selbst und der letzte Parameter beinhaltet die Anzahl der Zeichen des Strings.

Haben Sie die gewünschten Zeichenfunktionen aufgerufen, müssen Sie am Ende das Ende des Malvorgangs mit der Funktion EndPaint() angeben. Die Parameter sind dabei dieselben, wie bei BeginPaint(). Die Funktionen BeginPaint() und EndPaint() werden in der Regel nur in Verbindung mit der WM_PAINT-Nachricht verwendet.

Wollen Sie bspw. den String anstatt im Fenster auf den Windows-Desktop schreiben, können Sie die Behandlung von WM_PAINT ein wenig verändern:

        case WM_PAINT :
            hDC = GetDC(NULL);
            BeginPaint(NULL, &ps);
            TextOut(hDC, 0, 0, szPuffer, sizeof(szPuffer)-1);
            EndPaint(hWnd, &ps);
            return 0;

Und schon wird links oben auf dem Desktop der String ausgegeben. Wollen Sie auch noch die Textfarbe verändern, können Sie sich die Funktion SetTextColor() in der MSDN-Dokumention ansehen.