PopPad.mod: Translation to Stony Brook Modula-2

Last updated: 18. 1.1998, 17:29

<*/NOWARN:F*>
MODULE PopPad;
(*---------------------------------------
   POPPAD.C        --- Popup Editor
                   (c) Charles Petzold, 1996
   PopPad.mod      --- Translation to Stony Brook Modula-2
                   (c) Peter Stadler,   1997
  ---------------------------------------*)

%IF WIN32 %THEN
    <*/Resource:poppad.RES*>
%ELSE
%END
IMPORT WINUSER;
IMPORT WIN32;
IMPORT WINGDI;
IMPORT WINX;
IMPORT COMMDLG;
IMPORT SYSTEM;
IMPORT h2d_poppad;
IMPORT PopFile;
IMPORT PopFind;
IMPORT PopFont;
IMPORT PopPrnt;
IMPORT Strings;
IMPORT Str;
CONST
  EDITID = 1;
  UNTITLED = "(untitled)";

          (* Global variables  *)

CONST
  szAppName = "PopPad";
VAR
  bNeedSave       :  BOOLEAN;
  szFileName      :  ARRAY[0..WIN32.MAX_PATH] OF CHAR;
  szTitleName     :  ARRAY[0..WIN32.MAX_FNAME+WIN32.MAX_EXT] OF CHAR;
  hInst           :  WIN32.HINSTANCE;
  hwndEdit        :  WIN32.HWND;
  iMsgFindReplace :  CARDINAL;
  iSelBeg         :  INTEGER;
  iSelEnd         :  INTEGER;
  iEnable         :  INTEGER;
  pfr             :  COMMDLG.LPFINDREPLACE;
  iOffset         :  INTEGER;

  hDlgModeless    :  WIN32.HWND;
  hAccel          :  WIN32.HACCEL;
  hwnd            :  WIN32.HWND;
  msg             :  WINUSER.MSG;
  wc              :  WINUSER.WNDCLASSEX;
  ok              :  WIN32.BOOL;
  szCmdLine       :  WIN32.PSTR;
(*++++*****************************************************************)
PROCEDURE DoCaption (hwnd : WIN32.HWND;
(**********************************************************************)
                     VAR szTitleName : ARRAY OF CHAR);
VAR
  szCaption : ARRAY[0..64+WIN32.MAX_FNAME+WIN32.MAX_EXT] OF CHAR;
BEGIN

  IF(szTitleName[0]='') THEN
    Strings.Replace(UNTITLED,0,szTitleName);
  END;
  WINUSER.wsprintf (szCaption, "%s - %s", szAppName,
            szTitleName);
  WINUSER.SetWindowText (hwnd, szCaption);
END DoCaption;
(*++++*****************************************************************)
PROCEDURE OkMessage (hwnd        :  WIN32.HWND;
                     szMessage   :  ARRAY OF CHAR;
                     szTitleName :  ARRAY OF CHAR);
(**********************************************************************)
VAR
  szBuffer : ARRAY[0..64+WIN32.MAX_FNAME+WIN32.MAX_EXT] OF CHAR;
BEGIN
  IF(szTitleName[0]='') THEN
    Strings.Replace(UNTITLED,0,szTitleName);
  END;
  WINUSER.wsprintf (szBuffer, szMessage, szTitleName);
  WINUSER.MessageBox (hwnd, szBuffer, szAppName, WINUSER.MB_OK BOR WINUSER.MB_ICONEXCLAMATION);
END OkMessage;
(*++++*****************************************************************)
PROCEDURE AskAboutSave (hwnd          :  WIN32.HWND;
                        VAR szTitleName   :  ARRAY OF CHAR) : WIN32.SHORT;
(**********************************************************************)
VAR
  szBuffer : ARRAY[0..64+WIN32.MAX_FNAME+WIN32.MAX_EXT] OF CHAR;
  iReturn  : INTEGER;
