home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Better Windows, Better Works
/
CDRM93801.bin
/
winutil
/
util42
/
pundit.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-11-20
|
21KB
|
510 lines
/*
* Pundit.c
* Source for Pundit (V 2.0)
* Main routines, etc.
*
* Author: Jeff Bienstadt
*
* Environment:
*
* Run-Time: Microsoft Windows 3.0
*
* Compilers/Tools:
* Microsoft C 6.0
* Microsoft Windows SDK 3.0
*
*/
#include <windows.h> // All the Windows goodies
#include <stdlib.h> // for rand() and srand()
#include <string.h> // for strlen(), etc.
#include <time.h> // for time()
#include "pundit.h" // constants for Pundit
#include "extras.h" // for WriteProfileInt(), etc.
// Global variables
int count, // counts seconds window is hidden/visible
category, // what category are we using now?
hide_mode; // when we go away, do we hide or do we iconize?
WORD string_number; // store ID from string table here
BOOL inout_state, // are we shown or hidden?
paused; // ...... paused or counting?
HANDLE hinst, // a global Instance Handle
hOrgBrush; // a global Brush Handle
HWND Pundit; // a global Window Handle (for main window)
HDC hdc; // a global Display Context Handle
HMENU hmenu; // a Menu Handle (for (un)checking menu items)
SETTINGS settings; // the settings structure
char szAppName[] = "Pundit", // The Application Name
szProfName[] = "Pundit.INI", // The name of the Profile file
szHelpPath[PATH_SIZE+1]; // Path to the HELP file
// The main Window Procedure
int PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE hInstance, // Instance Handle
hPrevInstance; // Previous Instance Handle
LPSTR lpszCmdLine; // The Command Line (we don't use it here)
int nCmdShow; // The SHOW Method (we don't use this, either)
{
MSG msg; // a place to store Windows' Messages
WNDCLASS wndclass; // a Window Class structure
HANDLE hAccel; // an Accelator table Handle
InitGlobals(hInstance); // Initialize Global Varaibles;
// If we have NOT already defined our Window Class, do so now...
// (see the SDK documentation for how this works)
if (!hPrevInstance) {
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(hInstance, szAppName);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = hOrgBrush;
wndclass.lpszMenuName = szAppName;
wndclass.lpszClassName = szAppName;
RegisterClass(&wndclass); // Register the Window Class
}
// Create the Window, and put it's handle into our global Window Handle
Pundit = CreateWindow(szAppName, // Window Name
szAppName, // Window Caption
WS_OVERLAPPED |
WS_CAPTION |
WS_THICKFRAME |
WS_SYSMENU |
WS_MINIMIZEBOX, // The Window style
settings.x, // X position of Window
settings.y, // Y position of Window
settings.width, // Width of Window
settings.height, // Height of Window
NULL, // No Parent
NULL, // Use the Class menu
hInstance, // Instance for Window
NULL); // No additional params
// Try to get a timer... keep trying until we get one or the user gives up
while (!SetTimer(Pundit, ID_TIMER, 1000, NULL)) {
if (IDCANCEL == MessageBox(Pundit,
"I need a Timer, but Windows won't lemme"
"have one\012"
"(maybe you could close a clock"
"or something...)",
szAppName,
MB_ICONEXCLAMATION | MB_RETRYCANCEL))
return FALSE; // User gave up, bail out
}
BuildHelpPath(hInstance, szHelpPath); // build a path to the HELP file
hmenu = GetMenu(Pundit);
CheckMenuItem(hmenu, category, MF_CHECKED);
if (hide_mode == SW_HIDE)
CheckMenuItem(hmenu, IDM_HIDE, MF_CHECKED);
else
CheckMenuItem(hmenu, IDM_ICON, MF_CHECKED);
NewTitle();
NewQuote(Pundit, TRUE); // ShowWindow() & UpdateWindow()
// are contained herein
hAccel = LoadAccelerators(hInstance, szAppName); // Load Accelerator table
while (GetMessage(&msg, NULL, 0, 0)) { // Fetch a Message from Windows
if (!TranslateAccelerator(Pundit, hAccel, &msg)) {
TranslateMessage(&msg); // Translate Keyboard Messages
DispatchMessage(&msg); // Pass Message on to our callback function
}
} // until we get a QUIT Message
return msg.wParam; // return to Windows
} // end of WinMain
// Initialize Global Variables
void InitGlobals(hInstance)
HANDLE hInstance; // our Instance Handle
{
time_t ltime; // here we store the system time
settings.insecs = 5; // "Default" IN seconds
settings.outsecs = 20; // "Default" OUT seconds
settings.cat = 1; // "Default" category (Quotes)
settings.hide = 1; // "Default" hide mode (hidden)
settings.x = 1; // "Default" X position
settings.y = 1; // "Default" Y position
settings.width = 250; // "Default" Width
settings.height = 150; // "Default" Height
settings.back = GetSysColor(COLOR_WINDOW);
settings.fore = GetSysColor(COLOR_WINDOWTEXT);
FetchSettings(); // Now read settings from WIN.INI
count = 0; // Zero out the counter
paused = FALSE; // We're not paused yet
inout_state = TRUE; // We're in the "show" state
hinst = hInstance; // Save our current Instance
hOrgBrush = CreateSolidBrush(settings.back);
time(<ime); // Get the current time
srand((unsigned)ltime); // Use it to set the random number "seed"
}
// Our main Window ``callback'' function
long FAR PASCAL WndProc(hwnd, message, wParam, lParam)
HWND hwnd; // Window Handle for our Window
WORD message, // The Window's Message
wParam; // The WORD parameter value
LONG lParam; // The LONG parameter value
{
PAINTSTRUCT ps; // a Paint structure (for painting the Window)
HDC hdc; // a Display Context Handle (for writing text)
RECT rect; // a Rectangle structure (for writing text)
FARPROC lpProcAbout, // Pointer to function for "About" dialog
lpSettingsDialog; //.................."Settings" dialog
static char str_buffer[256]; // buffer for string from string table
switch (message) { // check for messages...
case WM_CREATE: // creating window
DeleteObject(GetClassWord(hwnd, GCW_HBRBACKGROUND));
SetClassWord(hwnd, GCW_HBRBACKGROUND,
CreateSolidBrush(settings.back));
InvalidateRect(hwnd, NULL, TRUE);
break;
case WM_INITMENU: // if a Menu is displayed...
SendMessage(hwnd, PM_PAUSE, 0, 0L); // ...stop the timer
break;
case WM_MENUSELECT: // if a Menu has been canceled...
if ((LOWORD(lParam) == 0xFFFF) && (HIWORD(lParam) == 0))
SendMessage(hwnd, PM_START, 0, 0L); // ...restart the timer
break;
case WM_SYSCOMMAND: // we got a System Menu Choice...
switch (wParam & 0xFFF0) { // Strip off the low-order 4 bits
case SC_MINIMIZE:
if (inout_state == TRUE) {
inout_state = FALSE; // switch the state
NewTitle();
ShowWindow(hwnd, hide_mode); // hide
count = 0; // reset the counter
return 0L;
}
break;
case SC_RESTORE:
if (inout_state == FALSE) {
inout_state = TRUE; // switch the state
NewTitle();
NewQuote(hwnd, TRUE);
count = 0; // reset the counter
}
break;
}
break;
case WM_COMMAND: // we got a Menu choice...
switch (wParam) { // ... which one?
case IDM_LAWS:
case IDM_QUOTES:
case IDM_SNIGS:
case IDM_MISC:
case IDM_RANDOM:
if (category != (int)wParam) {
hmenu = GetMenu(Pundit);
// CheckMenuItem(hmenu, settings.cat, MF_UNCHECKED);
CheckMenuItem(hmenu, category, MF_UNCHECKED);
// settings.cat = category = wParam;
category = wParam;
// CheckMenuItem(hmenu, settings.cat, MF_CHECKED);
CheckMenuItem(hmenu, category, MF_CHECKED);
NewQuote(hwnd, FALSE);
NewTitle();
}
break;
case IDM_HIDE:
if (hide_mode != SW_HIDE) {
hmenu = GetMenu(Pundit);
CheckMenuItem(hmenu, IDM_ICON, MF_UNCHECKED);
CheckMenuItem(hmenu, IDM_HIDE, MF_CHECKED);
hide_mode = SW_HIDE;
}
break;
case IDM_ICON:
if (hide_mode != SW_MINIMIZE) {
hmenu = GetMenu(Pundit);
CheckMenuItem(hmenu, IDM_HIDE, MF_UNCHECKED);
CheckMenuItem(hmenu, IDM_ICON, MF_CHECKED);
hide_mode = SW_MINIMIZE;
}
break;
case IDM_HELP_INDEX:
WinHelp(hwnd, szHelpPath, HELP_INDEX, 0L);
//MessageBox(hwnd, "Application HELP is not ready yet.\012"
//"After all, this is only a Beta version",
//szAppName,
//MB_ICONEXCLAMATION | MB_OK);
break;
case IDM_HELP_HELP:
WinHelp(hwnd, szHelpPath, HELP_HELPONHELP, 0L);
// WinHelp(hwnd, "WINHELP.HLP", HELP_INDEX, 0L);
break;
case IDM_ABOUT: // About Pundit...
// Make a function Instance
lpProcAbout = MakeProcInstance(About, hinst);
// Process the "About" dialog box
DialogBox(hinst, "ABOUTBOX", hwnd, lpProcAbout);
// Give back the function Instance
FreeProcInstance(lpProcAbout);
break;
case IDM_SETTINGS: // Settings...
// Make a function Instance
lpSettingsDialog = MakeProcInstance(Settings, hinst);
// Process the "About" dialog box
DialogBox(hinst, "SETTINGS", hwnd, lpSettingsDialog);
// Give back the function Instance
FreeProcInstance(lpSettingsDialog);
break;
case IDM_COPY: // Copy
{
LPSTR lpMem;
GLOBALHANDLE hMem;
hMem = GlobalAlloc(GHND, 256L);
lpMem = GlobalLock(hMem);
lstrcpy(lpMem, (LPSTR)str_buffer);
GlobalUnlock(hMem);
OpenClipboard(hwnd);
EmptyClipboard();
SetClipboardData(CF_TEXT, hMem);
CloseClipboard();
}
break;
case IDM_EXIT: // Exit
// Tell Windows to shut down this Application
PostMessage(hwnd, WM_CLOSE, 0, 0L);
break;
}
SendMessage(hwnd, PM_START, 0, 0L); // ...restart the timer
return 0L; // return 0 exit code
case WM_TIMER: // We got a TIMER Message
switch (inout_state) { // are we visible or hidden?
case FALSE: // hidden...
if (count >= settings.outsecs) { // if it's time to show up
inout_state = TRUE; // switch the state
NewTitle();
NewQuote(hwnd, TRUE);
count = 0; // reset the counter
}
else // still waiting to show up
++count; // bump the counter
break;
case TRUE: // shown...
if (count >= settings.insecs) { // if it's time to sleep
inout_state = FALSE; // switch the state
NewTitle();
ShowWindow(hwnd, hide_mode); // hide
count = 0; // reset the counter
}
else // still waiting to sleep
++count; // bump the counter
break;
}
return 0L;
case WM_PAINT: // We got a PAINT Message
GetClientRect(hwnd, &rect); // Get the dimensions of the client area
// Fetch a new string from the string table
LoadString(hinst, string_number, str_buffer, 256);
// Tell Windows we are ready to paint
// and get a Display Context Handle
hdc = BeginPaint(hwnd, &ps);
// Set Background Color to selected Background Color
SetBkColor(hdc, settings.back);
// Set Text Color to selected Foreground Color
SetTextColor(hdc, settings.fore);
// Set the Background Mode to TRANSPARENT (no background fill)
SetBkMode(hdc, TRANSPARENT);
// Write the new quote
DrawText(hdc, // our Display Context Handle
(LPSTR)str_buffer, // our new Quote String
-1, // let Windows figure the length
&rect, // write into entire client area rectangle
DT_LEFT | // left-justified,
DT_NOPREFIX | // `&' characters are not special
DT_WORDBREAK); // let Windows handle word-wrap
EndPaint(hwnd, &ps); // Tell Windows that we're done painting
return 0L;
// These next two Messages are our own messages, NOT Windows'
case PM_PAUSE: // We need to shut down the timer
if (paused == FALSE) // are we already shut down?
KillTimer(hwnd, ID_TIMER); // no, shut it down
paused = TRUE; // and keep track of that fact
return 0L;
case PM_START: // We need to restart the timer
if (paused == TRUE) // are we shut down now?
SetTimer(hwnd, ID_TIMER, 1000, NULL); // yes, set timer for 1 sec.
paused = FALSE; // and keep track of that fact
return 0L;
case WM_CLOSE:
if (settings.cat != category) {
WritePrivateProfileInt((LPSTR)szAppName, (LPSTR)"Category",
category, (LPSTR)szProfName);
}
if (settings.hide != hide_mode) {
WritePrivateProfileInt((LPSTR)szAppName, (LPSTR)"Hide",
(hide_mode == SW_HIDE), (LPSTR)szProfName);
}
DestroyWindow(hwnd); // Destroy main Window
break;
case WM_DESTROY: // We got a DESTROY Message
KillTimer(hwnd, ID_TIMER); // Shut down the timer
DeleteObject(hOrgBrush); // Delete the Window's background Brush
WinHelp(hwnd, szHelpPath, HELP_QUIT, 0L); // shut down HELP system
PostQuitMessage(0); // Post a QUIT Message
return 0L;
}
// We don't need to handle any other messages, but
// Windows might, so let it see them
return DefWindowProc(hwnd, message, wParam, lParam);
} // end of WndProc
struct str_tbl {
int start,
count;
};
struct str_tbl cat_table[] = {
{QUOTES_START, QUOTES_COUNT},
{LAWS_START, LAWS_COUNT},
{SNIGS_START, SNIGS_COUNT},
{MISC_START, MISC_COUNT}
};
void NewQuote(hwnd, showit)
HWND hwnd;
BOOL showit;
{
int start, // starting point in STRINGTABLE
max, // max number of quotes in current category
cat = category; // current category
if (cat == IDM_RANDOM) // are we set on Random?
cat = (rand() % IDM_MISC); // yes, pick one of the others
else
cat--; // no, decrement for 0-based index
// create a new string table ID
start = cat_table[cat].start; // get the starting position
max = cat_table[cat].count; // get the number of quotes
string_number = (rand() % max) + start; // pick one of the quotes
if (showit) // are we supposed re-display the window?
ShowWindow(hwnd, SW_SHOWNORMAL); // yes, show ourselves
// Tell Windows that we want to paint the entire client area
InvalidateRect(hwnd, NULL, TRUE); // invalidate client area
UpdateWindow(hwnd); // Update the window
}
void NewTitle()
{
HMENU hmenu;
char title[30],
temp[15];
if (inout_state) {
hmenu = GetMenu(Pundit);
GetMenuString(hmenu, category, (LPSTR)temp, sizeof(temp), MF_BYCOMMAND);
wsprintf((LPSTR)title, (LPSTR)"%s (%s)", (LPSTR)szAppName, (LPSTR)temp+1);
}
else
strcpy(title, szAppName);
SetWindowText(Pundit, (LPSTR)title);
}
// About Box manager function
BOOL FAR PASCAL About(hDlg, message, wParam, lParam)
HWND hDlg; // Window Handle for our Dialog Box
unsigned message; // The Window's Message
WORD wParam; // The WORD parameter value
LONG lParam; // The LONG parameter value
{
switch (message) { // check for messages...
case WM_INITDIALOG: // If the Dialog is just starting...
PostMessage(Pundit, PM_PAUSE, 0, 0L); // shut down the timer
return TRUE;
case WM_COMMAND: // We got a COMMAND
// if the Dialog's button was pressed
if (wParam == IDOK || wParam == IDCANCEL) {
EndDialog(hDlg, TRUE); // That's the end of the Dialog
return TRUE; // Say that we processed this message
}
break;
}
return FALSE; // Say that we did NOT process the message
}
// Build a "fully-qualified" path for the HELP file
// OK, I admit it --- this code was lifted from
// the HELPEX program supplied with the SDK.
// Only the names and some formatting have been
// changed to protect my ego.
void BuildHelpPath(hInst, PathName)
HANDLE hInst;
char *PathName;
{
char *BaseName;
int len;
// Fetch the path to the program file
len = GetModuleFileName(hInst, PathName, PATH_SIZE);
BaseName = PathName + len; // point to the end of the string
// Find the beginning of the program name, and "erase" it from the string
while (BaseName > PathName) {
if (*BaseName == '\\' || *BaseName == ':') {
*(++BaseName) = '\0';
break;
}
len--;
BaseName--;
}
if ((len+13) < PATH_SIZE) // There is room for the new filename
lstrcat(PathName, "pundit.hlp");
else // There is no room for the new filename
lstrcat(PathName, "?");
}