Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Komisches Problem beim Neuzeichnen (https://www.delphipraxis.net/62512-komisches-problem-beim-neuzeichnen.html)

Rastaman 5. Feb 2006 19:33


Komisches Problem beim Neuzeichnen
 
Hallo.
Ich hab einfach n bischn rumgespielt und bin auf ne komische Sache gestoßen.
Folgendes soll einen Kreis zeichnen, dessen Radius man in einem Edit editieren kann.
Das Problem zu schildern wäre zu kompliziert, probierts einfach mal aus :?

Delphi-Quellcode:
program TestProg;

uses
  Messages,
  Windows;

const
  CLASSNAME                = 'WindowClass';
  STYLEFLAGS               = WS_SYSMENU;
  STYLEFLAGSEDIT           = ES_AUTOHSCROLL or WS_BORDER or WS_CHILD or WS_VISIBLE;
var
  WndClassInfo: TWndClass;
  Msg: TMsg;

  Mittelpunkt: TPoint = (
    X: 200;
    Y: 180);
  Radius: Integer = 5;

function CreateControls(Handle: HWND): Boolean;
var
  ControlArray: Array [0..1] of HWND;
begin
  Result := True;
  ControlArray[0] := CreateWindow('EDIT', '5', STYLEFLAGSEDIT,
    0, 0, 30, 20, Handle, 1, hInstance, nil);

  if not IsWindow(ControlArray[0]) then
    Result := False;
end;

function WndProc(hWnd: HWND; uMsg: UINT; wParam: WPARAM;
  lParam: LPARAM): LRESULT; stdcall;
var
  ps: TPaintStruct;
  WndDC: HDC;
  Brush, BrushOld: HBRUSH;

  Buffer: Array [0..2] of Char;
  Code: Integer;
begin
  case uMsg of
    WM_CLOSE:
      begin
        DestroyWindow(hWnd);
        PostQuitMessage(0);
        Result := 0;
      end;
    WM_COMMAND:
      begin
        if HiWord(wParam) = EN_CHANGE then
        begin
          SendMessage(GetDlgItem(hWnd, 1), WM_GETTEXT, 3, Integer(@Buffer));
          Val(Buffer, Radius, Code);
          SendMessage(hWnd, WM_PAINT, 0, 0);
          Result := 0;
        end;
      end;
    WM_CREATE:
      begin
        if not CreateControls(hWnd) then
          SendMessage(hWnd, WM_CLOSE, 0, 0);

        SendMessage(GetDlgItem(hWnd, 1), EM_LIMITTEXT, 2, 0);
        ShowWindow(hWnd, SW_SHOW);
        Result := 0;
      end;
    WM_PAINT:
      begin
        WndDC := BeginPaint(hWnd, ps);
        Brush := CreateSolidBrush($00C8D0D4);
        BrushOld := SelectObject(WndDC, Brush);
        RectAngle(WndDC, -1, -1, 401, 361);
        SelectObject(WndDC, BrushOld);
        DeleteObject(Brush);
        Ellipse(WndDC, Mittelpunkt.X - Radius, Mittelpunkt.Y - Radius,
          Mittelpunkt.X + Radius, Mittelpunkt.Y + Radius);
        EndPaint(WndDC, ps);
        Result := 0;
      end;
  else
    Result := DefWindowProc(hWnd, uMsg, wParam, lParam);
  end;
end;

begin
  with WndClassInfo do
  begin
    style := CS_VREDRAW or CS_HREDRAW;
    lpfnWndProc := @WndProc;
    hInstance := hInstance;
    hCursor := LoadCursor(0, IDC_ARROW);
    hbrBackground := COLOR_APPWORKSPACE;
    lpszClassName := CLASSNAME;
  end;

  RegisterClass(WndClassInfo);

  CreateWindow(CLASSNAME, 'Test Prog', STYLEFLAGS,
    440, 332, 400, 360, 0, 0, hInstance, nil);

  while GetMessage(Msg, 0, 0, 0) do
  begin
    TranslateMessage(Msg);
    DispatchMessage(Msg);
  end;

end.
Danke!

DevilsCamp 5. Feb 2006 19:50

Re: Komisches Problem beim Neuzeichnen
 
Liste der Anhänge anzeigen (Anzahl: 1)
???
Was geht denn nun ab?


Schaut mal in den Anhang...

Assun 5. Feb 2006 19:58

Re: Komisches Problem beim Neuzeichnen
 
:shock: ich hab genau die selbe AntiVir Version und bei mir macht er keinen Mucks beim kompilieren :gruebel:

Edit : Also ich habe eben AntiVir 7 Personal und bei mir meldet er gar nix.

turboPASCAL 5. Feb 2006 20:22

Re: Komisches Problem beim Neuzeichnen
 
@DevilsCamp, da is wohl dein Antivirscanner etwas zu straff eingestellt, oder doch ein Virus ? ;)

@Rastaman,

Das stimmt schon so, du müsstest nur nach dem ändern des Wertes im Editfeld das zeichnen des Windows mit InvalidateRect aktualisieren...

Delphi-Quellcode:
var r: TRect;

//...

WM_COMMAND:
      begin
        if HiWord(wParam) = EN_CHANGE then
        begin
          SendMessage(GetDlgItem(hWnd, 1), WM_GETTEXT, 3, Integer(@Buffer));
          Val(Buffer, Radius, Code);

          GetClientRect(hWnd, r);
          InvalidateRect(hWnd, @r, true);
        end;
      end
Delphi-Quellcode:
WM_PAINT:
      begin
        WndDC := BeginPaint(hWnd, ps);

        Brush := CreateSolidBrush($0000D0D0);
        BrushOld := SelectObject(WndDC, Brush);
        RectAngle(WndDC, -1, -1, 401, 361);
        SelectObject(WndDC, BrushOld);
        DeleteObject(Brush);

        Brush := CreateSolidBrush($00FF00FF);
        BrushOld := SelectObject(WndDC, Brush);
        Ellipse(WndDC, Mittelpunkt.X - Radius, Mittelpunkt.Y - Radius,
          Mittelpunkt.X + Radius, Mittelpunkt.Y + Radius);
        SelectObject(WndDC, BrushOld);
        DeleteObject(Brush);


        EndPaint(WndDC, ps);
        Result := 0;
      end;

Rastaman 5. Feb 2006 20:38

Re: Komisches Problem beim Neuzeichnen
 
Danke, funktioniert :thumb:
Aber kann mir nochma jemand den InvalidateRect Befehl erklären?
Aus der Hilfe werd ich nich so ganz schlau.

turboPASCAL 5. Feb 2006 21:58

Re: Komisches Problem beim Neuzeichnen
 
InvalidateRect sagt Win welchen Bereich es neu zeichnen soll. Ohne diesen Aufruf wird nur dann neu gezeichnet wenn nötig.

bErase gibt an das der komplette Hintergrund gelöscht werden soll oder nur der bereich der sich geändert hat, ist bErase = true ruft dass dann auch die WM_ERASEBKGND-Message auf, auf die du dann reagieren kannst.


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:07 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz