=============================== FILEDIAL.CPP =============================== /* file_dialog() */ #include #include #include #include "filedial.h" /*----------------------------------------------------------------------------- This function pops up a file dialog box by calling on COMMDLG.DLL. file_dialog(handle, title, specs, specs_size, types, defext, flags, help_file, help_command, help_data); HWND handle handle of owner window char *title title to be put on title bar of dialog box char *specs specs to start with, including drive and directory path; if file name and extension are omitted, specs must end with \ int specs_size number of chars the specs buffer can hold char *types types of files to be displayed, see below char *defext default extension to be appended if file has no extension, or "" if none is to be appended DWORD flags flags char *help_file specs of .HLP file to be called up when user presses the Help button, or NULL if this feature is not to be used unsigned help_command help command to be invoked then user presses the Help button DWORD help_data data to be passed to help when user presses the Help button The flags word consists of the following bits, OR'ed together as required: FD_OPEN open file for input FD_SAVE open file for output FD_OVERWRITEPROMPT when used with FD_SAVE, prompt user before returning a file that already exists FD_MUSTEXIST when used with FD_OPEN, require that file exist FD_CREATEPROMPT when used with FD_SAVE, prompt user before returning a file that does not already exist The types argument is a sequence of strings, one for each type of file to be displayed in the files box. Each string has the format \0\0 The strings are run together, and the last string is followed by two nulls (\0\0). The description does not have to contain a copy of the ambiguous file specs, although this is a common practice. For example if types = "All files (*.*)\0*.*\0" then all files in the selected directory are displayed in the box. (The compiler supplies the second terminating \0.) If the help_file argument is not NULL, then the Help button will appear in the file dialog box. When the user clicks this button, the following API call will be invoked WinHelp(file_dialog_handle, help_file, help_command, help_data); See the Windows API documentation for permitted values of the arguments and other details. A typical call, which displays topic number 105, would be as follows: WinHelp(file_dialog_handle, "C:\\MYDIR\\MYHELP.HLP", HELP_CONTEXT, 105); The return value of file_dialog() is TRUE if a file was selected, or FALSE if the user clicked the Cancel button or closed the dialog box. The full specifications of the selected file are returned in the specs buffer, which must be large enough to hold them. If the function returns FALSE, the contents of the specs buffer are undefined. -----------------------------------------------------------------------------*/ extern "C" { unsigned far pascal _export file_dialog_callback(HWND handle, UINT message, WPARAM wParam, LPARAM lparam); } static char *static_help_file; static unsigned static_help_command; static DWORD static_help_data; unsigned far pascal _export file_dialog_callback(HWND handle, UINT message, WPARAM wParam, LPARAM /* lparam */) { if (message == WM_COMMAND && wParam == 1038) { WinHelp(GetWindowWord(handle, GWW_HWNDPARENT), static_help_file, static_help_command, static_help_data); return 1; } return 0; } BOOL file_dialog(HWND handle, char *title, char *specs, int specs_size, char *types, char *defext, DWORD flags, char *help_file, unsigned help_command, DWORD help_data) { BOOL fd; OPENFILENAME f; char directory[MAX_DIR+1]; /* directory path -> directory */ /* name.ext -> specs */ { char *s; char *t = specs; char *d = directory; char *dend = directory; int c; for (s = specs; (c = *s) != 0; s++) { if (c == '\\') { t = specs; dend = d; if (dend == directory + 2) dend++; } else if (c == ':') { t = specs; dend = d+1; } else *t++ = c; *d++ = c; } *t = 0; *dend = 0; } memset(&f, 0, sizeof(f)); f.lStructSize = sizeof(f); f.hwndOwner = handle; /* f.hInstance = 0; */ f.lpstrFilter = types; /* f.lpstrCustomFilter = NULL; */ /* f.nMaxCustFilter = 0; */ f.nFilterIndex = 1; f.lpstrFile = specs; f.nMaxFile = specs_size; /* f.lpstrFileTitle = NULL; */ /* f.nMaxFileTitle = 0; */ f.lpstrInitialDir = directory; f.lpstrTitle = title; f.Flags = flags & ~FD_SAVE | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST; /* f.nFileOffset = 0; */ /* f.nFileExtension = 0; */ f.lpstrDefExt = defext; /* f.lCustData = 0; */ if (help_file != NULL) { f.lpfnHook = (unsigned far pascal (*)(HWND, UINT, WPARAM, LPARAM)) MakeProcInstance((FARPROC) file_dialog_callback, GetWindowWord(handle, GWW_HINSTANCE)); f.Flags |= OFN_SHOWHELP | OFN_ENABLEHOOK; static_help_file = help_file; static_help_command = help_command; static_help_data = help_data; } /* f.lpTemplateName = NULL; */ fd = flags & FD_SAVE ? GetSaveFileName(&f): GetOpenFileName(&f); if (f.lpfnHook != NULL) FreeProcInstance((FARPROC) f.lpfnHook); InvalidateRect(handle, NULL, TRUE); return fd; } =============================== FILEDIAL.H =============================== /* header for file_dialog() */ #define FD_OVERWRITEPROMPT 0x00000002L #define FD_HELP 0x00000010L #define FD_MUSTEXIST 0x00001000L #define FD_CREATEPROMPT 0x00002000L #define FD_OPEN 0x00000000L #define FD_SAVE 0x10000000L #define MAX_DIR 143 #define MAX_FILE (8+1+3) extern int file_dialog(HWND, char *, char *, int, char *, char *, DWORD, char *, unsigned, DWORD); =============================== SPINNER.CPP =============================== // Spinner 1.0 #include #include #include "spinner.h" #include "filedial.h" const unsigned MAX_COUNT = 500; const unsigned MAX_MAX = 999; extern HANDLE _hInstance; extern "C" { int far pascal _export OverwriteProc(HWND, UINT,WPARAM, LPARAM); int far pascal _export RangeProc(HWND, UINT,WPARAM, LPARAM); long far pascal _export MainProc(HWND, UINT,WPARAM, LPARAM); int pascal WinMain(HINSTANCE, HINSTANCE, LPSTR, int); } struct limit { int minimum; int maximum; int new_value; int value; HWND handle; }; static limit min = {0, MAX_MAX - 1}; static limit max = {1, MAX_MAX}; static int minimum = 0; static int maximum = 255; static unsigned count = 0; static char filespecs[1024]; static char text[4 * MAX_COUNT + 2 * (MAX_COUNT/10) + 3]; static char help_file[1024]; int far pascal _export OverwriteProc(HWND handle, UINT message, WPARAM wParam, LPARAM /* lParam */) { switch (message) { case WM_INITDIALOG: SetDlgItemText(handle, FILESPECS_BOX, filespecs); return 1; case WM_COMMAND: switch (wParam) { case OVERWRITE_BUTTON: case APPEND_BUTTON: case CANCEL_BUTTON: EndDialog(handle, wParam); return 1; } break; case WM_CLOSE: EndDialog(handle, CANCEL_BUTTON); return 0; } return 0; } static void update_range(HWND handle) { char s[8]; if (min.new_value != min.value) SetScrollPos(min.handle, SB_CTL, min.new_value, TRUE); if (max.new_value != max.value) SetScrollPos(max.handle, SB_CTL, max.new_value, TRUE); if (min.new_value != min.value || max.new_value != max.value) { wsprintf(s, "%d-%d", min.new_value, max.new_value); SetDlgItemText(handle, RANGE_TEXT, s); min.value = min.new_value; max.value = max.new_value; } } int far pascal _export RangeProc(HWND handle, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: { min.value = -1; min.new_value = minimum; min.handle = GetDlgItem(handle, LEFT_SCROLL); max.value = -1; max.new_value = maximum; max.handle = GetDlgItem(handle, RIGHT_SCROLL); SetScrollRange(min.handle, SB_CTL, min.minimum, min.maximum, FALSE); SetScrollRange(max.handle, SB_CTL, max.minimum, max.maximum, FALSE); update_range(handle); return 0; } case WM_COMMAND: switch (wParam) { case IDOK: minimum = min.value; maximum = max.value; EndDialog(handle, 1); return 1; case IDCANCEL: EndDialog(handle, 0); return 1; case RANGE_HELP_BUTTON: WinHelp(handle, "SPINNER.HLP", HELP_CONTEXT, 103); return 0; } break; case WM_HSCROLL: { limit &p = (HWND) HIWORD(lParam) == min.handle ? min : max; min.new_value = min.value; max.new_value = max.value; switch (wParam) { case SB_LEFT: p.new_value = p.minimum; break; case SB_LINELEFT: p.new_value--; break; case SB_LINERIGHT: p.new_value++; break; case SB_PAGELEFT: p.new_value += 50; break; case SB_PAGERIGHT: p.new_value -= 50; break; case SB_RIGHT: p.new_value = p.maximum; break; case SB_THUMBPOSITION: case SB_THUMBTRACK: { p.new_value = LOWORD(lParam); break; } } if (p.new_value < p.minimum) p.new_value = p.minimum; if (p.new_value > p.maximum) p.new_value = p.maximum; if ((HWND) HIWORD(lParam) == min.handle) { if (min.new_value >= max.new_value) max.new_value = min.new_value + 1; } else { if (max.new_value <= min.new_value) min.new_value = max.new_value - 1; } update_range(handle); return 0; } case WM_CLOSE: EndDialog(handle, 0); return 0; } return 0; } long far pascal _export MainProc(HWND handle, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_CREATE: return 0; case WM_COMMAND: switch (wParam) { case FILE_BUTTON: if (file_dialog(handle, "Copy Spinner Results to File", filespecs, sizeof(filespecs), "All files (*.*)\0*.*\0", "", FD_SAVE, "SPINNER.HLP", HELP_CONTEXT, 102)) { int mode = OVERWRITE_BUTTON; int h = _lopen(filespecs, READ); if (h >= 0) { _lclose(h); DLGPROC proc = (DLGPROC) MakeProcInstance((FARPROC) OverwriteProc, _hInstance); mode = DialogBox(_hInstance, "OVERWRITE", handle, proc); FreeProcInstance((FARPROC) proc); } if (mode != CANCEL_BUTTON) { FILE *f = fopen(filespecs, mode == OVERWRITE_BUTTON ? "wb" : "ab"); if (f == NULL) MessageBox(handle, "Can't open file (may be read-only)", "Spinner", MB_OK | MB_ICONSTOP); else { char *t; GetDlgItemText(handle, EDIT_BOX, text, sizeof(text)); DWORD x = SendDlgItemMessage(handle, EDIT_BOX, EM_GETSEL, 0, 0L); if (LOWORD(x) < HIWORD(x)) { text[HIWORD(x)] = 0; t = &text[LOWORD(x)]; } else { SendDlgItemMessage(handle, EDIT_BOX, EM_SETSEL, 0, MAKELONG(0, -1)); t = text; } int e = fputs(t, f); if (fclose(f) == EOF || e == EOF) { MessageBox(handle, "File write error (possibly insufficient disk space)", "Spinner", MB_OK | MB_ICONSTOP); } else SetFocus(GetDlgItem(handle, EDIT_BOX)); } } } return 0; case CLIPBOARD_BUTTON: { DWORD x = SendDlgItemMessage(handle, EDIT_BOX, EM_GETSEL, 0, 0L); if (LOWORD(x) >= HIWORD(x)) SendDlgItemMessage(handle, EDIT_BOX, EM_SETSEL, 0, MAKELONG(0, -1)); SendDlgItemMessage(handle, EDIT_BOX, WM_COPY, 0, 0L); SetFocus(GetDlgItem(handle, EDIT_BOX)); return 0; } case RANGE_BUTTON: { DLGPROC proc = (DLGPROC) MakeProcInstance((FARPROC) RangeProc, _hInstance); if (DialogBox(_hInstance, "RANGE", handle, proc)) { char s[25]; wsprintf(s, "Spinner (%d-%d)", minimum, maximum); SetWindowText(handle, s); } FreeProcInstance((FARPROC) proc); return 0; } case HELP_BUTTON: WinHelp(handle, "SPINNER.HLP", HELP_CONTENTS, 0L); return 0; case EXIT_BUTTON: DestroyWindow(handle); return 0; case CLEAR_BUTTON: if (count == MAX_COUNT) EnableWindow(GetDlgItem(handle, SPIN_BUTTON), TRUE); if (count != 0) { EnableWindow(GetDlgItem(handle, FILE_BUTTON), FALSE); EnableWindow(GetDlgItem(handle, CLIPBOARD_BUTTON), FALSE); EnableWindow(GetDlgItem(handle, RANGE_BUTTON), TRUE); EnableWindow(GetDlgItem(handle, EDIT_BOX), FALSE); } count = 0; EnableWindow(GetDlgItem(handle, CLEAR_BUTTON), FALSE); SetFocus(GetDlgItem(handle, SPIN_BUTTON)); SetDlgItemText(handle, EDIT_BOX, ""); return 0; case SPIN_BUTTON: { int n; if (count == 0) n = 0; else { n = GetDlgItemText(handle, EDIT_BOX, text, sizeof(text)) - 2; text[n++] = ','; if (count % 10 == 0) { text[n++] = '\r'; text[n++] = '\n'; } } DWORD t = GetTickCount(); wsprintf(text + n, maximum < 10 ? "%1d\r\n" : maximum < 100 ? "%2d\r\n" : "%3d\r\n", (t + t/13) % (maximum - minimum + 1) + minimum); SetDlgItemText(handle, EDIT_BOX, text); if (++count == 1) { EnableWindow(GetDlgItem(handle, CLEAR_BUTTON), TRUE); EnableWindow(GetDlgItem(handle, FILE_BUTTON), TRUE); EnableWindow(GetDlgItem(handle, CLIPBOARD_BUTTON), TRUE); EnableWindow(GetDlgItem(handle, RANGE_BUTTON), FALSE); EnableWindow(GetDlgItem(handle, EDIT_BOX), TRUE); } else if (count == MAX_COUNT) { EnableWindow(GetDlgItem(handle, SPIN_BUTTON), FALSE); SetFocus(GetDlgItem(handle, EDIT_BOX)); } return 0; } } break; case WM_CLOSE: DestroyWindow(handle); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefDlgProc (handle, message, wParam, lParam); } int pascal WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR /* lpszCmdLine */, int nCmdShow) { HWND handle; if (!hPrevInstance) { WNDCLASS wndclass; wndclass.style = 0; wndclass.lpfnWndProc = (WNDPROC) MainProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = DLGWINDOWEXTRA; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(hInstance, "SPINNER_ICON"); wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); wndclass.hbrBackground = NULL; wndclass.lpszMenuName = NULL; wndclass.lpszClassName = "SPINNER"; RegisterClass (&wndclass); } handle = CreateDialog(hInstance, "SPINNER", 0, NULL); ShowWindow(handle, nCmdShow == SW_SHOWNORMAL); { MSG msg; while (GetMessage(&msg, NULL, 0, 0)) if (!IsDialogMessage(handle, &msg)) DispatchMessage(&msg); return msg.wParam; } } =============================== SPINNER.DEF =============================== NAME SPINNER DESCRIPTION 'Spinner' EXETYPE WINDOWS CODE PRELOAD MOVEABLE DATA PRELOAD MOVEABLE MULTIPLE STACKSIZE 8000 HEAPSIZE 4000 =============================== SPINNER.H =============================== #define SPIN_BUTTON 101 #define EDIT_BOX 102 #define FILE_BUTTON 103 #define CLIPBOARD_BUTTON 104 #define RANGE_BUTTON 105 #define CLEAR_BUTTON 106 #define EXIT_BUTTON 107 #define HELP_BUTTON 108 #define OVERWRITE_BUTTON IDOK #define APPEND_BUTTON 202 #define CANCEL_BUTTON IDCANCEL #define FILESPECS_BOX 204 #ifdef LEFT_HANDED #define BUTTON_OFFSET 0 #define EDIT_BOX_OFFSET 50 #else #define BUTTON_OFFSET 160 #define EDIT_BOX_OFFSET 0 #endif #define RANGE_TEXT 301 #define LEFT_SCROLL 302 #define RIGHT_SCROLL 303 #define RANGE_HELP_BUTTON 304 =============================== SPINNER.HPJ =============================== [OPTIONS] TITLE=Spinner COMPRESS=true [FILES] spinner.rtf [CONFIG] ;CreateButton("btn_about", "&About", "JumpContext(`spinner.hlp', 101)") CreateButton("btn_exit", "E&xit", "Exit()") [MAP] ;AboutSpinner 101 CopyFile 102 Range 103 =============================== SPINNER.RC =============================== #include "spinner.h" SPINNER DIALOG 54, 76, 210, 132 STYLE WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX CLASS "SPINNER" CAPTION "Spinner (0-255)" FONT 8, "MS Sans Serif" { PUSHBUTTON "Spin", SPIN_BUTTON, BUTTON_OFFSET, 84, 50, 48, WS_TABSTOP EDITTEXT EDIT_BOX, EDIT_BOX_OFFSET, 0, 160, 132, WS_DISABLED | ES_READONLY | NOT WS_BORDER | WS_VSCROLL | WS_TABSTOP | ES_MULTILINE PUSHBUTTON "File..", FILE_BUTTON, BUTTON_OFFSET, 0, 50, 14, WS_DISABLED | WS_TABSTOP PUSHBUTTON "Clipboard", CLIPBOARD_BUTTON, BUTTON_OFFSET, 14, 50, 14, WS_DISABLED | WS_TABSTOP PUSHBUTTON "Range..", RANGE_BUTTON, BUTTON_OFFSET, 28, 50, 14, WS_TABSTOP PUSHBUTTON "Clear", CLEAR_BUTTON, BUTTON_OFFSET, 42, 50, 14, WS_DISABLED | WS_TABSTOP PUSHBUTTON "Exit", EXIT_BUTTON, BUTTON_OFFSET, 56, 50, 14 PUSHBUTTON "Help", HELP_BUTTON, BUTTON_OFFSET, 70, 50, 14 } OVERWRITE DIALOG 75, 60, 145, 69 STYLE WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "File Already Exists" FONT 8, "MS Sans Serif" { DEFPUSHBUTTON "Overwrite", OVERWRITE_BUTTON, 10, 44, 40, 16 PUSHBUTTON "Append", APPEND_BUTTON, 54, 44, 40, 16 PUSHBUTTON "Cancel", CANCEL_BUTTON, 98, 44, 40, 16 LTEXT "", FILESPECS_BOX, 10, 6, 126, 30, SS_LEFT | WS_BORDER } RANGE DIALOG 31, 68, 186, 66 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Spinner Range Selection" FONT 8, "MS Sans Serif" { DEFPUSHBUTTON "OK", IDOK, 8, 42, 50, 14 PUSHBUTTON "Cancel", IDCANCEL, 68, 42, 50, 14 PUSHBUTTON "Help", RANGE_HELP_BUTTON, 129, 42, 50, 14 CTEXT "", RANGE_TEXT, 76, 7, 33, 10, SS_CENTER | NOT WS_GROUP | WS_BORDER SCROLLBAR LEFT_SCROLL, 9, 24, 78, 9, SBS_HORZ | WS_TABSTOP SCROLLBAR RIGHT_SCROLL, 99, 24, 80, 9, SBS_HORZ | WS_TABSTOP } SPINNER_ICON ICON { '00 00 01 00 01 00 20 20 10 00 00 00 00 00 E8 02' '00 00 16 00 00 00 28 00 00 00 20 00 00 00 40 00' '00 00 01 00 04 00 00 00 00 00 80 02 00 00 00 00' '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00' '00 00 00 00 80 00 00 80 00 00 00 80 80 00 80 00' '00 00 80 00 80 00 80 80 00 00 80 80 80 00 C0 C0' 'C0 00 00 00 FF 00 00 FF 00 00 00 FF FF 00 FF 00' '00 00 FF 00 FF 00 FF FF 00 00 FF FF FF 00 00 00' '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00' '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00' '00 00 00 00 BB BB BB BB 00 00 00 00 00 00 00 00' '00 00 0B BB BB B9 9B BB BB B0 00 00 00 00 00 00' '00 00 BB 99 BB B9 9B BB 99 BB 00 00 00 00 00 00' '00 BB BB 99 BB BB BB BB 99 BB BB 00 00 00 00 00' '0B BB BB BB BB BB BB BB BB BB BB B0 00 00 00 00' '0B 99 BB BB BB BB BB BB BB BB 99 B0 00 00 00 00' 'BB 99 BB BB BB BB BB BB BB BB 99 BB 00 00 00 0B' 'BB BB BB BB BB BB BB BB BB BB BB BB B0 00 00 0B' 'BB BB BB BB BB BB BB BB BB BB BB BB B0 00 00 0B' '99 BB BB BB BB BB BB BB BB BB BB 99 B0 00 00 BB' '99 BB BB BB BB BB BB BB BB BB BB 99 BB 00 00 BB' 'BB BB BB BB BB BB BB BB BB BB BB BB BB 00 00 BB' 'BB BB BB BB BB B0 0B BB BB BB BB BB BB 00 00 B9' '9B BB BB 00 0B 00 00 B0 00 00 00 00 0B 00 00 B9' '9B BB BB 00 0B 00 00 B0 00 00 00 00 0B 00 00 BB' 'BB BB BB BB BB B0 0B BB BB BB BB BB BB 00 00 BB' 'BB BB BB BB BB BB BB BB BB BB BB BB BB 00 00 BB' '99 BB BB BB BB BB BB BB BB BB BB 99 BB 00 00 0B' '99 BB BB BB BB BB BB BB BB BB BB 99 B0 00 00 0B' 'BB BB BB BB BB BB BB BB BB BB BB BB B0 00 00 0B' 'BB BB BB BB BB BB BB BB BB BB BB BB B0 00 00 00' 'BB 99 BB BB BB BB BB BB BB BB 99 BB 00 00 00 00' '0B 99 BB BB BB BB BB BB BB BB 99 B0 00 00 00 00' '0B BB BB BB BB BB BB BB BB BB BB B0 00 00 00 00' '00 BB BB 99 BB BB BB BB 99 BB BB 00 00 00 00 00' '00 00 BB 99 BB B9 9B BB 99 BB 00 00 00 00 00 00' '00 00 0B BB BB B9 9B BB BB B0 00 00 00 00 00 00' '00 00 00 00 BB BB BB BB 00 00 00 00 00 00 00 00' '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00' '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF' 'FF FF FF F0 0F FF FF 80 01 FF FF 00 00 FF FC 00' '00 3F F8 00 00 1F F0 00 00 0F F0 00 00 0F E0 00' '00 07 C0 00 00 03 C0 00 00 03 C0 00 00 03 80 00' '00 01 80 00 00 01 80 00 00 01 80 00 00 01 80 00' '00 01 80 00 00 01 80 00 00 01 80 00 00 01 C0 00' '00 03 C0 00 00 03 C0 00 00 03 E0 00 00 07 F0 00' '00 0F F0 00 00 0F F8 00 00 1F FC 00 00 3F FF 00' '00 FF FF 80 01 FF FF F0 0F FF FF FF FF FF' } =============================== SPINNER.RTF =============================== {\rtf1\ansi \deff0\deflang1024{\fonttbl{\f0\froman Times New Roman;}{\f1\froman Symbol;}{\f2\fswiss Arial;}{\f3\fmodern Roman 10cpi;}{\f4\fswiss Helv;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255; \red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue127;\red0\green127\blue127;\red0\green127\blue0;\red127\green0\blue127;\red127\green0\blue0; \red127\green127\blue0;\red127\green127\blue127;\red192\green192\blue192;}{\stylesheet{\s243\tqc\tx4320\tqr\tx8640 \f4\fs20\lang1033 \sbasedon0\snext243 header;}{\s244 \f4\fs16\up6\lang1033 \sbasedon0\snext0 footnote reference;}{\s245 \f4\fs20\lang1033 \sbasedon0\snext245 footnote text;}{\f4\fs20\lang1033 \snext0 Normal;}}{\info{\author Philip Erdelsky}{\creatim\yr1993\mo11\dy16\hr14\min20}{\version1}{\edmins1657}{\nofpages0}{\nofwords65536}{\nofchars65536}{\vern16433}} \paperw12240\paperh31680\margl1800\margr1800\margt1440\margb1440\gutter0 \widowctrl\ftnbj \sectd \linex0\endnhere \pard\plain \keepn \f4\fs20\lang1033 {\fs16\up6 #{\footnote \pard\plain \s245 \f4\fs20\lang1033 {\fs16\up6 #} Contents}}{\fs16\up6 $ {\footnote \pard\plain \s245 \f4\fs20\lang1033 {\fs16\up6 $} Spinner}}{\fs16\up6 K{\footnote \pard\plain \s245 \f4\fs20\lang1033 {\fs16\up6 K} Contents;Table of Contents;Spinner;Spinner Contents}} {\plain \b\f4\lang1033 Spinner} \par \par \pard {\strike Overview}{\v Overview} \par {\strike Generating Numbers}{\v Generating} \par {\strike Range Selection}{\v Range} \par {\strike Clearing the Numbers}{\v Clear} \par {\strike Copying Numbers to the Clipboard}{\v CopyClipboard} \par {\strike Copying Numbers to a File}{\v CopyFile} \par {\strike Marking Numbers to be Copied}{\v Marking} \par \par \pard \keepn \page {\fs16\up6 #{\footnote \pard\plain \s245 \f4\fs20\lang1033 {\fs16\up6 #} Generating}}{\fs16\up6 ${\footnote \pard\plain \s245 \f4\fs20\lang1033 {\fs16\up6 $} Generating Numbers}}{\fs16\up6 K{\footnote \pard\plain \s245 \f4\fs20\lang1033 {\fs16\up6 K} Generating Numbers;Spin;Numbers, Generating}} {\plain \b\f4\lang1033 Generating Numbers} \par \par \pard To "spin the wheel" and generate a number, press the {\b Spin} button. Every press generates a number. The elapsed time between presses determines which numbers are generated. Since the user's reaction time is variable, the numbers will be fairly random and unrepeatable. \par \par {\plain \f4\lang1033 CAUTION:} Once the input focus is on the {\b Spin} button, you can generate numbers quickly by holding the {\b Enter} key down. However, this is not recommended because the interval between keystrokes will be too regular to guarantee a reasonable amount of randomness. \par \par \pard \keepn \page {\fs16\up6 #{\footnote \pard\plain \s245 \f4\fs20\lang1033 {\fs16\up6 #} CopyClipboard}}{\fs16\up6 ${\footnote \pard\plain \s245 \f4\fs20\lang1033 {\fs16\up6 $} Copying Numbers to the Clipboard}}{\fs16\up6 K{\footnote \pard\plain \s245 \f4\fs20\lang1033 {\fs16\up6 K} Copying Numbers to the Clipboard;Clipboard, Copying Numbers to}} {\plain \b\f4\lang1033 Copying Numbers to the Clipboard} \par \par \pard To copy numbers to the Clipboard, \par \par \pard \fi-270\li540 (1) Mark the numbers to be copied. See {\strike Marking Numbers to be Copied}{\v Marking}. \par \par (2) Press the {\b Clipboard} button, or hold either {\b Ctrl} key down and strike the {\b C} key. \par \par \pard \tx9000 If no numbers are marked when the {\b Clipboard} button is pressed, all numbers are copied to the Clipboard. \par \pard \par \pard \keepn \page {\fs16\up6 #{\footnote \pard\plain \s245 \f4\fs20\lang1033 {\fs16\up6 #} CopyFile}}{\fs16\up6 ${\footnote \pard\plain \s245 \f4\fs20\lang1033 {\fs16\up6 $} Copying Numbers to a File}}{\fs16\up6 K{\footnote \pard\plain \s245 \f4\fs20\lang1033 {\fs16\up6 K} Copying Numbers to a File;File, Copying Numbers to}} {\plain \b\f4\lang1033 Copying Numbers to a File} \par \par \pard To copy numbers to a file, \par \par \pard \fi-270\li540 (1) Mark the numbers to be copied, or remove the marking if all numbers are to be copied. See {\strike Marking Numbers to be Copied}{\v Marking}. \par \par (2) Press the {\b File} button. A standard file dialog box will appear. \par \par (3) Select the desired file, or select the desired directory and enter a new file name. \par \par (4) Press the {\b OK} button (or strike the {\b Enter} key) to continue. Press the {\b Cancel} button (or strike the {\b Esc} key) to cancel the operation. \par \par (5) If the file already exists, a small dialog box will appear. In this case: \par \par \pard \fi-270\li1080 (a) Press the {\b Overwrite} button (or strike the {\b Enter} key) if you want to erase the current file contents before copying the numbers to it. \par \par (b) Press the {\b Append} button if you want keep the current file contents and append the numbers to the end. \par \par (c) Press the {\b Cancel} button (or strike the {\b Esc} key) to cancel the operation. \par \pard \fi-270\li540 \par \pard \keepn \page {\fs16\up6 #{\footnote \pard\plain \s245 \f4\fs20\lang1033 {\fs16\up6 #} Marking}}{\fs16\up6 ${\footnote \pard\plain \s245 \f4\fs20\lang1033 {\fs16\up6 $} Marking Numbers to be Copied}}{\fs16\up6 K{\footnote \pard\plain \s245 \f4\fs20\lang1033 {\fs16\up6 K} Marking Numbers;Numbers, Marking;Selecting Numbers;Numbers, Selecting}} {\plain \b\f4\lang1033 Marking Numbers to be Copied} \par \par \pard To mark numbers to be copied to the Clipboard or a file with the mouse: \par \par \pard \fi-270\li540 (1) Move the {\ul mouse cursor}{\v MouseCursor} to the left end of the first number to be copied. \par \par (2) Depress the left mouse button. \par \par (3) Hold the button down and move the mouse cursor to the right end of the last number to be copied. The numbers will be highlighted as the mouse cursor moves. \par \par (4) Release the mouse button. \par \par (5) To remove the marking, move the mouse cursor over any part of the text box and tap the left mouse button. (Do this if you want to copy all of the numbers.) \par \pard \par To mark numbers to be copied to the Clipboard or a file with the keyboard: \par \par \pard \fi-270\li540 (1) Strike the {\b Tab} key until the input focus reaches the text box containing the numbers. The {\ul text cursor}{\v TextCursor} will appear in the text box. \par \par (2) Use the arrow keys to move the text cursor to the left end of the first number to be copied. \par \par (3) Hold either {\b Shift} key down and move the text cursor to the right end of the last number to be copied. The numbers will be highlighted as the text cursor moves. \par \par (4) Release the {\b Shift} key. \par \par (5) To remove the marking, move the text cursor without holding either {\b Shift} key down. (Do this if you want to copy all of the numbers.) \par \pard \par \pard \keepn \page {\fs16\up6 #{\footnote \pard\plain \s245 \f4\fs20\lang1033 {\fs16\up6 #} Clear}}{\fs16\up6 ${\footnote \pard\plain \s245 \f4\fs20\lang1033 {\fs16\up6 $} Clearing the Numbers}}{\fs16\up6 K{\footnote \pard\plain \s245 \f4\fs20\lang1033 { \fs16\up6 K} Clearing the Numbers;Erasing the Numbers;Removing the Numbers}} {\plain \b\f4\lang1033 Clearing the Numbers} \par \par \pard To clear the numbers, press the {\b Clear} button. \par \par You must do this before you can change the range. See {\strike Range Selection}{\v Range}. \par \par \pard \keepn \page {\fs16\up6 #{\footnote \pard\plain \s245 \f4\fs20\lang1033 {\fs16\up6 #} Range}}{\fs16\up6 ${\footnote \pard\plain \s245 \f4\fs20\lang1033 {\fs16\up6 $} Range Selection}}{\fs16\up6 K{\footnote \pard\plain \s245 \f4\fs20\lang1033 { \fs16\up6 K} Range Selection;Select Range;Limits;Upper Limit;Lower Limit}} {\plain \b\f4\lang1033 Range Selection} \par \par \pard When the Spinner is first invoked, it is configured to generate random numbers in the range from 0 to 255, inclusive. The range is shown on the top line of the main window. \par \par You can change the range as follows: \par \par \pard \fi-270\li540 (1) If any numbers are showing, you must clear them by pressing the {\b Clear} button before you change the range. \par \par (2) Press the {\b Range} button to bring up the Spinner Range Selection dialog box. \par \par (3) The range is shown in numerical form in a small box. Below the box are two scroll bars that you can use to change the upper and lower limits of the range. \par \par (4) To change the LOWER LIMIT of the range, {\strike move the runner}{\v MoveRunner} in the LEFT SCROLL BAR. Move it to the left to lower the limit, or to the right to raise the limit. The range shown in the small box will be updated automatically. \par \par (5) To change the UPPER LIMIT of the range, move the runner in the RIGHT SCROLL BAR. Move it to the left to lower the limit, or to the right to raise the limit. The range shown in the small box will be updated automatically. \par \par (6) When you are satisfied with the new range, press the {\b OK} button (or strike the {\b Enter} key). \par \par (7) If you decide not to change the range, press the {\b Cancel} button (or strike the {\b Esc} key). \par \par \pard The limits must be no less than zero and no greater than 999. \par \par The lower limit must be less than the upper limit. When you change one limit, the other limit will also be changed, if necessary, to preserve this relationship. \par \par \pard \keepn \page {\fs16\up6 #{\footnote \pard\plain \s245 \f4\fs20\lang1033 {\fs16\up6 #} MoveRunner}}{\fs16\up6 ${\footnote \pard\plain \s245 \f4\fs20\lang1033 {\fs16\up6 $} Moving a Scroll Bar Runner}}{\fs16\up6 K{\footnote \pard\plain \s245 \f4\fs20\lang1033 {\fs16\up6 K} Runner;Scroll Bar Runner;Moving a Scroll Bar Runner}} {\plain \b\f4\lang1033 Moving a Scroll Bar Runner} \par \par \pard To move a scroll bar runner with the mouse: \par \par \pard \fi-270\li540 (1) Move the {\ul mouse cursor}{\v MouseCursor} to a box at the end of the scroll bar and \par \par \pard \fi-270\li1080 (a) tap the left mouse button to move the runner one step (in the direction of that end) for each tap, or \par \par (b) hold the left mouse button down until the runner reaches the desired position. \par \pard \fi-270\li540 \par (2) Move the mouse cursor to the runner and depress the left mouse button. Then hold the button down and move the mouse cursor to the desired position. The runner will follow it. When the runner reaches the desired position, release the button. \par \pard \par To move a scroll bar runner with the keyboard: \par \par \pard \fi-270\li540 (1) Strike the {\b Tab} key until the input focus reaches the scroll bar runner and makes it flash. \par \par (2) Strike the left arrow key to move the runner left one step. \par \par (3) Strike the right arrow key to move the runner right one step. \par \par (4) Strike the {\b PgDn} key to move the runner left 50 steps. \par \par (5) Strike the {\b PgUp} key to move the runner right 50 steps. \par \par (6) Strike the {\b Home} key to move the runner to the left end of the scroll bar. \par \par (7) Strike the {\b End} key to move the runner to the right end of the scroll bar. \par \pard \par \page {\fs16\up6 #{\footnote \pard\plain \s245 \f4\fs20\lang1033 {\fs16\up6 #} MouseCursor}}{\fs16\up6 ${\footnote \pard\plain \s245 \f4\fs20\lang1033 {\fs16\up6 $} Mouse Cursor}}{\fs16\up6 K{\footnote \pard\plain \s245 \f4\fs20\lang1033 {\fs16\up6 K} Mouse Cursor;Cursor}} {\plain \b\f4\lang1033 Mouse Cursor} \par \par An arrow or other small figure that moves with the mouse, trackball or other pointing device. It is also called the {\b Cursor}. \par \par \page {\fs16\up6 #{\footnote \pard\plain \s245 \f4\fs20\lang1033 {\fs16\up6 #} TextCursor}}{\fs16\up6 ${\footnote \pard\plain \s245 \f4\fs20\lang1033 {\fs16\up6 $} Text Cursor}}{\fs16\up6 K{\footnote \pard\plain \s245 \f4\fs20\lang1033 {\fs16\up6 K} Text Cursor;Caret;Cursor}} {\plain \b\f4\lang1033 Text Cursor} \par \par A flashing vertical line in a text box that indicates where text is to be inserted or marked. It is also called the {\b Caret}. \par \par \pard \keepn \page {\fs16\up6 #{\footnote \pard\plain \s245 \f4\fs20\lang1033 {\fs16\up6 #} Overview}}{\fs16\up6 ${\footnote \pard\plain \s245 \f4\fs20\lang1033 {\fs16\up6 $} OverView}}{\fs16\up6 K{\footnote \pard\plain \s245 \f4\fs20\lang1033 {\fs16\up6 K} Overview;Summary;Introduction}} {\plain \b\f4\lang1033 Overview of Spinner 1.0 for Windows} \par \par \pard The Spinner program generates random numbers, one at a time, by emulating a roulette wheel. The process is essentially as follows: \par \par \pard \fi-270\li540 (1) The system clock, which indicates the number of milliseconds since Windows was started, runs all the time. Hence it produces a sequence of numbers 0, 1, 2, 3, etc. that does not repeat (unless Windows is run continuously for about 49 days). \par \par (2) The Spinner performs a simple arithmetic operation to convert this sequence into a repeating sequence of numbers in the required range. \par \par (3) When the {\b Spin} button is pressed, the current number from the repeating sequence is used as a random number. \par \par (4) Since the number is determined by the exact time when the {\b Spin} button is pressed, it is highly unpredictable and fairly random. \par \pard \par The Spinner program {\i cannot} be used to generate random numbers for Monte Carlo simulation, because \par \par \pard \fi-270\li540 (1) The distribution is not sufficiently uniform. \par \par (2) Generating enough random numbers for a reliable simulation would take too much operator time and effort. \par \pard \par The Spinner program {\i can} be used to generate: \par \par \pard \fi-270\li540 (1) Passwords that nobody else can reconstruct, even if they use the same Spinner program. \par \par (2) Unique signature blocks that are not likely to be duplicated accidentally. \par \pard \par You can set the range of numbers to be generated. See {\strike Range Selection}{\v Range}. \par \par The generated numbers are displayed in a read-only text box in decimal form, separated by commas, ten numbers per line. As many as 500 can be generated. The numbers can easily be incorporated into a C or Pascal array initializer. \par \par }