MDIDemo.mod: Translation to XDS Modula-2

Last updated: 31. 1.1998, 17:54

<* +M2EXTENSIONS *>
MODULE MDIDemo;
(*--------------------------------------------------------
   MDIDEMO.C       --- Multiple Document Interface Demonstration
                   (c) Charles Petzold, 1996
   MDIDemo.mod     --- Translation to XDS Modula-2
                   (c) Peter Stadler,   1997
  --------------------------------------------------------*)






IMPORT Windows;

IMPORT SYSTEM;
IMPORT h2d_mdidemo;



IMPORT Lib;


VAR
  hPrevInstance :  Windows.HINSTANCE;


          (* structure for storing data unique to each Hello child window      *)

TYPE
  HELLODATA = RECORD
                   iColor    :  Windows.UINT;
                   clrText   :  Windows.COLORREF;
                 END;

  LPHELLODATA = POINTER TO HELLODATA;

          (* structure for storing data unique to each Rect child window       *)
  RECTDATA  = RECORD
                   cxClient  :  Windows.SHORT;
                   cyClient  :  Windows.SHORT;
                 END;
  LPRECTDATA = POINTER TO RECTDATA;

     (* global variables                                                  *)

VAR
   szFrameClass : ARRAY[0..20] OF CHAR;
   szHelloClass : ARRAY[0..20] OF CHAR;
   szRectClass  : ARRAY[0..20] OF CHAR;
VAR
   hInst        :  Windows.HINSTANCE;
   hMenuInit    :  Windows.HMENU;
   hMenuHello   :  Windows.HMENU;
   hMenuRect    :  Windows.HMENU;
   hMenuInitWindow     : Windows.HMENU;
   hMenuHelloWindow    : Windows.HMENU;
   hMenuRectWindow     : Windows.HMENU;
VAR
  hAccel       :    Windows.HACCEL;
  hwndFrame    :    Windows.HWND;
  hwndClient   :    Windows.HWND;
  msg          :    Windows.MSG;
  wc           :    Windows.WNDCLASSEX;
  hwndClientOfRect     :  Windows.HWND;
  hwndFrameOfRect      :  Windows.HWND;
  hwndClientOfFrame    :  Windows.HWND;
  hwndClientOfHello    :  Windows.HWND;
  hwndFrameOfHello     :  Windows.HWND;
TYPE
  COLORREFARRAY=  ARRAY[0..4] OF Windows.COLORREF;

VAR
  clrTextArray : COLORREFARRAY;



(*++++*****************************************************************)
PROCEDURE MaxInt (a,b : INTEGER) : INTEGER;
(**********************************************************************)
BEGIN
  IF(a>b) THEN
    RETURN a;
  ELSE
    RETURN b;
  END;
END MaxInt;
(*++++*****************************************************************)
PROCEDURE MinInt (a,b : INTEGER) : INTEGER;
(**********************************************************************)
BEGIN
  IF(a>b) THEN
    RETURN b;
  ELSE
    RETURN a;
  END;
END MinInt;


(*++++**********************************************************************)
PROCEDURE [Windows.CALLBACK] CloseEnumProc  (hwnd        : Windows.HWND;
                                            lParam       : Windows.LPARAM) : Windows.BOOL;
