OwnerDrw.mod: Translation to XDS Modula-2

Last updated: 18. 1.1998, 14:30

<* +M2EXTENSIONS *>
MODULE OwnerDrw;
(*----------------------------------------------
   OWNERDRW.C      --- Owner-Draw Button Demo Program
                   (c) Charles Petzold, 1996
   OwnerDrw.mod    --- Translation to XDS Modula-2
                   (c) Peter Stadler,   1998
  ----------------------------------------------*)
IMPORT Windows;



IMPORT SYSTEM;

CONST
  IDC_SMALLER =  1;
  IDC_LARGER  =  2;



VAR
  hInst      :  Windows.HINSTANCE;

CONST
  szAppName    =  "OwnerDrw";

VAR
  hwnd         :  Windows.HWND;
  msg          :  Windows.MSG;
  wc           :  Windows.WNDCLASSEX;
VAR
  hwndSmaller    : Windows.HWND;
  hwndLarger     : Windows.HWND;
  cxClient       : INTEGER;
  cyClient       : INTEGER;
  cxChar         : INTEGER;
  cyChar         : INTEGER;
  BTN_WIDTH      : INTEGER;
  BTN_HEIGHT     : INTEGER;
(**********************************************************************)
PROCEDURE Triangle (hdc : Windows.HDC; pt : ARRAY OF Windows.POINT);
(**********************************************************************)
BEGIN
     Windows.SelectObject (hdc, Windows.GetStockObject (Windows.BLACK_BRUSH));
     Windows.Polygon (hdc, pt, 3);
     Windows.SelectObject (hdc, Windows.GetStockObject (Windows.WHITE_BRUSH));
END Triangle;



    

    

(*++++*****************************************************************)
PROCEDURE [Windows.CALLBACK] WndProc (hwnd        : Windows.HWND;
(**********************************************************************)
                                      iMsg        : Windows.UINT;
                                      wParam      : Windows.WPARAM;
                                      lParam      : Windows.LPARAM) : Windows.LRESULT;
VAR
  cx      :  INTEGER;
  cy      :  INTEGER;
  rc      :  Windows.RECT;
  pdis    :  Windows.PDRAWITEMSTRUCT;
  pt      :  ARRAY[0..2] OF Windows.POINT;
