Last updated: 22. 1.1998, 22:34
<* +M2EXTENSIONS *> MODULE PopPad; (*--------------------------------------- POPPAD.C --- Popup Editor (c) Charles Petzold, 1996 PopPad.mod --- Translation to XDS Modula-2 (c) Peter Stadler, 1997 ---------------------------------------*) IMPORT Windows; 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..Windows.MAX_PATH] OF CHAR; szTitleName : ARRAY[0..Windows.MAX_FNAME+Windows.MAX_EXT] OF CHAR; hInst : Windows.HINSTANCE; hwndEdit : Windows.HWND; iMsgFindReplace : CARDINAL; iSelBeg : INTEGER; iSelEnd : INTEGER; iEnable : Windows.MF_SET; pfr : Windows.PFINDREPLACE; iOffset : INTEGER; hDlgModeless : Windows.HWND; hAccel : Windows.HACCEL; hwnd : Windows.HWND; msg : Windows.MSG; wc : Windows.WNDCLASSEX; ok : Windows.BOOL; szCmdLine : Windows.PSTR; (*++++*****************************************************************) PROCEDURE DoCaption (hwnd : Windows.HWND; (**********************************************************************) VAR szTitleName : ARRAY OF CHAR); VAR szCaption : ARRAY[0..64+Windows.MAX_FNAME+Windows.MAX_EXT] OF CHAR; BEGIN IF(szTitleName[0]='') THEN Strings.Replace(UNTITLED,0,szTitleName); END; Windows.wsprintf (szCaption, "%s - %s", szAppName, szTitleName); Windows.SetWindowText (hwnd, szCaption); END DoCaption; (*++++*****************************************************************) PROCEDURE OkMessage (hwnd : Windows.HWND; szMessage : ARRAY OF CHAR; szTitleName : ARRAY OF CHAR); (**********************************************************************) VAR szBuffer : ARRAY[0..64+Windows.MAX_FNAME+Windows.MAX_EXT] OF CHAR; BEGIN IF(szTitleName[0]='') THEN Strings.Replace(UNTITLED,0,szTitleName); END; Windows.wsprintf (szBuffer, szMessage, szTitleName); Windows.MessageBox (hwnd, szBuffer, SYSTEM.ADR(szAppName), Windows.MB_OK + Windows.MB_ICONEXCLAMATION); END OkMessage; (*++++*****************************************************************) PROCEDURE AskAboutSave (hwnd : Windows.HWND; VAR szTitleName : ARRAY OF CHAR) : Windows.SHORT; (**********************************************************************) VAR szBuffer : ARRAY[0..64+Windows.MAX_FNAME+Windows.MAX_EXT] OF CHAR; iReturn : INTEGER; BEGIN IF(szTitleName[0]='') THEN Strings.Replace(UNTITLED,0,szTitleName); END; Windows.wsprintf (szBuffer, "Save current changes in %s?", szTitleName); iReturn := Windows.MessageBox (hwnd, szBuffer, SYSTEM.ADR(szAppName), Windows.MB_YESNOCANCEL + Windows.MB_ICONQUESTION); IF (iReturn = Windows.IDYES) THEN IF (Windows.SendMessage (hwnd, Windows.WM_COMMAND, h2d_poppad.IDM_SAVE, 0000h)=0) THEN iReturn := Windows.IDCANCEL; END; END; RETURN iReturn; END AskAboutSave; (*++++*****************************************************************) PROCEDURE [Windows.CALLBACK] AboutDlgProc (hDlg : Windows.HWND; (**********************************************************************) iMsg : Windows.UINT; wParam : Windows.WPARAM; lParam : Windows.LPARAM) : Windows.BOOL; BEGIN CASE (iMsg) OF | Windows.WM_INITDIALOG : RETURN TRUE; | Windows.WM_COMMAND : CASE (Windows.LOWORD (wParam)) OF | Windows.IDOK : Windows.EndDialog (hDlg, 0); RETURN TRUE; ELSE RETURN TRUE; END; (*break; *) ELSE RETURN FALSE; END; RETURN FALSE; END AboutDlgProc; (*++++*****************************************************************) PROCEDURE [Windows.CALLBACK] WndProc (hwnd : Windows.HWND; iMsg : Windows.UINT; wParam : Windows.WPARAM; lParam : Windows.LPARAM) : Windows.LRESULT; (**********************************************************************) VAR bo : Windows.BOOL; lr : Windows.LRESULT; mf : Windows.MF_SET; lpcr : Windows.PCREATESTRUCT; pstr : Windows.PSTR; CONST edit = "edit"; outofsp = "Edit control out of space."; about = "AboutBox"; BEGIN bNeedSave := FALSE; CASE (iMsg) OF | Windows.WM_CREATE : (* Create the edit control child window *) lpcr := SYSTEM.CAST(Windows.PCREATESTRUCT,lParam); hInst := lpcr^.hInstance; hwndEdit := Windows.CreateWindow (SYSTEM.ADR(edit), "", Windows.WS_CHILD + Windows.WS_VISIBLE + Windows.WS_HSCROLL + Windows.WS_VSCROLL + Windows.WS_BORDER + Windows.ES_LEFT + Windows.ES_MULTILINE + Windows.ES_NOHIDESEL + Windows.ES_AUTOHSCROLL + Windows.ES_AUTOVSCROLL, 0, 0, 0, 0, hwnd, SYSTEM.CAST(Windows.HMENU,EDITID), hInst, NIL); Windows.SendMessage (hwndEdit, Windows.EM_LIMITTEXT, 32000, 0000h); (* Initialize common dialog box stuff *) PopFile.Initialize (hwnd); PopFont.Initialize (hwndEdit); iMsgFindReplace := Windows.RegisterWindowMessage (Windows.FINDMSGSTRING); (* Process command line *) lpcr := SYSTEM.CAST(Windows.PCREATESTRUCT,lParam); pstr := SYSTEM.CAST(Windows.PSTR,lpcr^.lpCreateParams); Str.Copy(szFileName,pstr^); IF (LENGTH(szFileName) > 0) THEN Windows.GetFileTitle (SYSTEM.ADR(szFileName), SYSTEM.ADR(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; | Windows.WM_SETFOCUS : Windows.SetFocus (hwndEdit); RETURN 0; | Windows.WM_SIZE : Windows.MoveWindow (hwndEdit, 0, 0, Windows.LOWORD (lParam), Windows.HIWORD (lParam), TRUE); RETURN 0; | Windows.WM_INITMENUPOPUP : CASE (lParam) OF | 1 : (* Edit menu *) (* Enable Undo if edit control can do it *) lr := Windows.SendMessage (hwndEdit, Windows.EM_CANUNDO, 0, 0000h); IF(lr=1) THEN mf := Windows.MF_ENABLED; ELSIF(lr=0) THEN mf := Windows.MF_GRAYED; END; Windows.EnableMenuItem (SYSTEM.CAST(Windows.HMENU,wParam), h2d_poppad.IDM_UNDO,mf); (* Enable Paste IF text is in the clipboard *) bo := Windows.IsClipboardFormatAvailable (Windows.CF_TEXT); IF(bo=TRUE) THEN mf := Windows.MF_ENABLED; ELSIF(bo=FALSE) THEN mf := Windows.MF_GRAYED; END; Windows.EnableMenuItem (SYSTEM.CAST(Windows.HMENU,wParam), h2d_poppad.IDM_PASTE,mf); (* Enable Cut, Copy, and Del IF text is selected *) Windows.SendMessage (hwndEdit, Windows.EM_GETSEL, SYSTEM.CAST(Windows.WPARAM,iSelBeg), SYSTEM.CAST(Windows.LPARAM,iSelEnd)); IF(iSelBeg#iSelEnd) THEN iEnable := Windows.MF_ENABLED; ELSE iEnable := Windows.MF_GRAYED; END; Windows.EnableMenuItem (SYSTEM.CAST(Windows.HMENU, wParam), h2d_poppad.IDM_CUT, iEnable); Windows.EnableMenuItem (SYSTEM.CAST(Windows.HMENU, wParam), h2d_poppad.IDM_COPY, iEnable); Windows.EnableMenuItem (SYSTEM.CAST(Windows.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 := Windows.MF_ENABLED; ELSE iEnable := Windows.MF_GRAYED; END; Windows.EnableMenuItem (SYSTEM.CAST(Windows.HMENU, wParam), h2d_poppad.IDM_FIND, iEnable); Windows.EnableMenuItem (SYSTEM.CAST(Windows.HMENU, wParam), h2d_poppad.IDM_NEXT, iEnable); Windows.EnableMenuItem (SYSTEM.CAST(Windows.HMENU, wParam), h2d_poppad.IDM_REPLACE, iEnable); ELSE RETURN 0; END; RETURN 0; | Windows.WM_COMMAND : (* Messages from edit control *) IF (lParam=1) AND (Windows.LOWORD (wParam) = EDITID) THEN CASE (Windows.HIWORD (wParam)) OF | Windows.EN_UPDATE : bNeedSave := TRUE; RETURN 0; | Windows.EN_ERRSPACE : Windows.MessageBox (hwnd, outofsp, SYSTEM.ADR(szAppName), Windows.MB_OK + Windows.MB_ICONSTOP); RETURN 0; | Windows.EN_MAXTEXT : Windows.MessageBox (hwnd, outofsp, SYSTEM.ADR(szAppName), Windows.MB_OK + Windows.MB_ICONSTOP); RETURN 0; ELSE RETURN 0; END; END; (*break;*) CASE (Windows.LOWORD (wParam)) OF (* Messages from File menu *) | h2d_poppad.IDM_NEW : IF (bNeedSave=TRUE) AND (Windows.IDCANCEL = AskAboutSave (hwnd, szTitleName)) THEN RETURN 0; END; Windows.SetWindowText (hwndEdit, ""); szFileName[0] := ''; szTitleName[0] := ''; DoCaption (hwnd, szTitleName); bNeedSave := FALSE; RETURN 0; | h2d_poppad.IDM_OPEN : IF (bNeedSave=TRUE) AND (Windows.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 : Windows.SendMessage (hwnd, Windows.WM_CLOSE, 0, 0); RETURN 0; (* Messages from Edit menu *) | h2d_poppad.IDM_UNDO : Windows.SendMessage (hwndEdit, Windows.WM_UNDO, 0, 0); RETURN 0; | h2d_poppad.IDM_CUT : Windows.SendMessage (hwndEdit, Windows.WM_CUT, 0, 0); RETURN 0; | h2d_poppad.IDM_COPY : Windows.SendMessage (hwndEdit, Windows.WM_COPY, 0, 0); RETURN 0; | h2d_poppad.IDM_PASTE : Windows.SendMessage (hwndEdit, Windows.WM_PASTE, 0, 0); RETURN 0; | h2d_poppad.IDM_CLEAR : Windows.SendMessage (hwndEdit, Windows.WM_CLEAR, 0, 0); RETURN 0; | h2d_poppad.IDM_SELALL : Windows.SendMessage (hwndEdit, Windows.EM_SETSEL, 0,0 (* -1*)); RETURN 0; (* Messages from Search menu *) | h2d_poppad.IDM_FIND : Windows.SendMessage (hwndEdit, Windows.EM_GETSEL, 0, SYSTEM.CAST(Windows.LPARAM,iOffset)); hDlgModeless := PopFind.FindDlg (hwnd); RETURN 0; | h2d_poppad.IDM_NEXT : Windows.SendMessage (hwndEdit, Windows.EM_GETSEL, 0, SYSTEM.CAST(Windows.LPARAM,iOffset)); IF (PopFind.ValidFind()=TRUE) THEN ok := PopFind.NextText (hwndEdit, iOffset); ELSE hDlgModeless := PopFind.FindDlg (hwnd); END; RETURN 0; | h2d_poppad.IDM_REPLACE : Windows.SendMessage (hwndEdit, Windows.EM_GETSEL, 0, SYSTEM.CAST(Windows.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 : Windows.DialogBox (hInst, SYSTEM.ADR(about), hwnd, AboutDlgProc); RETURN 0; ELSE RETURN 0; END; (* break; *) | Windows.WM_CLOSE : IF (bNeedSave=FALSE) OR (Windows.IDCANCEL # AskAboutSave (hwnd, szTitleName)) THEN Windows.DestroyWindow (hwnd); END; RETURN 0; | Windows.WM_QUERYENDSESSION : IF (bNeedSave=FALSE) OR (Windows.IDCANCEL # AskAboutSave (hwnd, szTitleName)) THEN RETURN 1; END; RETURN 0; | Windows.WM_DESTROY : PopFont.Deinitialize (); Windows.PostQuitMessage (0); RETURN 0; ELSE (* Process "Find-Replace" iMsgs *) IF (iMsg = iMsgFindReplace) THEN pfr := SYSTEM.CAST(Windows.PFINDREPLACE,lParam); IF ((pfr^.Flags - Windows.FR_DIALOGTERM)=SYSTEM.CAST(Windows.FR_SET,1)) THEN hDlgModeless := NIL; END; IF ((pfr^.Flags - Windows.FR_FINDNEXT)=SYSTEM.CAST(Windows.FR_SET,1)) THEN IF (PopFind.FindText (hwndEdit, iOffset, pfr)=FALSE) THEN OkMessage (hwnd, "Text not found!", ""); END; END; IF ((pfr^.Flags - Windows.FR_REPLACE)=SYSTEM.CAST(Windows.FR_SET,1)) OR ((pfr^.Flags - Windows.FR_REPLACEALL)=SYSTEM.CAST(Windows.FR_SET,1)) THEN IF (PopFind.ReplaceText (hwndEdit, iOffset, pfr)=TRUE) THEN OkMessage (hwnd, "Text not found!", ""); END; END; IF ((pfr^.Flags - Windows.FR_REPLACEALL)=SYSTEM.CAST(Windows.FR_SET,1)) THEN WHILE (PopFind.ReplaceText (hwndEdit, iOffset, pfr)=TRUE) DO; END; END; RETURN 0; END; (* break; *) RETURN Windows.DefWindowProc (hwnd, iMsg, wParam, lParam); END; RETURN Windows.DefWindowProc (hwnd, iMsg, wParam, lParam); END WndProc; (*++++*****************************************************************) PROCEDURE InitApplication () : BOOLEAN; (**********************************************************************) VAR rc : CARDINAL; BEGIN wc.cbSize := SIZE(wc); wc.style := Windows.CS_HREDRAW + Windows.CS_VREDRAW; wc.lpfnWndProc := WndProc; wc.cbClsExtra := 0; wc.cbWndExtra := 0; wc.hInstance := Windows.MyInstance(); wc.hIcon := Windows.LoadIcon (Windows.MyInstance(),SYSTEM.ADR(szAppName)); wc.hCursor := Windows.LoadCursor (NIL, Windows.IDC_ARROW); wc.hbrBackground := SYSTEM.CAST(Windows.HBRUSH, Windows.GetStockObject (Windows.WHITE_BRUSH)); wc.lpszMenuName := SYSTEM.ADR(szAppName); wc.lpszClassName := SYSTEM.ADR(szAppName); wc.hIconSm := Windows.LoadIcon (wc.hInstance,SYSTEM.ADR(szAppName)); rc := Windows.RegisterClassEx(wc); RETURN rc#0; END InitApplication; (*++++*****************************************************************) PROCEDURE InitMainWindow () : BOOLEAN; (**********************************************************************) BEGIN hwnd := Windows.CreateWindow ( SYSTEM.ADR(szAppName), (* window class name *) szAppName, (* window caption *) Windows.WS_OVERLAPPEDWINDOW, (* window style *) Windows.CW_USEDEFAULT, (* initial x position *) Windows.CW_USEDEFAULT, (* initial y position *) Windows.CW_USEDEFAULT, (* initial x size *) Windows.CW_USEDEFAULT, (* initial y size *) NIL, (* parent window handle *) NIL, (* window menu handle *) Windows.MyInstance(), (* program instance handle *) szCmdLine); (* creation parameters *) IF hwnd = NIL THEN RETURN FALSE; END; Windows.ShowWindow (hwnd, Windows.SW_SHOWDEFAULT); Windows.UpdateWindow (hwnd); hAccel := Windows.LoadAccelerators (wc.hInstance, SYSTEM.ADR(szAppName)); RETURN TRUE; END InitMainWindow; (*++++*****************************************************************) BEGIN IF InitApplication() AND InitMainWindow() THEN WHILE (Windows.GetMessage(msg,NIL,0,0)) DO IF (hDlgModeless = NIL) OR (Windows.IsDialogMessage(hDlgModeless, msg)=FALSE) THEN IF (Windows.TranslateAccelerator (hwnd, hAccel, msg)=FALSE) THEN Windows.TranslateMessage(msg); Windows.DispatchMessage(msg); END; END; END; END; END PopPad.