BEGIN
  IF(szTitleName[0]='') THEN
    Strings.Replace(UNTITLED,0,szTitleName);
  END;
  WINUSER.wsprintf (szBuffer, "Save current changes in %s?",
                   szTitleName);
     iReturn := WINUSER.MessageBox (hwnd, szBuffer, szAppName,
                           WINUSER.MB_YESNOCANCEL BOR WINUSER.MB_ICONQUESTION);

     IF (iReturn = WINUSER.IDYES) THEN
          IF (WINUSER.SendMessage (hwnd, WINUSER.WM_COMMAND, h2d_poppad.IDM_SAVE, 0000h)=0) THEN
               iReturn := WINUSER.IDCANCEL;
          END;
     END;
     RETURN iReturn;
END AskAboutSave;

<*/PUSH*>
%IF WIN32 %THEN
    <*/CALLS:WIN32SYSTEM*>
%ELSE
    <*/CALLS:WINSYSTEM*>
%END
(*++++*****************************************************************)
PROCEDURE AboutDlgProc (hDlg        : WIN32.HWND;
(**********************************************************************)
                        iMsg        : WIN32.UINT;
                        wParam      : WIN32.WPARAM;
                        lParam      : WIN32.LPARAM) : WIN32.BOOL [EXPORT];

BEGIN
     CASE (iMsg) OF
          | WINUSER.WM_INITDIALOG :
               RETURN TRUE;

          | WINUSER.WM_COMMAND :
               CASE (WINUSER.LOWORD (wParam)) OF
                    | WINUSER.IDOK :
                         WINUSER.EndDialog (hDlg, 0);
                         RETURN TRUE;
               ELSE
                         RETURN TRUE;
               END;
             (*break; *)
     ELSE
       RETURN FALSE;
     END;
     RETURN FALSE;
END AboutDlgProc;


<*/POP*>

<*/PUSH*>
%IF WIN32 %THEN
    <*/CALLS:WIN32SYSTEM*>
%ELSE
    <*/CALLS:WINSYSTEM*>
%END
(*++++*****************************************************************)
PROCEDURE WndProc (hwnd        : WIN32.HWND;
                   iMsg        : WIN32.UINT;
                   wParam      : WIN32.WPARAM;
                   lParam      : WIN32.LPARAM) : WIN32.LRESULT [EXPORT];
(**********************************************************************)

VAR
  bo   :  WIN32.BOOL;
  lr   :  WIN32.LRESULT;
  mf   :  CARDINAL;
  lpcr  : WINUSER.LPCREATESTRUCT;
  pstr  : WIN32.PSTR; 
