Einzelnen Beitrag anzeigen

DualCoreCpu
(Gast)

n/a Beiträge
 
#1

Warum werden Regionen in meinem Programm nicht gezeichnet!

  Alt 5. Feb 2018, 20:30
Hallo,
ich beschäftige mich gerade mit dem Windows API. Dazu arbeite ich mir nicht nur Luckies Tutorial durch, sondern auch das Buch "Programming Windows Fifth Edition" von Charles Petzold, Verlag Microsoft Press.

Aus dem Buch habe ich das folgende Programm nach Pascal übertragen, von Seite 205ff des letzgenannten Buches.

Nun werden die erzeugten Regionen aber nicht gezeichnet. Ich verstehe leider nicht, warum?

Das Erzeugen eines Stiftes ist im Originalprogramm aus dem Buch nicht enthalten. So dachte ich zuerst, im Buch sei das weggelassen worden, weil es klar ist, daß ich zum Zeichnen einen Stift brauche (wie auf einem Blatt Papier) und so diesen Teil selber zum Programm hinzufügen müsse. Aber auch mit dem Stift bleibt der Fensterhintergrund weiß.

Hier ist das in Pascal transferierte Programm:

Delphi-Quellcode:
program region;

{$APPTYPE GUI}

uses
  SysUtils,
  Windows,
  Messages;

var
  wnd: HWND;
  msg: TMsg;
  wndclass: TWndClass;
  szAppName: PAnsiChar = 'Clover';

//Die Funktion hypot wird im C Originalprogramm verwendet. Die erzeugt die
//Hypotenuse von zwei gegebenen Dreiecksseiten. Habe ich von dieser Erklärung
//her zumindest so verstanden:
//C++ Reference:
[URL="http://www.cplusplus.com/reference/cmath/hypot/"]http://www.cplusplus.com/reference/cmath/hypot/[/URL]

function hypot(a,b: double): double;
var h: double;
begin
  h := sqr(a) + sqr(b);
  Result := sqrt(h);
end;

function WndProc(wnd: HWND; msg: UINT; w: WPARAM; l: LPARAM): LRESULT; stdcall;
var
  hrgnClip: HRGN;
  cxClient: Integer;
  cyClient: Integer;
  fAngle,fRadius: double;
  cursor: HCURSOR;
  dc: HDC;
  hrgnTemp: array[0..6] of HRGN;
  i: Integer;
  ps: TPaintStruct;
  pen,penold: HPEN;
begin
  case msg of
    WM_SIZE:
      begin
        cxClient := LOWORD(l);
        cyClient := HIWORD(l);
        cursor := SetCursor(LoadCursor(0, IDC_WAIT));
        ShowCursor(true);

        if hRgnClip <> 0 then DeleteObject(hRgnClip);

        hRgnTemp[0] := CreateEllipticRgn(0, cyClient div 3, cxClient div 2, 2*cyClient div 3);
        hrgnTemp[1] := CreateEllipticRgn(cxClient div 2, cyClient div 3, cxClient, 2*cyClient div 3);
        hrgnTemp[2] := CreateEllipticRgn(cxClient div 3, 0, 2*cxClient div 3, cyClient div 2);
        hrgnTemp[3] := CreateEllipticRgn(cxClient div 3, cyClient div 2, 2*cxClient div 3, cyClient);
        hrgnTemp[4] := CreateRectRgn(0,0,1,1);
        hrgnTemp[5] := CreateRectRgn(0,0,1,1);
        hRgnClip := CreateRectRgn(0,0,1,1);

        CombineRgn(hRgnTemp[4], hRgnTemp[0], hRgnTemp[1], RGN_OR);
        CombineRgn(hRgnTemp[5],hRgnTemp[2],hRgnTemp[3], RGN_OR);
        CombineRgn(hRgnClip, hRgnTemp[4], hRgnTemp[5], RGN_XOR);
        for i:=0 to 5 do DeleteObject(hRgnTemp[i]);
        SetCursor(cursor);
        ShowCursor(false);
      end;
    WM_PAINT:
      begin
        dc := BeginPaint(wnd, ps);

        SetViewPortOrgEx(dc, cxClient div 2, cyClient div 2, nil);
        SelectClipRgn(dc, hRgnClip);

        fRadius := hypot(cxClient / 2.0, cyClient / 2.0);

        //Hatte zuerst gedacht, ich brauchte einen Stift, um zeichnen zu
        //können, wie auch auf einem Blatt Papier
        pen := CreatePen(PS_SOLID,1,RGB(0,0,255));
        penold := SelectObject(dc, pen);
        SelectObject(dc,penold);
        //Der erzeugte Stift führt nicht zum Erfolg, die Region wird dennoch
        //nicht gezeichnet, der Fensterhintergrund bleibt weiß

        fAngle := 0.0;
        for i := 0 to 359 do
        begin
          MoveToEx(dc,0,0,nil);
          LineTo(dc,Round(fRadius*cos(fAngle)+0.5),Round(-fRadius*sin(fAngle)+0.5));
        end;

        DeleteObject(pen);

        EndPaint(wnd, ps);
      end;
    WM_DESTROY:
      begin
        DeleteObject(hRgnClip);
        PostQuitMessage(0);
      end;
  end;
  Result := DefWindowProc(wnd,msg,w,l);
end;

begin
  { TODO -oUser -cConsole Main : Insert code here }
  wndclass.style := CS_HREDRAW or CS_VREDRAW;
  wndclass.lpfnWndProc := @WndProc;
  wndclass.cbClsExtra := 0;
  wndclass.cbWndExtra := 0;
  wndclass.hInstance := hInstance; //Innerhalb Windows definiert!
  wndclass.hIcon := LoadIcon(hInstance,IDI_APPLICATION);
  wndclass.hCursor := LoadCursor(Longint(NIL), IDC_ARROW);
  wndclass.hbrBackground := HBRUSH(GetStockObject(WHITE_BRUSH));
  wndclass.lpszMenuName := NIL;
  wndclass.lpszClassName := szAppName;

  if not Boolean(RegisterClass(wndclass)) then
  begin
    MessageBox(0,'Dieses Programm erfordert Windows NT!', szAppName, MB_ICONERROR);
    Halt(1);
  end;

  wnd := CreateWindow(szAppName, 'Zeichne ein Kleeblatt',
               WS_OVERLAPPEDWINDOW,
               CW_USEDEFAULT, CW_USEDEFAULT,
               CW_USEDEFAULT, CW_USEDEFAULT,
               0, 0, hInstance, nil
          );

  ShowWindow(wnd, Sw_Shownormal);
  UpdateWindow(wnd);


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

end.

P.S.:
Warum funktioniert das Einfügen von Internetlinks innerhalb der Klammer nicht?

Geändert von DualCoreCpu ( 5. Feb 2018 um 20:37 Uhr)
  Mit Zitat antworten Zitat