BEGIN
  CASE (iMsg) OF
          | Windows.WM_CREATE :
               cxChar := Windows.LOWORD (Windows.GetDialogBaseUnits ());
               cyChar := Windows.HIWORD (Windows.GetDialogBaseUnits ());
	       BTN_WIDTH   :=  8*cxChar;
               BTN_HEIGHT  :=  4*cyChar;

                         (* Create the owner-draw pushbuttons                  *)

               hwndSmaller := Windows.CreateWindow ("button", "",
                                  Windows.WS_CHILD + Windows.WS_VISIBLE + Windows.BS_OWNERDRAW,
                                  0, 0, BTN_WIDTH, BTN_HEIGHT,
                                  hwnd, SYSTEM.CAST(Windows.HMENU,IDC_SMALLER), hInst, NIL);

               hwndLarger := Windows.CreateWindow ("button", "",
                                  Windows.WS_CHILD + Windows.WS_VISIBLE + Windows.BS_OWNERDRAW,
                                  0, 0, BTN_WIDTH, BTN_HEIGHT,
                                  hwnd, SYSTEM.CAST(Windows.HMENU,IDC_LARGER), hInst, NIL);
               RETURN 0;

          | Windows.WM_SIZE :
               cxClient := Windows.LOWORD (lParam);
               cyClient := Windows.HIWORD (lParam);

                         (* Move the buttons to the new center                 *)

               Windows.MoveWindow (hwndSmaller, cxClient DIV 2 - 3 * BTN_WIDTH  DIV 2,
                                        cyClient DIV 2 -     BTN_HEIGHT DIV 2,
                                        BTN_WIDTH, BTN_HEIGHT, TRUE);

               Windows.MoveWindow (hwndLarger,  cxClient DIV 2 +     BTN_WIDTH  DIV 2,
                                        cyClient DIV 2 -     BTN_HEIGHT DIV 2,
                                        BTN_WIDTH, BTN_HEIGHT, TRUE);
               RETURN 0;

          | Windows.WM_COMMAND :
               Windows.GetWindowRect (hwnd, rc);

                         (* Make the window 10% smaller or larger              *)

               CASE (wParam) OF
                    | IDC_SMALLER :
                         rc.left   := rc.left   + cxClient DIV 20;
                         rc.right  := rc.right  - cxClient DIV 20;
                         rc.top    := rc.top    + cyClient DIV 20;
                         rc.bottom := rc.bottom - cyClient DIV 20;

                    | IDC_LARGER :
                         rc.left   := rc.left   - cxClient DIV 20;
                         rc.right  := rc.right  + cxClient DIV 20;
                         rc.top    := rc.top    - cyClient DIV 20;
                         rc.bottom := rc.bottom + cyClient DIV 20;

               ELSE
               END;
               Windows.MoveWindow (hwnd, rc.left, rc.top, rc.right  - rc.left,
                                                  rc.bottom - rc.top, TRUE);
               RETURN 0;

          | Windows.WM_DRAWITEM :
               pdis := SYSTEM.CAST(Windows.PDRAWITEMSTRUCT,lParam);

                         (* Fill area with white and frame it black            *)

               Windows.FillRect (pdis^.hDC, pdis^.rcItem,
                         SYSTEM.CAST(Windows.HBRUSH,Windows.GetStockObject (Windows.WHITE_BRUSH)));

               Windows.FrameRect (pdis^.hDC, pdis^.rcItem,
                          SYSTEM.CAST(Windows.HBRUSH,Windows.GetStockObject (Windows.BLACK_BRUSH)));


                         (* Draw inward and outward black triangles            *)

               cx := pdis^.rcItem.right  - pdis^.rcItem.left;
               cy := pdis^.rcItem.bottom - pdis^.rcItem.top ;

               CASE (pdis^.CtlID) OF
                    | IDC_SMALLER :
                         pt[0].x := 3 * cx DIV 8;  pt[0].y := 1 * cy DIV 8;
                         pt[1].x := 5 * cx DIV 8;  pt[1].y := 1 * cy DIV 8;
                         pt[2].x := 4 * cx DIV 8;  pt[2].y := 3 * cy DIV 8;

                         Triangle (pdis^.hDC, pt);

                         pt[0].x := 7 * cx DIV 8;  pt[0].y := 3 * cy DIV 8;
                         pt[1].x := 7 * cx DIV 8;  pt[1].y := 5 * cy DIV 8;
                         pt[2].x := 5 * cx DIV 8;  pt[2].y := 4 * cy DIV 8;

                         Triangle (pdis^.hDC, pt);

                         pt[0].x := 5 * cx DIV 8;  pt[0].y := 7 * cy DIV 8;
                         pt[1].x := 3 * cx DIV 8;  pt[1].y := 7 * cy DIV 8;
                         pt[2].x := 4 * cx DIV 8;  pt[2].y := 5 * cy DIV 8;

                         Triangle (pdis^.hDC, pt);

                         pt[0].x := 1 * cx DIV 8;  pt[0].y := 5 * cy DIV 8;
                         pt[1].x := 1 * cx DIV 8;  pt[1].y := 3 * cy DIV 8;
                         pt[2].x := 3 * cx DIV 8;  pt[2].y := 4 * cy DIV 8;

                         Triangle (pdis^.hDC, pt);

                    | IDC_LARGER :

                         pt[0].x := 5 * cx DIV 8;  pt[0].y := 3 * cy DIV 8;
                         pt[1].x := 3 * cx DIV 8;  pt[1].y := 3 * cy DIV 8;
                         pt[2].x := 4 * cx DIV 8;  pt[2].y := 1 * cy DIV 8;

                         Triangle (pdis^.hDC, pt);

                         pt[0].x := 5 * cx DIV 8;  pt[0].y := 5 * cy DIV 8;
                         pt[1].x := 5 * cx DIV 8;  pt[1].y := 3 * cy DIV 8;
                         pt[2].x := 7 * cx DIV 8;  pt[2].y := 4 * cy DIV 8;

                         Triangle (pdis^.hDC, pt);

                         pt[0].x := 3 * cx DIV 8;  pt[0].y := 5 * cy DIV 8;
                         pt[1].x := 5 * cx DIV 8;  pt[1].y := 5 * cy DIV 8;
                         pt[2].x := 4 * cx DIV 8;  pt[2].y := 7 * cy DIV 8;

                         Triangle (pdis^.hDC, pt);

                         pt[0].x := 3 * cx DIV 8;  pt[0].y := 3 * cy DIV 8;
                         pt[1].x := 3 * cx DIV 8;  pt[1].y := 5 * cy DIV 8;
                         pt[2].x := 1 * cx DIV 8;  pt[2].y := 4 * cy DIV 8;

                         Triangle (pdis^.hDC, pt);
              ELSE
              END;
                         (* Invert the rectangle if the button is selected     *)

               IF (pdis^.itemState - Windows.ODS_SELECTED=SYSTEM.CAST(Windows.ODS_SET,1)) THEN
                    Windows.InvertRect (pdis^.hDC, pdis^.rcItem);

               END;
                         (* Draw a focus rectangle if the button has the focus *)

               IF (pdis^.itemState - Windows.ODS_FOCUS=SYSTEM.CAST(Windows.ODS_SET,1)) THEN
                    pdis^.rcItem.left   := pdis^.rcItem.left   + cx DIV 16;
                    pdis^.rcItem.top    := pdis^.rcItem.top    + cy DIV 16;
                    pdis^.rcItem.right  := pdis^.rcItem.right  - cx DIV 16;
                    pdis^.rcItem.bottom := pdis^.rcItem.bottom - cy DIV 16;

                    Windows.DrawFocusRect (pdis^.hDC, pdis^.rcItem);
               END;

               RETURN 0;

          | Windows.WM_DESTROY :
               Windows.PostQuitMessage (0);
               RETURN 0;
     ELSE
               RETURN Windows.DefWindowProc (hwnd, iMsg, wParam, lParam);
     END;
