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.