home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tolkit45.zip / os2tk45 / samples / os2 / timeserv / wndproc.c < prev   
C/C++ Source or Header  |  1999-05-11  |  50KB  |  1,736 lines

  1. /*static char *SCCSID = "@(#)wndproc.c    6.11 92/03/10";*/
  2.  
  3. /*=========================================================================\
  4.  *                                                                         *
  5.  *       FILE:wndproc.c                                                    *
  6.  *                                                                         *
  7.  *       DESCRIPTION:    Window procedure for clock client window          *
  8.  *                                                                         *
  9.  *                                                                         *
  10.  *                                                                         *
  11.  *      Copyright 1989-1993 IBM Corp.                                      *
  12.  *                                                                         *
  13.  *      DISCLAIMER OF WARRANTIES.  The following [enclosed] code is        *
  14.  *      sample code created by IBM Corporation. This sample code is not    *
  15.  *      part of any standard or IBM product and is provided to you solely  *
  16.  *      for  the purpose of assisting you in the development of your       *
  17.  *      applications.  The code is provided "AS IS", without               *
  18.  *      warranty of any kind.  IBM shall not be liable for any damages     *
  19.  *      arising out of your use of the sample code, even if they have been *
  20.  *      advised of the possibility of   such damages.                      *
  21.  *                                                                         *
  22.  *-------------------------------------------------------------------------*
  23.  *
  24.  *
  25.  *
  26.  *
  27.  *
  28.  *
  29.  *
  30.  *
  31.  *
  32.  *
  33.  *
  34.  *--------------------------------------------------------------
  35.  *
  36.  *  This source file contains the following functions:
  37.  *
  38.  *
  39.  *
  40.  *
  41.  *
  42. \*==============================================================*/
  43.  
  44. /*--------------------------------------------------------------*\
  45.  *  Include files, macros, defined constants, and externs
  46. \*--------------------------------------------------------------*/
  47.  
  48. #define INCL_DEV
  49. #define INCL_WININPUT
  50. #define INCL_WINFRAMEMGR
  51. #define INCL_WINTRACKRECT
  52. #define INCL_WINMENUS
  53. #define INCL_WINSYS
  54. #define INCL_WINTIMER
  55. #define INCL_WINMESSAGEMGR
  56. #define INCL_WINSHELLDATA
  57. #define INCL_WINWINDOWMGR
  58. #define INCL_WINHELP
  59. #define INCL_GPICONTROL
  60. #define INCL_GPIPRIMITIVES
  61. #define INCL_GPILOGCOLORTABLE
  62. #define INCL_GPIBITMAPS
  63. #define INCL_GPITRANSFORMS
  64. #define INCL_DOSSEMAPHORES
  65. #define INCL_DOSDATETIME
  66.  
  67.  
  68. #include <os2.h>
  69. #include <time.h>
  70. #include <stdio.h>
  71. #include <stdlib.h>
  72. #include <string.h>
  73. #include "clock.h"
  74. #include "res.h"
  75. #include "clkdata.h"
  76. #include "help.h"
  77.  
  78. /*--------------------------------------------------------------*\
  79.  *  Global variables and definitions for this file
  80. \*--------------------------------------------------------------*/
  81.  
  82. HWND hwndHelpInstance;
  83.  
  84. /* Fields marked (RT) are filled in at run-time */
  85.  
  86. #define RESOURCEFLAG    0xFFFF0000
  87.  
  88. CHAR szHelpTitle [MAXTITLELENGTH + 1];
  89.  
  90.  
  91. /*d-------------------------------------------------------------*\
  92.  *  Entry point declarations
  93. \*-------------------------------------------------------------k*/
  94.  
  95. MRESULT EXPENTRY ClkTicksDlgProc (HWND hWnd,ULONG usMessage,
  96.                                   MPARAM mp1, MPARAM mp2);
  97. MRESULT EXPENTRY ClkColorsDlgProc(HWND hWnd,ULONG usMessage,
  98.                                   MPARAM mp1, MPARAM mp2);
  99. MRESULT EXPENTRY TimeDlgProc(HWND hWnd,ULONG usMessage,
  100.                              MPARAM mp1, MPARAM mp2);
  101. MRESULT EXPENTRY AlarmDlgProc (HWND hWnd,ULONG usMessage,
  102.                                MPARAM mp1, MPARAM mp2);
  103. VOID FAR SaveApplication (HWND hWnd);
  104.  
  105. VOID ClkPaint (HWND);
  106. VOID ClkCreate (HWND);
  107. VOID ClkDestroy (HWND);
  108. VOID ClkMinmax (HWND, PSWP);
  109. VOID ClkSize (HWND);
  110. VOID ClkTimer (HWND);
  111. VOID ClkCommand (HWND, MPARAM,MPARAM );
  112. VOID GetArrangedDate (CHAR []);
  113. VOID ClkDrawDate (HPS, USHORT);
  114.  
  115. VOID ClkHideFrameControls (HWND);
  116. VOID ClkShowFrameControls (HWND);
  117. VOID DrawDigitalTime (HWND);
  118. VOID GetCountryDependent (VOID);
  119. VOID SetDispMode (VOID);
  120. VOID SetRGBColors (VOID);
  121. VOID ShadeLight   (PLONG );
  122. BYTE LightRGBByte (BYTE);
  123. BYTE ShadeRGBByte (BYTE);
  124. VOID InitMenu(MPARAM mp1, MPARAM mp2);
  125. VOID EnableMenuItem(HWND hwndMenu, SHORT idItem, BOOL fEnable);
  126. /****************************************************************\
  127.  *  Routine Name:ClkWndProc()
  128.  *--------------------------------------------------------------
  129.  *
  130.  *  Name:
  131.  *
  132.  *  Purpose:
  133.  *
  134.  *
  135.  *
  136.  *  Usage:
  137.  *
  138.  *  Method:
  139.  *          -
  140.  *
  141.  *          -
  142.  *          -
  143.  *
  144.  *          -
  145.  *          -
  146.  *
  147.  *  Returns: MRESULT()
  148.  *
  149.  *
  150. \****************************************************************/
  151.  
  152. MRESULT EXPENTRY ClkWndProc (HWND hwnd, ULONG usMsg, MPARAM mp1, MPARAM mp2)
  153. {
  154.     switch (usMsg)
  155.     {
  156.  
  157.     case WM_CREATE:
  158.         ClkCreate (hwnd);
  159.         return (WinDefWindowProc (hwnd, usMsg, mp1, mp2));
  160.  
  161.     case WM_DESTROY:
  162.         ClkDestroy (hwnd);
  163.         return (WinDefWindowProc (hwnd, usMsg, mp1, mp2));
  164.  
  165.     case WM_TIMER:
  166.         ClkTimer (hwnd);
  167.         if ( (BOOL) hDateTime)
  168.             WinSendMsg (hDateTime, WM_TIMER, mp1, mp2);
  169.         break;
  170.  
  171.     case WM_PAINT:
  172.         ClkPaint (hwnd);
  173.         break;
  174.  
  175.     case WM_MINMAXFRAME:
  176.         ClkMinmax (hwnd, (PSWP)mp1);
  177.         break;
  178.  
  179.     case WM_SIZE:
  180.         ClkSize (hwnd);
  181.         return (WinDefWindowProc (hwnd, usMsg, mp1, mp2));
  182.  
  183.     case WM_COMMAND:
  184.         ClkCommand (hwnd, mp1,mp2);
  185.         break;
  186.  
  187.     case WM_BUTTON1DOWN:
  188.         return WinSendMsg (hwndFrame, WM_TRACKFRAME,
  189.                            MPFROMSHORT((USHORT)mp2 | TF_MOVE), MPVOID);
  190.  
  191.     case WM_BUTTON1DBLCLK:
  192.         if (cp.fControlsHidden)
  193.             ClkShowFrameControls (hwndFrame);
  194.         else
  195.             ClkHideFrameControls (hwndFrame);
  196.         break;
  197.  
  198.     case WM_TRANSLATEACCEL:
  199.         return WinSendMsg(hwndFrame, usMsg, mp1, mp2);
  200.         break;
  201.  
  202.     case WM_SAVEAPPLICATION:
  203.         /***********************************************************\
  204.         *  Task Manager option to Save Desktop sends this message.
  205.         *  Save window state (MIN/RESTORE) and position in OS2.INI
  206.         \***********************************************************/
  207.         SaveApplication (hwndFrame);
  208.         break;
  209.  
  210.      case WM_INITMENU:
  211.          InitMenu(mp1, mp2);
  212.          break;
  213.  
  214.     case HM_QUERY_KEYS_HELP:
  215.         return (MRESULT)PANEL_HELPKEYS;   /* return id of key help panel */
  216.         break;
  217.  
  218.     default:
  219.         /* let default window procedure handle it. */
  220.         return (WinDefWindowProc (hwnd, usMsg, mp1, mp2));
  221.     }
  222.  
  223.     return (MRFROMLONG(0));
  224. }
  225.  
  226.  
  227.  
  228. /****************************************************************\
  229.  *
  230.  *--------------------------------------------------------------
  231.  *
  232.  *  Name:ClkCreate()
  233.  *
  234.  *  Purpose:Intialize a newly created client window
  235.  *
  236.  *
  237.  *
  238.  *  Usage:
  239.  *
  240.  *  Method:
  241.  *          -
  242.  *
  243.  *          -
  244.  *          -
  245.  *
  246.  *          -
  247.  *          -
  248.  *
  249.  *  Returns:
  250.  *          1 - if sucessful execution completed
  251.  *          0 - if error
  252. \****************************************************************/
  253. VOID ClkCreate ( HWND hwnd )
  254. {
  255.     LONG cxScreen , cyScreen;  /* screen dimensions */
  256.     LONG xLeft , yBottom ;      /* frame window location */
  257.     ULONG cbBuf;
  258.     LONG cyHeight;
  259.     LONG cxWidth;
  260.  
  261.     hwndClient = hwnd;
  262.  
  263.     WinLoadString(hab, NULLHANDLE, IDS_TITLE,  0, (PSZ)szTitle   );
  264.     WinLoadString(hab, NULLHANDLE, IDS_HELPTITLE, 256, (PSZ)szHelpTitle);
  265.     GetCountryDependent();
  266.     /* we are called before the global hwndFrame is valid */
  267.     hwndFrame = WinQueryWindow ( hwnd , QW_PARENT) ;
  268.     hwndTitleBar = WinWindowFromID ( hwndFrame , FID_TITLEBAR ) ;
  269.     hwndSysMenu = WinWindowFromID ( hwndFrame , FID_SYSMENU ) ;
  270.     hwndMinMax = WinWindowFromID ( hwndFrame , FID_MINMAX ) ;
  271.  
  272.     /* load our menus */
  273.     hwndMenu = WinLoadMenu (hwndFrame, NULLHANDLE, IDR_MAIN);
  274.     /* determine screen dimensions */
  275.     /* open a device context and create a presentation space */
  276.  
  277.     hdc = WinOpenWindowDC (hwnd);
  278.     hps = GpiCreatePS (hab, hdc, &sizl, PU_ARBITRARY | GPIT_MICRO |
  279.             GPIA_ASSOC);
  280.  
  281.     /*
  282.      * Create our off-screen 'buffer'.
  283.      */
  284.     hdcBuffer = DevOpenDC ( (HAB)0L, OD_MEMORY, "*", 0L, NULL, hdc);
  285.     hpsBuffer = GpiCreatePS (hab, hdcBuffer, &sizl, PU_ARBITRARY |
  286.                                GPIT_MICRO | GPIA_ASSOC);
  287.  
  288.     GpiCreateLogColorTable (hpsBuffer, 0, LCOLF_RGB, 0, 0, (PLONG)NULL);
  289.  
  290.     /* get the device resolutions so we can make the face appear circular */
  291.     DevQueryCaps (hdc, (LONG)CAPS_VERTICAL_RESOLUTION,(LONG) 1L, &cyRes);
  292.     DevQueryCaps (hdc, CAPS_HORIZONTAL_RESOLUTION, 1L, &cxRes);
  293.     DevQueryCaps (hdc, CAPS_COLOR_PLANES, 1L, &cColorPlanes);
  294.     DevQueryCaps (hdc, CAPS_COLOR_BITCOUNT, 1L, &cColorBitcount);
  295.  
  296.     cxScreen = WinQuerySysValue (HWND_DESKTOP, SV_CXSCREEN);
  297.     cyScreen = WinQuerySysValue (HWND_DESKTOP, SV_CYSCREEN);
  298.  
  299.     /*
  300.      * Calculate an initial window position and size.
  301.      */
  302.     xLeft = cxScreen / 8;
  303.     yBottom = cyScreen / 2;
  304.     cxWidth = cxScreen / 3;
  305.     cyHeight = cyScreen / 2;
  306.     WinSetWindowPos (hwndFrame, NULLHANDLE, xLeft, yBottom,
  307.                        cxWidth, cyHeight,
  308.                        SWP_SIZE | SWP_MOVE | SWP_ACTIVATE);
  309.  
  310.     cbBuf = sizeof(cp);
  311.     if (!PrfQueryProfileData(HINI_USER, SZ_APPNAME, SZ_KEYNAME, &cp, &cbBuf))
  312.     {
  313.         cp.usMajorTickPref = CLKTM_ALWAYS;
  314.         cp.usMinorTickPref = CLKTM_NOTICONIC;
  315.         cp.clrBackground = 0x00008080;
  316.         cp.clrFace = 0x00008080;
  317.         cp.clrHourHand = RGB_RED;
  318.         cp.clrMinuteHand = RGB_RED;
  319.         cp.fControlsHidden = FALSE;
  320.         cp.usDispMode = DM_TIME | DM_ANALOG | DM_SECONDHAND;
  321.         cp.alarm.uchHour = 0;
  322.         cp.alarm.uchMinutes = 0;
  323.         cp.alarm.usMode = 0;
  324.         SetRGBColors();
  325.         /* position the window and make it visible */
  326.         WinSetWindowPos( hwndFrame , NULLHANDLE ,
  327.                            xLeft , yBottom ,
  328.                            cxWidth , cyHeight ,
  329.                            SWP_SIZE | SWP_MOVE | SWP_ACTIVATE);
  330.         WinQueryWindowPos(hwndFrame, &cp.swp);
  331.     }
  332.     else
  333.     { /*Protect against garbage swp*/
  334.  
  335.         cp.swp.hwnd = hwndFrame;
  336.         cp.swp.hwndInsertBehind = HWND_TOP;
  337.  
  338.         cp.swp.fl = (cp.swp.fl & (SWP_MINIMIZE | SWP_MAXIMIZE)) | SWP_SIZE | SWP_MOVE | SWP_ACTIVATE;
  339.         SetRGBColors();
  340.         WinSetMultWindowPos(hab, &cp.swp, 1);
  341.     }
  342.  
  343.     if (cp.fControlsHidden)
  344.         ClkHideFrameControls (hwndFrame);
  345.  
  346.     /*
  347.      * Check relevant items.
  348.      */
  349.     WinSendMsg( hwndMenu,
  350.                 MM_SETITEMATTR,
  351.                 MPFROM2SHORT( IDM_TIME, TRUE),
  352.                 MPFROM2SHORT( MIA_CHECKED,
  353.                               ( (cp.usDispMode & DM_TIME)?  MIA_CHECKED
  354.                                       : ~MIA_CHECKED) ) );
  355.     WinSendMsg( hwndMenu,
  356.                 MM_SETITEMATTR,
  357.                 MPFROM2SHORT( IDM_DATE, TRUE),
  358.                 MPFROM2SHORT( MIA_DISABLED,
  359.                               ( (!(cp.usDispMode & DM_TIME))?  MIA_DISABLED
  360.                                       : ~MIA_DISABLED) ) );
  361.     WinSendMsg( hwndMenu,
  362.                 MM_SETITEMATTR,
  363.                 MPFROM2SHORT( IDM_DATE, TRUE),
  364.                 MPFROM2SHORT( MIA_CHECKED,
  365.                               ( (cp.usDispMode & DM_DATE)?  MIA_CHECKED
  366.                                       : ~MIA_CHECKED) ) );
  367.     WinSendMsg( hwndMenu,
  368.                 MM_SETITEMATTR,
  369.                 MPFROM2SHORT( IDM_TIME, TRUE),
  370.                 MPFROM2SHORT( MIA_DISABLED,
  371.                               ( ((!(cp.usDispMode & DM_DATE) || (cp.usDispMode & DM_ANALOG)))?  MIA_DISABLED
  372.                                       : ~MIA_DISABLED) ) );
  373.     WinSendMsg( hwndMenu,
  374.                 MM_SETITEMATTR,
  375.                 MPFROM2SHORT( (cp.usDispMode & DM_DIGITAL)
  376.                                                           ?IDM_DIGITAL
  377.                                                           :IDM_ANALOG,
  378.                                TRUE),
  379.                 MPFROM2SHORT( MIA_CHECKED,
  380.                               MIA_CHECKED));
  381.  
  382.     WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(IDM_SECONDHAND, TRUE),
  383.                 MPFROM2SHORT( MIA_CHECKED,
  384.                               ( (cp.usDispMode & DM_SECONDHAND) ? MIA_CHECKED
  385.                                       : ~MIA_CHECKED)));
  386.  
  387.  
  388.     /*
  389.      * Disable these items if the digital clock is visible
  390.      * since they won't apply.
  391.      */
  392.     if (cp.usDispMode & DM_DIGITAL)
  393.     {
  394.         WinSendMsg (hwndMenu, MM_SETITEMATTR,
  395.                 MPFROM2SHORT(IDM_SECONDHAND, TRUE),
  396.                 MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED));
  397.  
  398.         WinSendMsg (hwndMenu, MM_SETITEMATTR,
  399.                 MPFROM2SHORT( IDM_TICKS, TRUE), MPFROM2SHORT( MIA_DISABLED,
  400.                 MIA_DISABLED));
  401.     }
  402.  
  403.     /* have we been asked to start as an icon? */
  404.     if (fStartAsIcon)
  405.         WinSetWindowPos(hwndFrame, NULLHANDLE, 0, 0, 0, 0, SWP_MINIMIZE);
  406.  
  407.     WinShowWindow(hwndFrame, TRUE);
  408.  
  409.     /* get the time in a format for dislaying */
  410.     DosGetDateTime(&dt);
  411.     dt.hours = (UCHAR )(dt.hours * (UCHAR) 5) % (UCHAR) 60 + dt.minutes / (UCHAR)12;
  412.  
  413.     /* start a timer */
  414.     WinStartTimer (hab, hwnd, IDR_MAIN, 1000);
  415.  
  416.     WinLoadString(hab, NULLHANDLE, IDS_TITLE, 80, (PSZ)szTitle);
  417.     GetCountryDependent();
  418.  
  419. }
  420.  
  421.  
  422. /****************************************************************\
  423.  *
  424.  *--------------------------------------------------------------
  425.  *
  426.  *  Name:ClkDestroy()
  427.  *
  428.  *  Purpose: Destroy clock face.
  429.  *
  430.  *
  431.  *
  432.  *  Usage:
  433.  *
  434.  *  Method:
  435.  *          -
  436.  *
  437.  *          -
  438.  *          -
  439.  *
  440.  *          -
  441.  *          -
  442.  *
  443.  *  Returns:VOID
  444.  *
  445.  *
  446. \****************************************************************/
  447. VOID ClkDestroy (HWND hwnd)
  448. {
  449.     HBITMAP hbm;
  450.  
  451.     hbm = GpiSetBitmap (hpsBuffer, NULLHANDLE);
  452.  
  453.     if (hbm != NULLHANDLE)
  454.         GpiDeleteBitmap (hbm);
  455.  
  456.     GpiDestroyPS (hpsBuffer);
  457.     DevCloseDC (hdcBuffer);
  458. }
  459. /****************************************************************\
  460.  *
  461.  *--------------------------------------------------------------
  462.  *
  463.  *  Name: ClkSize()
  464.  *
  465.  *  Purpose:When the window has been sized, we calculate  a page
  466.  *          rectangle which: (a) fills the window rectangle in either
  467.  *          the x or y dimension, (b) appears square, and (c) is centered
  468.  *          in the window rectangle
  469.  *  Usage:
  470.  *
  471.  *  Method:
  472.  *          -
  473.  *
  474.  *          -
  475.  *          -
  476.  *
  477.  *          -
  478.  *          -
  479.  *
  480.  *  Returns:
  481.  *
  482.  *
  483. \****************************************************************/
  484. VOID ClkSize (HWND hwnd)
  485. {
  486.     RECTL rclWindow;
  487.     SIZEF sizef;
  488.     LONG cxSquare, cySquare, cxEdge, cyEdge;
  489.     LONG cyHeight;
  490.     LONG cxWidth;
  491.     HBITMAP hbm;
  492.     BITMAPINFOHEADER bmp;
  493.  
  494.     /*
  495.      * First get rid of any buffer bitmap already there.
  496.      */
  497.     hbm = GpiSetBitmap (hpsBuffer, NULLHANDLE);
  498.  
  499.     if (hbm != NULLHANDLE)
  500.         GpiDeleteBitmap (hbm);
  501.  
  502.     /*
  503.      * Get the width and height of the window rectangle.
  504.      */
  505.     WinQueryWindowRect (hwnd, &rclWindow);
  506.     cxWidth = rclWindow.xRight - rclWindow.xLeft - 2;
  507.     cyHeight = rclWindow.yTop - rclWindow.yBottom - 2;
  508.  
  509.     /*
  510.      * Now create a bitmap the size of the window.
  511.      */
  512.     bmp.cbFix = sizeof(BITMAPINFOHEADER);
  513.     bmp.cx = (SHORT)cxWidth;
  514.     bmp.cy = (SHORT)cyHeight;
  515.     bmp.cPlanes = (SHORT)cColorPlanes;
  516.     bmp.cBitCount = (SHORT)cColorBitcount;
  517.     hbm = GpiCreateBitmap(hpsBuffer, (PBITMAPINFOHEADER2)&bmp,
  518.                           0x0000, (PBYTE)NULL, (PBITMAPINFO2)NULL);
  519.     GpiSetBitmap (hpsBuffer, hbm);
  520.  
  521.     /*
  522.      * Assume the size of the page rectangle is constrained in the y
  523.      * dimension,compute the x size which would make the rectangle appear
  524.      * square, then check the assumption and do the reverse calculation
  525.      * if necessary.
  526.      */
  527.     cySquare = cyHeight - 2;
  528.     cxSquare = ( cyHeight * cxRes ) / cyRes;
  529.  
  530.     if (cxWidth < cxSquare)
  531.     {
  532.         cxSquare = cxWidth - 2;
  533.         cySquare = (cxWidth * cyRes) / cxRes;
  534.     }
  535.  
  536.     /*
  537.      * Fill in the page rectangle and set the page viewport.
  538.      */
  539.     cxEdge = (cxWidth - cxSquare ) / 2;
  540.     cyEdge = (cyHeight - cySquare ) / 2;
  541.     rclPage.xLeft = cxEdge;
  542.     rclPage.xRight = cxWidth - cxEdge;
  543.     rclPage.yBottom = cyEdge;
  544.     rclPage.yTop = cyHeight - cyEdge;
  545.  
  546.     /*
  547.      * Determine where to put the date. If we have room under the clock, we
  548.      * put it there. If we have more room on the left we put it there. If we
  549.      * have more room in the midlle, it goes there.
  550.      */
  551.     if (cp.usDispMode & DM_DATE)
  552.     {
  553.         vclrDate[SURFACE] = vclrBG[SHADE];
  554.         vclrDate[LIGHT] = vclrBG[LIGHT];
  555.         vclrDate[SHADE] = vclrBG[SHADE];
  556.         vclrDate[BACKGROUND] = vclrBG[SURFACE];
  557.         if (cyHeight > (cySquare*6/5)) { /*Goes under*/
  558.             vmatlfDateTrans.lM31 = (LONG)15;            /*Horizontal*/
  559.             vmatlfDateTrans.lM32 = -(LONG)17;    /*vertical*/
  560.             vmatlfDateScale.fxM11 = MAKEFIXED(2,0x8000);
  561.             vmatlfDateScale.fxM22 = MAKEFIXED(2,0x8000);
  562.             rclPage. yTop += cyEdge;
  563.             rclPage. yBottom += cyEdge;
  564.             vusDatePos = DP_UNDER;
  565.         }
  566.         else
  567.         {
  568.             if (cxWidth > (cxSquare * 31/10 ))
  569.             {
  570.                 vmatlfDateTrans.lM31 = -(LONG)53 ;            /*Horizontal*/
  571.                 vmatlfDateTrans.lM32 = (LONG)04;    /*vertical*/
  572.                 vmatlfDateScale.fxM11 = MAKEFIXED(7,0xe000);
  573.                 vmatlfDateScale.fxM22 = MAKEFIXED(7,0xe000);
  574.                 rclPage.xRight += cxEdge;
  575.                 rclPage.xLeft += cxEdge;
  576.                 vusDatePos = DP_LEFTMIDDLE;
  577.  
  578.             }
  579.             else
  580.             {
  581.                 if (cxWidth > (cxSquare * 2)) { /*Goes on the left*/
  582.                     vmatlfDateTrans.lM31 = -(LONG)52 ;            /*Horizontal*/
  583.                     vmatlfDateTrans.lM32 = (LONG)2;    /*vertical*/
  584.                     vmatlfDateScale.fxM11 = MAKEFIXED(3,0xd000);
  585.                     vmatlfDateScale.fxM22 = MAKEFIXED(3,0xd000);
  586.                     rclPage.xRight += cxEdge;
  587.                     rclPage.xLeft += cxEdge;
  588.                     vusDatePos = DP_LEFTDOWN  ;
  589.  
  590.                 }
  591.                 else
  592.                 {   /*Goes inside*/
  593.                     vmatlfDateTrans.lM31 = (LONG)24 ;            /*Horizontal*/
  594.                     vmatlfDateTrans.lM32 = (LONG)23;    /*vertical*/
  595.                     vmatlfDateScale.fxM11 = MAKEFIXED(2,0);
  596.                     vmatlfDateScale.fxM22 = MAKEFIXED(2,0);
  597.                     vclrDate[SURFACE] = vclrFace[SHADE] ;
  598.                     vclrDate[LIGHT] = vclrFace[LIGHT] ;
  599.                     vclrDate[SHADE] = vclrFace[SHADE];
  600.                     vclrDate[BACKGROUND] = vclrFace[SURFACE];
  601.                     vusDatePos = DP_INSIDE;
  602.                 }
  603.             }
  604.         }
  605.     }
  606.  
  607.     f = GpiSetPageViewport (hps, &rclPage);
  608.     f = GpiSetPageViewport (hpsBuffer, &rclPage);
  609.  
  610.     /*
  611.      * Are we iconic?
  612.      */
  613.     f = WinQueryWindowPos (hwndFrame, &swp);
  614.     fIconic = (BOOL)(swp.fl & SWP_MINIMIZE );
  615.     fShowSecondHand = (BOOL) !(fIconic);
  616.  
  617.     GpiQueryCharBox(hpsBuffer, &sizef);
  618.     GpiSetCharBox(hpsBuffer, &sizef);
  619.  
  620.     fBufferDirty = TRUE;
  621. }
  622.  
  623. /****************************************************************\
  624.  *
  625.  *--------------------------------------------------------------
  626.  *
  627.  *  Name:ClkMinMax()
  628.  *
  629.  *  Purpose:
  630.  *
  631.  *
  632.  *
  633.  *  Usage:
  634.  *
  635.  *  Method:
  636.  *          -
  637.  *
  638.  *          -
  639.  *          -
  640.  *
  641.  *          -
  642.  *          -
  643.  *
  644.  *  Returns:
  645.  *          VOID
  646.  *
  647. \****************************************************************/
  648. VOID ClkMinmax (HWND hwnd, PSWP pswp)
  649. {
  650.     char achFinalDate[10];
  651.     HWND hwndFrame;
  652.  
  653.  
  654.     /*
  655.      * We want the date as the icon text if the clock is
  656.      * minimized and the user has selected both date and
  657.      * time be displayed.
  658.      */
  659.     if ((cp.usDispMode & (DM_TIME | DM_DATE)) == (DM_TIME | DM_DATE))
  660.     {
  661.         hwndFrame = WinQueryWindow (hwnd, QW_PARENT);
  662.         if (pswp->fl & SWP_MINIMIZE) {
  663.             GetArrangedDate (achFinalDate);
  664.             WinSetWindowText (hwndFrame, achFinalDate);
  665.         } else {
  666.             WinSetWindowText (hwndFrame, "Clock");
  667.         }
  668.     }
  669. }
  670. /****************************************************************\
  671.  *
  672.  *--------------------------------------------------------------
  673.  *
  674.  *  Name:ClkTimer()
  675.  *
  676.  *  Purpose: Handles window timer events
  677.  *
  678.  *
  679.  *
  680.  *  Usage:
  681.  *
  682.  *  Method:
  683.  *          -
  684.  *
  685.  *          -
  686.  *          -
  687.  *
  688.  *          -
  689.  *          -
  690.  *
  691.  *  Returns:
  692.  *          1 - if sucessful execution completed
  693.  *          0 - if error
  694. \****************************************************************/
  695. VOID ClkTimer (HWND hwnd)
  696. {
  697.     DATETIME  dtNew;
  698.     static LONG lTimeChangeCheck = 0L;
  699.     LONG  lTime;
  700.     DosGetDateTime ( &dtNew ) ;
  701.  
  702.     if (cp.usDispMode & DM_ANALOG)
  703.     {
  704.  
  705.         /* get the new time */
  706.         DosGetDateTime (&dtNew);
  707.  
  708.         /* adjust the hour hand */
  709.         dtNew.hours = (dtNew.hours * (UCHAR) 5 ) % (UCHAR) 60
  710.                       + dtNew.minutes / (UCHAR)12;
  711.  
  712.         /* if we must move the hour and minute hands, redraw it all */
  713.         if (dtNew.minutes != dt.minutes)
  714.         {
  715.  
  716.             ClkDrawFace(hpsBuffer);
  717.             ClkDrawDate(hpsBuffer, DM_REDRAW);
  718.             ClkDrawHand(hpsBuffer, HT_HOUR_SHADE, dtNew.hours);
  719.             ClkDrawHand(hpsBuffer, HT_MINUTE_SHADE, dtNew.minutes);
  720.             ClkDrawHand(hpsBuffer, HT_HOUR, dtNew.hours);
  721.             ClkDrawHand(hpsBuffer, HT_MINUTE, dtNew.minutes);
  722.  
  723.             UpdateScreen (hps, NULL);
  724.  
  725.             if (fShowSecondHand && (cp.usDispMode & DM_SECONDHAND))
  726.             {
  727.                 GpiSetMix(hps, FM_INVERT);
  728.                 ClkDrawHand(hps, HT_SECOND, dtNew.seconds);
  729.             }
  730.         }
  731.  
  732.         /* otherwise just undraw the old second hand and draw the new */
  733.         else if (fShowSecondHand  && (cp.usDispMode & DM_SECONDHAND))
  734.         {
  735.             GpiSetMix(hps, FM_INVERT);
  736.             ClkDrawHand(hps, HT_SECOND, dt.seconds);
  737.             ClkDrawHand(hps, HT_SECOND, dtNew.seconds);
  738.         }
  739.  
  740.         dt = dtNew ;
  741.     }
  742.     else /*Must be Digital*/
  743.     {
  744.         DrawDigitalTime(hwnd);
  745.     }
  746.  
  747.     /*
  748.      *if this is the first
  749.      *time through init it
  750.      */
  751.     if(!lTimeChangeCheck)
  752.     {
  753.           time(&lTimeChangeCheck);
  754.  
  755.     }
  756.  
  757.     /*
  758.      *a quick check to see if
  759.      *any other session
  760.      *adjusted our time
  761.      *if so reset the timer
  762.      */
  763.     else
  764.     {
  765.           time(&lTime);
  766.           /*
  767.            *did the clock get changed by more than 60 seconds
  768.            */
  769.           if( lTime  > ( lTimeChangeCheck  + 60L ) ||
  770.               lTimeChangeCheck > ( lTime   + 60L ) )
  771.           {
  772.  
  773.                AlarmSetTimer(cp.alarm.uchHour,
  774.                                    cp.alarm.uchMinutes);
  775.           }
  776.           lTimeChangeCheck = lTime;
  777.      }
  778.  
  779. }
  780.  
  781. /****************************************************************\
  782.  *
  783.  *--------------------------------------------------------------
  784.  *
  785.  *  Name:DrawDigitalTime()
  786.  *
  787.  *  Purpose:
  788.  *
  789.  *
  790.  *
  791.  *  Usage:
  792.  *
  793.  *  Method:
  794.  *          -
  795.  *
  796.  *          -
  797.  *          -
  798.  *
  799.  *          -
  800.  *          -
  801.  *
  802.  *  Returns:
  803.  *          1 - if sucessful execution completed
  804.  *          0 - if error
  805. \****************************************************************/
  806.  
  807. VOID DrawDigitalTime(HWND hwnd)
  808. {
  809.     RECTL rcl;
  810.     RECTL rclChar;
  811.     RECTL rclCharOld;
  812.     RECTL rclTime;
  813.     RECTL rclAmPm;
  814.     RECTL rclDate;
  815.     HPS hpsWnd;
  816.     SIZEF sizef;
  817.     USHORT usi;
  818.     ULONG  ulCharWidth,ulCharModulu;
  819.     char achTime[9];
  820.     char achFinalDate[9];
  821.     time_t     tTime;
  822.     struct tm  *pLocalTime;
  823.  
  824.     WinQueryWindowRect (hwnd, &rcl);
  825.     hpsWnd = WinGetPS (hwnd);
  826.  
  827.     memset(achTime,0,sizeof(achTime) );
  828.     memset(achFinalDate,0,sizeof(achFinalDate) );
  829.  
  830.     GpiCreateLogColorTable (hpsWnd, LCOL_RESET, LCOLF_RGB, 0, 0,
  831.                                  (PLONG) NULL);
  832.  
  833.     /*
  834.      *if black hands and black background
  835.      *selected force the background to
  836.      *blue
  837.      */
  838.  
  839.     if( !cp.clrMinuteHand && !cp.clrBackground )
  840.     {
  841.           cp.clrBackground = RGB_BLUE;
  842.     }
  843.  
  844.  
  845.  
  846.     switch (cp.usDispMode & (DM_TIME | DM_DATE))
  847.     {
  848.     case DM_DATE:
  849.         rclDate = rcl;
  850.         break;
  851.  
  852.     case DM_TIME | DM_DATE:
  853.         if (!fIconic)
  854.         {
  855.             rclTime = rclDate = rcl;
  856.             rclTime.yBottom = rclDate.yTop = rcl.yTop / 2;
  857.             break;
  858.         } /*else fall through*/
  859.  
  860.     case DM_TIME:
  861.         rclTime = rcl;
  862.         break;
  863.     }
  864.  
  865.     if (cp.usDispMode & DM_TIME)
  866.     {
  867.  
  868.         rclAmPm = rclTime;
  869.         time(&tTime);
  870.         pLocalTime = localtime(&tTime);
  871.         if (bTwelveHourFormat)
  872.         {
  873.            strftime(achTime, sizeof(achTime), "%I %M %S", pLocalTime);
  874.         }
  875.         else
  876.         {
  877.            strftime(achTime, sizeof(achTime), "%H %M %S", pLocalTime);
  878.         }
  879.  
  880.         /*insert country time separator*/
  881.         achTime[2] = achTime[5] = szTimeSep[0];
  882.         achTime[8] = '\000';
  883.         /*Process 12 hours mode*/
  884.         if (bTwelveHourFormat)
  885.         {
  886.  
  887.             if (fIconic)
  888.             {
  889.                 rclTime.yBottom = rclAmPm.yTop = rclTime.yTop / 2;
  890.             }
  891.             else
  892.             {
  893.                 rclTime.xRight = rcl.xRight * 8 / 11;
  894.                 rclAmPm.xLeft = rclTime.xRight;
  895.             }
  896.  
  897.             strcpy(achAmPm,szAnteMeridian);
  898.  
  899.             if (pLocalTime->tm_hour >= 12)
  900.             {
  901.                 strcpy(achAmPm,szPostMeridian);
  902.             }
  903.  
  904.         }
  905.  
  906.         GpiSetCharMode(hpsWnd, CM_MODE3);
  907.  
  908.         if (fIconic)
  909.         {
  910.             sizef.cx = MAKEFIXED(LOUSHORT((rclTime.xRight - rclTime.xLeft)
  911.                     / 3), 0);
  912.             sizef.cy = MAKEFIXED(LOUSHORT((rclTime.yTop - rclTime.yBottom)
  913.                     * 1400 / 1000), 0);
  914.         }
  915.         else
  916.         {
  917.             sizef.cx = MAKEFIXED(LOUSHORT((rclTime.xRight - rclTime.xLeft)
  918.                     / 6), 8000);
  919.             sizef.cy = MAKEFIXED(LOUSHORT((rclTime.yTop - rclTime.yBottom)
  920.                     * 1000 / 1500), 0);
  921.         }
  922.  
  923.         GpiSetCharBox(hpsWnd, &sizef);
  924.  
  925.         if (bTwelveHourFormat)
  926.         {
  927.  
  928.             if( strcmp(achAmPm,achOldAmPm) )
  929.             {
  930.                 WinFillRect(hpsWnd, &rclAmPm, cp.clrBackground);
  931.                 WinDrawText(hpsWnd, sizeof(achAmPm) - 1, (PSZ)achAmPm,
  932.                         (PRECTL)&rclAmPm, cp.clrMinuteHand, cp.clrBackground,
  933.                         DT_CENTER | DT_VCENTER );
  934.             }
  935.         }
  936.  
  937.         if (!fIconic)
  938.         {
  939.  
  940.             WinDrawText(hpsWnd, sizeof(achTime) - 1 , (PSZ)achTime,
  941.                     (PRECTL)&rclTime, cp.clrMinuteHand, cp.clrBackground,
  942.                     DT_CENTER | DT_VCENTER | DT_QUERYEXTENT);
  943.  
  944.             ulCharWidth = (rclTime.xRight - rclTime.xLeft) / (sizeof(achTime) - 1 );
  945.             ulCharModulu = (rclTime.xRight - rclTime.xLeft) % (sizeof(achTime) - 1 );
  946.             rclCharOld.xRight = rclTime.xLeft;
  947.  
  948.             rclChar.yTop = rclTime.yTop;
  949.             rclChar.yBottom = rclTime.yBottom;
  950.  
  951.             for (usi = 0; usi < (sizeof(achTime)); usi++)
  952.             {
  953.                 rclChar.xLeft = rclCharOld.xRight + (ULONG)1;
  954.                 rclChar.xRight = rclChar.xLeft + ulCharWidth +
  955.                         ((ulCharModulu > 0L) ? 1L : 0L);
  956.  
  957.                 if (ulCharModulu)
  958.                     ulCharModulu--;
  959.  
  960.                 if (achTime[usi] == szTimeSep[0])
  961.                 {
  962.                     rclChar.xRight -= 3;
  963.                 }
  964.                 else
  965.                 {
  966.                     rclChar.xRight += 1;
  967.                 }
  968.  
  969.                 rclCharOld = rclChar;
  970.  
  971.                 if (achTime[usi] != achOldTime[usi])
  972.                 {
  973.                     WinFillRect (hpsWnd, &rclChar, cp.clrBackground);
  974.                     if (!((usi == 0) && (achTime[0] == '0') &&
  975.                             (bTwelveHourFormat)))
  976.                         WinDrawText (hpsWnd, 1, (PSZ)&achTime[usi], &rclChar,
  977.                                 cp.clrMinuteHand, cp.clrBackground,
  978.                                 DT_CENTER | DT_VCENTER);
  979.                 }
  980.             }
  981.         }
  982.         else
  983.         {   /*Iconic. just draw if minute changed*/
  984.  
  985.             if (strncmp(achTime,achOldTime,5))
  986.             {
  987.                 WinFillRect(hpsWnd,&rclTime,cp.clrBackground);
  988.                 WinDrawText(hpsWnd, sizeof(achTime) - 4 , (PSZ)achTime,
  989.                         (PRECTL)&rclTime, cp.clrMinuteHand, cp.clrBackground,
  990.                         DT_CENTER | DT_VCENTER);
  991.             }
  992.         }
  993.     }
  994.  
  995.     if ((!(cp.usDispMode & DM_TIME)) || ((cp.usDispMode & DM_DATE) &&
  996.             (!fIconic)))
  997.     {
  998.         GetArrangedDate(achFinalDate);
  999.         if (strncmp(achFinalDate, achOldDate,
  1000.                 sizeof(achFinalDate) - fIconic ? 4 : 1))
  1001.         {
  1002.  
  1003.             WinFillRect (hpsWnd, &rclDate, cp.clrBackground);
  1004.             GpiSetCharMode (hpsWnd, CM_MODE3);
  1005.  
  1006.             sizef.cx = MAKEFIXED(LOUSHORT(
  1007.                             (rclDate.xRight - rclDate.xLeft) / 5), 0);
  1008.             sizef.cy = MAKEFIXED(LOUSHORT(
  1009.                             (rclDate.yTop - rclDate.yBottom) * 1000 / 1500), 0);
  1010.  
  1011.             GpiSetCharBox(hpsWnd, &sizef);
  1012.             WinDrawText(hpsWnd,
  1013.                         (sizeof(achFinalDate) - (fIconic ? 4 : 1) ),
  1014.                         (PSZ)achFinalDate,(PRECTL)&rclDate,
  1015.                         (LONG)cp.clrMinuteHand,
  1016.                         (LONG)cp.clrBackground,
  1017.                         (ULONG )(DT_CENTER | DT_VCENTER ) );
  1018.         }
  1019.     }
  1020.  
  1021.     WinReleasePS(hpsWnd);
  1022.  
  1023.     strncpy(achOldTime,achTime,sizeof(achOldTime));
  1024.     strncpy(achOldAmPm,achAmPm,sizeof(achOldAmPm));
  1025.     strncpy(achOldDate,achFinalDate,sizeof(achOldDate));
  1026. }
  1027. /****************************************************************\
  1028.  *
  1029.  *--------------------------------------------------------------
  1030.  *
  1031.  *  Name:ClkCommand()
  1032.  *
  1033.  *  Purpose:Handle  WM_COMMAND events.
  1034.  *
  1035.  *
  1036.  *
  1037.  *  Usage:
  1038.  *
  1039.  *  Method:
  1040.  *          -
  1041.  *
  1042.  *          -
  1043.  *          -
  1044.  *
  1045.  *          -
  1046.  *          -
  1047.  *
  1048.  *  Returns:
  1049.  *          VOID
  1050.  *
  1051. \****************************************************************/
  1052. VOID ClkCommand ( HWND hwnd , MPARAM mp1, MPARAM mp2 )
  1053. {
  1054.     DATETIME  dtNew ;
  1055.  
  1056.     switch ( SHORT1FROMMP ( mp1 ) )
  1057.     {
  1058.  
  1059.         case IDM_TICKS :
  1060.             WinDlgBox ( HWND_DESKTOP , hwndFrame , ClkTicksDlgProc ,
  1061.                         NULLHANDLE ,
  1062.                         IDD_TICKS , (PVOID )NULL ) ;
  1063.             break;
  1064.  
  1065.         case IDM_EXIT:
  1066.             /*
  1067.              *post the event semaphore
  1068.              *for our alarm thread
  1069.              */
  1070.             fEndThread = TRUE;
  1071.             DosPostEventSem(TimerResources.hTimerDev);
  1072.             WinPostMsg(hwnd, WM_QUIT,MPVOID, MPVOID);
  1073.  
  1074.  
  1075.             break;
  1076.  
  1077.         case IDM_COLORS :
  1078.             WinDlgBox ( HWND_DESKTOP , hwndFrame ,ClkColorsDlgProc ,
  1079.                         NULLHANDLE ,
  1080.                         IDD_COLORS , NULL ) ;
  1081.             SetRGBColors();
  1082.             ClkSize(hwnd);
  1083.             break ;
  1084.  
  1085.         case IDM_TOGGLECONTROLS :
  1086.             if (cp.fControlsHidden) {
  1087.                 ClkShowFrameControls( hwndFrame );
  1088.             } else {
  1089.                 ClkHideFrameControls ( hwndFrame ) ;
  1090.             }
  1091.             break ;
  1092.  
  1093.         case IDM_DATETIME:
  1094.             if (hDateTime == NULLHANDLE)
  1095.             {
  1096.                 WinDlgBox(HWND_DESKTOP,hwndFrame,TimeDlgProc,
  1097.                           NULLHANDLE,IDD_TIME ,NULL);
  1098.                 dt.minutes += 2; /*Fool the ClkTimer proc. It will now think it have
  1099.                                   to redraw*/
  1100.             } else {
  1101.                 WinSetFocus (HWND_DESKTOP, hDateTime);
  1102.             }
  1103.             break;
  1104.         case IDM_ALARM:
  1105.             if (hAlarmTime == (HWND)NULL)
  1106.             {
  1107.                 WinDlgBox(HWND_DESKTOP,hwndFrame,AlarmDlgProc,
  1108.                           NULLHANDLE,IDD_ALARM ,NULL);
  1109.             }
  1110.             else
  1111.             {
  1112.                 WinSetFocus(HWND_DESKTOP,hAlarmTime);
  1113.             }
  1114.  
  1115.             break;
  1116.  
  1117.         case IDM_SECONDHAND:
  1118.             cp.usDispMode = ((cp.usDispMode & DM_SECONDHAND) ?
  1119.                     (cp.usDispMode & (~DM_SECONDHAND)) : (cp.usDispMode | DM_SECONDHAND));
  1120.  
  1121.             GpiSetMix(hps, FM_INVERT);
  1122.  
  1123.             /*
  1124.              * Depending on the current mode draw or remove the second hand.
  1125.              */
  1126.             if (cp.usDispMode & DM_SECONDHAND) {
  1127.                 DosGetDateTime(&dtNew);
  1128.                 ClkDrawHand(hps, HT_SECOND, dtNew.seconds);
  1129.                 dt.seconds = dtNew.seconds;
  1130.             } else {
  1131.                 ClkDrawHand(hps, HT_SECOND, dt.seconds);
  1132.             }
  1133.  
  1134.             WinSendMsg( hwndMenu,
  1135.                         MM_SETITEMATTR,
  1136.                         MPFROM2SHORT( IDM_SECONDHAND, TRUE),
  1137.                         MPFROM2SHORT( MIA_CHECKED,
  1138.                                       ( (cp.usDispMode & DM_SECONDHAND)?  MIA_CHECKED
  1139.                                               : ~MIA_CHECKED) ) );
  1140.             break;
  1141.  
  1142.         case IDM_TIME:
  1143.             cp.usDispMode = ((cp.usDispMode & DM_TIME) ? (cp.usDispMode & (~DM_TIME))
  1144.                                                       : (cp.usDispMode | DM_TIME));
  1145.  
  1146.             WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(IDM_TIME, TRUE),
  1147.                     MPFROM2SHORT(MIA_CHECKED, ((cp.usDispMode & DM_TIME) ?
  1148.                     MIA_CHECKED : ~MIA_CHECKED)));
  1149.  
  1150.             WinSendMsg( hwndMenu,
  1151.                         MM_SETITEMATTR,
  1152.                         MPFROM2SHORT( IDM_DATE, TRUE),
  1153.                         MPFROM2SHORT( MIA_DISABLED,
  1154.                                       ( (!(cp.usDispMode & DM_TIME)) ? MIA_DISABLED
  1155.                                               : ~MIA_DISABLED) ) );
  1156.             ClkSize(hwnd);
  1157.             WinInvalidateRect(hwnd, NULL, TRUE);
  1158.             break;
  1159.  
  1160.         case IDM_DATE:
  1161.             cp.usDispMode = ((cp.usDispMode & DM_DATE) ? (cp.usDispMode & (~DM_DATE))
  1162.                                                       : (cp.usDispMode | DM_DATE));
  1163.             WinSendMsg( hwndMenu,
  1164.                         MM_SETITEMATTR,
  1165.                         MPFROM2SHORT( IDM_DATE, TRUE),
  1166.                         MPFROM2SHORT( MIA_CHECKED,
  1167.                                       ( (cp.usDispMode & DM_DATE)?  MIA_CHECKED
  1168.                                               : ~MIA_CHECKED) ) );
  1169.             WinSendMsg( hwndMenu,
  1170.                         MM_SETITEMATTR,
  1171.                         MPFROM2SHORT( IDM_TIME, TRUE),
  1172.                         MPFROM2SHORT( MIA_DISABLED,
  1173.                                       ( ((!(cp.usDispMode & DM_DATE)) || (cp.usDispMode & DM_ANALOG))?  MIA_DISABLED
  1174.                                               : ~MIA_DISABLED) ) );
  1175.             ClkSize(hwnd);
  1176.             WinInvalidateRect(hwnd,(PRECTL)NULL,TRUE);
  1177.  
  1178.             break;
  1179.         case IDM_DIGITAL:
  1180.             cp.usDispMode |=  DM_DIGITAL;
  1181.             cp.usDispMode &=  (~DM_ANALOG);
  1182.             WinSendMsg( hwndMenu,
  1183.                         MM_SETITEMATTR,
  1184.                         MPFROM2SHORT( IDM_DIGITAL, TRUE),
  1185.                         MPFROM2SHORT( MIA_CHECKED,
  1186.                                       MIA_CHECKED));
  1187.             WinSendMsg( hwndMenu,
  1188.                         MM_SETITEMATTR,
  1189.                         MPFROM2SHORT( IDM_ANALOG , TRUE),
  1190.                         MPFROM2SHORT( MIA_CHECKED,
  1191.                                      ~MIA_CHECKED));
  1192.             WinSendMsg( hwndMenu,
  1193.                         MM_SETITEMATTR,
  1194.                         MPFROM2SHORT( IDM_SECONDHAND, TRUE),
  1195.                         MPFROM2SHORT( MIA_DISABLED,
  1196.                                         MIA_DISABLED));
  1197.             WinSendMsg( hwndMenu,
  1198.                         MM_SETITEMATTR,
  1199.                         MPFROM2SHORT( IDM_TICKS, TRUE),
  1200.                         MPFROM2SHORT( MIA_DISABLED,
  1201.                                         MIA_DISABLED));
  1202.             WinSendMsg( hwndMenu,
  1203.                         MM_SETITEMATTR,
  1204.                         MPFROM2SHORT( IDM_TIME, TRUE),
  1205.                         MPFROM2SHORT( MIA_DISABLED,
  1206.                                       ( ((!(cp.usDispMode & DM_DATE)) || (cp.usDispMode & DM_ANALOG))?  MIA_DISABLED
  1207.                                               : ~MIA_DISABLED) ) );
  1208.             WinInvalidateRect(hwnd,(PRECTL)NULL,TRUE);
  1209.             break;
  1210.         case IDM_ANALOG :
  1211.             cp.usDispMode |=  DM_ANALOG;
  1212.             cp.usDispMode &=  (~DM_DIGITAL);
  1213.             WinSendMsg( hwndMenu,
  1214.                         MM_SETITEMATTR,
  1215.                         MPFROM2SHORT( IDM_ANALOG, TRUE),
  1216.                         MPFROM2SHORT( MIA_CHECKED,
  1217.                                       MIA_CHECKED));
  1218.             WinSendMsg( hwndMenu,
  1219.                         MM_SETITEMATTR,
  1220.                         MPFROM2SHORT( IDM_DIGITAL, TRUE),
  1221.                         MPFROM2SHORT( MIA_CHECKED,
  1222.                                      ~MIA_CHECKED));
  1223.             WinSendMsg( hwndMenu,
  1224.                         MM_SETITEMATTR,
  1225.                         MPFROM2SHORT( IDM_TIME, TRUE),
  1226.                         MPFROM2SHORT( MIA_DISABLED,
  1227.                                         MIA_DISABLED));
  1228.             WinSendMsg( hwndMenu,
  1229.                         MM_SETITEMATTR,
  1230.                         MPFROM2SHORT( IDM_DATE, TRUE),
  1231.                         MPFROM2SHORT( MIA_DISABLED,
  1232.                                         ~MIA_DISABLED));
  1233.  
  1234.             WinSendMsg( hwndMenu,
  1235.                         MM_SETITEMATTR,
  1236.                         MPFROM2SHORT( IDM_SECONDHAND, TRUE),
  1237.                         MPFROM2SHORT( MIA_DISABLED,
  1238.                                         ~MIA_DISABLED));
  1239.             WinSendMsg( hwndMenu,
  1240.                         MM_SETITEMATTR,
  1241.                         MPFROM2SHORT( IDM_TICKS, TRUE),
  1242.                         MPFROM2SHORT( MIA_DISABLED,
  1243.                                         ~MIA_DISABLED));
  1244.  
  1245.             cp.usDispMode |= DM_TIME;
  1246.             WinSendMsg( hwndMenu,
  1247.                         MM_SETITEMATTR,
  1248.                         MPFROM2SHORT( IDM_TIME, TRUE),
  1249.                         MPFROM2SHORT( MIA_CHECKED,
  1250.                                       MIA_CHECKED));
  1251.             WinInvalidateRect(hwnd,(PRECTL)NULL,TRUE);
  1252.             break;
  1253.  
  1254.  
  1255.         case IDM_HELPHELPFORHELP:
  1256.             HelpHelpForHelp(mp2);
  1257.             break;
  1258.  
  1259.         case IDM_HELPEXTENDED:
  1260.             HelpExtended(mp2);
  1261.             break;
  1262.  
  1263.         case IDM_HELPKEYS:
  1264.             HelpKeys(mp2);
  1265.             break;
  1266.  
  1267.         case IDM_HELPINDEX:
  1268.             HelpIndex(mp2);
  1269.             break;
  1270.  
  1271.         case IDM_HELPTUTORIAL:
  1272.             HelpTutorial(mp2);
  1273.             break;
  1274.  
  1275.         case IDM_HELPABOUT:
  1276.             HelpAbout(mp2);
  1277.             break;
  1278.  
  1279.      case IDM_ALARM_EXPIRED:
  1280.            WinMessageBox(HWND_DESKTOP,
  1281.                          hwndFrame,
  1282.                          (PSZ)"Alarm Expired",
  1283.                          (PSZ)"The Bells Are Ringing",
  1284.                          0,
  1285.                          MB_OK);
  1286.             break;
  1287.     }
  1288. }
  1289.  
  1290.  
  1291. /****************************************************************\
  1292.  *
  1293.  *--------------------------------------------------------------
  1294.  *
  1295.  *  Name:ClkHideFrameControls
  1296.  *
  1297.  *  Purpose:Hide the title bar and associted controls
  1298.  *
  1299.  *
  1300.  *
  1301.  *  Usage:
  1302.  *
  1303.  *  Method:
  1304.  *          -
  1305.  *
  1306.  *          -
  1307.  *          -
  1308.  *
  1309.  *          -
  1310.  *          -
  1311.  *
  1312.  *  Returns:
  1313.  *
  1314.  *
  1315. \****************************************************************/
  1316. VOID ClkHideFrameControls ( HWND hwndFrame )
  1317. {
  1318.  
  1319.     WinSetParent ( hwndTitleBar , HWND_OBJECT , FALSE ) ;
  1320.     WinSetParent ( hwndSysMenu , HWND_OBJECT , FALSE ) ;
  1321.     WinSetParent ( hwndMinMax , HWND_OBJECT , FALSE ) ;
  1322.     WinSetParent ( hwndMenu , HWND_OBJECT , FALSE ) ;
  1323.  
  1324.     WinSendMsg ( hwndFrame , WM_UPDATEFRAME ,
  1325.                  MPFROMLONG( FCF_TITLEBAR | FCF_SYSMENU | FCF_MINMAX | FCF_MENU ) ,
  1326.                  MPVOID) ;
  1327.  
  1328.     cp.fControlsHidden = TRUE ;
  1329. }
  1330. /****************************************************************\
  1331.  *
  1332.  *--------------------------------------------------------------
  1333.  *
  1334.  *  Name:ClkShowFrameControls
  1335.  *
  1336.  *  Purpose:Show the title bar and associated contols
  1337.  *
  1338.  *
  1339.  *
  1340.  *  Usage:
  1341.  *
  1342.  *  Method:
  1343.  *          -
  1344.  *
  1345.  *          -
  1346.  *          -
  1347.  *
  1348.  *          -
  1349.  *          -
  1350.  *
  1351.  *  Returns:
  1352.  *          VOID
  1353.  *
  1354. \****************************************************************/
  1355.  
  1356.  
  1357. VOID ClkShowFrameControls ( HWND hwndFrame )
  1358. {
  1359.  
  1360.     WinSetParent ( hwndTitleBar , hwndFrame , FALSE ) ;
  1361.     WinSetParent ( hwndSysMenu , hwndFrame , FALSE ) ;
  1362.     WinSetParent ( hwndMinMax , hwndFrame , FALSE ) ;
  1363.     WinSetParent ( hwndMenu , hwndFrame , FALSE ) ;
  1364.  
  1365.     WinSendMsg ( hwndFrame , WM_UPDATEFRAME ,
  1366.                 MPFROMLONG( FCF_TITLEBAR | FCF_SYSMENU | FCF_MINMAX | FCF_MENU ) ,
  1367.                 MPVOID) ;
  1368.     WinInvalidateRect ( hwndFrame , NULL , TRUE ) ;
  1369.  
  1370.     cp.fControlsHidden = FALSE ;
  1371. }
  1372.  
  1373.  
  1374. /****************************************************************\
  1375.  *
  1376.  *--------------------------------------------------------------
  1377.  *
  1378.  *  Name:GetArrangedDate()
  1379.  *
  1380.  *  Purpose:
  1381.  *
  1382.  *
  1383.  *
  1384.  *  Usage:
  1385.  *
  1386.  *  Method:
  1387.  *          -
  1388.  *
  1389.  *          -
  1390.  *          -
  1391.  *
  1392.  *          -
  1393.  *          -
  1394.  *
  1395.  *  Returns: VOID
  1396.  *
  1397. \****************************************************************/
  1398. VOID GetArrangedDate(CHAR achFinalDate[])
  1399. {
  1400.     time_t     tTime;
  1401.     struct tm  *pLocalTime;
  1402.  
  1403.     time(&tTime);
  1404.     pLocalTime = localtime(&tTime);
  1405.     switch (vusDateFormat)
  1406.     {
  1407.         case 2: /*YMD*/
  1408.             if (fIconic)
  1409.             {
  1410.                strftime(achFinalDate, sizeof(achFinalDate), "%m %d %y", pLocalTime);
  1411.             }
  1412.             else
  1413.             {
  1414.                strftime(achFinalDate, sizeof(achFinalDate), "%y %m %d", pLocalTime);
  1415.             }
  1416.     /*put date separators*/
  1417.             achFinalDate[2] = achFinalDate[5] = szDateSep[0];
  1418.             break;
  1419.  
  1420.         case 1: /*DMY*/
  1421.             strftime(achFinalDate, sizeof(achFinalDate), "%d %m %y", pLocalTime);
  1422.             achFinalDate[2] = achFinalDate[5] = szDateSep[0];
  1423.             break;
  1424.  
  1425.         default:
  1426.             strftime(achFinalDate, 99, "%x", pLocalTime);
  1427.             break;
  1428.     }
  1429.     achFinalDate[8] = '\0';
  1430. }
  1431.  
  1432. /****************************************************************\
  1433.  *
  1434.  *--------------------------------------------------------------
  1435.  *
  1436.  *  Name:SaveApplication()
  1437.  *
  1438.  *  Purpose:Handle the   WM_SAVEAPPLICATION message from the desktop
  1439.  *
  1440.  *
  1441.  *
  1442.  *  Usage:
  1443.  *
  1444.  *  Method:
  1445.  *          -
  1446.  *
  1447.  *          -
  1448.  *          -
  1449.  *
  1450.  *          -
  1451.  *          -
  1452.  *
  1453.  *  Returns: VOID
  1454.  *
  1455.  *
  1456. \****************************************************************/
  1457. VOID FAR SaveApplication( HWND hwnd )
  1458. {
  1459.  
  1460.     WinQueryWindowPos(hwnd, (PSWP)&cp.swp);
  1461.     PrfWriteProfileData(HINI_USER, SZ_APPNAME, SZ_KEYNAME, &cp, sizeof(cp));
  1462. }
  1463.  
  1464.  
  1465. /****************************************************************\
  1466.  *
  1467.  *--------------------------------------------------------------
  1468.  *
  1469.  *  Name: SetRGBColors
  1470.  *
  1471.  *  Purpose: Set the RGB schema so that each time a user changes the
  1472.  *           color we update it here.
  1473.  *
  1474.  *
  1475.  *  Usage:
  1476.  *
  1477.  *  Method:
  1478.  *          -
  1479.  *
  1480.  *          -
  1481.  *          -
  1482.  *
  1483.  *          -
  1484.  *          -
  1485.  *
  1486.  *  Returns:VOID
  1487.  *
  1488.  *
  1489. \****************************************************************/
  1490. VOID SetRGBColors(VOID)
  1491. {
  1492.     vclrFace[SURFACE] = cp.clrFace;
  1493.     vclrBG[SURFACE] = cp.clrBackground;
  1494.     vclrHands[SURFACE] = cp.clrMinuteHand;
  1495.     vclrMajorTicks[SURFACE] = cp.clrHourHand;
  1496.  
  1497.     /*Fill color tables*/
  1498.     ShadeLight(vclrMajorTicks);
  1499.  
  1500.     vclrMinorTicks[SURFACE] = vclrFace[SURFACE];
  1501.     ShadeLight(vclrMinorTicks);
  1502.  
  1503.     ShadeLight(vclrFace);
  1504.  
  1505.     vclrRing[SURFACE] = vclrFace[SURFACE];
  1506.     ShadeLight(vclrRing);
  1507.  
  1508.     #ifdef DISABLE
  1509.     ShadeLight(vclrHands);
  1510.     #endif
  1511.     vclrHands[SHADE] = RGB_BLACK;
  1512.  
  1513.     ShadeLight(vclrBG);
  1514. }
  1515. /****************************************************************\
  1516.  *
  1517.  *--------------------------------------------------------------
  1518.  *
  1519.  *  Name:ShadeLight()
  1520.  *
  1521.  *  Purpose: Find the shade and light color index values and
  1522.  *           install them in the colors   array of the element
  1523.  *
  1524.  *
  1525.  *
  1526.  *  Usage:
  1527.  *
  1528.  *  Method:
  1529.  *          -
  1530.  *
  1531.  *          -
  1532.  *          -
  1533.  *
  1534.  *          -
  1535.  *          -
  1536.  *
  1537.  *  Returns:
  1538.  *
  1539.  *
  1540. \****************************************************************/
  1541. VOID ShadeLight(PLONG nplColors)
  1542. {
  1543.    typedef  union  _RGBLONG
  1544.    {
  1545.         RGB rgb;
  1546.         LONG lng;
  1547.    } RGBLONG ;
  1548.    RGBLONG  rgbSurface,rgbShade,rgbLight;
  1549.  
  1550.    rgbSurface.lng = rgbShade.lng = rgbLight.lng = 0L;
  1551.  
  1552.    #ifdef DISABLE
  1553.    rgbSurface.lng = GpiQueryRGBColor(hps,0L,);
  1554.    #endif
  1555.    rgbSurface.lng = nplColors[SURFACE];
  1556.    rgbShade.rgb.bBlue = ShadeRGBByte(rgbSurface.rgb.bBlue);
  1557.    rgbShade.rgb.bRed = ShadeRGBByte(rgbSurface.rgb.bRed);
  1558.    rgbShade.rgb.bGreen = ShadeRGBByte(rgbSurface.rgb.bGreen);
  1559.    rgbLight.rgb.bBlue = LightRGBByte(rgbSurface.rgb.bBlue);
  1560.    rgbLight.rgb.bRed = LightRGBByte(rgbSurface.rgb.bRed);
  1561.    rgbLight.rgb.bGreen = LightRGBByte(rgbSurface.rgb.bGreen);
  1562.    nplColors[SHADE] = rgbShade.lng;
  1563.    nplColors[LIGHT] = rgbLight.lng;
  1564. }
  1565.  
  1566.  
  1567. /****************************************************************\
  1568.  *
  1569.  *--------------------------------------------------------------
  1570.  *
  1571.  *  Name:ShadeRGBByte
  1572.  *
  1573.  *  Purpose:
  1574.  *
  1575.  *
  1576.  *
  1577.  *  Usage:
  1578.  *
  1579.  *  Method:
  1580.  *          -
  1581.  *
  1582.  *          -
  1583.  *          -
  1584.  *
  1585.  *          -
  1586.  *          -
  1587.  *
  1588.  *  Returns:
  1589.  *
  1590.  *
  1591. \****************************************************************/
  1592.  
  1593. BYTE ShadeRGBByte(BYTE brgb)
  1594. {
  1595.   #define SHADER   ( (BYTE) 0x50)
  1596.  
  1597.   if (brgb > SHADER)
  1598.   {
  1599.      return (brgb - SHADER);
  1600.   }
  1601.   else
  1602.   {
  1603.      return (0);
  1604.   }
  1605.  
  1606. }
  1607. /****************************************************************\
  1608.  *
  1609.  *--------------------------------------------------------------
  1610.  *
  1611.  *  Name:LightRGBByte
  1612.  *
  1613.  *  Purpose:
  1614.  *
  1615.  *
  1616.  *
  1617.  *  Usage:
  1618.  *
  1619.  *  Method:
  1620.  *          -
  1621.  *
  1622.  *          -
  1623.  *          -
  1624.  *
  1625.  *          -
  1626.  *          -
  1627.  *
  1628.  *  Returns:
  1629.  *
  1630.  *
  1631. \****************************************************************/
  1632. BYTE LightRGBByte(BYTE brgb)
  1633. {
  1634.  
  1635.   #define LIGHTER  ( (BYTE) 0x40)
  1636.  
  1637.   if (brgb < (0xff - LIGHTER) )
  1638.   {
  1639.      return (brgb + LIGHTER);
  1640.   }
  1641.  
  1642.   else return (0xff);
  1643.  
  1644. }
  1645.  
  1646.  
  1647.  
  1648. /****************************************************************\
  1649.  *  Menu item intialization routine
  1650.  *--------------------------------------------------------------
  1651.  *
  1652.  *  Name:   InitMenu(mp1, mp2)
  1653.  *
  1654.  *  Purpose: Processes the WM_INITMENU message for the main window,
  1655.  *              disabling any menus that are not active
  1656.  *
  1657.  *  Usage:  Routine is called each time a menu is dropped
  1658.  *
  1659.  *  Method: A switch statement branches control based upon
  1660.  *          the id of the menu that is being displayed
  1661.  *
  1662.  *  Returns:
  1663. \****************************************************************/
  1664. VOID InitMenu(MPARAM mp1, MPARAM mp2)
  1665. {
  1666.  
  1667.     /* define a shorthand way of denoting the menu handle */
  1668.     #define hwndMenu        HWNDFROMMP(mp2)
  1669.  
  1670.     switch(SHORT1FROMMP(mp1))
  1671.     {
  1672.  
  1673.         case IDM_HELP:
  1674.             /*
  1675.              * Enable or disable the Help menu depending upon whether the
  1676.              * help manager has been enabled
  1677.              */
  1678.             EnableMenuItem(hwndMenu, IDM_HELPHELPFORHELP, fHelpEnabled);
  1679.             EnableMenuItem(hwndMenu, IDM_HELPEXTENDED, fHelpEnabled);
  1680.             EnableMenuItem(hwndMenu, IDM_HELPKEYS, fHelpEnabled);
  1681.             EnableMenuItem(hwndMenu, IDM_HELPINDEX, fHelpEnabled);
  1682.  
  1683.             /** REMEMBER: add a case for IDM_HELPTUTORIAL if you include
  1684.                 the Tutorial menu item   **/
  1685.  
  1686.             break;
  1687.  
  1688.         default:
  1689.             break;
  1690.     }
  1691.  
  1692.     #undef hwndMenu
  1693.  
  1694. }   /* InitMenu() */
  1695.  
  1696.  
  1697. /****************************************************************\
  1698.  *  Enables/Disables the menu item of the given menu
  1699.  *--------------------------------------------------------------
  1700.  *
  1701.  *  Name:   EnableMenuItem(hwndMenu, idItem, fEnable)
  1702.  *
  1703.  *  Purpose: Enables or disables the menu item
  1704.  *
  1705.  *  Usage:  Called whenever a menu item is to be enabled or
  1706.  *          disabled
  1707.  *
  1708.  *  Method: Sends a MM_SETITEMATTR to the menu with the
  1709.  *          given item id.  Sets the MIA_DISABLED attribute
  1710.  *          flag if the item is to be disabled, clears the flag
  1711.  *          if enabling
  1712.  *
  1713.  *  Returns:
  1714.  *
  1715. \****************************************************************/
  1716. VOID EnableMenuItem(HWND hwndMenu, SHORT idItem, BOOL fEnable)
  1717. {
  1718.     SHORT fsFlag;
  1719.  
  1720.     if(fEnable)
  1721.         fsFlag = 0;
  1722.     else
  1723.         fsFlag = MIA_DISABLED;
  1724.  
  1725.     WinSendMsg(hwndMenu,
  1726.                MM_SETITEMATTR,
  1727.                MPFROM2SHORT(idItem, TRUE),
  1728.                MPFROM2SHORT(MIA_DISABLED, fsFlag));
  1729.  
  1730. }   /* EnableMenuItem() */
  1731.  
  1732.  
  1733. /*--------------------------------------------------------------*\
  1734.  *  End of file :wndproc.c
  1735. \*--------------------------------------------------------------*/
  1736.