home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / PMASC.ZIP / PMASC.C < prev    next >
Text File  |  1990-01-11  |  14KB  |  348 lines

  1. /*-------------------------------------------------------------------
  2.    PMASC.C -- ASCII (and EBCDIC) Table for OS/2 Presentation Manager
  3.               (c) 1989, Ziff Communications Co.
  4.               PC Magazine * Charles Petzold, March 1989
  5.   -------------------------------------------------------------------*/
  6.  
  7. #define INCL_WIN
  8. #define INCL_GPI
  9. #include <os2.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include "pmasc.h"
  13.  
  14. MRESULT EXPENTRY ClientWndProc (HWND, USHORT, MPARAM, MPARAM) ;
  15. MRESULT EXPENTRY AboutDlgProc  (HWND, USHORT, MPARAM, MPARAM) ;
  16.  
  17. int main (void)
  18.      {
  19.      static CHAR  szClientClass[] = "PMASC" ;
  20.      static ULONG flFrameFlags = FCF_SYSMENU | FCF_TITLEBAR   |
  21.                                  FCF_BORDER  | FCF_MINBUTTON  |
  22.                                  FCF_MENU    | FCF_VERTSCROLL |
  23.                                  FCF_ICON    | FCF_TASKLIST ;
  24.      HAB          hab ;
  25.      HMQ          hmq ;
  26.      HWND         hwndFrame, hwndClient ;
  27.      QMSG         qmsg ;
  28.  
  29.      hab = WinInitialize (0) ;
  30.      hmq = WinCreateMsgQueue (hab, 0) ;
  31.  
  32.      WinRegisterClass (hab, szClientClass, ClientWndProc, 0L, 0) ;
  33.  
  34.      hwndFrame = WinCreateStdWindow (HWND_DESKTOP, WS_VISIBLE,
  35.                                      &flFrameFlags, szClientClass, NULL,
  36.                                      0L, NULL, ID_RESOURCE, &hwndClient) ;
  37.  
  38.      while (WinGetMsg (hab, &qmsg, NULL, 0, 0))
  39.           WinDispatchMsg (hab, &qmsg) ;
  40.  
  41.      WinDestroyWindow (hwndFrame) ;
  42.      WinDestroyMsgQueue (hmq) ;
  43.      WinTerminate (hab) ;
  44.      return 0 ;
  45.      }
  46.  
  47. MRESULT EXPENTRY ClientWndProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  48.      {
  49.      static CHAR   *szHeading[] = { "Dec", "Hex", "Char" },
  50.                    achHex[] = "0123456789ABCDEF" ;
  51.      static HWND   hwndFrame, hwndMenu, hwndScroll ;
  52.      static RECTL  rcl ;
  53.      static SHORT  sScroll, cxChar, cyChar, cyDesc ;
  54.      static USHORT usDefCodePage, usSelCodePage ;
  55.      CHAR          szBuffer[40] ;
  56.      FONTMETRICS   fm ;
  57.      POINTL        ptl, aptlText[TXTBOX_COUNT] ;
  58.      HPS           hps ;
  59.      RECTL         rclInvalid ;
  60.      SHORT         sLineBeg, sLineEnd, sLine, sCol, sNum, i, j ;
  61.  
  62.      switch (msg)
  63.           {
  64.           case WM_CREATE:
  65.                hps = WinGetPS (hwnd) ;
  66.                usDefCodePage = GpiQueryCp (hps) ;
  67.                usSelCodePage = usDefCodePage ;
  68.  
  69.                          // Get text dimensions
  70.  
  71.                GpiQueryFontMetrics (hps, (LONG) sizeof fm, &fm) ;
  72.                cxChar = (SHORT) fm.lAveCharWidth ;
  73.                cyChar = (SHORT) fm.lMaxBaselineExt ;
  74.                cyDesc = (SHORT) fm.lMaxDescender ;
  75.                WinReleasePS (hps) ;
  76.  
  77.                          // Get handles of scroll bar and menu windows
  78.  
  79.                hwndFrame  = WinQueryWindow (hwnd, QW_PARENT, FALSE) ;
  80.                hwndScroll = WinWindowFromID (hwndFrame, FID_VERTSCROLL) ;
  81.                hwndMenu   = WinWindowFromID (hwndFrame, FID_MENU) ;
  82.  
  83.                          // Set scroll bar range
  84.  
  85.                WinSendMsg (hwndScroll, SBM_SETSCROLLBAR,
  86.                            MPFROMSHORT (0), MPFROM2SHORT (0, 224)) ;
  87.  
  88.                          // Put check mark in menu for current code page
  89.  
  90.                WinSendMsg (hwndMenu, MM_SETITEMATTR,
  91.                            MPFROM2SHORT (usSelCodePage, TRUE),
  92.                            MPFROM2SHORT (MIA_CHECKED, MIA_CHECKED)) ;
  93.  
  94.                          // Calculate client window size and position
  95.  
  96.                rcl.xLeft   = (WinQuerySysValue (HWND_DESKTOP, SV_CXSCREEN) -
  97.                                            36 * cxChar) / 2 ;
  98.                rcl.yBottom = (WinQuerySysValue (HWND_DESKTOP, SV_CYSCREEN) -
  99.                                            18 * cyChar) / 2 ;
  100.                rcl.xRight  = rcl.xLeft   + 36 * cxChar ;
  101.                rcl.yTop    = rcl.yBottom + 18 * cyChar ;
  102.  
  103.                          // Set frame window position and size
  104.  
  105.                WinCalcFrameRect (hwndFrame, &rcl, FALSE) ;
  106.                WinSetWindowPos  (hwndFrame, NULL,
  107.                                  (SHORT) rcl.xLeft, (SHORT) rcl.yBottom,
  108.                                  (SHORT) (rcl.xRight - rcl.xLeft),
  109.                                  (SHORT) (rcl.yTop - rcl.yBottom),
  110.                                  SWP_MOVE | SWP_SIZE | SWP_ACTIVATE) ;
  111.  
  112.                          // Rectangle of table (without heading)
  113.  
  114.                rcl.xLeft   = 0 ;
  115.                rcl.yBottom = 0 ;
  116.                rcl.xRight  = 36 * cxChar ;
  117.                rcl.yTop    = 16 * cyChar ;
  118.                return 0 ;
  119.  
  120.           case WM_VSCROLL:
  121.                switch (SHORT2FROMMP (mp2))
  122.                     {
  123.                               // Scroll bar line up or down: Scroll window
  124.  
  125.                     case SB_LINEUP:
  126.                          if (sScroll > 0)
  127.                               {
  128.                               sScroll-- ;
  129.                               WinScrollWindow (hwnd, 0, -cyChar, &rcl, &rcl,
  130.                                                NULL, NULL, SW_INVALIDATERGN) ;
  131.                               }
  132.                          break ;
  133.  
  134.                     case SB_LINEDOWN:
  135.                          if (sScroll < 224)
  136.                               {
  137.                               sScroll++ ;
  138.                               WinScrollWindow (hwnd, 0, cyChar, &rcl, &rcl,
  139.                                                NULL, NULL, SW_INVALIDATERGN) ;
  140.                               }
  141.                          break ;
  142.  
  143.                               // Scroll bar page up or down: Invalidate window
  144.  
  145.                     case SB_PAGEUP:
  146.                          if (sScroll > 0)
  147.                               {
  148.                               sScroll = max (0, sScroll - 32) ;
  149.                               WinInvalidateRect (hwnd, &rcl, FALSE) ;
  150.                               }
  151.                          break ;
  152.  
  153.                     case SB_PAGEDOWN:
  154.                          if (sScroll < 224)
  155.                               {
  156.                               sScroll = min (224, sScroll + 32) ;
  157.                               WinInvalidateRect (hwnd, &rcl, FALSE) ;
  158.                               }
  159.                          break ;
  160.  
  161.                     case SB_SLIDERPOSITION:
  162.                          if (sScroll != SHORT1FROMMP (mp2))
  163.                               {
  164.                               sScroll = SHORT1FROMMP (mp2) ;
  165.                               WinInvalidateRect (hwnd, &rcl, FALSE) ;
  166.                               }
  167.                          break ;
  168.  
  169.                     default:
  170.                          return 0 ;
  171.                     }
  172.  
  173.                WinSendMsg (hwndScroll, SBM_SETPOS,
  174.                                        MPFROMSHORT (sScroll), NULL) ;
  175.                return 0 ;
  176.  
  177.                     // Keyboard messages: Mimic scroll bar
  178.  
  179.           case WM_CHAR:
  180.                switch (CHARMSG(&msg)->vkey)
  181.                     {
  182.                     case VK_HOME:
  183.                          return WinSendMsg (hwnd, WM_VSCROLL, NULL,
  184.                                    MPFROM2SHORT (0, SB_SLIDERPOSITION)) ;
  185.                     case VK_END:
  186.                          return WinSendMsg (hwnd, WM_VSCROLL, NULL,
  187.                                    MPFROM2SHORT (224, SB_SLIDERPOSITION)) ;
  188.                     default:
  189.                          return WinSendMsg (hwndScroll, msg, mp1, mp2) ;
  190.                     }
  191.  
  192.                     // Menu messages: Invoke "About" box or set new code page
  193.  
  194.           case WM_COMMAND:
  195.                if (COMMANDMSG(&msg)->cmd == IDM_ABOUT)
  196.                     WinDlgBox (HWND_DESKTOP, hwnd, AboutDlgProc,
  197.                                NULL, IDD_ABOUT, NULL) ;
  198.                else
  199.                     {
  200.                     WinSendMsg (hwndMenu, MM_SETITEMATTR,
  201.                                 MPFROM2SHORT (usSelCodePage, TRUE),
  202.                                 MPFROM2SHORT (MIA_CHECKED, 0)) ;
  203.  
  204.                     hps = WinGetPS (hwnd) ;
  205.                     GpiSetCp (hps, COMMANDMSG(&msg)->cmd) ;
  206.                     usSelCodePage = GpiQueryCp (hps) ;
  207.                     GpiSetCp (hps, usDefCodePage) ;
  208.                     WinReleasePS (hps) ;
  209.  
  210.                     WinSendMsg (hwndMenu, MM_SETITEMATTR,
  211.                                 MPFROM2SHORT (usSelCodePage, TRUE),
  212.                                 MPFROM2SHORT (MIA_CHECKED, MIA_CHECKED)) ;
  213.  
  214.                     WinInvalidateRect (hwnd, NULL, FALSE) ;
  215.                     }
  216.                return 0 ;
  217.  
  218.           case WM_PAINT:
  219.                hps = WinBeginPaint (hwnd, NULL, &rclInvalid) ;
  220.                WinFillRect (hps, &rclInvalid, CLR_WHITE) ;
  221.  
  222.                          // Draw lines in window
  223.  
  224.                GpiSetColor (hps, CLR_BLACK) ;
  225.  
  226.                ptl.x = rcl.xRight / 2 ;  ptl.y = 0 ;  GpiMove (hps, &ptl) ;
  227.                ptl.y = rcl.yTop + cyChar ;            GpiLine (hps, &ptl) ;
  228.                ptl.x = 0 ;  ptl.y = rcl.yTop ;        GpiMove (hps, &ptl) ;
  229.                ptl.x = rcl.xRight ;                   GpiLine (hps, &ptl) ;
  230.  
  231.                          // Determine text line range within invalid rectangle
  232.  
  233.                sLineBeg = (SHORT) (16 - (rclInvalid.yTop+cyChar-1) / cyChar) ;
  234.                sLineEnd = (SHORT) (16 -  rclInvalid.yBottom        / cyChar) ;
  235.  
  236.                for (sLine = sLineBeg ; sLine < sLineEnd ; sLine++)
  237.                     {
  238.                     ptl.y = (15 - sLine) * cyChar + cyDesc ;
  239.  
  240.                               // Display codepage name
  241.  
  242.                     if (sLine == -2)
  243.                          {
  244.                          GpiSetColor (hps, CLR_RED) ;
  245.  
  246.                          WinSendMsg (hwndMenu, MM_QUERYITEMTEXT,
  247.                                      MPFROM2SHORT (usSelCodePage,
  248.                                                    (SHORT) sizeof (szBuffer)),
  249.                                      szBuffer) ;
  250.  
  251.                                         // Strip out '~' character
  252.  
  253.                          for (i = 0, j = 0 ; szBuffer[j] != '\0' ; )
  254.                               if (szBuffer[i++] != '~')
  255.                                    szBuffer[j++] = szBuffer[i-1] ;
  256.  
  257.                                         // Display centered text
  258.  
  259.                          GpiQueryTextBox (hps, (LONG) strlen (szBuffer),
  260.                                           szBuffer, TXTBOX_COUNT, aptlText) ;
  261.  
  262.                          ptl.x = (rcl.xRight - aptlText[TXTBOX_CONCAT].x) / 2 ;
  263.                          GpiCharStringAt (hps, &ptl, (LONG) strlen (szBuffer),
  264.                                           szBuffer) ;
  265.                          }
  266.  
  267.                               // Display heading
  268.  
  269.                     else if (sLine == -1)
  270.                          {
  271.                          GpiSetColor (hps, CLR_BLUE) ;
  272.  
  273.                          for (sCol = 0 ; sCol < 6 ; sCol++)
  274.                               {
  275.                               ptl.x = cxChar * (5 * sCol + (sCol > 2 ? 4 : 2));
  276.  
  277.                               GpiCharStringAt (hps, &ptl,
  278.                                    (LONG) strlen (szHeading[sCol % 3]),
  279.                                    szHeading[sCol % 3]) ;
  280.                               }
  281.                          }
  282.                     else
  283.                          {
  284.                          GpiSetColor (hps, CLR_BLACK) ;
  285.  
  286.                          for (sCol = 0 ; sCol < 6 ; sCol++)
  287.                               {
  288.                               ptl.x = cxChar * (5 * sCol + (sCol > 2 ? 4 : 2));
  289.                               sNum = sScroll + sLine + (sCol > 2 ? 16 : 0) ;
  290.  
  291.                                         // Decimal ASCII/EBCDIC code
  292.  
  293.                               if (sCol % 3 == 0)
  294.                                    {
  295.                                    szBuffer[0] = (CHAR) ('0' + sNum/100) ;
  296.                                    szBuffer[1] = (CHAR) ('0' + sNum%100/10) ;
  297.                                    szBuffer[2] = (CHAR) ('0' + sNum%10) ;
  298.                                    szBuffer[3] = '\0' ;
  299.                                    }
  300.                                         // Hexadecimal ASCII/EBCDIC code
  301.  
  302.                               else if (sCol % 3 == 1)
  303.                                    {
  304.                                    szBuffer[0] = ' ' ;
  305.                                    szBuffer[1] = achHex[sNum >> 4] ;
  306.                                    szBuffer[2] = achHex[sNum & 15] ;
  307.                                    szBuffer[3] = '\0' ;
  308.                                    }
  309.                                         // ASCII/EBCDIC character
  310.                               else
  311.                                    {
  312.                                    szBuffer[0] = ' ' ;
  313.                                    szBuffer[1] = (CHAR) sNum ;
  314.                                    szBuffer[2] = '\0' ;
  315.  
  316.                                    GpiSetCp (hps, usSelCodePage) ;
  317.                                    }
  318.  
  319.                               GpiCharStringAt (hps, &ptl,
  320.                                         (LONG) strlen (szBuffer), szBuffer) ;
  321.  
  322.                               GpiSetCp (hps, usDefCodePage) ;
  323.                               }
  324.                          }
  325.                     }
  326.                WinEndPaint (hps) ;
  327.                return 0 ;
  328.           }
  329.      return WinDefWindowProc (hwnd, msg, mp1, mp2) ;
  330.      }
  331.  
  332. MRESULT EXPENTRY AboutDlgProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  333.      {
  334.      switch (msg)
  335.           {
  336.           case WM_COMMAND:
  337.                switch (COMMANDMSG(&msg)->cmd)
  338.                     {
  339.                     case DID_OK:
  340.                     case DID_CANCEL:
  341.                          WinDismissDlg (hwnd, TRUE) ;
  342.                          return 0 ;
  343.                     }
  344.                break ;
  345.           }
  346.      return WinDefDlgProc (hwnd, msg, mp1, mp2) ;
  347.      }
  348.