/***************************************************************************/
/***************************************************************************/
/** **/
/** Simple Lisp File Editor **/
/** Adapted from examples in MS Windows Guide to Programming **/
/** **/
/***************************************************************************/
/***************************************************************************/
// clean up file opening, closing, fstat, etc.
// try to allow for multiple windows
// search facility
#include <windows.h>
#include <windowsx.h>
#include <commdlg.h>
#include <dir.h>
#include <ddeml.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
#include <sys\types.h>
#include "winutils.h"
#include "ledit.h"
#include "lspedit.h"
HINSTANCE hInst;
HWND hWnd;
HWND hEditWnd;
HACCEL hAccTable;
#define NAMESIZE 129
char FileName[NAMESIZE];
BOOL bChanges = FALSE;
char buf[255];
HCURSOR hHourGlass;
char Untitled[] = "LSPEdit - (untitled)";
DWORD ddeInst;
static void OpenInitialFile(char *);
static BOOL OpenDlg(void);
static BOOL SaveAsDlg(void);
static void ReanInFile(FILE *);
static BOOL InitApplication(HINSTANCE);
static BOOL InitInstance(HINSTANCE, int);
static BOOL SaveFile(void);
static BOOL QuerySaveFile(void);
static void SetNewBuffer(HANDLE, PSTR);
#define OkOrCancelBox(s) \
MessageBox(GetFocus(), s, "LSPEdit", MB_YESNOCANCEL | MB_ICONEXCLAMATION)
int PASCAL WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
/* Try to cooperate with other running instances of the application */
if (!hPrevInstance)
if (!InitApplication(hInstance))
return(FALSE);
/* initialize the specific instance */
if (!InitInstance(hInstance, nCmdShow))
return(FALSE);
/* initialize DDEML */
/**** ought to check thisis available */
DdeInitialize(&ddeInst, NULL,
APPCLASS_STANDARD | APPCMD_CLIENTONLY |
CBF_SKIP_ALLNOTIFICATIONS,
0L);
/* open an initial file if there is a command line argument */
#if defined(WIN32) && defined(__BORLANDC__) && (__BORLANDC__ <= 0x452)
{
int i;
if (sscanf(lpCmdLine, "%128s%n", buf, &i) == 1)
lpCmdLine += i;
}
#endif
if (sscanf(lpCmdLine, "%128s", buf) == EOF)
buf[0] = '\0';
OpenInitialFile(buf);
/* process messages until a WM_QUIT message */
while (GetMessage(&msg, NULL, 0, 0)) {
if (! TranslateAccelerator(hWnd, hAccTable, &msg)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
/* drop DDEML */
DdeUninitialize(ddeInst);
return(msg.wParam);
}
BOOL InitApplication(HINSTANCE hInstance)
{
WNDCLASS wc;
/* fill in the class structure for the main window */
wc.style = 0;
wc.lpfnWndProc = MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(hInstance, "LEditIcon");
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = "LSPEditMenu";
wc.lpszClassName = "LSPEditWClass";
/* register the window class and return result code */
return(RegisterClass(&wc));
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance;
_fmode = O_BINARY;
hHourGlass = LoadCursor(hInstance, IDC_WAIT);
InitLEditClass(NULL, NULL);
/* create a main window for this instance */
hWnd = CreateWindow("LSPEditWClass",
Untitled,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
hEditWnd = CreateLEditWindow(hWnd, (HMENU) IDC_EDIT, hInstance);
if (! hEditWnd) {
DestroyWindow(hWnd);
return(FALSE);
}
hAccTable = LoadAccelerators(hInst, "LSPEdit");
/* if the window could not be created, return failure code */
if (! hWnd) return(FALSE);
/* make the window visible, update it, and return success */
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return(TRUE);
}
LONG WINAPI MainWndProc(HWND hWnd, UINT message, WPARAM wPrm, LONG lPrm)
{
DLGPROC lpProcAbout;
FILE *fp;
switch(message) {
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wPrm, lPrm)) {
case IDM_ABOUT:
lpProcAbout = (DLGPROC) MakeProcInstance((FARPROC) About, hInst);
DialogBox(hInst, "AboutBox", hWnd, lpProcAbout);
(void) FreeProcInstance((FARPROC) lpProcAbout);
break;
case IDM_NEW:
if (! QuerySaveFile()) return(FALSE);
bChanges = FALSE;
FileName[0] = 0;
SetNewBuffer(NULL, Untitled);
break;
case IDM_OPEN:
if (! QuerySaveFile())
return FALSE;
if (! OpenDlg() || (fp = fopen(FileName, "r")) == NULL)
return FALSE;
ReanInFile(fp);
return FALSE;
case IDM_SAVE:
if (! FileName[0]) goto saveas;
if (bChanges) SaveFile();
break;
case IDM_SAVEAS:
saveas:
if (SaveAsDlg()) {
sprintf(buf, "LSPEdit - %s", FileName);
if (SaveFile())
SetWindowText(hWnd, buf);
else {
FileName[0] = 0;
SetWindowText(hWnd, Untitled);
}
}
break;
case IDM_PRINT:
WarningBox("Command Not Implemented");
break;
case IDM_EXIT:
if (! QuerySaveFile()) return FALSE;
DestroyWindow(hWnd);
break;
case IDM_UNDO:
WarningBox("Command Not Implemented");
break;
case IDM_CUT:
TTYSelToClip();
TTYClearSel();
break;
case IDM_COPY:
TTYSelToClip();
break;
case IDM_PASTE:
TTYPasteFromClip();
break;
case IDM_CLEAR:
TTYClearSel();
break;
case IDM_EVAL:
{
HSZ service, topic;
HCONV hconv;
service = DdeCreateStringHandle(ddeInst, "XLISP-STAT", CP_WINANSI);
topic = DdeCreateStringHandle(ddeInst, "XLISP-STAT", CP_WINANSI);
if ((hconv = DdeConnect(ddeInst, service, topic, NULL)) == NULL)
WarningBox("Can't connect to XLISP-STAT");
else {
/**** switch to allocated buffer? */
char *data = TTYSelectionStr();
if (! DdeClientTransaction((LPVOID) data, strlen(data) + 1,
hconv, NULL, CF_TEXT, XTYP_EXECUTE,
60000L, NULL))
WarningBox("Transaction failed");
DdeDisconnect(hconv);
}
DdeFreeStringHandle(ddeInst, service);
DdeFreeStringHandle(ddeInst, topic);
}
break;
case IDC_EDIT:
if (GET_WM_COMMAND_CMD(wPrm, lPrm) == EN_ERRSPACE) {
WarningBox("Out of memory");
}
if (GET_WM_COMMAND_CMD(wPrm, lPrm) == EN_CHANGE) bChanges = TRUE;
break;
default: return(DefWindowProc(hWnd, message, wPrm, lPrm));
}
break;
case WM_SETFOCUS:
SetFocus(hEditWnd);
break;
case WM_SIZE:
MoveWindow(hEditWnd, 0, 0, LOWORD(lPrm), HIWORD(lPrm), TRUE);
break;
case WM_QUERYENDSESSION:
return(QuerySaveFile());
case WM_CLOSE:
if (QuerySaveFile()) DestroyWindow(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return(DefWindowProc(hWnd, message, wPrm, lPrm));
}
return FALSE;
}
BOOL CALLBACK About(HWND hDlg, UINT message, WPARAM wPrm, LONG lPrm)
#pragma argsused hDlg message wPrm
{
UINT which;
switch(message) {
case WM_INITDIALOG:
return(TRUE);
case WM_COMMAND:
which = GET_WM_COMMAND_ID(wPrm, lPrm);
if (which == IDOK || which == IDCANCEL) {
EndDialog(hDlg, TRUE);
return(TRUE);
}
break;
}
return(FALSE);
}
#define FILTERSIZE 255
#define STRMAX 255
static char szFilter[FILTERSIZE + 2];
static char szDfltFilter[] = "Lisp Files(*.LSP)|*.lsp|All Files(*.*)|*.*";
static char szDirName[256];
static BOOL OpenDlg(void)
{
int i, n;
OPENFILENAME ofn;
strcpy(szFilter, szDfltFilter);
n = strlen(szFilter);
for (i = 0; i < n; i++)
if (szFilter[i] == '|')
szFilter[i] = '\0';
szFilter[n] = '\0';
szFilter[n + 1] = '\0';
if (! getcwd(szDirName, sizeof(szDirName)))
return FALSE;
buf[0] = '\0';
memset(&ofn, 0, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.lpstrFilter = szFilter;
ofn.nFilterIndex = 1;
ofn.lpstrFile = buf;
ofn.nMaxFile = STRMAX;
ofn.lpstrFileTitle = FileName;
ofn.nMaxFileTitle = sizeof(FileName);
ofn.lpstrInitialDir = szDirName;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
if (GetOpenFileName(&ofn))
return TRUE;
else
return FALSE;
}
static BOOL SaveAsDlg(void)
{
int i, n;
OPENFILENAME ofn;
strcpy(szFilter, szDfltFilter);
n = strlen(szFilter);
for (i = 0; i < n; i++)
if (szFilter[i] == '|')
szFilter[i] = '\0';
szFilter[n] = '\0';
szFilter[n + 1] = '\0';
if (! getcwd(szDirName, sizeof(szDirName)))
return FALSE;
buf[0] = '\0';
memset(&ofn, 0, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.lpstrFilter = szFilter;
ofn.nFilterIndex = 1;
ofn.lpstrFile = buf;
ofn.nMaxFile = STRMAX;
ofn.lpstrFileTitle = FileName;
ofn.nMaxFileTitle = sizeof(FileName);
ofn.lpstrInitialDir = szDirName;
ofn.Flags = OFN_OVERWRITEPROMPT;
if (GetSaveFileName(&ofn))
return TRUE;
else
return FALSE;
}
static BOOL SaveFile(void)
{
BOOL bSuccess;
HANDLE hEditBuffer;
HCURSOR hSaveCursor;
PSTR pEditBuffer;
int IOStatus, length;
FILE *fp;
if ((fp = fopen(FileName, "w")) == NULL) {
sprintf(buf, "Cannot write to %s.", FileName);
WarningBox(buf);
return(FALSE);
}
hSaveCursor = SetCursor(hHourGlass);
length = Edit_GetTextLength(hEditWnd);
hEditBuffer = LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT, length + 1);
if (! hEditBuffer) {
WarningBox("Not enough memory.");
return FALSE;
}
pEditBuffer = LocalLock(hEditBuffer);
GetWindowText(hEditWnd, pEditBuffer, length + 1);
IOStatus = fwrite(pEditBuffer, 1, length, fp);
fclose(fp);
SetCursor(hSaveCursor);
if (IOStatus != length) {
sprintf(buf, "Error writing to %s.", FileName);
WarningBox(buf);
bSuccess = FALSE;
}
else {
bSuccess = TRUE;
bChanges = FALSE;
}
LocalUnlock(hEditBuffer);
LocalFree(hEditBuffer);
return(bSuccess);
}
BOOL QuerySaveFile()
{
int Response;
if (bChanges) {
sprintf(buf, "Save current changes: %s", FileName);
Response = OkOrCancelBox(buf);
if (Response == IDYES) {
if (! SaveAsDlg())
return FALSE;
else
return SaveFile();
}
else if (Response == IDCANCEL)
return FALSE;
}
return(TRUE);
}
void SetNewBuffer(HANDLE hNewBuffer, PSTR Title)
{
if (hNewBuffer) {
char *p = LocalLock(hNewBuffer);
SetWindowText(hEditWnd, p);
LocalUnlock(hNewBuffer);
}
else
SetWindowText(hEditWnd, "");
SetWindowText(hWnd, Title);
bChanges = FALSE;
}
static void OpenInitialFile(char *name)
{
FILE *fp;
if (strchr(name, '*') || strchr(name, '?')) name[0] = 0;
if (! name[0]) return;
if (! strrchr(name, '.'))
strcat(name, ".lsp");
if ((fp = fopen(name, "r")) == NULL) {
sprintf(buf, "Error opening %s.", name);
WarningBox(buf);
}
else {
strcpy(FileName, name);
ReanInFile(fp);
}
}
static void ReanInFile(FILE *fp)
{
HCURSOR hSaveCursor;
unsigned long IOStatus, FileSize;
HANDLE hEditBuffer;
PSTR pEditBuffer;
FileSize = (size_t) filelength(fileno(fp));
if (FileSize > MAXFILESIZE) {
sprintf(buf, "Not enough memory to load %s.\n%s exceeds %d bytes",
FileName, FileName, MAXFILESIZE);
WarningBox(buf);
return;
}
hEditBuffer = LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT,
(size_t) FileSize + 1);
if (! hEditBuffer) {
WarningBox("Not enough memory.");
return;
}
hSaveCursor = SetCursor(hHourGlass);
pEditBuffer = LocalLock(hEditBuffer);
IOStatus = fread(pEditBuffer, 1, (size_t) FileSize, fp);
fclose(fp);
if (IOStatus != FileSize) {
sprintf(buf, "Error reading %s.", FileName);
SetCursor(hSaveCursor);
WarningBox(buf);
pEditBuffer[0] = '\0';
FileName[0] = '\0';
}
LocalUnlock(hEditBuffer);
sprintf(buf, "LSPEdit - %s", FileName);
SetNewBuffer(hEditBuffer, buf);
LocalFree(hEditBuffer);
SetCursor(hSaveCursor);
}
syntax highlighted by Code2HTML, v. 0.9.1