BEGIN
     bNeedSave := FALSE;
     CASE (iMsg) OF
          | WINUSER.WM_CREATE :

                         (* Create the edit control child window                *)

               
               lpcr := SYSTEM.CAST(WINUSER.LPCREATESTRUCT,lParam);
               hInst := lpcr^.hInstance;
               hwndEdit := WINUSER.CreateWindow ("edit",
                         "",
                         WINUSER.WS_CHILD BOR WINUSER.WS_VISIBLE BOR WINUSER.WS_HSCROLL BOR WINUSER.WS_VSCROLL BOR
                         WINUSER.WS_BORDER BOR WINUSER.ES_LEFT BOR WINUSER.ES_MULTILINE BOR
                         WINUSER.ES_NOHIDESEL BOR WINUSER.ES_AUTOHSCROLL BOR WINUSER.ES_AUTOVSCROLL,
                         0,
                         0,
                         0,
                         0,
                         hwnd,
                         SYSTEM.CAST(WIN32.HMENU,EDITID),
                         hInst,
                         NIL);

               WINUSER.SendMessage (hwndEdit, WINUSER.EM_LIMITTEXT, 32000, 0000h);

                         (* Initialize common dialog box stuff                  *)

               PopFile.Initialize (hwnd);
               PopFont.Initialize (hwndEdit);

               iMsgFindReplace := WINUSER.RegisterWindowMessage (COMMDLG.FINDMSGSTRING);

                         (* Process command line                                *)
               lpcr := SYSTEM.CAST(WINUSER.LPCREATESTRUCT,lParam);
               pstr := SYSTEM.CAST(WIN32.PSTR,lpcr^.lpCreateParams);
               Str.Copy(szFileName,pstr^);
               IF (LENGTH(szFileName) > 0) THEN
                    COMMDLG.GetFileTitle (szFileName, szTitleName,
                                  LENGTH(szTitleName));
                    IF (PopFile.Read (hwndEdit, SYSTEM.ADR(szFileName))=FALSE) THEN
                         OkMessage (hwnd, "File %s cannot be read!",
                                          szTitleName);
                    END;
               END;
               DoCaption (hwnd, szTitleName);
               RETURN 0;

          | WINUSER.WM_SETFOCUS :
               WINUSER.SetFocus (hwndEdit);
               RETURN 0;

          | WINUSER.WM_SIZE :
               WINUSER.MoveWindow (hwndEdit, 0, 0, WINUSER.LOWORD (lParam),
                                           WINUSER.HIWORD (lParam), TRUE);
               RETURN 0;

          | WINUSER.WM_INITMENUPOPUP :
               CASE (lParam) OF
                    | 1 :     (* Edit menu                                   *)

                              (* Enable Undo if edit control can do it          *)

                         lr := WINUSER.SendMessage (hwndEdit, WINUSER.EM_CANUNDO, 0, 0000h);
                         IF(lr=1) THEN
                           mf := WINUSER.MF_ENABLED;
                         ELSIF(lr=0) THEN
                           mf := WINUSER.MF_GRAYED;
                         END;
                         WINUSER.EnableMenuItem (SYSTEM.CAST(WIN32.HMENU,wParam), h2d_poppad.IDM_UNDO,mf);

                              (* Enable Paste IF text is in the clipboard       *)

                         bo := WINUSER.IsClipboardFormatAvailable (WINUSER.CF_TEXT);
                         IF(bo=TRUE) THEN
                           mf := WINUSER.MF_ENABLED;
                         ELSIF(bo=FALSE) THEN
                           mf := WINUSER.MF_GRAYED;
                         END;
                         WINUSER.EnableMenuItem (SYSTEM.CAST(WIN32.HMENU,wParam), h2d_poppad.IDM_PASTE,mf);

                              (* Enable Cut, Copy, and Del IF text is selected  *)

                         WINUSER.SendMessage (hwndEdit, WINUSER.EM_GETSEL, SYSTEM.CAST(WIN32.WPARAM,iSelBeg),
                                                           SYSTEM.CAST(WIN32.LPARAM,iSelEnd));

                         IF(iSelBeg#iSelEnd) THEN
                           iEnable := SYSTEM.CAST(INTEGER,WINUSER.MF_ENABLED);
                         ELSE
                           iEnable := SYSTEM.CAST(INTEGER,WINUSER.MF_GRAYED);
                         END;

                         WINUSER.EnableMenuItem (SYSTEM.CAST(WIN32.HMENU, wParam), h2d_poppad.IDM_CUT,   iEnable);
                         WINUSER.EnableMenuItem (SYSTEM.CAST(WIN32.HMENU, wParam), h2d_poppad.IDM_COPY,  iEnable);
                         WINUSER.EnableMenuItem (SYSTEM.CAST(WIN32.HMENU, wParam), h2d_poppad.IDM_CLEAR, iEnable);

                    | 2 :     (* Search menu                                 *)

                              (* Enable Find, Next, and Replace IF modeless     *)
                              (*   dialogs are not already active               *)

                         IF(hDlgModeless=NIL) THEN
                           iEnable := SYSTEM.CAST(INTEGER,WINUSER.MF_ENABLED);
                         ELSE
                           iEnable := SYSTEM.CAST(INTEGER,WINUSER.MF_GRAYED);
                         END;

                         WINUSER.EnableMenuItem (SYSTEM.CAST(WIN32.HMENU, wParam), h2d_poppad.IDM_FIND,    iEnable);
                         WINUSER.EnableMenuItem (SYSTEM.CAST(WIN32.HMENU, wParam), h2d_poppad.IDM_NEXT,    iEnable);
                         WINUSER.EnableMenuItem (SYSTEM.CAST(WIN32.HMENU, wParam), h2d_poppad.IDM_REPLACE, iEnable);
               ELSE
                 RETURN 0;
               END;
               RETURN 0;

          | WINUSER.WM_COMMAND :
                              (* Messages from edit control                     *)

               IF (lParam=1) AND (WINUSER.LOWORD (wParam) = EDITID) THEN
                    CASE (WINUSER.HIWORD (wParam)) OF
                         | WINUSER.EN_UPDATE :
                              bNeedSave := TRUE;
                              RETURN 0;

                         | WINUSER.EN_ERRSPACE :
                              WINUSER.MessageBox (hwnd, "Edit control out of space.",
                                        szAppName, WINUSER.MB_OK BOR WINUSER.MB_ICONSTOP);
                              RETURN 0;
                         | WINUSER.EN_MAXTEXT :
                              WINUSER.MessageBox (hwnd, "Edit control out of space.",
                                        szAppName, WINUSER.MB_OK BOR WINUSER.MB_ICONSTOP);
                              RETURN 0;
                    ELSE
                              RETURN 0;
                    END;
               END;
                  (*break;*)
               CASE (WINUSER.LOWORD (wParam)) OF
                              (* Messages from File menu                        *)

                    | h2d_poppad.IDM_NEW :
                         IF (bNeedSave=TRUE) AND (WINUSER.IDCANCEL =
                                   AskAboutSave (hwnd, szTitleName)) THEN
                              RETURN 0;
                         END;
                         WINUSER.SetWindowText (hwndEdit, "");
                         szFileName[0]  := '';
                         szTitleName[0] := '';
                         DoCaption (hwnd, szTitleName);
                         bNeedSave := FALSE;
                         RETURN 0;

                    | h2d_poppad.IDM_OPEN :
                         IF (bNeedSave=TRUE) AND (WINUSER.IDCANCEL =
                                   AskAboutSave (hwnd, szTitleName)) THEN
                            RETURN 0;
                         END;


                         IF (PopFile.OpenDlg (hwnd, SYSTEM.ADR(szFileName), SYSTEM.ADR(szTitleName))=TRUE) THEN
                              IF (PopFile.Read (hwndEdit, SYSTEM.ADR(szFileName))=FALSE) THEN
                                   OkMessage (hwnd, "Could not read file %s!",
                                                    szTitleName);
                                   szFileName[0]  := '';
                                   szTitleName[0] := '';
                              END;
                         END;

                         DoCaption (hwnd, szTitleName);
                         bNeedSave := FALSE;
                         RETURN 0;

                    | h2d_poppad.IDM_SAVE :
                         IF (szFileName[0]#'') THEN
                              IF (PopFile.Write (hwndEdit, SYSTEM.ADR(szFileName))) THEN
                                   bNeedSave := FALSE;
                                   RETURN 1;
                              ELSE
                                   OkMessage (hwnd, "Could not write file %s",
                                                    szTitleName);
                              END;
                              RETURN 0;
                         END;
                                                  (* fall through               *)
                    | h2d_poppad.IDM_SAVEAS :
                         IF (PopFile.SaveDlg (hwnd, SYSTEM.ADR(szFileName), SYSTEM.ADR(szTitleName))=TRUE) THEN
                              DoCaption (hwnd, szTitleName);
                              IF (PopFile.Write (hwndEdit, SYSTEM.ADR(szFileName))=TRUE) THEN
                                   bNeedSave := FALSE;
                                   RETURN 1;
                              ELSE
                                   OkMessage (hwnd, "Could not write file %s",
                                                    szTitleName);
                              END;
                         END;
                         RETURN 0;

                    | h2d_poppad.IDM_PRINT :
                         IF (PopPrnt.PrintFile (hInst, hwnd, hwndEdit,
                                                SYSTEM.ADR(szTitleName))=FALSE) THEN
                              OkMessage (hwnd, "Could not print file %s",
                                         szTitleName);
                         END;
                         RETURN 0;

                    | h2d_poppad.IDM_EXIT :
                         WINUSER.SendMessage (hwnd, WINUSER.WM_CLOSE, 0, 0);
                         RETURN 0;

                              (* Messages from Edit menu                        *)

                    | h2d_poppad.IDM_UNDO :
                         WINUSER.SendMessage (hwndEdit, WINUSER.WM_UNDO, 0, 0);
                         RETURN 0;

                    | h2d_poppad.IDM_CUT :
                         WINUSER.SendMessage (hwndEdit, WINUSER.WM_CUT, 0, 0);
                         RETURN 0;

                    | h2d_poppad.IDM_COPY :
                         WINUSER.SendMessage (hwndEdit, WINUSER.WM_COPY, 0, 0);
                         RETURN 0;

                    | h2d_poppad.IDM_PASTE :
                         WINUSER.SendMessage (hwndEdit, WINUSER.WM_PASTE, 0, 0);
                         RETURN 0;

                    | h2d_poppad.IDM_CLEAR :
                         WINUSER.SendMessage (hwndEdit, WINUSER.WM_CLEAR, 0, 0);
                         RETURN 0;

                    | h2d_poppad.IDM_SELALL :
                         WINUSER.SendMessage (hwndEdit, WINUSER.EM_SETSEL, 0,0 (* -1*));
                         RETURN 0;

                              (* Messages from Search menu                      *)

                    | h2d_poppad.IDM_FIND :
                         WINUSER.SendMessage (hwndEdit, WINUSER.EM_GETSEL, 0,
                                                           SYSTEM.CAST(WIN32.LPARAM,iOffset));

                         hDlgModeless := PopFind.FindDlg (hwnd);
                         RETURN 0;

                    | h2d_poppad.IDM_NEXT :
                         WINUSER.SendMessage (hwndEdit, WINUSER.EM_GETSEL, 0,
                                                           SYSTEM.CAST(WIN32.LPARAM,iOffset));

                         IF (PopFind.ValidFind()=TRUE) THEN
                              ok := PopFind.NextText (hwndEdit, iOffset);
                         ELSE
                              hDlgModeless := PopFind.FindDlg (hwnd);
                         END;
                         RETURN 0;

                    | h2d_poppad.IDM_REPLACE :
                         WINUSER.SendMessage (hwndEdit, WINUSER.EM_GETSEL, 0,
                                                           SYSTEM.CAST(WIN32.LPARAM,iOffset));

                         hDlgModeless := PopFind.ReplaceDlg (hwnd);
                         RETURN 0;

                    | h2d_poppad.IDM_FONT :
                         IF (PopFont.ChooseFont (hwnd)=TRUE) THEN
                              PopFont.SetFont (hwndEdit);
                         END;
                         RETURN 0;

                              (* Messages from Help menu                        *)

                    | h2d_poppad.IDM_HELP :
                         OkMessage (hwnd, "Help not yet implemented!", "");
                         RETURN 0;

                    | h2d_poppad.IDM_ABOUT :
                         WINUSER.DialogBox (hInst, "AboutBox", hwnd, AboutDlgProc);
                         RETURN 0;
               ELSE
                 RETURN 0;
               END;
            (* break; *)
          | WINUSER.WM_CLOSE :
               IF (bNeedSave=FALSE) OR (WINUSER.IDCANCEL # AskAboutSave (hwnd, szTitleName)) THEN
                    WINUSER.DestroyWindow (hwnd);
               END;
               RETURN 0;

          | WINUSER.WM_QUERYENDSESSION :
               IF (bNeedSave=FALSE) OR (WINUSER.IDCANCEL # AskAboutSave (hwnd, szTitleName)) THEN
                    RETURN 1;
               END;
               RETURN 0;

          | WINUSER.WM_DESTROY :
               PopFont.Deinitialize ();
               WINUSER.PostQuitMessage (0);
               RETURN 0;

     ELSE
                         (* Process "Find-Replace" iMsgs                        *)

               IF (iMsg = iMsgFindReplace) THEN
                    pfr := SYSTEM.CAST(COMMDLG.LPFINDREPLACE,lParam);

                    IF ((pfr^.Flags BAND COMMDLG.FR_DIALOGTERM)=1) THEN
                         hDlgModeless := NIL;
                    END;
                    IF ((pfr^.Flags BAND COMMDLG.FR_FINDNEXT)=1) THEN
                         IF (PopFind.FindText (hwndEdit, iOffset, pfr)=FALSE) THEN
                              OkMessage (hwnd, "Text not found!", "");
                         END;
                    END;
                    IF ((pfr^.Flags BAND COMMDLG.FR_REPLACE)=1) OR
                       ((pfr^.Flags BAND COMMDLG.FR_REPLACEALL)=1) THEN
                         IF (PopFind.ReplaceText (hwndEdit, iOffset, pfr)=TRUE) THEN
                              OkMessage (hwnd, "Text not found!", "");
                         END;
                    END;
                    IF ((pfr^.Flags BAND COMMDLG.FR_REPLACEALL)=1) THEN
                         WHILE (PopFind.ReplaceText (hwndEdit, iOffset, pfr)=TRUE) DO;
                         END;
                    END;
                    RETURN 0;
               END;
            (* break; *)
               RETURN WINUSER.DefWindowProc (hwnd, iMsg, wParam, lParam);
     END;
     RETURN WINUSER.DefWindowProc (hwnd, iMsg, wParam, lParam);
END WndProc;
<*/POP*>

(*++++*****************************************************************)
PROCEDURE InitApplication () : BOOLEAN;
(**********************************************************************)
VAR
  rc   :  CARDINAL;
BEGIN
  wc.cbSize        := SIZE(wc);
  wc.style         := WINUSER.CS_HREDRAW BOR WINUSER.CS_VREDRAW;
  wc.lpfnWndProc   := WndProc;
  wc.cbClsExtra    := 0;
  wc.cbWndExtra    := 0;
  wc.hInstance     := WINX.Instance;
  wc.hIcon         := WINUSER.LoadIcon (WINX.Instance,szAppName);
  wc.hCursor       := WINUSER.LoadCursor (NIL, WINUSER.IDC_ARROW^);
  wc.hbrBackground := SYSTEM.CAST(WIN32.HBRUSH, WINGDI.GetStockObject (WINGDI.WHITE_BRUSH));
  wc.lpszMenuName  := SYSTEM.ADR(szAppName);
  wc.lpszClassName := SYSTEM.ADR(szAppName);
  wc.hIconSm       := WINUSER.LoadIcon (wc.hInstance,szAppName);

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

(*++++*****************************************************************)
PROCEDURE InitMainWindow () : BOOLEAN;
(**********************************************************************)
BEGIN
  hwnd := WINUSER.CreateWindow (
                       szAppName,                      (* window class name            *)
                       szAppName,                      (* window caption               *)
                       WINUSER.WS_OVERLAPPEDWINDOW,    (* window style                 *)
                       WINUSER.CW_USEDEFAULT,          (* initial x position           *)
                       WINUSER.CW_USEDEFAULT,          (* initial y position           *)
                       WINUSER.CW_USEDEFAULT,          (* initial x size               *)
                       WINUSER.CW_USEDEFAULT,          (* initial y size               *)
                       NIL,                            (* parent window handle         *)
                       NIL,                            (* window menu handle           *)
                       WINX.Instance,                  (* program instance handle      *)
                       szCmdLine);                     (* creation parameters          *)

  IF hwnd = NIL THEN
    RETURN FALSE;
  END;
  WINUSER.ShowWindow (hwnd, WINUSER.SW_SHOWDEFAULT);
  WINUSER.UpdateWindow (hwnd);
  hAccel := WINUSER.LoadAccelerators (wc.hInstance, szAppName);
  RETURN TRUE;
END InitMainWindow;
(*++++*****************************************************************)
BEGIN
  IF InitApplication()  AND  InitMainWindow() THEN
    WHILE (WINUSER.GetMessage(msg,NIL,0,0)) DO
      IF (hDlgModeless = NIL) OR  (WINUSER.IsDialogMessage(hDlgModeless, msg)=FALSE) THEN


        IF (WINUSER.TranslateAccelerator (hwnd, hAccel, msg)=0) THEN
          WINUSER.TranslateMessage(msg);
          WINUSER.DispatchMessage(msg);
        END;
      END;
    END;
  END;
END PopPad.