END WndProc;

(*++++*****************************************************************)
PROCEDURE InitApplication () : BOOLEAN;
(**********************************************************************)
VAR
  rc   :  CARDINAL;
BEGIN
  hInst := Windows.MyInstance();

  wc.cbSize        := SIZE(wc);
  wc.style         := Windows.CS_HREDRAW + Windows.CS_VREDRAW;
  wc.lpfnWndProc   := WndProc;
  wc.cbClsExtra    := 0;
  wc.cbWndExtra    := 0;
  wc.hInstance     := Windows.MyInstance();
  wc.hIcon         := Windows.LoadIcon (NIL, Windows.IDI_APPLICATION);
  wc.hCursor       := Windows.LoadCursor (NIL, Windows.IDC_ARROW);
  wc.hbrBackground := SYSTEM.CAST(Windows.HBRUSH,Windows.GetStockObject(Windows.WHITE_BRUSH));
  wc.lpszMenuName  := SYSTEM.ADR(szAppName);
  wc.lpszClassName := SYSTEM.ADR(szAppName);
  wc.hIconSm       := Windows.LoadIcon (NIL,Windows.IDI_APPLICATION);

  rc := Windows.RegisterClassEx(wc);
  RETURN rc#0;
END InitApplication;

(*++++*****************************************************************)
PROCEDURE InitMainWindow () : BOOLEAN;
(**********************************************************************)
BEGIN
  hwnd := Windows.CreateWindow (
                       szAppName,                      (* window class name            *)
                       "Owner-Draw Button Demo: Translation to XDS Modula-2",
                                                       (* window caption               *)
                       Windows.WS_OVERLAPPEDWINDOW,    (* window style                 *)
                       Windows.CW_USEDEFAULT,          (* initial x position           *)
                       Windows.CW_USEDEFAULT,          (* initial y position           *)
                       Windows.CW_USEDEFAULT,          (* initial x size               *)
                       Windows.CW_USEDEFAULT,          (* initial y size               *)
                       NIL,                            (* parent window handle         *)
                       NIL,                            (* window menu handle           *)
                       wc.hInstance,                   (* program instance handle      *)
                       NIL);                           (* creation parameters          *)

  IF hwnd = NIL THEN
    RETURN FALSE;
  END;
  Windows.ShowWindow (hwnd, Windows.SW_SHOWDEFAULT);
  Windows.UpdateWindow (hwnd);
  RETURN TRUE;
END InitMainWindow;


BEGIN
  IF InitApplication()  AND  InitMainWindow() THEN
    WHILE (Windows.GetMessage(msg,NIL,0,0)) DO
      Windows.TranslateMessage(msg);
      Windows.DispatchMessage(msg);
    END;
  END;
END OwnerDrw.