AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) C++ Warum wird Fensterinhalt nicht neu gezeichnet?

Warum wird Fensterinhalt nicht neu gezeichnet?

Ein Thema von delphifan2004 · begonnen am 6. Jul 2020 · letzter Beitrag vom 6. Jul 2020
Antwort Antwort
delphifan2004

Registriert seit: 26. Nov 2004
Ort: Dresden
170 Beiträge
 
Delphi 7 Personal
 
#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
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
7.751 Beiträge
 
Delphi XE4 Professional
 
#2

AW: Warum wird Fensterinhalt nicht neu gezeichnet?

  Alt 6. Jul 2020, 21:42
Hallo,
ein Masochist

Du musst WM_RESIZE mit reinbringen in deine WindowProcedure.
Es müsste ein UpdateWindow(hwnd) schon reichen oder ein InvalidateRect,
um das WM_PAINT "aufzurufen" und damit das Neuzeichnen anzuwerfen.

https://docs.microsoft.com/en-us/win...r-updatewindow

https://docs.microsoft.com/en-us/win...he-client-area
Heiko

Geändert von hoika ( 6. Jul 2020 um 21:45 Uhr)
  Mit Zitat antworten Zitat
TurboMagic

Registriert seit: 28. Feb 2016
Ort: Nordost Baden-Württemberg
845 Beiträge
 
Delphi 10.3 Rio
 
#3

AW: Warum wird Fensterinhalt nicht neu gezeichnet?

  Alt 6. Jul 2020, 21:47
I glaube es liegt daran, dass du den Code in der Window Proc auskommentiert hast.
Wenn du was auf den Canvas einer Form zeichnest oder ähnliches, dann weiß Windows
nicht was du da mal gezeichnet hattest.

Wenn es verdeckt war und dann wieder aufgedeckt wurde, dann musst du es neu zeichnen.
Windows schickt daher eine wm_paint Nachricht an das Fenster, welches sich neu zeichnen
soll.

Das wird in dem Buch (besitze das auch) aber auch irgendwo erklärt.
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:13 Uhr.
Powered by vBulletin® Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2020 by Daniel R. Wolf