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