Einzelnen Beitrag anzeigen

delphifan2004

Registriert seit: 26. Nov 2004
Ort: Dresden
266 Beiträge
 
Delphi 10.3 Rio
 
#1

Warum wird Fensterinhalt nicht neu gezeichnet?

  Alt 6. Jul 2020, 21:25
Hallo,

ich beschäftige mich gerade etwas mit C++, zu Delphi gibt es ja neben dem Pascal Compiler auch den C++ Compiler und da habe ich aus dem Buch "Programming Windows" fifth Edition von Charles Petzold das folgende Programm von Seite 44 abgetippt:

Delphi-Quellcode:
#include <windows.h>
#include <winuser.h>
#include <stdarg.h>
#include <tchar.h>
#include <stdio.h>

int cxscreen, cyscreen;

int CDECL MessageBoxPrintf(TCHAR *szCaption, TCHAR *szFormat, ...);

/* Declare Windows procedure */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

/* Make the class name into a global variable */
char szClassName[ ] = "WindowsApp";

int WINAPI WinMain (HINSTANCE hThisInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpszArgument,
                    int nFunsterStil)

{
    HWND hwnd;              /* This is the handle for our window */
    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */

    /* The Window structure */
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    wincl.style = CS_DBLCLKS;                /* Catch double-clicks */
    wincl.cbSize = sizeof (WNDCLASSEX);

    /* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;                /* No menu */
    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
    wincl.cbWndExtra = 0;                      /* structure or the window instance */
    /* Use Windows's default color as the background of the window */
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

    /* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl))
        return 0;

    /* The class is registered, let's create the program*/
    hwnd = CreateWindowEx (
          0,                  /* Extended possibilites for variation */
          szClassName,        /* Classname */
          "Windows App",      /* Title Text */
          WS_OVERLAPPEDWINDOW, /* default window */
          CW_USEDEFAULT,      /* Windows decides the position */
          CW_USEDEFAULT,      /* where the window ends up on the screen */
          544,                /* The programs width */
          375,                /* and height in pixels */
          HWND_DESKTOP,        /* The window is a child-window to desktop */
          NULL,                /* No menu */
          hThisInstance,      /* Program Instance handler */
          NULL                /* No Window Creation data */
          );

    /* Make the window visible on the screen */
    ShowWindow (hwnd, nFunsterStil);

    /* Run the message loop. It will run until GetMessage() returns 0 */
    while (GetMessage (&messages, NULL, 0, 0))
    {
        /* Translate virtual-key messages into character messages */
        TranslateMessage(&messages);
        /* Send message to WindowProcedure */
        DispatchMessage(&messages);
    }


    /* The program return-value is 0 - The value that PostQuitMessage() gave */
    return messages.wParam;
}


/* This function is called by the Windows function DispatchMessage() */

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  HDC        hdc;
  PAINTSTRUCT ps;
  RECT        rect;

    switch (message)                  /* handle the messages */
    {
        case WM_PAINT:
            /*
            cxscreen = GetSystemMetrics(SM_CXSCREEN);
            cyscreen = GetSystemMetrics(SM_CYSCREEN);
            MessageBoxPrintf(TEXT("Scrnsize"),
                            TEXT("The screen is %1 pixels wide by %2 pixels height!"),
                            cxscreen,cyscreen);
                            */
            //InValidateRect(hwnd, NULL, TRUE);
            RedrawWindow(hwnd, NULL, NULL, RDW_INTERNALPAINT);

            hdc = BeginPaint(hwnd, &ps);

            GetClientRect(hwnd, &rect);

            //RedrawWindow(hwnd,NULL,NULL,RDW_INTERNALPAINT);
            DrawText(hdc, TEXT("Hello Windows!"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);

            EndPaint(hwnd,&ps);

            break;

        case WM_DESTROY:
            PostQuitMessage (0);      /* send a WM_QUIT to the message queue */
            break;
        default:                      /* for messages that we don't deal with */
            return DefWindowProc (hwnd, message, wParam, lParam);
    }


    return 0;
}

int CDECL MessageBoxPrintf(TCHAR *szCaption, TCHAR *szFormat, ...)
{
    TCHAR szBuffer[1024];
    va_list pArgList;

    // The va_start macro, defined in stdarg.h is usually equivalent to:
    // pArgList = (char *) &szFormat + sizeof(szFormat)

    va_start(pArgList, szFormat);

    // the last argument to _vsnprintf points to the arguments
        _vsntprintf( szBuffer, sizeof(szBuffer)/sizeof(TCHAR),szFormat,pArgList);

    // the va_end macro just zeroes out pArglist for no good reason

    va_end(pArgList);

    return MessageBox(NULL, szBuffer, szCaption, 0);
}
Wenn ich nun das Fenster derart verkleinere, dass der Text "Hello Windows" nicht mehr zu sehen ist und anschließend das Fenster wieder auf seine ursprüngliche Ausdehnung vergrößere, wird der Text nicht neu gezeichnet, der Hintergrund bleibt leer. Ich will aber den Text neu zeichnen lassen. Wenn ich das Fenster in der Breite ändere, wird der Text auch nicht neu zentriert, obwohl ich in der DrawText Funktion die Flags DT_CENTER | DT_VCENTER gesetzt habe.

Wie erreiche ich das korrekte Neuzeichnen des Textes im Fenster bei Breiten und Größenänderung?
  Mit Zitat antworten Zitat