home *** CD-ROM | disk | FTP | other *** search
/ Hall of Fame / HallofFameCDROM.cdr / proglc / therme.lzh / THERME.C next >
Encoding:
C/C++ Source or Header  |  1986-12-17  |  15.2 KB  |  544 lines

  1. /* (c) Copyright 1986 MICROGRAFX, Inc.,
  2.    1820 N. Greenville Ave., Richardson, Tx. 75081.
  3.  
  4. **********************************************************************
  5. **********************************************************************
  6.  
  7.                 THERME.C
  8.  
  9. **********************************************************************
  10. **********************************************************************
  11.  
  12. This Module defines the all routines that control the application.
  13. When the application is loaded, Windows calls the WinMain procedure.  
  14. WinMain initializes key variables used by the various functions in the 
  15. application and creates a window for it via the initialization 
  16. function.  It then waits for input values, passing them to the window 
  17. procedure each time an event occurs. */
  18.  
  19. #include <windows.h>
  20. #include "therme.h"
  21. #include "stdlib.h"
  22. #include "string.h"
  23.  
  24. /* *************************** History **************************** */
  25.  
  26. /* 11/24/86 (PML) - signoff */
  27.  
  28. /* ************************** Constants *************************** */
  29.  
  30. #define LOCAL
  31.  
  32. #define APP_CLASS     "Therme"    /* Window Class Name */
  33. #define HIGHTEMP     100        /* Highest Displayable Temp */
  34. #define LOWTEMP      -20        /* Lowest Displayable Temp */
  35. #define ICON_NAME     "ClassIcon"    /* Resource Icon ID String */
  36. #define IDABOUT      005        /* ID for About... */
  37. #define MENUNAME     "MainMenu"    /* Resource Menu ID String */
  38. #define VIEWPORT_ORGX     0        /* Viewport Origin X Coord */
  39. #define VIEWPORT_ORGY     0        /* Viewport Origin Y Coord */
  40. #define WINDOW_EXTX     1000        /* Window Extent X Coord */
  41. #define WINDOW_EXTY     1000        /* Window Extent Y Coord */
  42. #define WINDOW_ORGX     0        /* Window Origin X Coord */
  43. #define WINDOW_ORGY     0        /* Window Origin Y Coord */
  44. #define WND_NAME     "Therme"    /* Window Name */
  45.  
  46. /* ************************** Local Data ************************** */
  47.  
  48. BOOL   bCurrentTempMode = TRUE,        /* TRUE for Farenheit */
  49.        bOldTempMode = TRUE;        /* Previous Temp Mode */
  50. char   ProStringBuffer [80];        /* Profile String Buffer */
  51. HANDLE hModule,                /* Instance Handle */
  52.        hWindow;                /* Window Handle */
  53. int    GraphicTemp = 0,            /* Graphic Temp Setting */
  54.        DegreeInc = 1,            /* Temperature Increment */
  55.        OldTemp,                /* Previous Temp Setting */
  56.        MathTemp;            /* Math Temp. Conversion */
  57. PAINTSTRUCT Paint;            /* Window Paint Structure */
  58. RECT   ClientRect;            /* Client Area Rect. */
  59. WORD   ViewportWidth,            /* Viewport X Extent */
  60.        ViewportHeight,            /* Viewport Y Extent */
  61.        ViewportOriginX = 0,        /* Viewport X Extent */
  62.        ViewportOriginY = 0;        /* Viewport Y Extent */
  63.  
  64. /* ************************ Local Routines ************************ */
  65.  
  66. LOCAL BOOL NEAR PASCAL command (HWND,WORD);
  67. LOCAL WORD NEAR PASCAL dialog_box (HWND,LPSTR,FARPROC);
  68. LOCAL HWND NEAR PASCAL init_app (HANDLE,HANDLE,LPSTR,int);
  69. LOCAL void NEAR PASCAL paint_window (HDC,WORD,WORD);
  70. LOCAL BOOL NEAR PASCAL show_menu (HANDLE,HWND);
  71.  
  72. LOCAL BOOL NEAR PASCAL command (hWindow,Choice)
  73.    /* This routine receives and processes menu input. It calls the 
  74.       various dialog box functions and initiating the print task */
  75. HWND hWindow;
  76. WORD Choice;
  77. {
  78.     BOOL    bHandled = TRUE;
  79.     BYTE    Item;
  80.     FARPROC lpPrintProc;
  81.     HANDLE    hPrintDlg;
  82.     HDC    hPrintDC;
  83.     int    PrintResult;
  84.     PSTR    pDriverName,
  85.         pPortName;
  86.     WORD    HRes,
  87.         VRes;
  88.  
  89.     switch (Choice)
  90.     {
  91.     case IDABOUT:
  92.        dialog_box (hWindow,(LPSTR) "AboutDlg",about_dialog);
  93.        break;
  94.  
  95.     case SET_TEMPERATURE:
  96.        dialog_box (hWindow,(LPSTR) "SetTempDlg",set_temp_dialog);
  97.        break;
  98.  
  99.     case PRINT:
  100.        GetProfileString ((LPSTR) "windows",
  101.                  (LPSTR) "device",
  102.                  NULL,
  103.                  (LPSTR) ProStringBuffer,
  104.                  80);
  105.        pDriverName = strchr (ProStringBuffer,',');
  106.        *pDriverName = '\0';
  107.        pDriverName++;
  108.        pPortName = strchr (pDriverName,',');
  109.        *pPortName = '\0';
  110.        pPortName++;
  111.        hPrintDC = CreateDC ((LPSTR) pDriverName,
  112.                 (LPSTR) ProStringBuffer,
  113.                 (LPSTR) pPortName,
  114.                 NULL);
  115.        if (hPrintDC == NULL)
  116.           Item = MessageBox (hWindow,
  117.             (LPSTR) "Cannot Print. Please Select Printer",
  118.             (LPSTR) NULL,
  119.             MB_OK | MB_ICONHAND);
  120.        else
  121.        {
  122.           HRes = GetDeviceCaps (hPrintDC,HORZRES);
  123.           VRes = GetDeviceCaps (hPrintDC,VERTRES);
  124.           lpPrintProc = MakeProcInstance (print_dialog,hModule);
  125.           hPrintDlg = CreateDialog (hModule,(LPSTR) "SpoolDlg",
  126.                 hWindow,lpPrintProc);
  127.           PrintResult = Escape (hPrintDC,STARTDOC,11,
  128.                 (LPSTR) "Thermometer",NULL);
  129.           if (PrintResult == -1)
  130.          Item = MessageBox (hWindow,
  131.         (LPSTR) "Cannot Print.  Bad Port or Insuffic. Memory",
  132.                    (LPSTR) NULL,
  133.                    MB_OK | MB_ICONHAND);
  134.           else
  135.           {
  136.           paint_window (hPrintDC,HRes,VRes);
  137.           Escape (hPrintDC,NEWFRAME,NULL,NULL,NULL);
  138.           Escape (hPrintDC,ENDDOC,NULL,NULL,NULL);
  139.           DestroyWindow (hPrintDlg);
  140.           DeleteDC (hPrintDC);
  141.           FreeProcInstance (lpPrintProc);
  142.           }
  143.        }
  144.        break;
  145.  
  146.     default:
  147.        bHandled = FALSE;
  148.     }
  149.  
  150.     return (bHandled);
  151. }
  152.  
  153. LOCAL WORD NEAR PASCAL dialog_box (hWindow,lpDialog,lpCallBack)
  154.    /* This function displays a given dialog box and returns the value 
  155.       ret'd by the dialog box call-back function.  The function first 
  156.       creates a relocation-independent version of the call-back 
  157.       function, then calls DialogBox. If Windows indicates an 
  158.       insufficient memory condition exists, then the user is so 
  159.       informed. Additionally, since the drawing area always needs to 
  160.       be updated after a dialog box is removed, the client area of the 
  161.       window is invalidated so as to be completely redrawn. */
  162. HWND    hWindow;
  163. LPSTR    lpDialog;
  164. FARPROC lpCallBack;
  165. {
  166.     BYTE    Item;
  167.     FARPROC lpProc = MakeProcInstance (lpCallBack,hModule);
  168.     int    Result = DialogBox (hModule,lpDialog,hWindow,lpProc);
  169.  
  170.     if (Result == -1)
  171.     {
  172.        Item = MessageBox (hWindow,
  173.         (LPSTR) "Not Enough Memory To Display Dialog Box",
  174.                  (LPSTR) NULL,
  175.                  MB_OK | MB_ICONHAND);
  176.  
  177.     }
  178.  
  179.     FreeProcInstance (lpProc);
  180.  
  181.     InvalidateRect (hWindow,(LPRECT) &ClientRect,TRUE);
  182.  
  183.     return (Result);
  184. }
  185.  
  186. LOCAL HWND NEAR PASCAL init_app (hPrevious,hInstance,lpCmdLine,Show)
  187.    /* This function handles the initialization of the sample 
  188.       application.  This includes registering the window class, 
  189.       creating the window, and loading the menus. The viewport 
  190.       coordinates of the client area of the window are also 
  191.       established in globally available variables */
  192. HANDLE hPrevious,
  193.        hInstance;
  194. int    Show;
  195. LPSTR  lpCmdLine;
  196. {
  197.     BOOL        bRegistered;
  198.     HWND        hWindow;
  199.     WNDCLASS    Class;
  200.  
  201.     hModule = hInstance;
  202.  
  203.     Class.style        = CS_OWNDC | CS_VREDRAW | CS_HREDRAW;
  204.     Class.lpfnWndProc   = AppWndProc;
  205.     Class.cbClsExtra    = NULL;
  206.     Class.cbWndExtra    = NULL;
  207.     Class.hInstance     = hInstance;
  208.     Class.hCursor        = LoadCursor(NULL,IDC_ARROW);
  209.     Class.hIcon        = LoadIcon(hInstance,(LPSTR) "ClassIcon");
  210.     Class.hbrBackground = GetStockObject (WHITE_BRUSH);
  211.     Class.lpszMenuName  = (LPSTR) NULL;
  212.     Class.lpszClassName = (LPSTR) APP_CLASS;
  213.  
  214.     bRegistered = RegisterClass((LPWNDCLASS) &Class);
  215.  
  216.     hWindow = CreateWindow ((LPSTR) APP_CLASS,
  217.                 (LPSTR) WND_NAME,
  218.                 WS_TILEDWINDOW,
  219.                 0,
  220.                 0,
  221.                 0,
  222.                 0,
  223.                 (HWND) NULL,
  224.                 (HMENU) NULL,
  225.                 (HANDLE) hInstance,
  226.                 (LPSTR) NULL);
  227.  
  228.     ShowWindow (hWindow,Show);
  229.  
  230.     GetClientRect (hWindow,(LPRECT) &ClientRect);
  231.     ViewportWidth = ClientRect.right;
  232.     ViewportHeight= ClientRect.bottom;
  233.  
  234.     show_menu (hInstance,hWindow);
  235.  
  236.     return (hWindow);
  237. }
  238.  
  239. LOCAL void NEAR PASCAL paint_window (hDC,ExtentX,ExtentY)
  240.    /* This function erases the window background and repaints the 
  241.       thermometer using the given device context.  The variable 
  242.       GraphicTemp is used to visibly update the rectangle that 
  243.       represents the temperature. */
  244. HDC  hDC;
  245. WORD ExtentX,
  246.      ExtentY;
  247. {
  248.     char        Buffer[3];
  249.     int        StartHashX = 460,
  250.             StartHashY = 100,
  251.             EndHashX   = 485,
  252.             EndHashY   = 100,
  253.             HashCount  = 12,
  254.             HashInc    = 5,
  255.             Degree     = HIGHTEMP,
  256.             StringLength;
  257.     PSTR        pDegreeString;
  258.  
  259.     SetMapMode (hDC,MM_ISOTROPIC);
  260.     SetWindowOrg (hDC,0,0);
  261.     SetWindowExt (hDC,1000,1000);
  262.     SetViewportOrg (hDC,ViewportOriginX,ViewportOriginY);
  263.     SetViewportExt (hDC,ExtentX,ExtentY);
  264.     FillRect (hDC,(LPRECT) &Paint.rcPaint,
  265.             GetStockObject (WHITE_BRUSH));
  266.  
  267.     Rectangle (hDC,460,50,540,725);
  268.     SelectObject (hDC,CreateSolidBrush (RGB (255,00,00)));
  269.     Ellipse (hDC,375,700,625,950);
  270.     Rectangle (hDC,480,(600 - (GraphicTemp * 5)),520,700);
  271.     SelectObject (hDC,GetStockObject (WHITE_BRUSH));
  272.  
  273.     for (;HashCount>=1;--HashCount)
  274.     {
  275.        pDegreeString = itoa (Degree,Buffer,10);
  276.        StringLength = strlen (pDegreeString);
  277.        MoveTo (hDC,StartHashX,StartHashY);
  278.        TextOut (hDC,
  279.             (StartHashX-75),
  280.             (StartHashY-15),
  281.             pDegreeString,
  282.             StringLength);
  283.        LineTo (hDC,EndHashX,EndHashY);
  284.        MoveTo (hDC,(EndHashX + 30),(EndHashY + 25));
  285.        LineTo (hDC,(EndHashX + 55),(EndHashY + 25));
  286.        Degree = Degree - HashInc;
  287.        pDegreeString = itoa (Degree,Buffer,10);
  288.        StringLength = strlen (pDegreeString);
  289.        TextOut (hDC,
  290.             (EndHashX + 65),
  291.             (EndHashY + 10),
  292.             pDegreeString,
  293.             StringLength);
  294.  
  295.        StartHashY = StartHashY + 50;
  296.        EndHashY = EndHashY + 50;
  297.        Degree = Degree - HashInc;
  298.     }
  299.  
  300. }
  301.  
  302. LOCAL BOOL NEAR PASCAL show_menu (hInstance,hWindow)
  303.    /* This function loads and displays the available menu resources, 
  304.       and adds the "About..." option to the system menu. */
  305. HANDLE hInstance;
  306. HWND   hWindow;
  307. {
  308.     BOOL     bSetMenu;
  309.     HMENU     hMenuResource,
  310.          hSysMenu;
  311.  
  312.     hMenuResource = LoadMenu (hInstance,(LPSTR) MENUNAME);
  313.     bSetMenu = SetMenu (hWindow,hMenuResource);
  314.     hSysMenu = GetSystemMenu(hWindow,0);
  315.     ChangeMenu (hSysMenu,NULL,(LPSTR) NULL,NULL,
  316.         MF_SEPARATOR | MF_APPEND);
  317.     ChangeMenu (hSysMenu,IDABOUT,(LPSTR) "About...",IDABOUT,
  318.         MF_APPEND);
  319.     return (bSetMenu);
  320. }
  321.  
  322. /* ********************** Exported Routines *********************** */
  323.  
  324. long FAR PASCAL AppWndProc (hWindow,Message,Word,Long)
  325.    /* This Routine handles all input to the application.  Any input 
  326.       values that the routine chooses not to handle are passed to the 
  327.       default window procedure. */
  328. HWND     hWindow;
  329. unsigned Message;
  330. WORD     Word;
  331. long     Long;
  332. {
  333.     BOOL bHandled = TRUE;
  334.     long Result;
  335.  
  336.     if (Message == WM_COMMAND || Message == WM_SYSCOMMAND)
  337.         bHandled = command (hWindow,Word);
  338.     else if (Message == WM_PAINT)
  339.     {
  340.        paint_window (BeginPaint (hWindow,(LPPAINTSTRUCT) &Paint),
  341.             ViewportWidth,
  342.             ViewportHeight);
  343.        EndPaint (hWindow,(LPPAINTSTRUCT) &Paint);
  344.     }
  345.     else
  346.        bHandled = FALSE;
  347.  
  348.     if (bHandled == TRUE)
  349.        Result = (long) 0;
  350.     else
  351.        Result = DefWindowProc (hWindow,Message,Word,Long);
  352.  
  353.     return (Result);
  354.  
  355. }
  356.  
  357. BOOL FAR PASCAL about_dialog (hDialog,Message,Word,Long)
  358. HWND hDialog;
  359. unsigned Message;
  360. WORD Word;
  361. LONG Long;
  362.  /* This function is called by Windows to handle input to the About...
  363.     dialog box.  Since "OK" is the only option available to the user, 
  364.     only one message is processed, namely, WM_COMMAND. */
  365. {
  366.     BOOL Result = TRUE;
  367.  
  368.     if (Message == WM_COMMAND)
  369.        EndDialog (hDialog,Result);
  370.     else
  371.        Result = FALSE;
  372.  
  373.     return (Result);
  374.  
  375. }
  376.  
  377. BOOL FAR PASCAL print_dialog (hDialog,Message,Word,Long)
  378. HWND hDialog;
  379. unsigned Message;
  380. WORD Word;
  381. LONG Long;
  382.    /* This function processes input to the modeless dialog box created 
  383.       when the user selects the "Print" command from the file menu. */
  384. {
  385.     BOOL Result = TRUE;
  386.  
  387.     if (Message == WM_COMMAND && Word == IDCANCEL)
  388.        EndDialog (hDialog,Result);
  389.     else
  390.        Result = FALSE;
  391.  
  392.     return (Result);
  393.  
  394. }
  395.  
  396. BOOL FAR PASCAL set_temp_dialog (hDialog,Message,Word,Long)
  397. HWND hDialog;
  398. unsigned Message;
  399. WORD Word;
  400. LONG Long;
  401.    /* This function is called by Windows to process input to the Set 
  402.       Temperature dialog box.  It looks for input from the scroll bars 
  403.       and updates the associated control each time a WM_VSCROLL 
  404.       message is received.  As part of the dialog's initialization, 
  405.       the current temperature is remembered in case the user changes 
  406.       it and then cancels the dialog.  This ensures that the correct 
  407.       temperature will be displayed.  The GraphicTemp variable is used 
  408.       for visible updating of the Thermometer when MathTemp falls 
  409.       within displayable limits. */
  410. {
  411.     BOOL Result = TRUE;
  412.  
  413.     if (Message == WM_INITDIALOG)
  414.     {
  415.        SetDlgItemInt (hDialog,SET_DEGS,MathTemp,1);
  416.        OldTemp = MathTemp;
  417.        bOldTempMode = bCurrentTempMode;
  418.        if (bCurrentTempMode == TRUE)
  419.           CheckRadioButton (hDialog,FARENHEIT,CELSIUS,FARENHEIT);
  420.        else
  421.           CheckRadioButton (hDialog,FARENHEIT,CELSIUS,CELSIUS);
  422.     }
  423.     else if (Message == WM_COMMAND)
  424.     {
  425.        switch (Word)
  426.        {
  427.           case CELSIUS:
  428.          CheckRadioButton (hDialog,FARENHEIT,CELSIUS,CELSIUS);
  429.          if (bCurrentTempMode == TRUE)
  430.          {
  431.             MathTemp = (5*(MathTemp - 32))/9;
  432.             if (MathTemp > HIGHTEMP)
  433.                GraphicTemp = HIGHTEMP;
  434.             else if (MathTemp < LOWTEMP)
  435.                GraphicTemp = LOWTEMP;
  436.             else
  437.                GraphicTemp = MathTemp;
  438.  
  439.             bCurrentTempMode = FALSE;
  440.             SetDlgItemInt (hDialog,SET_DEGS,MathTemp,1);
  441.          }
  442.          else
  443.             break;
  444.  
  445.          break;
  446.  
  447.           case FARENHEIT:
  448.          CheckRadioButton (hDialog,FARENHEIT,CELSIUS,FARENHEIT);
  449.          if (bCurrentTempMode == FALSE)
  450.          {
  451.             MathTemp = ((9*MathTemp)/5)+32;
  452.             if (MathTemp > HIGHTEMP)
  453.                GraphicTemp = HIGHTEMP;
  454.             else if (MathTemp < LOWTEMP)
  455.                GraphicTemp = LOWTEMP;
  456.             else
  457.                GraphicTemp = MathTemp;
  458.             bCurrentTempMode = TRUE;
  459.             SetDlgItemInt (hDialog,SET_DEGS,MathTemp,1);
  460.          }
  461.          else
  462.             break;
  463.  
  464.          break;
  465.  
  466.           case IDOK:
  467.          EndDialog (hDialog,Word);
  468.          break;
  469.           case IDCANCEL:
  470.          MathTemp = OldTemp;
  471.          bCurrentTempMode = bOldTempMode;
  472.          EndDialog (hDialog,Word);
  473.          break;
  474.           default:
  475.          ;
  476.        }
  477.     }
  478.     else if (Message == WM_VSCROLL)
  479.     {
  480.        switch (Word)
  481.        {
  482.           case SB_LINEUP:
  483.          MathTemp = MathTemp + DegreeInc;
  484.          break;
  485.           case SB_LINEDOWN:
  486.          MathTemp = MathTemp - DegreeInc;
  487.          break;
  488.           default:
  489.          MathTemp = MathTemp + 0;
  490.        }
  491.  
  492.        if (MathTemp < LOWTEMP)
  493.        {
  494.           GraphicTemp = LOWTEMP;
  495.           SetDlgItemInt (hDialog,SET_DEGS,MathTemp,1);
  496.        }
  497.        else if (MathTemp > HIGHTEMP)
  498.        {
  499.           GraphicTemp = HIGHTEMP;
  500.           SetDlgItemInt (hDialog,SET_DEGS,MathTemp,1);
  501.        }
  502.        else
  503.        {
  504.           GraphicTemp = MathTemp;
  505.           SetDlgItemInt (hDialog,SET_DEGS,MathTemp,1);
  506.        }
  507.  
  508.     }
  509.  
  510.     else
  511.        Result = FALSE;
  512.  
  513.     return (Result);
  514.  
  515. }
  516.  
  517. int FAR PASCAL WinMain(hInstance,hPrevious,lpCmdLine,Show)
  518.    /* This routine is called whenever a new instance of the 
  519.       application is created.  First, init_app is called so that all 
  520.       necessary initialization can take place.  Then a loop is created 
  521.       that waits for input to the application and dispatches the input 
  522.       values to the application's window procedure. */
  523. HANDLE hInstance,
  524.        hPrevious;
  525. LPSTR  lpCmdLine;
  526. int    Show;
  527. {
  528.     HWND hWindow;
  529.  
  530.     hWindow = init_app (hPrevious,hInstance,lpCmdLine,Show);
  531.  
  532.     if (hWindow != NULL)
  533.     {
  534.         MSG Message;
  535.  
  536.         while (GetMessage ((LPMSG) &Message,NULL,0,0))
  537.         {
  538.             TranslateMessage ((LPMSG) &Message);
  539.             DispatchMessage ((LPMSG) &Message);
  540.         }
  541.     }
  542.     return (0);
  543. }
  544.