// winmain.c
// 12/04/96 Lynn McGuire created
// 01/27/97 Lynn McGuire added check for loading RICHED32.DLL library
// 11/29/00 Lynn McGuire delete the temporary file if there is one
// when we are done
// 01/26/01 Lynn McGuire increase filename buffers
#define STRICT 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <windows.h>
#include "winmain.h"
static char mainClass [] = "DESIGN II Main Window";
/* Text for window title bar */
char WinTitleBar [] = "DESIGN II Application";
#define KBFSIZE 256
#define AllowableChars " 0123456789abcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/\\|?,.<>`'\";:~!@#$%^&*()_+-="
HWND ScreenOutputWindow;
HWND MainWindow;
HFONT FixedFont;
HMENU MainMenu;
char AboutMsg [4096];
char AboutTitle [4096];
char keyboardBuffer [KBFSIZE];
int keyboardBufferSize = 0;
int totalCharactersWrittenToScreen = 0;
WNDPROC oldEditWindowProc = NULL;
static BOOL firstInstance( HANDLE );
static int windowsInit( HANDLE, int );
LRESULT CALLBACK MainWindowProc (HWND hwnd, UINT message, WPARAM wParam,
LPARAM lParam);
LRESULT CALLBACK EditWindowProc (HWND hwnd, UINT message, WPARAM wParam,
LPARAM lParam);
int BlockingMessageLoop (void);
void SaveAsToFile ( void );
void KILL_DII_WINDOW (int status);
int WINAPI WinMain (HINSTANCE inst, HINSTANCE previnst, LPSTR cmd, int show)
{
int rc = 0;
char filename [2048];
char inputFile [2048];
char outputFile [2048];
int i = 0;
int len = strlen (cmd);
int quote = FALSE;
int count = 0;
// MessageBox (NULL, cmd, "DII Command Line", MB_OK);
if ( ! firstInstance ( inst ) ) return ( FALSE );
if ( ! windowsInit ( inst, show ) ) return ( FALSE );
GetModuleFileName (NULL, filename, sizeof (filename));
for (i = strlen (filename); i > 0; i--)
{
if ('\\' == filename [i] || '/' == filename [i]) break;
filename [i] = '\0';
}
// the input file and the output file are the 1st and 2nd arguments
// the name of the excutable is NOT here
inputFile [0] = '\0';
outputFile [0] = '\0';
for (i = 0; i < len; i++)
{
if ( ! quote && ' ' == cmd [i]) break;
if (quote && '"' == cmd [i])
quote = FALSE;
else
{
if ('"' == cmd [i])
quote = TRUE;
else
{
inputFile [count] = cmd [i];
count++;
inputFile [count] = '\0';
}
}
}
// look for whitespace
while (i < len && (' ' == cmd [i] || '\t' == cmd [i])) i++;
quote = FALSE; // reset
count = 0; // reset
// get the second argument
for ( ; i < len; i++)
{
if ( ! quote && ' ' == cmd [i]) break;
if (quote && '"' == cmd [i])
quote = FALSE;
else
{
if ('"' == cmd [i])
quote = TRUE;
else
{
outputFile [count] = cmd [i];
count++;
outputFile [count] = '\0';
}
}
}
// set the current working directory to the directory of the
// input file
if (inputFile [0])
{
char workingDirectory [2048];
sprintf (workingDirectory, inputFile);
for (i = strlen (workingDirectory) - 1;
i > 0 && workingDirectory [i] != '\\';
i--)
workingDirectory [i] = '\0';
SetCurrentDirectory (workingDirectory);
GetCurrentDirectory (2048, workingDirectory);
// MessageBox (NULL, workingDirectory, "Working Directory", MB_OK);
}
// MessageBox (NULL, inputFile, "DII Input File", MB_OK);
// MessageBox (NULL, outputFile, "DII Output File", MB_OK);
if ( ! SetForegroundWindow (MainWindow))
{
#ifdef NOT_USED
int lastError = GetLastError ();
char msg [1024];
sprintf (msg, "WARNING ! ! !\n\n"
"Could not set the Main Window to be the\n"
"Foreground Window. Error code %d",
lastError);
MessageBox (MainWindow, msg, AboutTitle,
MB_APPLMODAL | MB_ICONINFORMATION | MB_OK );
#endif
}
// call the simulator kernel
mymain (filename, inputFile, outputFile);
// delete the temporary file if there is one
if (inputFile [0])
{
char tempFile [2048];
strcpy (tempFile, inputFile);
// remove the trailing "in"
for (i = strlen (tempFile) - 1;
i > 0 && tempFile [i] && '.' != tempFile [i]; i--)
tempFile [i] = '\0';
strcat (tempFile, "tmp");
DeleteFile (tempFile);
}
// go ahead and quit now if they put -QUIT on the command line
// otherwise continue until the user kills the window manually
if ( ! strstr (cmd, "-QUIT") && ! strstr (cmd, "-Quit") &&
! strstr (cmd, "-quit"))
while (BlockingMessageLoop () == TRUE);
return ( rc );
} /* WinMain */
/*
* firstInstance - initialization at startup
*/
static BOOL firstInstance( HANDLE inst)
{
char tmp[128];
BOOL rc;
WNDCLASS wc;
HMENU smf, smh, sme;
strcpy (AboutTitle, "");
strcpy (AboutMsg, "");
/*
* make a menu (this way, we don't need resources)
*/
smf = CreateMenu();
if( smf == NULL ) return( FALSE );
AppendMenu( smf, MF_ENABLED, MSG_SAVEAS, "&Save As..." );
AppendMenu( smf, MF_SEPARATOR, 0, NULL );
AppendMenu( smf, MF_ENABLED, MSG_EXIT, "E&xit" );
sme = CreateMenu();
if( sme == NULL ) return( FALSE );
AppendMenu( sme, MF_ENABLED, MSG_COPY, "&Copy" );
AppendMenu( sme, MF_SEPARATOR, 0, NULL );
AppendMenu( sme, MF_ENABLED, MSG_SELECTALL, "Select &All" );
smh = CreateMenu();
if( smh == NULL ) return( FALSE );
AppendMenu( smh, MF_ENABLED, MSG_ABOUT, "&About..." );
MainMenu = CreateMenu();
if( MainMenu == NULL ) return( FALSE );
AppendMenu( MainMenu, MF_POPUP, (UINT) smf, "&File" );
AppendMenu( MainMenu, MF_POPUP, (UINT) sme, "&Edit" );
AppendMenu( MainMenu, MF_POPUP, (UINT) smh, "&Help" );
// register window classes
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC) MainWindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = inst;
wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hbrBackground = GetStockObject( WHITE_BRUSH );
wc.lpszMenuName = NULL;
wc.lpszClassName = mainClass;
rc = RegisterClass( &wc );
return rc;
} /* firstInstance */
/*
* windowsInit - windows-specific initialization
*/
static int windowsInit( HANDLE inst, int showcmd )
{
LOGFONT logfont;
WORD x, y;
WORD width = 640;
WORD height = 400;
RECT rect;
char msg [256];
int limit = 0;
char *editControlName = NULL;
x = GetSystemMetrics( SM_CXSCREEN );
y = GetSystemMetrics( SM_CYSCREEN );
MainWindow = CreateWindow(
mainClass, /* our class */
"Main Window", /* Text for window title bar */
WS_OVERLAPPEDWINDOW, /* Window style. */
(x - width) / 2, /* horizontal position. */
(y - height) / 2, /* vertical position. */
width, /* width. */
height, /* height. */
NULL, /* parent */
MainMenu, /* menu handle */
inst, /* owner of window */
NULL /* extra data pointer */
);
if ( ! MainWindow ) return ( FALSE );
// display the window
//ShowWindow ( MainWindow, showcmd );
ShowWindow ( MainWindow, SW_SHOWNORMAL );
UpdateWindow ( MainWindow );
// this library is available in Win 95, Win 31 with Win32s 1.30,
// and Win NT 3.51 and up
if (LoadLibrary ("RICHED32.DLL"))
// RICHEDIT allows an unlimited text buffer
editControlName = "RICHEDIT";
else
{
// EDIT only allows a 64K buffer
editControlName = "EDIT";
MessageBox (MainWindow,
"Could not load the RICHED32.DLL dynamic link libary.\n"
"If this is Windows 3.1/3.11 then you must install\n"
"version 1.30 of Microsoft Win32s. If this is Windows\n"
"95 or Windows NT then you should reinstall the\n"
"operating system. Using the EDIT control for now.",
AboutTitle, MB_APPLMODAL | MB_ICONINFORMATION | MB_OK );
}
GetClientRect( MainWindow, &rect );
ScreenOutputWindow = CreateWindow(
editControlName, /* class */
NULL, /* no caption */
WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL |
ES_READONLY |
ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL, /* style */
0, /* init. x pos */
0, /* init. y pos */
rect.right-rect.left, /* init. x size (entire parent) */
rect.bottom-rect.top, /* init. y size (entire parent) */
MainWindow, /* parent window */
MainMenu, /* i.d. */
inst, /* program handle */
NULL /* create parms */
);
// set the font for the edit window
// Create a font to use, could also use ANSI_FIXED_FONT but it is
// not as pretty a font
FixedFont = GetStockObject( SYSTEM_FIXED_FONT );
GetObject( FixedFont, sizeof(LOGFONT), (LPSTR) &logfont );
FixedFont = CreateFontIndirect( &logfont );
SendMessage (ScreenOutputWindow, WM_SETFONT, (WPARAM) FixedFont, 0);
// see what the current text buffer size is
// limit = SendMessage (ScreenOutputWindow, EM_GETLIMITTEXT, 0, 0);
// sprintf (msg, "window size is %d", limit);
// writeLineToScreen (msg);
// reset the current text buffer size limit to 10,000,000 bytes
SendMessage (ScreenOutputWindow, EM_LIMITTEXT, 10000000, 0);
// limit = SendMessage (ScreenOutputWindow, EM_GETLIMITTEXT, 0, 0);
// sprintf (msg, "new window size is %d", limit);
// writeLineToScreen (msg);
// put my edit window proc first
oldEditWindowProc = (WNDPROC) SetWindowLong
(ScreenOutputWindow, GWL_WNDPROC, (LONG) EditWindowProc);
return( TRUE );
} /* windowsInit */
LRESULT CALLBACK MainWindowProc(
HWND hwnd, /* window handle */
UINT message, /* type of message */
WPARAM wParam, /* additional information */
LPARAM lParam) /* additional information */
{
switch (message)
{
case WM_CHAR:
MessageBox (MainWindow, "", "got WM_CHAR msg in MainWindowProc",
MB_APPLMODAL | MB_ICONINFORMATION | MB_OK );
if (keyboardBufferSize < KBFSIZE)
{
keyboardBuffer [keyboardBufferSize] = wParam;
keyboardBufferSize++;
keyboardBuffer [keyboardBufferSize] = '\0';
}
break;
case WM_CREATE:
return 0;
case WM_COMMAND:
switch (wParam)
{
case MSG_ABOUT:
MessageBox (MainWindow, AboutMsg, AboutTitle,
MB_APPLMODAL | MB_ICONINFORMATION | MB_OK);
break;
case MSG_COPY:
SendMessage (ScreenOutputWindow, WM_COPY, 0, 0);
break;
case MSG_EXIT:
DestroyWindow (MainWindow);
break;
case MSG_SELECTALL:
SendMessage (ScreenOutputWindow, EM_SETSEL, 0, -1);
break;
case MSG_SAVEAS:
SaveAsToFile ();
break;
// case IDM_ABOUT:
// DialogBox(hinst, /* current instance */
// "AboutBox", /* resource to use */
// hwnd, /* parent handle */
// (DLGPROC) About);
// break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
break;
case WM_KEYDOWN:
MessageBox (MainWindow, "", "got WM_KEYDOWN msg",
MB_APPLMODAL | MB_ICONINFORMATION | MB_OK );
if( wParam == VK_CANCEL )
{
MessageBox( MainWindow, "SIGBREAK", AboutTitle,
MB_APPLMODAL | MB_ICONINFORMATION | MB_OK );
raise( SIGBREAK );
break;
}
case WM_SETFOCUS:
SetFocus(ScreenOutputWindow);
return 0;
case WM_SIZE:
// Make the edit control the size of the window's client area
MoveWindow(ScreenOutputWindow,
0, 0, /* starting x- and y-coordinates */
LOWORD(lParam), /* width of client area */
HIWORD(lParam), /* height of client area */
TRUE); /* repaint window */
return 0;
case WM_DESTROY:
DeleteObject (FixedFont);
PostQuitMessage(0);
return 0;
case WM_QUIT:
DestroyWindow (MainWindow);
exit (0);
return 0;
case WM_CLOSE:
DestroyWindow (MainWindow);
exit (0);
return 0;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return NULL;
}
LRESULT CALLBACK EditWindowProc(
HWND hwnd, /* window handle */
UINT message, /* type of message */
WPARAM wParam, /* additional information */
LPARAM lParam) /* additional information */
{
char msg [80];
switch (message)
{
case WM_CHAR:
// sprintf (msg, "%c %d, '\\n' is %d", wParam, wParam, '\n');
// MessageBox (MainWindow, msg, "got WM_CHAR msg in EditWindowProc",
// MB_APPLMODAL | MB_ICONINFORMATION | MB_OK );
if (keyboardBufferSize < KBFSIZE &&
(strrchr (AllowableChars, (char) wParam) ||
wParam == VK_RETURN ||
wParam == VK_BACK))
{
keyboardBuffer [keyboardBufferSize] = wParam;
keyboardBufferSize++;
keyboardBuffer [keyboardBufferSize] = '\0';
}
else
return CallWindowProc
(oldEditWindowProc, hwnd, message, wParam, lParam);
break;
case WM_KEYDOWN:
// MessageBox (MainWindow, "", "got WM_KEYDOWN msg in EditWindowProc",
// MB_APPLMODAL | MB_ICONINFORMATION | MB_OK );
// look for control-Break combination
if ( wParam == VK_CANCEL )
{
MessageBox ( MainWindow, "Stopping Execution", AboutTitle,
MB_APPLMODAL | MB_ICONINFORMATION | MB_OK );
SendMessage (MainWindow, WM_CLOSE, 0, 0);
}
// look for a control-C combination
else if ((wParam == 'C' || wParam == 'c') &&
HIBYTE (GetKeyState (VK_CONTROL)) != 0)
{
MessageBox ( MainWindow, "Stopping Execution", AboutTitle,
MB_APPLMODAL | MB_ICONINFORMATION | MB_OK );
SendMessage (MainWindow, WM_CLOSE, 0, 0);
}
// pass the message along to the edit window regardless
return CallWindowProc (oldEditWindowProc, hwnd, message, wParam, lParam);
break;
default:
return CallWindowProc
(oldEditWindowProc, hwnd, message, wParam, lParam);
}
return NULL;
}
int BlockingMessageLoop ( void )
{
MSG msg;
WORD rc=1;
rc = GetMessage ( &msg, NULL, NULL, NULL );
if (rc == TRUE)
{
TranslateMessage ( &msg );
DispatchMessage ( &msg );
return MessageLoop ();
}
else
return rc;
} /* BlockingMessageLoop */
void SaveAsToFile ( void )
{
char fname[256];
OPENFILENAME of;
BOOL rc;
FILE *f;
int numLines = 0;
int index = 0;
char buffer [256];
int *pBuffer = (int *) buffer;
int length = 0;
char filterFiles[] = "Result Files (*.TXT)" \
"\0" \
"*.TXT" \
"\0\0";
fname[0] = 0;
memset( &of, 0, sizeof( OPENFILENAME ) );
of.lStructSize = sizeof( OPENFILENAME );
of.hwndOwner = MainWindow;
of.lpstrFilter = filterFiles;
of.nFilterIndex = 1L;
of.lpstrFile = fname;
of.nMaxFile = 256;
of.lpstrTitle = "Save File Name Selection";
of.Flags = OFN_HIDEREADONLY;
rc = GetSaveFileName( &of );
if ( !rc ) return;
f = fopen( fname, "w" );
if ( f == NULL )
{
MessageBox ( NULL, fname,"Error opening file", MB_OK );
return;
}
numLines = SendMessage (ScreenOutputWindow, EM_GETLINECOUNT, 0, 0);
for (index = 0; index < numLines; index++)
{
*pBuffer = 255;
length = SendMessage (ScreenOutputWindow, EM_GETLINE, index,
(LPARAM) (LPCSTR) buffer);
// remove the carriage return and line feed
if (length > 1) length -= 2;
buffer [length] = '\0';
fprintf ( f, "%s\n", buffer );
}
fclose ( f );
MessageBox ( NULL, fname, "Data saved to file", MB_OK );
} /* SaveAllLines */
int MessageLoop ( void )
{
MSG msg;
int rc = TRUE;
while ( PeekMessage( &msg, NULL, NULL, NULL, PM_NOREMOVE ) == TRUE )
{
rc = GetMessage( &msg, NULL, NULL, NULL );
if (rc == TRUE)
{
TranslateMessage ( &msg );
DispatchMessage ( &msg );
}
}
Sleep (0);
return ( rc );
} /* MessageLoop */