(***************************************************************************)
BEGIN
     IF (Windows.GetWindow (hwnd, Windows.GW_OWNER)#NIL) THEN    (* Check for icon title           *)
          RETURN SYSTEM.CAST(Windows.BOOL,1);
     END;
     Windows.SendMessage (Windows.GetParent (hwnd), Windows.WM_MDIRESTORE, SYSTEM.CAST(Windows.WPARAM,hwnd), 0);

     IF (Windows.SendMessage (hwnd, Windows.WM_QUERYENDSESSION, 0, 0)#0) THEN
          RETURN SYSTEM.CAST(Windows.BOOL,1);
     END;
     Windows.SendMessage (Windows.GetParent (hwnd), Windows.WM_MDIDESTROY, SYSTEM.CAST(Windows.WPARAM,hwnd), 0);
          RETURN SYSTEM.CAST(Windows.BOOL,1);
END CloseEnumProc;

    

    

(*++++**********************************************************************)
PROCEDURE [Windows.CALLBACK] FrameWndProc (hwnd        : Windows.HWND;
                                           iMsg        : Windows.UINT;
                                           wParam      : Windows.WPARAM;
                                           lParam      : Windows.LPARAM) : Windows.LRESULT;
(***************************************************************************)
VAR
  clientcreate    : Windows.CLIENTCREATESTRUCT;
  hwndChild       : Windows.HWND;
  mdicreate       : Windows.MDICREATESTRUCT;
CONST
  hello  = "Hello";
  mdi    = "MDICLIENT";
  rect   = "Rectangles";
BEGIN
     CASE (iMsg) OF
          | Windows.WM_CREATE :          (* Create the client window                *)

               clientcreate.hWindowMenu  := SYSTEM.CAST(Windows.HANDLE,hMenuInitWindow);
               clientcreate.idFirstChild := h2d_mdidemo.IDM_FIRSTCHILD;

               hwndClientOfFrame := Windows.CreateWindow (SYSTEM.ADR(mdi), "",
                              Windows.WS_CHILD + Windows.WS_CLIPCHILDREN + Windows.WS_VISIBLE,
                              0, 0, 0, 0, hwnd, SYSTEM.CAST(Windows.HMENU, 1), hInst,
                              SYSTEM.CAST(Windows.PSTR, SYSTEM.ADR(clientcreate)));
               RETURN 0;

          | Windows.WM_COMMAND :
               CASE (wParam) OF
                    | h2d_mdidemo.IDM_NEWHELLO :       (* Create a Hello child window   *)

                         mdicreate.szClass := SYSTEM.ADR(szHelloClass);
                         mdicreate.szTitle := SYSTEM.ADR(hello);
                         mdicreate.hOwner  := SYSTEM.CAST(Windows.HANDLE,hInst);
                         mdicreate.x       := Windows.CW_USEDEFAULT;
                         mdicreate.y       := Windows.CW_USEDEFAULT;
                         mdicreate.cx      := Windows.CW_USEDEFAULT;
                         mdicreate.cy      := Windows.CW_USEDEFAULT;
                         mdicreate.style   := 0;
                         mdicreate.lParam  := 0;

                         hwndChild := SYSTEM.CAST(Windows.HWND, Windows.SendMessage (hwndClient,
                                        Windows.WM_MDICREATE, 0,
                                        SYSTEM.CAST(Windows.LPARAM,SYSTEM.CAST(Windows.PMDICREATESTRUCT, SYSTEM.ADR(mdicreate)))));
                         RETURN 0;

                    | h2d_mdidemo.IDM_NEWRECT :        (* Create a Rect child window    *)

                         mdicreate.szClass := SYSTEM.ADR(szRectClass);
                         mdicreate.szTitle := SYSTEM.ADR(rect);
                         mdicreate.hOwner  := SYSTEM.CAST(Windows.HANDLE,hInst);
                         mdicreate.x       := Windows.CW_USEDEFAULT;
                         mdicreate.y       := Windows.CW_USEDEFAULT;
                         mdicreate.cx      := Windows.CW_USEDEFAULT;
                         mdicreate.cy      := Windows.CW_USEDEFAULT;
                         mdicreate.style   := 0;
                         mdicreate.lParam  := 0;

                         hwndChild := SYSTEM.CAST(Windows.HWND, Windows.SendMessage (hwndClient,
                                        Windows.WM_MDICREATE, 0,
                                        SYSTEM.CAST(Windows.LPARAM,SYSTEM.CAST(Windows.PMDICREATESTRUCT, SYSTEM.ADR(mdicreate)))));
                         RETURN 0;

                    | h2d_mdidemo.IDM_CLOSE :          (* Close the active window       *)

                         hwndChild := SYSTEM.CAST(Windows.HWND, Windows.SendMessage (hwndClient,
                                                  Windows.WM_MDIGETACTIVE, 0, 0));

                         IF (Windows.SendMessage (hwndChild, Windows.WM_QUERYENDSESSION, 0, 0)=1) THEN
                              Windows.SendMessage (hwndClientOfFrame, Windows.WM_MDIDESTROY,
                                           SYSTEM.CAST(Windows.WPARAM, hwndChild), 0);
                         END;
                         RETURN 0;

                    | h2d_mdidemo.IDM_EXIT :           (* Exit the program              *)

                         Windows.SendMessage (hwnd, Windows.WM_CLOSE, 0, 0);
                         RETURN 0;

                                   (* messages for arranging windows           *)
                    | h2d_mdidemo.IDM_TILE :
                         Windows.SendMessage (hwndClientOfFrame, Windows.WM_MDITILE, 0, 0);
                         RETURN 0;

                    | h2d_mdidemo.IDM_CASCADE :
                         Windows.SendMessage (hwndClientOfFrame, Windows.WM_MDICASCADE, 0, 0);
                         RETURN 0;

                    | h2d_mdidemo.IDM_ARRANGE :
                         Windows.SendMessage (hwndClientOfFrame, Windows.WM_MDIICONARRANGE, 0, 0);
                         RETURN 0;

                    | h2d_mdidemo.IDM_CLOSEALL :       (* Attempt to close all children *)

                         Windows.EnumChildWindows (hwndClientOfFrame, CloseEnumProc, 0);
                         RETURN 0;

                    ELSE                 (* Pass to active child...            *)

                         hwndChild := SYSTEM.CAST(Windows.HWND, Windows.SendMessage (hwndClientOfFrame,
                                                  Windows.WM_MDIGETACTIVE, 0, 0));

                        IF (Windows.IsWindow (hwndChild)) THEN
                             Windows.SendMessage (hwndChild, Windows.WM_COMMAND,
                                          wParam, lParam);
                        END;
                        RETURN 0;(*break*)        (* ...and then to DefFrameProc          *)
                    END;
               RETURN 0;(*break*)

          | Windows.WM_QUERYENDSESSION :
          | Windows.WM_CLOSE :                     (* Attempt to close all children *)

               Windows.SendMessage (hwnd, Windows.WM_COMMAND, h2d_mdidemo.IDM_CLOSEALL, 0);

               IF (NIL # Windows.GetWindow (hwndClientOfFrame, Windows.GW_CHILD)) THEN
                    RETURN 0;
               END;
               RETURN 0;(*break*)   (* I.e., call DefFrameProc                            *)

          | Windows.WM_DESTROY :
               Windows.PostQuitMessage (0);
               RETURN 0;
               (* Pass unprocessed messages to DefFrameProc (not DefWindowProc)*)

       RETURN Windows.DefFrameProc (hwnd, hwndClientOfFrame, iMsg, wParam, lParam);
     ELSE
       RETURN 0;
     END;
END FrameWndProc;




    

    




    

    

(*++++**********************************************************************)
PROCEDURE [Windows.CALLBACK] HelloWndProc (hwnd        : Windows.HWND;
                                           iMsg        : Windows.UINT;
                                           wParam      : Windows.WPARAM;
                                           lParam      : Windows.LPARAM) : Windows.LRESULT;
(***************************************************************************)


VAR
  hdc            :  Windows.HDC;
  hMenu          :  Windows.HMENU;
  lpHelloData    :  LPHELLODATA;
  ps             :  Windows.PAINTSTRUCT;
  rect           :  Windows.RECT;
CONST
  world = "Hello, World!";
  hello = "Hello";


BEGIN
     CASE (iMsg) OF
          | Windows.WM_CREATE :
                         (* Allocate memory for window private data            *)

               lpHelloData := SYSTEM.CAST(LPHELLODATA, Windows.HeapAlloc (Windows.GetProcessHeap (),
                                                      Windows.HEAP_ZERO_MEMORY,
                                                      SIZE(HELLODATA)));
               lpHelloData^.iColor  := h2d_mdidemo.IDM_BLACK;
               lpHelloData^.clrText := Windows.RGB (0, 0, 0);
               Windows.SetWindowLong (hwnd, 0, SYSTEM.CAST(Windows.LONG, lpHelloData));

                         (* Save some window handles                           *)

               hwndClientOfHello := Windows.GetParent (hwnd);
               hwndFrameOfHello  := Windows.GetParent (hwndClientOfHello);
               RETURN 0;

          | Windows.WM_COMMAND :
               CASE (wParam) OF
                    | h2d_mdidemo.IDM_BLACK :
                         lpHelloData := SYSTEM.CAST(LPHELLODATA, Windows.GetWindowLong (hwnd, 0));
                         hMenu := Windows.GetMenu (hwndFrameOfHello);
                         Windows.CheckMenuItem (hMenu, lpHelloData^.iColor,
                                               Windows.MF_UNCHECKED);
                         lpHelloData^.iColor := wParam;
                         Windows.CheckMenuItem (hMenu, lpHelloData^.iColor,
                                               Windows.MF_CHECKED);
                         lpHelloData^.clrText :=
                               clrTextArray[wParam - h2d_mdidemo.IDM_BLACK];
                         Windows.InvalidateRect (hwnd, NIL, FALSE);
                         RETURN 0;
                    | h2d_mdidemo.IDM_RED :
                         lpHelloData := SYSTEM.CAST(LPHELLODATA, Windows.GetWindowLong (hwnd, 0));
                         hMenu := Windows.GetMenu (hwndFrameOfHello);
                         Windows.CheckMenuItem (hMenu, lpHelloData^.iColor,
                                               Windows.MF_UNCHECKED);
                         lpHelloData^.iColor := wParam;
                         Windows.CheckMenuItem (hMenu, lpHelloData^.iColor,
                                               Windows.MF_CHECKED);
                         lpHelloData^.clrText :=
                               clrTextArray[wParam - h2d_mdidemo.IDM_BLACK];
                         Windows.InvalidateRect (hwnd, NIL, FALSE);
                         RETURN 0;
                    | h2d_mdidemo.IDM_GREEN :
                         lpHelloData := SYSTEM.CAST(LPHELLODATA, Windows.GetWindowLong (hwnd, 0));
                         hMenu := Windows.GetMenu (hwndFrameOfHello);
                         Windows.CheckMenuItem (hMenu, lpHelloData^.iColor,
                                               Windows.MF_UNCHECKED);
                         lpHelloData^.iColor := wParam;
                         Windows.CheckMenuItem (hMenu, lpHelloData^.iColor,
                                               Windows.MF_CHECKED);
                         lpHelloData^.clrText :=
                               clrTextArray[wParam - h2d_mdidemo.IDM_BLACK];
                         Windows.InvalidateRect (hwnd, NIL, FALSE);
                         RETURN 0;
                    | h2d_mdidemo.IDM_BLUE :
                         lpHelloData := SYSTEM.CAST(LPHELLODATA, Windows.GetWindowLong (hwnd, 0));
                         hMenu := Windows.GetMenu (hwndFrameOfHello);
                         Windows.CheckMenuItem (hMenu, lpHelloData^.iColor,
                                               Windows.MF_UNCHECKED);
                         lpHelloData^.iColor := wParam;
                         Windows.CheckMenuItem (hMenu, lpHelloData^.iColor,
                                               Windows.MF_CHECKED);
                         lpHelloData^.clrText :=
                               clrTextArray[wParam - h2d_mdidemo.IDM_BLACK];
                         Windows.InvalidateRect (hwnd, NIL, FALSE);
                         RETURN 0;
                    | h2d_mdidemo.IDM_WHITE :
                                   (* Change the text color                    *)

                         lpHelloData := SYSTEM.CAST(LPHELLODATA, Windows.GetWindowLong (hwnd, 0));
                         hMenu := Windows.GetMenu (hwndFrameOfHello);
                         Windows.CheckMenuItem (hMenu, lpHelloData^.iColor,
                                               Windows.MF_UNCHECKED);
                         lpHelloData^.iColor := wParam;
                         Windows.CheckMenuItem (hMenu, lpHelloData^.iColor,
                                               Windows.MF_CHECKED);
                         lpHelloData^.clrText :=
                               clrTextArray[wParam - h2d_mdidemo.IDM_BLACK];
                         Windows.InvalidateRect (hwnd, NIL, FALSE);
                         RETURN 0;
               ELSE
                         RETURN 0;
               END;
          | Windows.WM_PAINT :
                         (* Paint the window                                   *)

               hdc := Windows.BeginPaint (hwnd, ps);

               lpHelloData := SYSTEM.CAST(LPHELLODATA, Windows.GetWindowLong (hwnd, 0));
               Windows.SetTextColor (hdc, lpHelloData^.clrText);

               Windows.GetClientRect (hwnd, rect);

               Windows.DrawText (hdc, SYSTEM.ADR(world), -1, rect,
                         Windows.DT_SINGLELINE + Windows.DT_CENTER + Windows.DT_VCENTER);

               Windows.EndPaint (hwnd, ps);
               RETURN 0;

          | Windows.WM_MDIACTIVATE :

                         (* Set the Hello menu if gaining focus                *)

               IF (lParam = SYSTEM.CAST(Windows.LPARAM, hwnd)) THEN
                    Windows.SendMessage (hwndClientOfHello, Windows.WM_MDISETMENU,
                               SYSTEM.CAST(Windows.WPARAM, hMenuHello), SYSTEM.CAST(Windows.LPARAM, hMenuHelloWindow));
               END;
                         (* Check or uncheck menu item                         *)

               lpHelloData := SYSTEM.CAST(LPHELLODATA, Windows.GetWindowLong (hwnd, 0));

               IF(lParam = SYSTEM.CAST(Windows.LPARAM,hwnd)) THEN
                           IF(SYSTEM.CAST(Windows.LPARAM,hwnd)=1) THEN
                             lParam := SYSTEM.CAST(INTEGER,Windows.MF_CHECKED);
                           ELSIF(SYSTEM.CAST(Windows.LPARAM,hwnd)=0) THEN
                             lParam := SYSTEM.CAST(INTEGER,Windows.MF_UNCHECKED);
                           END;
               END;
               Windows.CheckMenuItem (hMenuHello, lpHelloData^.iColor,SYSTEM.CAST(Windows.MF_SET,lParam));

                         (* Set the Init menu IF losing focus                  *)

               IF (lParam # SYSTEM.CAST(Windows.LPARAM, hwnd)) THEN
                    Windows.SendMessage (hwndClientOfHello, Windows.WM_MDISETMENU, SYSTEM.CAST(Windows.WPARAM, hMenuInit),
                                 SYSTEM.CAST(Windows.LPARAM, hMenuInitWindow));
               END;
               Windows.DrawMenuBar (hwndFrameOfHello);
               RETURN 0;

          | Windows.WM_QUERYENDSESSION :
          | Windows.WM_CLOSE :
               IF (Windows.IDOK # Windows.MessageBox (hwnd, "OK to close window?", SYSTEM.ADR(hello),
                                       Windows.MB_ICONQUESTION + Windows.MB_OKCANCEL)) THEN
                    RETURN 0;
               END;
               RETURN 0;(*break*)   (* I.e., call DefMDIChildProc                         *)

          | Windows.WM_DESTROY :
               lpHelloData := SYSTEM.CAST(LPHELLODATA, Windows.GetWindowLong (hwnd, 0));
               Windows.HeapFree (Windows.GetProcessHeap (), SYSTEM.CAST(Windows.HEAP_SET,0), lpHelloData);
               RETURN 0;
     ELSE
               (* Pass unprocessed message to DefMDIChildProc                  *)

       RETURN Windows.DefMDIChildProc (hwnd, iMsg, wParam, lParam);
     END;
END HelloWndProc;




    

    

(*++++**********************************************************************)
PROCEDURE [Windows.CALLBACK] RectWndProc  (hwnd        : Windows.HWND;
                                           iMsg        : Windows.UINT;
                                           wParam      : Windows.WPARAM;
                                           lParam      : Windows.LPARAM) : Windows.LRESULT;
(***************************************************************************)
VAR
  hBrush         :  Windows.HBRUSH;
  hdc            :  Windows.HDC;
  lpRectData     :  LPRECTDATA;
  ps             :  Windows.PAINTSTRUCT;
  xLeft          :  INTEGER;
  xRight         :  INTEGER;
  yTop           :  INTEGER;
  yBottom        :  INTEGER;
  nRed           :  Windows.SHORT;
  nGreen         :  Windows.SHORT;
  nBlue          :  Windows.SHORT;
BEGIN
     CASE (iMsg) OF
          | Windows.WM_CREATE :
                         (* Allocate memory for window private data            *)

               lpRectData := SYSTEM.CAST(LPRECTDATA, Windows.HeapAlloc (Windows.GetProcessHeap (),
                                                    Windows.HEAP_ZERO_MEMORY,
                                                    SIZE(RECTDATA)));

               Windows.SetWindowLong (hwnd, 0, SYSTEM.CAST(Windows.LONG,lpRectData));

                         (* Start the timer going                              *)

               Windows.SetTimer (hwnd, 1, 250, NIL);

                         (* Save some window handles                           *)

               hwndClientOfRect := Windows.GetParent (hwnd);
               hwndFrameOfRect  := Windows.GetParent (hwndClientOfRect);
               RETURN 0;

          | Windows.WM_SIZE :            (* If not minimized, save the window size  *)

               IF (wParam # Windows.SIZE_MINIMIZED) THEN
                    lpRectData := SYSTEM.CAST(LPRECTDATA, Windows.GetWindowLong (hwnd, 0));

                    lpRectData^.cxClient := Windows.LOWORD (lParam);
                    lpRectData^.cyClient := Windows.HIWORD (lParam);
               END;

               RETURN 0;(*break*)        (* Windows.WM_SIZE must be processed by DefMDIChildProc  *)

          | Windows.WM_TIMER :           (* Display a random rectangle              *)

               lpRectData := SYSTEM.CAST(LPRECTDATA, Windows.GetWindowLong (hwnd, 0));

               xLeft   := SYSTEM.CAST(INTEGER,Lib.RANDOM(1000) REM VAL(CARDINAL,lpRectData^.cxClient));
               xRight  := SYSTEM.CAST(INTEGER,Lib.RANDOM(1000) REM VAL(CARDINAL,lpRectData^.cxClient));
               yTop    := SYSTEM.CAST(INTEGER,Lib.RANDOM(1000) REM VAL(CARDINAL,lpRectData^.cyClient));
               yBottom := SYSTEM.CAST(INTEGER,Lib.RANDOM(1000) REM VAL(CARDINAL,lpRectData^.cyClient));
               nRed    := SYSTEM.CAST(INTEGER,Lib.RANDOM(1000) - 255);
               nGreen  := SYSTEM.CAST(INTEGER,Lib.RANDOM(1000) - 255);
               nBlue   := SYSTEM.CAST(INTEGER,Lib.RANDOM(1000) - 255);

               hdc := Windows.GetDC (hwnd);
               hBrush := Windows.CreateSolidBrush (Windows.RGB (nRed, nGreen, nBlue));
               Windows.SelectObject (hdc, SYSTEM.CAST(Windows.HGDIOBJ,hBrush));

               Windows.Rectangle (hdc, MinInt (xLeft, xRight), MinInt (yTop, yBottom),
                               MaxInt (xLeft, xRight), MaxInt (yTop, yBottom));

               Windows.ReleaseDC (hwnd, hdc);
               Windows.DeleteObject (SYSTEM.CAST(Windows.HGDIOBJ,hBrush));
               RETURN 0;

          | Windows.WM_PAINT :           (* Clear the window                        *)

               Windows.InvalidateRect (hwnd, NIL, TRUE);
               hdc := Windows.BeginPaint (hwnd, ps);
               Windows.EndPaint (hwnd, ps);
               RETURN 0;

          | Windows.WM_MDIACTIVATE :     (* Set the appropriate menu                *)
               IF (lParam = SYSTEM.CAST(Windows.LPARAM, hwnd)) THEN
                    Windows.SendMessage (hwndClientOfRect, Windows.WM_MDISETMENU, SYSTEM.CAST(Windows.WPARAM, hMenuRect),
                                 SYSTEM.CAST(Windows.LPARAM,hMenuRectWindow));
               ELSE
                    Windows.SendMessage (hwndClientOfRect, Windows.WM_MDISETMENU, SYSTEM.CAST(Windows.WPARAM, hMenuInit),
                                 SYSTEM.CAST(Windows.LPARAM, hMenuInitWindow));
               END;

               Windows.DrawMenuBar (hwndFrameOfRect);
               RETURN 0;

          | Windows.WM_DESTROY :
               lpRectData := SYSTEM.CAST(LPRECTDATA, Windows.GetWindowLong (hwnd, 0));
               Windows.HeapFree (Windows.GetProcessHeap (), SYSTEM.CAST(Windows.HEAP_SET,0), lpRectData);
               Windows.KillTimer (hwnd, 1);
               RETURN 0;
               (* Pass unprocessed message to DefMDIChildProc                  *)

     ELSE
       RETURN Windows.DefMDIChildProc (hwnd, iMsg, wParam, lParam);
     END;
END RectWndProc;

(*+++***********************************************************************)
PROCEDURE InitApplication () : BOOLEAN;
(***************************************************************************)

VAR
  rc : CARDINAL;
BEGIN
  hInst := Windows.MyInstance();
  hPrevInstance := Windows.PrevInstance();

  IF (hPrevInstance=NIL) THEN
                 (* Register the frame window class                         *)

    wc.cbSize        := SIZE(Windows.WNDCLASSEX);
    wc.style         := Windows.CS_HREDRAW + Windows.CS_VREDRAW;
    wc.lpfnWndProc   := FrameWndProc;
    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,SYSTEM.CAST(Windows.COLOR_TYPE,SYSTEM.CAST(CARDINAL,Windows.COLOR_APPWORKSPACE) + 1));
    wc.lpszMenuName  := NIL;
    wc.lpszClassName := SYSTEM.ADR(szFrameClass);
    wc.hIconSm       := Windows.LoadIcon (NIL, Windows.IDI_APPLICATION);

    rc := Windows.RegisterClassEx (wc);

              (* Register the Hello child window class                   *)

    wc.cbSize        := SIZE(Windows.WNDCLASSEX);
    wc.style         := Windows.CS_HREDRAW + Windows.CS_VREDRAW;
    wc.lpfnWndProc   := HelloWndProc;
    wc.cbClsExtra    := 0;
    wc.cbWndExtra    := SIZE(Windows.HANDLE);
    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  := NIL;
    wc.lpszClassName := SYSTEM.ADR(szHelloClass);
    wc.hIconSm       := Windows.LoadIcon (NIL, Windows.IDI_APPLICATION);

    rc := Windows.RegisterClassEx (wc);

              (* Register the Rect child window class                    *)

    wc.cbSize        := SIZE(Windows.WNDCLASSEX);
    wc.style         := Windows.CS_HREDRAW +  Windows.CS_VREDRAW;
    wc.lpfnWndProc   := RectWndProc;
    wc.cbClsExtra    := 0;
    wc.cbWndExtra    := SIZE(Windows.HANDLE);
    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  := NIL;
    wc.lpszClassName := SYSTEM.ADR(szRectClass);
    wc.hIconSm       := Windows.LoadIcon (NIL, Windows.IDI_APPLICATION);

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

(*+++***********************************************************************)
PROCEDURE InitMainWindow () : BOOLEAN;
(***************************************************************************)
CONST
  Init   = "MdiMenuInit";
  Hello  = "MdiMenuHello";
  Rect   = "MdiMenuRect";
  Accel  = "MdiAccel";
  Demo   = "MDI Demonstration : XDS Modula-2";

BEGIN
     hMenuInit  := Windows.LoadMenu (hInst, SYSTEM.ADR(Init));
     hMenuHello := Windows.LoadMenu (hInst, SYSTEM.ADR(Hello));
     hMenuRect  := Windows.LoadMenu (hInst, SYSTEM.ADR(Rect));

     hMenuInitWindow  := Windows.GetSubMenu (hMenuInit,   h2d_mdidemo.INIT_MENU_POS);
     hMenuHelloWindow := Windows.GetSubMenu (hMenuHello, h2d_mdidemo.HELLO_MENU_POS);
     hMenuRectWindow  := Windows.GetSubMenu (hMenuRect,   h2d_mdidemo.RECT_MENU_POS);

               (* Load accelerator table                                       *)

     hAccel := Windows.LoadAccelerators (hInst, SYSTEM.ADR(Accel));

               (* Obtain handles to three possible menus & submenus            *)


     hwndFrame := Windows.CreateWindow (SYSTEM.ADR(szFrameClass),Demo,
                               Windows.WS_OVERLAPPEDWINDOW + Windows.WS_CLIPCHILDREN,
                               Windows.CW_USEDEFAULT, Windows.CW_USEDEFAULT,
                               Windows.CW_USEDEFAULT, Windows.CW_USEDEFAULT,
                               NIL, hMenuInit, Windows.MyInstance(), NIL);

     hwndClient := Windows.GetWindow (hwndFrame, Windows.GW_CHILD);

  IF hwndFrame = NIL THEN
     RETURN FALSE;
  END;
  Windows.ShowWindow (hwndFrame, Windows.SW_SHOWDEFAULT);
  Windows.UpdateWindow (hwndFrame);
  RETURN TRUE;
END InitMainWindow;
BEGIN
  szFrameClass := "MdiFrame";
  szHelloClass := "MdiHelloChild";
  szRectClass  := "MdiRectChild";
  clrTextArray := COLORREFARRAY
                             { Windows.RGB (0,   0, 0), Windows.RGB (255, 0,   0),
                               Windows.RGB (0, 255, 0), Windows.RGB (  0, 0, 255),
                               Windows.RGB (255, 255, 255) } ;
  IF InitApplication() AND InitMainWindow() THEN
               (* Enter the modified message loop                              *)
    WHILE (Windows.GetMessage (msg, NIL, 0, 0)) DO
          IF ( Windows.TranslateMDISysAccel (hwndClient, msg)=SYSTEM.CAST(Windows.BOOL,0)) AND
              (Windows.TranslateAccelerator (hwndFrame, hAccel, msg)=FALSE) THEN
            Windows.TranslateMessage (msg);
            Windows.DispatchMessage (msg);
          END;
    END;

               (* Clean up by deleting unattached menus                        *)
     Windows.DestroyMenu (hMenuHello);
     Windows.DestroyMenu (hMenuRect);
  END;
END MDIDemo.