Last updated: 4. 3.1998, 23:49
<*/NOWARN:F*> MODULE MDIDemo; (*-------------------------------------------------------- MDIDEMO.C --- Multiple Document Interface Demonstration (c) Charles Petzold, 1996 MDIDemo.mod --- Translation to Stony Brook Modula-2 (c) Peter Stadler, 1998 --------------------------------------------------------*) %IF WIN32 %THEN <*/Resource:MDIDEMO.RES*> %ELSE %END IMPORT WIN32; IMPORT WINUSER; IMPORT SYSTEM; IMPORT h2d_mdidemo; IMPORT WINGDI; IMPORT COMMCTRL; IMPORT COMMDLG; IMPORT RandomNumbers; IMPORT WINX; VAR hPrevInstance : WIN32.HINSTANCE; (* structure for storing data unique to each Hello child window *) TYPE HELLODATA = RECORD iColor : WIN32.UINT; clrText : WIN32.COLORREF; END; LPHELLODATA = POINTER TO HELLODATA; (* structure for storing data unique to each Rect child window *) RECTDATA = RECORD cxClient : WIN32.SHORT; cyClient : WIN32.SHORT; END; LPRECTDATA = POINTER TO RECTDATA; (* global variables *) VAR szFrameClass : ARRAY[0..20] OF CHAR = "MdiFrame"; szHelloClass : ARRAY[0..20] OF CHAR = "MdiHelloChild"; szRectClass : ARRAY[0..20] OF CHAR = "MdiRectChild"; VAR hInst : WIN32.HINSTANCE; hMenuInit : WIN32.HMENU; hMenuHello : WIN32.HMENU; hMenuRect : WIN32.HMENU; hMenuInitWindow : WIN32.HMENU; hMenuHelloWindow : WIN32.HMENU; hMenuRectWindow : WIN32.HMENU; VAR hAccel : WIN32.HACCEL; hwndFrame : WIN32.HWND; hwndClient : WIN32.HWND; msg : WINUSER.MSG; wc : WINUSER.WNDCLASSEX; (* static in different WndProcs *) hwndClientOfRect : WIN32.HWND; hwndFrameOfRect : WIN32.HWND; hwndClientOfFrame : WIN32.HWND; hwndClientOfHello : WIN32.HWND; hwndFrameOfHello : WIN32.HWND; TYPE COLORREFARRAY= ARRAY[0..4] OF WIN32.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; <*/PUSH*> %IF WIN32 %THEN <*/CALLS:WIN32SYSTEM*> %ELSE <*/CALLS:WINSYSTEM*> %END (*++++**********************************************************************) PROCEDURE FrameWndProc (hwnd : WIN32.HWND; iMsg : WIN32.UINT; wParam : WIN32.WPARAM; lParam : WIN32.LPARAM) : WIN32.LRESULT [EXPORT]; (***************************************************************************) VAR clientcreate : WINUSER.CLIENTCREATESTRUCT; hwndChild : WIN32.HWND; mdicreate : WINUSER.MDICREATESTRUCT; BEGIN CASE (iMsg) OF | WINUSER.WM_CREATE : (* Create the client window *) clientcreate.hWindowMenu := hMenuInitWindow; clientcreate.idFirstChild := h2d_mdidemo.IDM_FIRSTCHILD; hwndClientOfFrame := WINUSER.CreateWindow ("MDICLIENT", "", WINUSER.WS_CHILD BOR WINUSER.WS_CLIPCHILDREN BOR WINUSER.WS_VISIBLE, 0, 0, 0, 0, hwnd, SYSTEM.CAST(WIN32.HMENU, 1), hInst, SYSTEM.CAST(WIN32.LPSTR, SYSTEM.ADR(clientcreate))); RETURN 0; | WINUSER.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 := hInst; mdicreate.x := WINUSER.CW_USEDEFAULT; mdicreate.y := WINUSER.CW_USEDEFAULT; mdicreate.cx := WINUSER.CW_USEDEFAULT; mdicreate.cy := WINUSER.CW_USEDEFAULT; mdicreate.style := 0; mdicreate.lParam := 0; hwndChild := SYSTEM.CAST(WIN32.HWND, WINUSER.SendMessage (hwndClientOfFrame, WINUSER.WM_MDICREATE, 0, SYSTEM.CAST(WIN32.LPARAM,SYSTEM.CAST(WINUSER.LPMDICREATESTRUCT, SYSTEM.ADR(mdicreate))))); RETURN 0; | h2d_mdidemo.IDM_NEWRECT : (* Create a Rect child window *) mdicreate.szClass := SYSTEM.ADR(szRectClass); mdicreate.szTitle := SYSTEM.ADR("Rectangles"); mdicreate.hOwner := hInst; mdicreate.x := WINUSER.CW_USEDEFAULT; mdicreate.y := WINUSER.CW_USEDEFAULT; mdicreate.cx := WINUSER.CW_USEDEFAULT; mdicreate.cy := WINUSER.CW_USEDEFAULT; mdicreate.style := 0; mdicreate.lParam := 0; hwndChild := SYSTEM.CAST(WIN32.HWND, WINUSER.SendMessage (hwndClientOfFrame, WINUSER.WM_MDICREATE, 0, SYSTEM.CAST(WIN32.LPARAM,SYSTEM.CAST(WINUSER.LPMDICREATESTRUCT, SYSTEM.ADR(mdicreate))))); RETURN 0; | h2d_mdidemo.IDM_CLOSE : (* Close the active window *) hwndChild := SYSTEM.CAST(WIN32.HWND, WINUSER.SendMessage (hwndClientOfFrame, WINUSER.WM_MDIGETACTIVE, 0, 0)); IF (WINUSER.SendMessage (hwndChild, WINUSER.WM_QUERYENDSESSION, 0, 0)=1) THEN WINUSER.SendMessage (hwndClientOfFrame, WINUSER.WM_MDIDESTROY, SYSTEM.CAST(WIN32.WPARAM, hwndChild), 0); END; RETURN 0; | h2d_mdidemo.IDM_EXIT : (* Exit the program *) WINUSER.SendMessage (hwnd, WINUSER.WM_CLOSE, 0, 0); RETURN 0; (* messages for arranging windows *) | h2d_mdidemo.IDM_TILE : WINUSER.SendMessage (hwndClientOfFrame, WINUSER.WM_MDITILE, 0, 0); RETURN 0; | h2d_mdidemo.IDM_CASCADE : WINUSER.SendMessage (hwndClientOfFrame, WINUSER.WM_MDICASCADE, 0, 0); RETURN 0; | h2d_mdidemo.IDM_ARRANGE : WINUSER.SendMessage (hwndClientOfFrame, WINUSER.WM_MDIICONARRANGE, 0, 0); RETURN 0; | h2d_mdidemo.IDM_CLOSEALL : (* Attempt to close all children *) WINUSER.EnumChildWindows (hwndClientOfFrame, CloseEnumProc, 0); RETURN 0; ELSE (* Pass to active child... *) hwndChild := SYSTEM.CAST(WIN32.HWND, WINUSER.SendMessage (hwndClientOfFrame, WINUSER.WM_MDIGETACTIVE, 0, 0)); IF (WINUSER.IsWindow (hwndChild)) THEN WINUSER.SendMessage (hwndChild, WINUSER.WM_COMMAND, wParam, lParam); END; (*break*) (* ...and then to DefFrameProc *) END; (*break*) | WINUSER.WM_QUERYENDSESSION : | WINUSER.WM_CLOSE : (* Attempt to close all children *) WINUSER.SendMessage (hwnd, WINUSER.WM_COMMAND, h2d_mdidemo.IDM_CLOSEALL, 0); IF (NIL # WINUSER.GetWindow (hwndClientOfFrame, WINUSER.GW_CHILD)) THEN RETURN 0; END; (*break*) (* I.e., call DefFrameProc *) | WINUSER.WM_DESTROY : WINUSER.PostQuitMessage (0); RETURN 0; (* Pass unprocessed messages to DefFrameProc (not DefWindowProc)*) RETURN WINUSER.DefFrameProc (hwnd, hwndClientOfFrame, iMsg, wParam, lParam); ELSE RETURN 0; END; END FrameWndProc; <*/POP*> <*/PUSH*> %IF WIN32 %THEN <*/CALLS:WIN32SYSTEM*> %ELSE <*/CALLS:WINSYSTEM*> %END (*++++**********************************************************************) PROCEDURE CloseEnumProc (hwnd : WIN32.HWND; lParam : WIN32.LPARAM) : WIN32.BOOL [EXPORT]; (***************************************************************************) BEGIN IF (WINUSER.GetWindow (hwnd, WINUSER.GW_OWNER)#NIL) THEN (* Check for icon title *) RETURN SYSTEM.CAST(WIN32.BOOL,1); END; WINUSER.SendMessage (WINUSER.GetParent (hwnd), WINUSER.WM_MDIRESTORE, SYSTEM.CAST(WIN32.WPARAM,hwnd), 0); IF (WINUSER.SendMessage (hwnd, WINUSER.WM_QUERYENDSESSION, 0, 0)#0) THEN RETURN SYSTEM.CAST(WIN32.BOOL,1); END; WINUSER.SendMessage (WINUSER.GetParent (hwnd), WINUSER.WM_MDIDESTROY, SYSTEM.CAST(WIN32.WPARAM,hwnd), 0); RETURN SYSTEM.CAST(WIN32.BOOL,1); END CloseEnumProc; <*/POP*> <*/PUSH*> %IF WIN32 %THEN <*/CALLS:WIN32SYSTEM*> %ELSE <*/CALLS:WINSYSTEM*> %END (*++++**********************************************************************) PROCEDURE HelloWndProc (hwnd : WIN32.HWND; iMsg : WIN32.UINT; wParam : WIN32.WPARAM; lParam : WIN32.LPARAM) : WIN32.LRESULT [EXPORT]; (***************************************************************************) VAR hdc : WIN32.HDC; hMenu : WIN32.HMENU; lpHelloData : LPHELLODATA; ps : WINUSER.PAINTSTRUCT; rect : WIN32.RECT; par : WIN32.LPARAM; BEGIN CASE (iMsg) OF | WINUSER.WM_CREATE : (* Allocate memory for window private data *) lpHelloData := SYSTEM.CAST(LPHELLODATA, WIN32.HeapAlloc (WIN32.GetProcessHeap (), WIN32.HEAP_ZERO_MEMORY, SIZE(HELLODATA))); lpHelloData^.iColor := h2d_mdidemo.IDM_BLACK; lpHelloData^.clrText := WINGDI.RGB (0, 0, 0); WINUSER.SetWindowLong (hwnd, 0, SYSTEM.CAST(WIN32.LONG, lpHelloData)); (* Save some window handles *) hwndClientOfHello := WINUSER.GetParent (hwnd); hwndFrameOfHello := WINUSER.GetParent (hwndClientOfHello); RETURN 0; | WINUSER.WM_COMMAND : CASE (wParam) OF | h2d_mdidemo.IDM_BLACK : lpHelloData := SYSTEM.CAST(LPHELLODATA, WINUSER.GetWindowLong (hwnd, 0)); hMenu := WINUSER.GetMenu (hwndFrameOfHello); WINUSER.CheckMenuItem (hMenu, lpHelloData^.iColor, WINUSER.MF_UNCHECKED); lpHelloData^.iColor := wParam; WINUSER.CheckMenuItem (hMenu, lpHelloData^.iColor, WINUSER.MF_CHECKED); lpHelloData^.clrText := clrTextArray[wParam - h2d_mdidemo.IDM_BLACK]; WINUSER.InvalidateRect (hwnd, WINX.NIL_RECT, FALSE); RETURN 0; | h2d_mdidemo.IDM_RED : lpHelloData := SYSTEM.CAST(LPHELLODATA, WINUSER.GetWindowLong (hwnd, 0)); hMenu := WINUSER.GetMenu (hwndFrameOfHello); WINUSER.CheckMenuItem (hMenu, lpHelloData^.iColor, WINUSER.MF_UNCHECKED); lpHelloData^.iColor := wParam; WINUSER.CheckMenuItem (hMenu, lpHelloData^.iColor, WINUSER.MF_CHECKED); lpHelloData^.clrText := clrTextArray[wParam - h2d_mdidemo.IDM_BLACK]; WINUSER.InvalidateRect (hwnd, WINX.NIL_RECT, FALSE); RETURN 0; | h2d_mdidemo.IDM_GREEN : lpHelloData := SYSTEM.CAST(LPHELLODATA, WINUSER.GetWindowLong (hwnd, 0)); hMenu := WINUSER.GetMenu (hwndFrameOfHello); WINUSER.CheckMenuItem (hMenu, lpHelloData^.iColor, WINUSER.MF_UNCHECKED); lpHelloData^.iColor := wParam; WINUSER.CheckMenuItem (hMenu, lpHelloData^.iColor, WINUSER.MF_CHECKED); lpHelloData^.clrText := clrTextArray[wParam - h2d_mdidemo.IDM_BLACK]; WINUSER.InvalidateRect (hwnd, WINX.NIL_RECT, FALSE); RETURN 0; | h2d_mdidemo.IDM_BLUE : lpHelloData := SYSTEM.CAST(LPHELLODATA, WINUSER.GetWindowLong (hwnd, 0)); hMenu := WINUSER.GetMenu (hwndFrameOfHello); WINUSER.CheckMenuItem (hMenu, lpHelloData^.iColor, WINUSER.MF_UNCHECKED); lpHelloData^.iColor := wParam; WINUSER.CheckMenuItem (hMenu, lpHelloData^.iColor, WINUSER.MF_CHECKED); lpHelloData^.clrText := clrTextArray[wParam - h2d_mdidemo.IDM_BLACK]; WINUSER.InvalidateRect (hwnd, WINX.NIL_RECT, FALSE); RETURN 0; | h2d_mdidemo.IDM_WHITE : (* Change the text color *) lpHelloData := SYSTEM.CAST(LPHELLODATA, WINUSER.GetWindowLong (hwnd, 0)); hMenu := WINUSER.GetMenu (hwndFrameOfHello); WINUSER.CheckMenuItem (hMenu, lpHelloData^.iColor, WINUSER.MF_UNCHECKED); lpHelloData^.iColor := wParam; WINUSER.CheckMenuItem (hMenu, lpHelloData^.iColor, WINUSER.MF_CHECKED); lpHelloData^.clrText := clrTextArray[wParam - h2d_mdidemo.IDM_BLACK]; WINUSER.InvalidateRect (hwnd, WINX.NIL_RECT, FALSE); RETURN 0; ELSE RETURN 0; END; | WINUSER.WM_PAINT : (* Paint the window *) hdc := WINUSER.BeginPaint (hwnd, ps); lpHelloData := SYSTEM.CAST(LPHELLODATA, WINUSER.GetWindowLong (hwnd, 0)); WINGDI.SetTextColor (hdc, lpHelloData^.clrText); WINUSER.GetClientRect (hwnd, rect); WINUSER.DrawText (hdc, "Hello, World!", -1, rect, WINUSER.DT_SINGLELINE BOR WINUSER.DT_CENTER BOR WINUSER.DT_VCENTER); WINUSER.EndPaint (hwnd, ps); RETURN 0; | WINUSER.WM_MDIACTIVATE : (* Set the Hello menu if gaining focus *) IF (lParam = SYSTEM.CAST(WIN32.LPARAM, hwnd)) THEN WINUSER.SendMessage (hwndClientOfHello, WINUSER.WM_MDISETMENU, SYSTEM.CAST(WIN32.WPARAM, hMenuHello), SYSTEM.CAST(WIN32.LPARAM, hMenuHelloWindow)); END; (* Check or uncheck menu item *) lpHelloData := SYSTEM.CAST(LPHELLODATA, WINUSER.GetWindowLong (hwnd, 0)); IF(lParam = SYSTEM.CAST(WIN32.LPARAM,hwnd)) THEN par := WINUSER.MF_CHECKED; ELSE par := WINUSER.MF_UNCHECKED; END; WINUSER.CheckMenuItem (hMenuHello, lpHelloData^.iColor,par); (* Set the Init menu if losing focus *) IF (lParam # SYSTEM.CAST(WIN32.LPARAM, hwnd)) THEN WINUSER.SendMessage (hwndClientOfHello, WINUSER.WM_MDISETMENU, SYSTEM.CAST(WIN32.WPARAM, hMenuInit), SYSTEM.CAST(WIN32.LPARAM, hMenuInitWindow)); END; WINUSER.DrawMenuBar (hwndFrameOfHello); RETURN 0; | WINUSER.WM_QUERYENDSESSION : | WINUSER.WM_CLOSE : IF (WINUSER.IDOK # WINUSER.MessageBox (hwnd, "OK to close window?", "Hello", WINUSER.MB_ICONQUESTION BOR WINUSER.MB_OKCANCEL)) THEN RETURN 0; END; (*break*) (* I.e., call DefMDIChildProc *) | WINUSER.WM_DESTROY : lpHelloData := SYSTEM.CAST(LPHELLODATA, WINUSER.GetWindowLong (hwnd, 0)); WIN32.HeapFree (WIN32.GetProcessHeap (), 0, lpHelloData); RETURN 0; ELSE (* Pass unprocessed message to DefMDIChildProc *) RETURN WINUSER.DefMDIChildProc (hwnd, iMsg, wParam, lParam); END; END HelloWndProc; <*/POP*> <*/PUSH*> %IF WIN32 %THEN <*/CALLS:WIN32SYSTEM*> %ELSE <*/CALLS:WINSYSTEM*> %END (*++++**********************************************************************) PROCEDURE RectWndProc (hwnd : WIN32.HWND; iMsg : WIN32.UINT; wParam : WIN32.WPARAM; lParam : WIN32.LPARAM) : WIN32.LRESULT [EXPORT]; (***************************************************************************) VAR hBrush : WIN32.HBRUSH; hdc : WIN32.HDC; lpRectData : LPRECTDATA; ps : WINUSER.PAINTSTRUCT; xLeft : INTEGER; xRight : INTEGER; yTop : INTEGER; yBottom : INTEGER; nRed : WIN32.SHORT; nGreen : WIN32.SHORT; nBlue : WIN32.SHORT; BEGIN CASE (iMsg) OF | WINUSER.WM_CREATE : (* Allocate memory for window private data *) lpRectData := SYSTEM.CAST(LPRECTDATA, WIN32.HeapAlloc (WIN32.GetProcessHeap (), WIN32.HEAP_ZERO_MEMORY, SIZE(RECTDATA))); WINUSER.SetWindowLong (hwnd, 0, SYSTEM.CAST(WIN32.LONG,lpRectData)); (* Start the timer going *) WINUSER.SetTimer (hwnd, 1, 250, NIL); (* Save some window handles *) hwndClientOfRect := WINUSER.GetParent (hwnd); hwndFrameOfRect := WINUSER.GetParent (hwndClientOfRect); RETURN 0; | WINUSER.WM_SIZE : (* If not minimized, save the window size *) IF (wParam # WINUSER.SIZE_MINIMIZED) THEN lpRectData := SYSTEM.CAST(LPRECTDATA, WINUSER.GetWindowLong (hwnd, 0)); lpRectData^.cxClient := WINUSER.LOWORD (lParam); lpRectData^.cyClient := WINUSER.HIWORD (lParam); END; (*break*) (* WINUSER.WM_SIZE must be processed by DefMDIChildProc *) | WINUSER.WM_TIMER : (* Display a random rectangle *) lpRectData := SYSTEM.CAST(LPRECTDATA, WINUSER.GetWindowLong (hwnd, 0)); xLeft := VAL(INTEGER,RandomNumbers.Random(0,1000) REM VAL(CARDINAL,lpRectData^.cxClient)); xRight := VAL(INTEGER,RandomNumbers.Random(0,1000) REM VAL(CARDINAL,lpRectData^.cxClient)); yTop := VAL(INTEGER,RandomNumbers.Random(0,1000) REM VAL(CARDINAL,lpRectData^.cyClient)); yBottom := VAL(INTEGER,RandomNumbers.Random(0,1000) REM VAL(CARDINAL,lpRectData^.cyClient)); nRed := VAL(INTEGER,RandomNumbers.Random(0,1000) BAND 255); nGreen := VAL(INTEGER,RandomNumbers.Random(0,1000) BAND 255); nBlue := VAL(INTEGER,RandomNumbers.Random(0,1000) BAND 255); hdc := WINUSER.GetDC (hwnd); hBrush := WINGDI.CreateSolidBrush (WINGDI.RGB (nRed, nGreen, nBlue)); WINGDI.SelectObject (hdc, SYSTEM.CAST(WIN32.HGDIOBJ,hBrush)); WINGDI.Rectangle (hdc, MinInt (xLeft, xRight), MinInt (yTop, yBottom), MaxInt (xLeft, xRight), MaxInt (yTop, yBottom)); WINUSER.ReleaseDC (hwnd, hdc); WINGDI.DeleteObject (SYSTEM.CAST(WIN32.HGDIOBJ,hBrush)); RETURN 0; | WINUSER.WM_PAINT : (* Clear the window *) WINUSER.InvalidateRect (hwnd, WINX.NIL_RECT, TRUE); hdc := WINUSER.BeginPaint (hwnd, ps); WINUSER.EndPaint (hwnd, ps); RETURN 0; | WINUSER.WM_MDIACTIVATE : (* Set the appropriate menu *) IF (lParam = SYSTEM.CAST(WIN32.LPARAM, hwnd)) THEN WINUSER.SendMessage (hwndClientOfRect, WINUSER.WM_MDISETMENU, SYSTEM.CAST(WIN32.WPARAM, hMenuRect), SYSTEM.CAST(WIN32.LPARAM,hMenuRectWindow)); ELSE WINUSER.SendMessage (hwndClientOfRect, WINUSER.WM_MDISETMENU, SYSTEM.CAST(WIN32.WPARAM, hMenuInit), SYSTEM.CAST(WIN32.LPARAM, hMenuInitWindow)); END; WINUSER.DrawMenuBar (hwndFrameOfRect); RETURN 0; | WINUSER.WM_DESTROY : lpRectData := SYSTEM.CAST(LPRECTDATA, WINUSER.GetWindowLong (hwnd, 0)); WIN32.HeapFree (WIN32.GetProcessHeap (), 0, lpRectData); WINUSER.KillTimer (hwnd, 1); RETURN 0; (* Pass unprocessed message to DefMDIChildProc *) ELSE RETURN WINUSER.DefMDIChildProc (hwnd, iMsg, wParam, lParam); END; END RectWndProc; <*/POP*> (*+++***********************************************************************) PROCEDURE InitApplication () : BOOLEAN; (***************************************************************************) VAR rc : CARDINAL; BEGIN hInst := WINX.Instance; hPrevInstance := WINX.PrevInstance; IF (hPrevInstance=NIL) THEN (* Register the frame window class *) wc.cbSize := SIZE(WINUSER.WNDCLASSEX); wc.style := WINUSER.CS_HREDRAW BOR WINUSER.CS_VREDRAW; wc.lpfnWndProc := FrameWndProc; wc.cbClsExtra := 0; wc.cbWndExtra := 0; wc.hInstance := WINX.Instance; wc.hIcon := WINUSER.LoadIcon (NIL, WINUSER.IDI_APPLICATION^); wc.hCursor := WINUSER.LoadCursor (NIL, WINUSER.IDC_ARROW^); wc.hbrBackground := SYSTEM.CAST(WIN32.HBRUSH,WINUSER.COLOR_APPWORKSPACE + 1); wc.lpszMenuName := NIL; wc.lpszClassName := SYSTEM.ADR(szFrameClass); wc.hIconSm := WINUSER.LoadIcon (NIL, WINUSER.IDI_APPLICATION^); rc := WINUSER.RegisterClassEx (wc); (* Register the Hello child window class *) wc.cbSize := SIZE(WINUSER.WNDCLASSEX); wc.style := WINUSER.CS_HREDRAW BOR WINUSER.CS_VREDRAW; wc.lpfnWndProc := HelloWndProc; wc.cbClsExtra := 0; wc.cbWndExtra := SIZE(WIN32.HANDLE); wc.hInstance := WINX.Instance; wc.hIcon := WINUSER.LoadIcon (NIL, WINUSER.IDI_APPLICATION^); wc.hCursor := WINUSER.LoadCursor (NIL, WINUSER.IDC_ARROW^); wc.hbrBackground := SYSTEM.CAST(WIN32.HBRUSH, WINGDI.GetStockObject (WINGDI.WHITE_BRUSH)); wc.lpszMenuName := NIL; wc.lpszClassName := SYSTEM.ADR(szHelloClass); wc.hIconSm := WINUSER.LoadIcon (NIL, WINUSER.IDI_APPLICATION^); rc := WINUSER.RegisterClassEx (wc); (* Register the Rect child window class *) wc.cbSize := SIZE(WINUSER.WNDCLASSEX); wc.style := WINUSER.CS_HREDRAW BOR WINUSER.CS_VREDRAW; wc.lpfnWndProc := RectWndProc; wc.cbClsExtra := 0; wc.cbWndExtra := SIZE(WIN32.HANDLE); wc.hInstance := WINX.Instance; wc.hIcon := WINUSER.LoadIcon (NIL, WINUSER.IDI_APPLICATION^); wc.hCursor := WINUSER.LoadCursor (NIL, WINUSER.IDC_ARROW^); wc.hbrBackground := SYSTEM.CAST(WIN32.HBRUSH, WINGDI.GetStockObject (WINGDI.WHITE_BRUSH)); wc.lpszMenuName := NIL; wc.lpszClassName := SYSTEM.ADR(szRectClass); wc.hIconSm := WINUSER.LoadIcon (NIL, WINUSER.IDI_APPLICATION^); rc := WINUSER.RegisterClassEx (wc); RETURN rc #0; END; END InitApplication; (*+++***********************************************************************) PROCEDURE InitMainWindow () : BOOLEAN; (***************************************************************************) BEGIN hMenuInit := WINUSER.LoadMenu (hInst, "MdiMenuInit"); hMenuHello := WINUSER.LoadMenu (hInst, "MdiMenuHello"); hMenuRect := WINUSER.LoadMenu (hInst, "MdiMenuRect"); hMenuInitWindow := WINUSER.GetSubMenu (hMenuInit, h2d_mdidemo.INIT_MENU_POS); hMenuHelloWindow := WINUSER.GetSubMenu (hMenuHello, h2d_mdidemo.HELLO_MENU_POS); hMenuRectWindow := WINUSER.GetSubMenu (hMenuRect, h2d_mdidemo.RECT_MENU_POS); (* Load accelerator table *) hAccel := WINUSER.LoadAccelerators (hInst, "MdiAccel"); (* Obtain handles to three possible menus & submenus *) hwndFrame := WINUSER.CreateWindow (szFrameClass, "MDI Demonstration : Stony Brook Modula-2", WINUSER.WS_OVERLAPPEDWINDOW BOR WINUSER.WS_CLIPCHILDREN, WINUSER.CW_USEDEFAULT, WINUSER.CW_USEDEFAULT, WINUSER.CW_USEDEFAULT, WINUSER.CW_USEDEFAULT, NIL, hMenuInit, WINX.Instance, NIL); hwndClient := WINUSER.GetWindow (hwndFrame, WINUSER.GW_CHILD); IF hwndFrame = NIL THEN RETURN FALSE; END; WINUSER.ShowWindow (hwndFrame, WINUSER.SW_SHOWDEFAULT); WINUSER.UpdateWindow (hwndFrame); RETURN TRUE; END InitMainWindow; BEGIN clrTextArray := COLORREFARRAY { WINGDI.RGB (0, 0, 0), WINGDI.RGB (255, 0, 0), WINGDI.RGB (0, 255, 0), WINGDI.RGB ( 0, 0, 255), WINGDI.RGB (255, 255, 255) } ; IF InitApplication() AND InitMainWindow() THEN (* Enter the modified message loop *) WHILE (WINUSER.GetMessage (msg, NIL, 0, 0)) DO IF ( WINUSER.TranslateMDISysAccel (hwndClient, msg)=SYSTEM.CAST(WIN32.BOOL,0)) AND (WINUSER.TranslateAccelerator (hwndFrame, hAccel, msg)=0) THEN WINUSER.TranslateMessage (msg); WINUSER.DispatchMessage (msg); END; END; (* Clean up by deleting unattached menus *) WINUSER.DestroyMenu (hMenuHello); WINUSER.DestroyMenu (hMenuRect); END; END MDIDemo.