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.