home *** CD-ROM | disk | FTP | other *** search
/ Better Windows, Better Works / CDRM93801.bin / winutil / util42 / pundit.c < prev    next >
C/C++ Source or Header  |  1991-11-20  |  21KB  |  510 lines

  1. /*
  2.  *  Pundit.c
  3.  *      Source for Pundit (V 2.0)
  4.  *      Main routines, etc.
  5.  *
  6.  *  Author:         Jeff Bienstadt
  7.  *
  8.  *  Environment:
  9.  *
  10.  *      Run-Time:   Microsoft Windows 3.0
  11.  *
  12.  *      Compilers/Tools:
  13.  *                  Microsoft C 6.0
  14.  *                  Microsoft Windows SDK 3.0
  15.  *
  16.  */
  17.  
  18. #include    <windows.h>     // All the Windows goodies
  19. #include    <stdlib.h>      // for rand() and srand()
  20. #include    <string.h>      // for strlen(), etc.
  21. #include    <time.h>        // for time()
  22. #include    "pundit.h"      // constants for Pundit
  23. #include    "extras.h"      // for WriteProfileInt(), etc.
  24.  
  25.  
  26. //  Global variables
  27. int     count,          // counts seconds window is hidden/visible
  28.         category,       // what category are we using now?
  29.         hide_mode;      // when we go away, do we hide or do we iconize?
  30.  
  31. WORD    string_number;  // store ID from string table here
  32.  
  33. BOOL    inout_state,    // are we shown or hidden?
  34.         paused;         // ...... paused or counting?
  35.  
  36. HANDLE  hinst,          // a global Instance Handle
  37.         hOrgBrush;      // a global Brush Handle
  38.  
  39. HWND    Pundit;         // a global Window Handle (for main window)
  40.  
  41. HDC     hdc;            // a global Display Context Handle
  42. HMENU   hmenu;          // a Menu Handle (for (un)checking menu items)
  43.  
  44. SETTINGS    settings;   // the settings structure
  45.  
  46. char    szAppName[] = "Pundit",         // The Application Name
  47.         szProfName[] = "Pundit.INI",    // The name of the Profile file
  48.         szHelpPath[PATH_SIZE+1];        // Path to the HELP file
  49.  
  50.  
  51. //  The main Window Procedure
  52. int PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
  53. HANDLE  hInstance,      // Instance Handle
  54.         hPrevInstance;  // Previous Instance Handle
  55. LPSTR   lpszCmdLine;    // The Command Line (we don't use it here)
  56. int     nCmdShow;       // The SHOW Method  (we don't use this, either)
  57. {
  58.     MSG             msg;        // a place to store Windows' Messages
  59.     WNDCLASS        wndclass;   // a Window Class structure
  60.     HANDLE          hAccel;     // an Accelator table Handle
  61.  
  62.     InitGlobals(hInstance);     // Initialize Global Varaibles;
  63.  
  64.  
  65.     //  If we have NOT already defined our Window Class, do so now...
  66.     //  (see the SDK documentation for how this works)
  67.     if (!hPrevInstance) {
  68.         wndclass.style          = CS_HREDRAW | CS_VREDRAW;
  69.         wndclass.lpfnWndProc    = WndProc;
  70.         wndclass.cbClsExtra     = 0;
  71.         wndclass.cbWndExtra     = 0;
  72.         wndclass.hInstance      = hInstance;
  73.         wndclass.hIcon          = LoadIcon(hInstance, szAppName);
  74.         wndclass.hCursor        = LoadCursor(NULL, IDC_ARROW);
  75.         wndclass.hbrBackground  = hOrgBrush;
  76.         wndclass.lpszMenuName   = szAppName;
  77.         wndclass.lpszClassName  = szAppName;
  78.  
  79.         RegisterClass(&wndclass);   // Register the Window Class
  80.     }
  81.  
  82.  
  83.     // Create the Window, and put it's handle into our global Window Handle
  84.     Pundit = CreateWindow(szAppName,                // Window Name
  85.                              szAppName,             // Window Caption
  86.                              WS_OVERLAPPED |
  87.                                 WS_CAPTION |
  88.                                 WS_THICKFRAME |
  89.                                 WS_SYSMENU |
  90.                                 WS_MINIMIZEBOX,     // The Window style
  91.                              settings.x,            // X position of Window
  92.                              settings.y,            // Y position of Window
  93.                              settings.width,        // Width of Window
  94.                              settings.height,       // Height of Window
  95.                              NULL,                  // No Parent
  96.                              NULL,                  // Use the Class menu
  97.                              hInstance,             // Instance for Window
  98.                              NULL);                 // No additional params
  99.  
  100.     //  Try to get a timer... keep trying until we get one or the user gives up
  101.     while (!SetTimer(Pundit, ID_TIMER, 1000, NULL)) {
  102.         if (IDCANCEL == MessageBox(Pundit,
  103.                                    "I need a Timer, but Windows won't lemme"
  104.                                         "have one\012"
  105.                                         "(maybe you could close a clock"
  106.                                         "or something...)",
  107.                                    szAppName,
  108.                                    MB_ICONEXCLAMATION | MB_RETRYCANCEL))
  109.             return FALSE;   // User gave up, bail out
  110.     }
  111.  
  112.     BuildHelpPath(hInstance, szHelpPath);   // build a path to the HELP file
  113.  
  114.     hmenu = GetMenu(Pundit);
  115.     CheckMenuItem(hmenu, category, MF_CHECKED);
  116.     if (hide_mode == SW_HIDE)
  117.         CheckMenuItem(hmenu, IDM_HIDE, MF_CHECKED);
  118.     else
  119.         CheckMenuItem(hmenu, IDM_ICON, MF_CHECKED);
  120.     NewTitle();
  121.     NewQuote(Pundit, TRUE);                 // ShowWindow() & UpdateWindow()
  122.                                             // are contained herein
  123.  
  124.     hAccel = LoadAccelerators(hInstance, szAppName);    // Load Accelerator table
  125.  
  126.     while (GetMessage(&msg, NULL, 0, 0)) {  // Fetch a Message from Windows
  127.         if (!TranslateAccelerator(Pundit, hAccel, &msg)) {
  128.             TranslateMessage(&msg);     // Translate Keyboard Messages
  129.             DispatchMessage(&msg);      // Pass Message on to our callback function
  130.         }
  131.     }                           // until we get a QUIT Message
  132.     return msg.wParam;          // return to Windows
  133. }   // end of WinMain
  134.  
  135.  
  136. //  Initialize Global Variables
  137. void InitGlobals(hInstance)
  138. HANDLE  hInstance;  // our Instance Handle
  139. {
  140.     time_t          ltime;      // here we store the system time
  141.  
  142.     settings.insecs  =   5;     // "Default" IN seconds
  143.     settings.outsecs =  20;     // "Default" OUT seconds
  144.     settings.cat     =   1;     // "Default" category (Quotes)
  145.     settings.hide    =   1;     // "Default" hide mode (hidden)
  146.     settings.x       =   1;     // "Default" X position
  147.     settings.y       =   1;     // "Default" Y position
  148.     settings.width   = 250;     // "Default" Width
  149.     settings.height  = 150;     // "Default" Height
  150.     settings.back    = GetSysColor(COLOR_WINDOW);
  151.     settings.fore    = GetSysColor(COLOR_WINDOWTEXT);
  152.     FetchSettings();            // Now read settings from WIN.INI
  153.  
  154.     count            = 0;       // Zero out the counter
  155.     paused           = FALSE;   // We're not paused yet
  156.     inout_state      = TRUE;    // We're in the "show" state
  157.     hinst            = hInstance;   // Save our current Instance
  158.     hOrgBrush        = CreateSolidBrush(settings.back);
  159.  
  160.     time(<ime);               // Get the current time
  161.     srand((unsigned)ltime);     // Use it to set the random number "seed"
  162. }
  163.  
  164.  
  165. //  Our main Window ``callback'' function
  166. long FAR PASCAL WndProc(hwnd, message, wParam, lParam)
  167. HWND    hwnd;       // Window Handle for our Window
  168. WORD    message,    // The Window's Message
  169.         wParam;     // The WORD parameter value
  170. LONG    lParam;     // The LONG parameter value
  171. {
  172.     PAINTSTRUCT     ps;     // a Paint structure (for painting the Window)
  173.     HDC             hdc;    // a Display Context Handle (for writing text)
  174.     RECT            rect;   // a Rectangle structure (for writing text)
  175.     FARPROC         lpProcAbout,    // Pointer to function for "About" dialog
  176.                     lpSettingsDialog;   //.................."Settings" dialog
  177.     static char     str_buffer[256];    // buffer for string from string table
  178.  
  179.     switch (message) {      // check for messages...
  180.     case    WM_CREATE:          // creating window
  181.         DeleteObject(GetClassWord(hwnd, GCW_HBRBACKGROUND));
  182.         SetClassWord(hwnd, GCW_HBRBACKGROUND,
  183.                 CreateSolidBrush(settings.back));
  184.         InvalidateRect(hwnd, NULL, TRUE);
  185.         break;
  186.  
  187.     case    WM_INITMENU:        // if a Menu is displayed...
  188.         SendMessage(hwnd, PM_PAUSE, 0, 0L); // ...stop the timer
  189.         break;
  190.  
  191.     case    WM_MENUSELECT:      // if a Menu has been canceled...
  192.         if ((LOWORD(lParam) == 0xFFFF) && (HIWORD(lParam) == 0))
  193.             SendMessage(hwnd, PM_START, 0, 0L); // ...restart the timer
  194.         break;
  195.  
  196.     case    WM_SYSCOMMAND:      // we got a System Menu Choice...
  197.         switch (wParam & 0xFFF0) {          // Strip off the low-order 4 bits
  198.         case    SC_MINIMIZE:
  199.             if (inout_state == TRUE) {
  200.                 inout_state = FALSE;            // switch the state
  201.                 NewTitle();
  202.                 ShowWindow(hwnd, hide_mode);    // hide
  203.                 count = 0;                      // reset the counter
  204.                 return 0L;
  205.             }
  206.             break;
  207.         case    SC_RESTORE:
  208.             if (inout_state == FALSE) {
  209.                 inout_state = TRUE;                 // switch the state
  210.                 NewTitle();
  211.                 NewQuote(hwnd, TRUE);
  212.                 count = 0;                          // reset the counter
  213.             }
  214.             break;
  215.         }
  216.         break;
  217.  
  218.     case    WM_COMMAND:         // we got a Menu choice...
  219.         switch (wParam) {       // ... which one?
  220.         case    IDM_LAWS:
  221.         case    IDM_QUOTES:
  222.         case    IDM_SNIGS:
  223.         case    IDM_MISC:
  224.         case    IDM_RANDOM:
  225.             if (category != (int)wParam) {
  226.                 hmenu = GetMenu(Pundit);
  227. //                CheckMenuItem(hmenu, settings.cat, MF_UNCHECKED);
  228.                 CheckMenuItem(hmenu, category, MF_UNCHECKED);
  229. //                settings.cat = category = wParam;
  230.                 category = wParam;
  231. //                CheckMenuItem(hmenu, settings.cat, MF_CHECKED);
  232.                 CheckMenuItem(hmenu, category, MF_CHECKED);
  233.                 NewQuote(hwnd, FALSE);
  234.                 NewTitle();
  235.             }
  236.             break;
  237.  
  238.         case    IDM_HIDE:
  239.             if (hide_mode != SW_HIDE) {
  240.                 hmenu = GetMenu(Pundit);
  241.                 CheckMenuItem(hmenu, IDM_ICON, MF_UNCHECKED);
  242.                 CheckMenuItem(hmenu, IDM_HIDE, MF_CHECKED);
  243.                 hide_mode = SW_HIDE;
  244.             }
  245.             break;
  246.  
  247.         case    IDM_ICON:
  248.             if (hide_mode != SW_MINIMIZE) {
  249.                 hmenu = GetMenu(Pundit);
  250.                 CheckMenuItem(hmenu, IDM_HIDE, MF_UNCHECKED);
  251.                 CheckMenuItem(hmenu, IDM_ICON, MF_CHECKED);
  252.                 hide_mode = SW_MINIMIZE;
  253.             }
  254.             break;
  255.  
  256.         case    IDM_HELP_INDEX:
  257.             WinHelp(hwnd, szHelpPath, HELP_INDEX, 0L);
  258. //MessageBox(hwnd, "Application HELP is not ready yet.\012"
  259. //"After all, this is only a Beta version",
  260. //szAppName,
  261. //MB_ICONEXCLAMATION | MB_OK);
  262.             break;
  263.  
  264.         case    IDM_HELP_HELP:
  265.             WinHelp(hwnd, szHelpPath, HELP_HELPONHELP, 0L);
  266. //            WinHelp(hwnd, "WINHELP.HLP", HELP_INDEX, 0L);
  267.             break;
  268.  
  269.         case    IDM_ABOUT:          // About Pundit...
  270.         // Make a function Instance
  271.             lpProcAbout = MakeProcInstance(About, hinst);
  272.         // Process the "About" dialog box
  273.             DialogBox(hinst, "ABOUTBOX", hwnd, lpProcAbout);
  274.         // Give back the function Instance
  275.             FreeProcInstance(lpProcAbout);
  276.             break;
  277.  
  278.         case    IDM_SETTINGS:       // Settings...
  279.         // Make a function Instance
  280.             lpSettingsDialog = MakeProcInstance(Settings, hinst);
  281.         // Process the "About" dialog box
  282.             DialogBox(hinst, "SETTINGS", hwnd, lpSettingsDialog);
  283.         // Give back the function Instance
  284.             FreeProcInstance(lpSettingsDialog);
  285.             break;
  286.  
  287.         case    IDM_COPY:           // Copy
  288.             {
  289.                 LPSTR           lpMem;
  290.                 GLOBALHANDLE    hMem;
  291.  
  292.                 hMem = GlobalAlloc(GHND, 256L);
  293.                 lpMem = GlobalLock(hMem);
  294.                 lstrcpy(lpMem, (LPSTR)str_buffer);
  295.                 GlobalUnlock(hMem);
  296.                 OpenClipboard(hwnd);
  297.                 EmptyClipboard();
  298.                 SetClipboardData(CF_TEXT, hMem);
  299.                 CloseClipboard();
  300.             }
  301.             break;
  302.  
  303.         case    IDM_EXIT:           // Exit
  304.         // Tell Windows to shut down this Application
  305.             PostMessage(hwnd, WM_CLOSE, 0, 0L);
  306.             break;
  307.         }
  308.         SendMessage(hwnd, PM_START, 0, 0L); // ...restart the timer
  309.         return 0L;  // return 0 exit code
  310.  
  311.     case    WM_TIMER:           // We got a TIMER Message
  312.         switch (inout_state) {      // are we visible or hidden?
  313.         case    FALSE:              // hidden...
  314.             if (count >= settings.outsecs) {  // if it's time to show up
  315.                 inout_state = TRUE;                 // switch the state
  316.                 NewTitle();
  317.                 NewQuote(hwnd, TRUE);
  318.                 count = 0;                          // reset the counter
  319.             }
  320.             else        // still waiting to show up
  321.                 ++count;        // bump the counter
  322.             break;
  323.         case    TRUE:               // shown...
  324.             if (count >= settings.insecs) {  // if it's time to sleep
  325.                 inout_state = FALSE;            // switch the state
  326.                 NewTitle();
  327.                 ShowWindow(hwnd, hide_mode);    // hide
  328.                 count = 0;                      // reset the counter
  329.             }
  330.             else        // still waiting to sleep
  331.                 ++count;        // bump the counter
  332.             break;
  333.         }
  334.         return 0L;
  335.  
  336.     case    WM_PAINT:           // We got a PAINT Message
  337.         GetClientRect(hwnd, &rect);  // Get the dimensions of the client area
  338.             // Fetch a new string from the string table
  339.         LoadString(hinst, string_number, str_buffer, 256);
  340.             // Tell Windows we are ready to paint
  341.             // and get a Display Context Handle
  342.         hdc = BeginPaint(hwnd, &ps);
  343.             // Set Background Color to selected Background Color
  344.         SetBkColor(hdc, settings.back);
  345.             // Set Text Color to selected Foreground Color
  346.         SetTextColor(hdc, settings.fore);
  347.             // Set the Background Mode to TRANSPARENT (no background fill)
  348.         SetBkMode(hdc, TRANSPARENT);
  349.             // Write the new quote
  350.         DrawText(hdc,               // our Display Context Handle
  351.                 (LPSTR)str_buffer,  // our new Quote String
  352.                 -1,                 // let Windows figure the length
  353.                 &rect,              // write into entire client area rectangle
  354.                 DT_LEFT |           // left-justified,
  355.                     DT_NOPREFIX |   // `&' characters are not special
  356.                     DT_WORDBREAK);  // let Windows handle word-wrap
  357.         EndPaint(hwnd, &ps);    // Tell Windows that we're done painting
  358.         return 0L;
  359.  
  360.     //  These next two Messages are our own messages, NOT Windows'
  361.     case    PM_PAUSE:           // We need to shut down the timer
  362.         if (paused == FALSE)            // are we already shut down?
  363.             KillTimer(hwnd, ID_TIMER);  // no, shut it down
  364.         paused = TRUE;                  // and keep track of that fact
  365.         return 0L;
  366.  
  367.     case    PM_START:           // We need to restart the timer
  368.         if (paused == TRUE)             // are we shut down now?
  369.             SetTimer(hwnd, ID_TIMER, 1000, NULL);   // yes, set timer for 1 sec.
  370.         paused = FALSE;                 // and keep track of that fact
  371.         return 0L;
  372.  
  373.     case    WM_CLOSE:
  374.         if (settings.cat != category) {
  375.             WritePrivateProfileInt((LPSTR)szAppName, (LPSTR)"Category",
  376.                     category, (LPSTR)szProfName);
  377.         }
  378.         if (settings.hide != hide_mode) {
  379.             WritePrivateProfileInt((LPSTR)szAppName, (LPSTR)"Hide",
  380.                     (hide_mode == SW_HIDE), (LPSTR)szProfName);
  381.         }
  382.         DestroyWindow(hwnd);    // Destroy main Window
  383.         break;
  384.  
  385.     case    WM_DESTROY:         //  We got a DESTROY Message
  386.         KillTimer(hwnd, ID_TIMER);  // Shut down the timer
  387.         DeleteObject(hOrgBrush);    // Delete the Window's background Brush
  388.         WinHelp(hwnd, szHelpPath, HELP_QUIT, 0L);   // shut down HELP system
  389.         PostQuitMessage(0);         // Post a QUIT Message
  390.         return 0L;
  391.     }
  392.         // We don't need to handle any other messages, but
  393.         // Windows might, so let it see them
  394.     return DefWindowProc(hwnd, message, wParam, lParam);
  395. }   // end of WndProc
  396.  
  397.  
  398. struct str_tbl {
  399.     int     start,
  400.             count;
  401. };
  402.  
  403. struct str_tbl  cat_table[] = {
  404.                     {QUOTES_START, QUOTES_COUNT},
  405.                     {LAWS_START,   LAWS_COUNT},
  406.                     {SNIGS_START,  SNIGS_COUNT},
  407.                     {MISC_START,   MISC_COUNT}
  408.                 };
  409.  
  410. void NewQuote(hwnd, showit)
  411. HWND    hwnd;
  412. BOOL    showit;
  413. {
  414.     int     start,          // starting point in STRINGTABLE
  415.             max,            // max number of quotes in current category
  416.             cat = category; // current category
  417.  
  418.     if (cat == IDM_RANDOM)          // are we set on Random?
  419.         cat = (rand() % IDM_MISC);  // yes, pick one of the others
  420.     else
  421.         cat--;                      // no, decrement for 0-based index
  422.  
  423.         // create a new string table ID
  424.     start = cat_table[cat].start;   // get the starting position
  425.     max   = cat_table[cat].count;   // get the number of quotes
  426.     string_number = (rand() % max) + start;     // pick one of the quotes
  427.  
  428.     if (showit)                     // are we supposed re-display the window?
  429.         ShowWindow(hwnd, SW_SHOWNORMAL);    // yes, show ourselves
  430.  
  431.        // Tell Windows that we want to paint the entire client area
  432.     InvalidateRect(hwnd, NULL, TRUE);   // invalidate client area
  433.     UpdateWindow(hwnd);                 // Update the window
  434. }
  435.  
  436.  
  437. void NewTitle()
  438. {
  439.     HMENU   hmenu;
  440.     char    title[30],
  441.             temp[15];
  442.  
  443.     if (inout_state) {
  444.         hmenu = GetMenu(Pundit);
  445.         GetMenuString(hmenu, category, (LPSTR)temp, sizeof(temp), MF_BYCOMMAND);
  446.         wsprintf((LPSTR)title, (LPSTR)"%s (%s)", (LPSTR)szAppName, (LPSTR)temp+1);
  447.     }
  448.     else
  449.         strcpy(title, szAppName);
  450.     SetWindowText(Pundit, (LPSTR)title);
  451. }
  452.  
  453.  
  454. //  About Box manager function
  455. BOOL FAR PASCAL About(hDlg, message, wParam, lParam)
  456. HWND        hDlg;       // Window Handle for our Dialog Box
  457. unsigned    message;    // The Window's Message
  458. WORD        wParam;     // The WORD parameter value
  459. LONG        lParam;     // The LONG parameter value
  460. {
  461.     switch (message) {      // check for messages...
  462.     case    WM_INITDIALOG:      // If the Dialog is just starting...
  463.         PostMessage(Pundit, PM_PAUSE, 0, 0L);   // shut down the timer
  464.         return TRUE;
  465.  
  466.     case    WM_COMMAND:     // We got a COMMAND
  467.             // if the Dialog's button was pressed
  468.         if (wParam == IDOK || wParam == IDCANCEL) {
  469.             EndDialog(hDlg, TRUE);  // That's the end of the Dialog
  470.             return TRUE;            // Say that we processed this message
  471.         }
  472.         break;
  473.     }
  474.     return FALSE;       // Say that we did NOT process the message
  475. }
  476.  
  477.  
  478. //  Build a "fully-qualified" path for the HELP file
  479. //      OK, I admit it --- this code was lifted from
  480. //      the HELPEX program supplied with the SDK.
  481. //      Only the names and some formatting have been
  482. //      changed to protect my ego.
  483. void BuildHelpPath(hInst, PathName)
  484. HANDLE  hInst;
  485. char    *PathName;
  486. {
  487.     char    *BaseName;
  488.     int     len;
  489.  
  490.     // Fetch the path to the program file
  491.     len = GetModuleFileName(hInst, PathName, PATH_SIZE);
  492.     BaseName = PathName + len;  // point to the end of the string
  493.  
  494.     // Find the beginning of the program name, and "erase" it from the string
  495.     while (BaseName > PathName) {
  496.         if (*BaseName == '\\' || *BaseName == ':') {
  497.             *(++BaseName) = '\0';
  498.             break;
  499.         }
  500.         len--;
  501.         BaseName--;
  502.     }
  503.  
  504.     if ((len+13) < PATH_SIZE)   // There is room for the new filename
  505.         lstrcat(PathName, "pundit.hlp");
  506.     else                        // There is no room for the new filename
  507.        lstrcat(PathName, "?");
  508. }
  509.  
  510.