home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast.iso / pcmag / vol11n19.zip / DIGIT.C < prev    next >
Text File  |  1992-09-22  |  20KB  |  683 lines

  1. //========================================================================
  2. // 
  3. //  DIGIT.C - DLL that creates a Digit Class
  4. //
  5. //  (c) Douglas Boling 1992
  6. //
  7. //  For better readability, set tab stops to every 3 characters.
  8. //
  9. //========================================================================
  10.  
  11. #include <windows.h>
  12. #include <custcntl.h>
  13. #include <string.h>
  14. #include "digit.h"
  15.  
  16. typedef struct {
  17.     int    sValue;
  18.     int    sBase;
  19. } DIGITDATA;
  20. typedef DIGITDATA *    PDIGITDATA;
  21.  
  22. //------------------------------------------------------------------------
  23. // Function prototypes
  24. //------------------------------------------------------------------------
  25. BOOL FAR PASCAL DigitDlgFn (HWND, WORD, WORD, LONG);
  26. long FAR PASCAL DigitWndFn (HWND, WORD, WORD, LONG);
  27. BOOL FAR PASCAL AboutDlgProc (HWND, WORD, WORD, LONG);
  28.  
  29. //------------------------------------------------------------------------
  30. // Globals
  31. //------------------------------------------------------------------------
  32. HANDLE        hInstance;
  33. BOOL            bDigitRegistered = FALSE;
  34. HANDLE        hCtlStyle;
  35. LPFNSTRTOID lpfnStr2ID;
  36. LPFNIDTOSTR lpfnID2Str;
  37.  
  38.  
  39. #define    NUMSTYLES   4
  40. struct {
  41.     DWORD    dwStyle;
  42.     char    szLabel[20];
  43. } ssStyleTags [NUMSTYLES] = {
  44.                      {DIGS_LED, DIGS_LEDSTR},
  45.                      {DIGS_BLANK, DIGS_BLANKSTR},
  46.                      {DIGS_COLON, DIGS_COLONSTR},
  47.                      {DIGS_DECIMAL, DIGS_DECIMALSTR}
  48.                     };
  49.  
  50. //------------------------------------------------------------------------
  51. // LibMain (DigitInit) - Control initialization routine
  52. //------------------------------------------------------------------------
  53. int FAR PASCAL LibMain (HANDLE hInst, WORD wDataSeg, WORD wHeapSize,
  54.                          LPSTR lpszCmdLine) {
  55.    WNDCLASS    wndclass;
  56.     hInstance = hInst;
  57.  
  58.     if (!bDigitRegistered) {
  59.       wndclass.style          = CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS;
  60.       wndclass.lpfnWndProc    = (FARPROC) DigitWndFn;
  61.       wndclass.cbClsExtra     = 0;
  62.       wndclass.cbWndExtra     = sizeof (PDIGITDATA);
  63.       wndclass.hInstance      = hInstance;
  64.       wndclass.hIcon          = NULL;
  65.       wndclass.hCursor        = LoadCursor (NULL, IDC_ARROW);
  66.       wndclass.hbrBackground  = GetStockObject (BLACK_BRUSH);
  67.       wndclass.lpszMenuName   = NULL;
  68.       wndclass.lpszClassName  = DIGITCLASS;
  69.       
  70.       bDigitRegistered = RegisterClass (&wndclass);
  71.    }
  72.     return bDigitRegistered;
  73. }
  74. //------------------------------------------------------------------------
  75. // WEP - DLL termination routine
  76. //------------------------------------------------------------------------
  77. int FAR PASCAL WEP (int nParameter) {
  78.  
  79.     if (bDigitRegistered) {
  80.         UnregisterClass (DIGITCLASS, hInstance);
  81.         bDigitRegistered = FALSE;
  82.     }
  83.     return 1;
  84. }
  85.  
  86. //------------------------------------------------------------------------
  87. // DigitInfo - Returns basic info about control
  88. //------------------------------------------------------------------------
  89. HANDLE FAR PASCAL DigitInfo () {
  90.                
  91.     HANDLE         hCtlInfo;
  92.     LPCTLINFO    lpCtlInfo;
  93.  
  94.     hCtlInfo = GlobalAlloc (GHND | GMEM_SHARE, sizeof (CTLINFO));
  95.     if (hCtlInfo != 0) {
  96.  
  97.         lpCtlInfo = (LPCTLINFO) GlobalLock (hCtlInfo);
  98.         lpCtlInfo->wVersion = 0x10;
  99.         lpCtlInfo->wCtlTypes = 1;
  100.         lstrcpy (lpCtlInfo->szClass, DIGITCLASS);
  101.         lstrcpy (lpCtlInfo->szTitle, "Digit - Copyright 1992 Douglas Boling");
  102.  
  103.         lpCtlInfo->Type->wType = 0;
  104.         lpCtlInfo->Type->wWidth = 16;
  105.         lpCtlInfo->Type->wHeight = 24;
  106.         lpCtlInfo->Type->dwStyle = WS_CHILD;
  107.         lstrcpy (lpCtlInfo->Type->szDescr, "Digit Control");
  108.  
  109.         GlobalUnlock (hCtlInfo);
  110.     }
  111.     return hCtlInfo;
  112. }
  113.  
  114. //------------------------------------------------------------------------
  115. // DigitStyle - Displays the Style Dialog box (in Dialog editor) for the
  116. //              control.
  117. //------------------------------------------------------------------------
  118. BOOL FAR PASCAL DigitStyle (HWND hWnd, HANDLE hCtlStyle, 
  119.                             LPFNSTRTOID lpfnStrToId,
  120.                                      LPFNIDTOSTR lpfnIdToStr) {
  121.     WORD            rc;
  122.     FARPROC        lpfnDigitDlgFn;
  123.  
  124.     lpfnStr2ID = lpfnStrToId;
  125.     lpfnID2Str = lpfnIdToStr;
  126.  
  127.     lpfnDigitDlgFn = MakeProcInstance (DigitDlgFn, hInstance);
  128.     rc = DialogBoxParam (hInstance, "Style", hWnd, lpfnDigitDlgFn, 
  129.                          (LONG) hCtlStyle);
  130.     FreeProcInstance (lpfnDigitDlgFn);
  131.  
  132.     if (rc == 0) hCtlStyle = 0;
  133.     return hCtlStyle;
  134. }
  135.  
  136. //------------------------------------------------------------------------
  137. // DigitDlgFn - The Dialog box proc for the Style dialog box
  138. //------------------------------------------------------------------------
  139. BOOL FAR PASCAL DigitDlgFn (HWND hWnd, WORD message, WORD wParam, 
  140.                             LONG lParam) {
  141.  
  142.     static        DWORD        dwMyStyle;
  143.  
  144.     LPCTLSTYLE    lpCtlStyle;
  145.     WORD            wMyCtlID, rc;
  146.     DWORD            dwRC;
  147.     char            szTemp[64];
  148.  
  149.     switch (message) {
  150.  
  151.         case WM_INITDIALOG:
  152.  
  153.             hCtlStyle = (HANDLE) lParam;
  154.             lpCtlStyle = (LPCTLSTYLE) GlobalLock (hCtlStyle);
  155.             //
  156.             // Different from Docs.  It appears that user defined
  157.             // styles should be in the low word.
  158.             //
  159.             dwMyStyle = lpCtlStyle->dwStyle; 
  160.             wMyCtlID = lpCtlStyle->wId;
  161.  
  162.             rc = lpfnID2Str (wMyCtlID, szTemp, sizeof (szTemp));
  163.             if (rc) 
  164.                 SetDlgItemText (hWnd, IDD_CTLID, szTemp);
  165.             else
  166.                 SetDlgItemInt (hWnd, IDD_CTLID, wMyCtlID, FALSE);
  167.  
  168.             if (dwMyStyle & DIGS_BLANK)
  169.                 CheckDlgButton (hWnd, IDD_BLANK, TRUE);
  170.             else
  171.                 CheckDlgButton (hWnd, IDD_BLANK, FALSE);
  172.  
  173.             if (dwMyStyle & DIGS_COLON)
  174.                 CheckDlgButton (hWnd, IDD_COLON, TRUE);
  175.             else
  176.                 CheckDlgButton (hWnd, IDD_COLON, FALSE);
  177.  
  178.             if (dwMyStyle & DIGS_DECIMAL)
  179.                 CheckDlgButton (hWnd, IDD_DECIMAL, TRUE);
  180.             else
  181.                 CheckDlgButton (hWnd, IDD_DECIMAL, FALSE);
  182.  
  183.             if (dwMyStyle & DIGS_LED)
  184.                 CheckRadioButton (hWnd, IDD_LED, IDD_LCD, IDD_LED);
  185.             else
  186.                 CheckRadioButton (hWnd, IDD_LED, IDD_LCD, IDD_LCD);
  187.  
  188.             GlobalUnlock (hCtlStyle);
  189.  
  190.             return TRUE;
  191.  
  192.         case WM_COMMAND:
  193.             switch (wParam) {
  194.  
  195.                 case IDD_ABOUT:
  196.                     {
  197.                         FARPROC    lpfnAboutDlgFn;
  198.  
  199.                         lpfnAboutDlgFn = MakeProcInstance (AboutDlgProc, hInstance);
  200.                         DialogBox (hInstance, "About", hWnd, lpfnAboutDlgFn);
  201.                         FreeProcInstance (lpfnAboutDlgFn);
  202.                     }
  203.                     break;
  204.  
  205.                 case IDD_LED:
  206.                 case IDD_LCD:
  207.                     CheckRadioButton (hWnd, IDD_LED, IDD_LCD, wParam);
  208.                     break;
  209.  
  210.                 case IDOK:
  211.  
  212.                     lpCtlStyle = (LPCTLSTYLE) GlobalLock (hCtlStyle);
  213.  
  214.                     GetDlgItemText (hWnd, IDD_CTLID, szTemp, sizeof (szTemp));
  215.                     dwRC = lpfnStr2ID (szTemp);
  216.  
  217.                     if (LOWORD (dwRC)) 
  218.                         lpCtlStyle->wId = HIWORD (dwRC);
  219.                     else {
  220.                         GlobalUnlock (hCtlStyle);
  221.                         break;
  222.                     }                    
  223.                 
  224.                     dwMyStyle = 0;
  225.                     if (IsDlgButtonChecked (hWnd, IDD_BLANK))
  226.                         dwMyStyle |= DIGS_BLANK;
  227.                     else
  228.                         dwMyStyle &= ~DIGS_BLANK;
  229.  
  230.                     if (IsDlgButtonChecked (hWnd, IDD_COLON))
  231.                         dwMyStyle |= DIGS_COLON;
  232.                     else
  233.                         dwMyStyle &= ~DIGS_COLON;
  234.  
  235.                     if (IsDlgButtonChecked (hWnd, IDD_DECIMAL))
  236.                         dwMyStyle |= DIGS_DECIMAL;
  237.                     else
  238.                         dwMyStyle &= ~DIGS_DECIMAL;
  239.  
  240.                     if (IsDlgButtonChecked (hWnd, IDD_LED))
  241.                         dwMyStyle |= DIGS_LED;
  242.                     else
  243.                         dwMyStyle &= ~DIGS_LED;
  244.  
  245.                     lpCtlStyle->dwStyle &= 0xffff0000;
  246.                     lpCtlStyle->dwStyle |= dwMyStyle;
  247.  
  248.                     GlobalUnlock (hCtlStyle);
  249.  
  250.                     EndDialog (hWnd, TRUE);
  251.                     break;
  252.                     
  253.                 case IDCANCEL:
  254.                     EndDialog (hWnd, FALSE);
  255.                     break;
  256.             }
  257.             return TRUE;
  258.  
  259.         case WM_CLOSE:
  260.             EndDialog (hWnd, FALSE);
  261.             return TRUE;
  262.     }
  263.     return FALSE;
  264. }
  265.  
  266. //------------------------------------------------------------------------
  267. // DigitFlags - Translates the class style flags provided into a
  268. //              corresponding text string for the .RC file.
  269. //------------------------------------------------------------------------
  270. WORD FAR PASCAL DigitFlags (DWORD dwFlags, LPSTR lpStyle, WORD wMaxString) {
  271.  
  272.     WORD    wChars, i, sLen;
  273.  
  274.     lpStyle[0] = 0;
  275.     wChars = 0;
  276.  
  277.     for (i = 0; i < NUMSTYLES; i++) {
  278.         if (dwFlags & ssStyleTags[i].dwStyle) {
  279.             sLen = strlen (ssStyleTags[i].szLabel);
  280.             if (wChars) {
  281.                 if (wMaxString > wChars + sLen + 3) {
  282.                     lstrcat (lpStyle, " | ");
  283.                     lstrcat (lpStyle, ssStyleTags[i].szLabel);
  284.                     sLen += 3;
  285.                 } else {
  286.                     return 0;
  287.                 }
  288.             } else {
  289.                 if (wMaxString > wChars + sLen) {
  290.                     lstrcpy (lpStyle, ssStyleTags[i].szLabel);
  291.                 } else {
  292.                     return 0;
  293.                 }
  294.             }
  295.             wChars += sLen;
  296.         }
  297.     }
  298.     return lstrlen (lpStyle);
  299. }
  300.  
  301. //------------------------------------------------------------------------
  302. //Routines used to draw LED segments
  303. //------------------------------------------------------------------------
  304. void DrawTop (HDC hdc, WORD xUnit, WORD yUnit, WORD wPenWidth) {
  305.     MoveTo (hdc, xUnit*3 + wPenWidth, yUnit*1 + wPenWidth);
  306.     LineTo (hdc, xUnit*6 + wPenWidth, yUnit*1 + wPenWidth);
  307. }
  308. void DrawMid (HDC hdc, WORD xUnit, WORD yUnit, WORD wPenWidth) {
  309.     MoveTo (hdc, xUnit*3 + wPenWidth, yUnit*6 + wPenWidth);
  310.     LineTo (hdc, xUnit*6 + wPenWidth, yUnit*6 + wPenWidth);
  311. }
  312. void DrawBot (HDC hdc, WORD xUnit, WORD yUnit, WORD wPenWidth) {
  313.     MoveTo (hdc, xUnit*3 + wPenWidth, yUnit*11 + wPenWidth);
  314.     LineTo (hdc, xUnit*6 + wPenWidth, yUnit*11 + wPenWidth);
  315. }
  316. void DrawRTop (HDC hdc, WORD xUnit, WORD yUnit, WORD wPenWidth) {
  317.     MoveTo (hdc, xUnit*7 + wPenWidth, yUnit*2 + wPenWidth);
  318.     LineTo (hdc, xUnit*7 + wPenWidth, yUnit*5 + wPenWidth);
  319. }
  320. void DrawRBot (HDC hdc, WORD xUnit, WORD yUnit, WORD wPenWidth) {
  321.     MoveTo (hdc, xUnit*7 + wPenWidth, yUnit*7 + wPenWidth);
  322.     LineTo (hdc, xUnit*7 + wPenWidth, yUnit*10 + wPenWidth);
  323. }
  324. void DrawLTop (HDC hdc, WORD xUnit, WORD yUnit, WORD wPenWidth) {
  325.     MoveTo (hdc, xUnit*2 + wPenWidth, yUnit*2 + wPenWidth);
  326.     LineTo (hdc, xUnit*2 + wPenWidth, yUnit*5 + wPenWidth);
  327. }
  328. void DrawLBot (HDC hdc, WORD xUnit, WORD yUnit, WORD wPenWidth) {
  329.     MoveTo (hdc, xUnit*2 + wPenWidth, yUnit*7 + wPenWidth);
  330.     LineTo (hdc, xUnit*2 + wPenWidth, yUnit*10 + wPenWidth);
  331. }
  332. void DrawDecimal (HDC hdc, WORD xUnit, WORD yUnit, WORD wPenWidth) {
  333.  
  334.     Ellipse (hdc, xUnit-wPenWidth/2, yUnit*11-wPenWidth/2, 
  335.                   xUnit+wPenWidth/2, yUnit*11+wPenWidth/2);
  336. }
  337. void DrawColon (HDC hdc, WORD xUnit, WORD yUnit, WORD wPenWidth) {
  338.     Ellipse (hdc, xUnit-wPenWidth/2, yUnit*4-wPenWidth/2, 
  339.                   xUnit+wPenWidth/2, yUnit*4+wPenWidth/2);
  340.     Ellipse (hdc, xUnit-wPenWidth/2, yUnit*8-wPenWidth/2, 
  341.                   xUnit+wPenWidth/2, yUnit*8+wPenWidth/2);
  342. }
  343.  
  344. //------------------------------------------------------------------------
  345. // DigitWndFn - The window proc for the control
  346. //------------------------------------------------------------------------
  347. long FAR PASCAL DigitWndFn (HWND hWnd, WORD message, WORD wParam, 
  348.                             LONG lParam) {
  349.     HANDLE         hData;
  350.     PDIGITDATA    pData;
  351.  
  352.     HDC            hdc;
  353.     PAINTSTRUCT    ps;
  354.      RECT            rect;
  355.     int            i;
  356.  
  357.     if (message != WM_CREATE) 
  358.         hData = GetWindowWord (hWnd, 0);
  359.         
  360.     switch (message) {
  361.  
  362.         case WM_CREATE:
  363.             hData = LocalAlloc (LHND, sizeof (DIGITDATA));
  364.             pData = (PDIGITDATA) LocalLock (hData);
  365.             pData->sValue = 0;
  366.             pData->sBase = 10;
  367.             SetWindowWord (hWnd, 0, hData);
  368.             
  369. //           MessageBeep(0);
  370.             
  371.             LocalUnlock (hData);
  372.             return 0;
  373.  
  374.         case DIGM_SET:
  375.             pData = (PDIGITDATA) LocalLock (hData);
  376.  
  377.             if (pData->sValue != (int) wParam) {
  378.                 pData->sValue = wParam; 
  379.  
  380.                 if (pData->sValue < 0) pData->sValue = 0;
  381.  
  382.                 if (pData->sValue >= pData->sBase)
  383.                     pData->sValue = pData->sBase - 1;
  384.                 InvalidateRect (hWnd, NULL, FALSE);
  385.             }
  386.             LocalUnlock (hData);    
  387.             return 0;
  388.             
  389.         case DIGM_GET:
  390.             pData = (PDIGITDATA) LocalLock (hData);
  391.             i = pData->sValue;
  392.             LocalUnlock (hData);    
  393.             return i;
  394.  
  395.         case DIGM_GETBASE:
  396.             pData = (PDIGITDATA) LocalLock (hData);
  397.             i = pData->sBase;
  398.             LocalUnlock (hData);    
  399.             return i;
  400.                               
  401.         case DIGM_INC:
  402.             pData = (PDIGITDATA) LocalLock (hData);
  403.             pData->sValue++;
  404.             if (pData->sValue >= pData->sBase) {
  405.                 pData->sValue = 0;
  406.                 PostMessage (GetParent (hWnd), WM_COMMAND,
  407.                              GetWindowWord (hWnd, GWW_ID), 
  408.                                  MAKELONG (hWnd, DIGN_CARRY)); 
  409.             }
  410.             LocalUnlock (hData);
  411.             InvalidateRect (hWnd, NULL, FALSE);
  412.             return 0;
  413.  
  414.             
  415.         case DIGM_DEC:
  416.             pData = (PDIGITDATA) LocalLock (hData);
  417.             pData->sValue--;
  418.             if (pData->sValue < 0) {
  419.                 pData->sValue = pData->sBase - 1;
  420.                 PostMessage (GetParent (hWnd), WM_COMMAND,
  421.                              GetWindowWord (hWnd, GWW_ID), 
  422.                                  MAKELONG (hWnd, DIGN_BORROW)); 
  423.             }
  424.             LocalUnlock (hData);
  425.             InvalidateRect (hWnd, NULL, FALSE);
  426.             return 0;
  427.  
  428.  
  429.         case DIGM_SETBASE:
  430.             pData = (PDIGITDATA) LocalLock (hData);
  431.             if (wParam > 16)
  432.                 pData->sBase = 16;
  433.             else
  434.                 if (wParam <= 0)
  435.                     pData->sBase = 2;
  436.                 else
  437.                     pData->sBase = wParam;
  438.             pData->sValue %= pData->sBase;
  439.             LocalUnlock (hData);
  440.             return 0;
  441.  
  442.  
  443.         case DIGM_BLANK:
  444.             pData = (PDIGITDATA) LocalLock (hData);
  445.             if (wParam) 
  446.                 SetWindowLong (hWnd, GWL_STYLE, 
  447.                                GetWindowLong (hWnd, GWL_STYLE) | DIGS_BLANK);
  448.             else
  449.                 SetWindowLong (hWnd, GWL_STYLE, 
  450.                                GetWindowLong (hWnd, GWL_STYLE) & ~DIGS_BLANK);
  451.             LocalUnlock (hData);
  452.             InvalidateRect (hWnd, NULL, FALSE);
  453.             return 0;
  454.  
  455.  
  456.  
  457.         case WM_LBUTTONUP:
  458.             PostMessage (GetParent (hWnd), WM_COMMAND,
  459.                          GetWindowWord (hWnd, GWW_ID), 
  460.                              MAKELONG (hWnd, DIGN_LCLICK)); 
  461.             break;
  462.  
  463.  
  464.         case WM_RBUTTONUP:
  465.             PostMessage (GetParent (hWnd), WM_COMMAND,
  466.                          GetWindowWord (hWnd, GWW_ID), 
  467.                              MAKELONG (hWnd, DIGN_RCLICK)); 
  468.             break;
  469.  
  470.  
  471.         case WM_PAINT:
  472.             {
  473.                 HPEN        hPen;
  474.                 HBRUSH    hBrush;
  475.                 WORD        xUnit, yUnit, wPenWidth;
  476.  
  477.                 pData = (PDIGITDATA) LocalLock (hData);
  478.                 hdc = BeginPaint (hWnd, &ps);
  479.                 GetWindowRect (hWnd, &rect);
  480.  
  481.                 xUnit = (rect.right-rect.left)/8;
  482.                 yUnit = (rect.bottom-rect.top)/12;
  483.                 wPenWidth = max (2, (rect.right-rect.left)/32);
  484.  
  485.                 if (GetWindowLong (hWnd, GWL_STYLE) & DIGS_LED) 
  486.                     hBrush = GetStockObject (BLACK_BRUSH);
  487.                 else 
  488.                     hBrush = GetStockObject (GRAY_BRUSH);
  489.  
  490.                 SelectObject (hdc, GetStockObject (NULL_PEN));
  491.                 SelectObject (hdc, hBrush);
  492.                 SelectObject (hdc, GetStockObject (NULL_PEN));
  493.                 SelectObject (hdc, hBrush);
  494.                 Rectangle (hdc, 0, 0, rect.right, rect.bottom);
  495.  
  496.                 //
  497.                 //If blank set, don't write number
  498.                 //
  499.                 if (GetWindowLong (hWnd, GWL_STYLE) & DIGS_BLANK) {
  500.                     EndPaint (hWnd, &ps);
  501.                     return 0;
  502.                 }        
  503.                 //
  504.                 //Get color for segments
  505.                 //
  506.                 if (GetWindowLong (hWnd, GWL_STYLE) & DIGS_LED) 
  507.                     hPen = CreatePen (PS_SOLID, wPenWidth, RGB (255, 0, 0));
  508.                 else                                      
  509.                     hPen = CreatePen (PS_SOLID, wPenWidth, RGB (0,0,0));
  510.                 SelectObject (hdc, hPen);
  511.                 //
  512.                 //Draw colon or decimal if necessary
  513.                 //
  514.                 if (GetWindowLong (hWnd, GWL_STYLE) & DIGS_COLON) 
  515.                     DrawColon (hdc, xUnit, yUnit, wPenWidth);
  516.  
  517.                 if (GetWindowLong (hWnd, GWL_STYLE) & DIGS_DECIMAL) 
  518.                     DrawDecimal (hdc, xUnit, yUnit, wPenWidth);
  519.                 //
  520.                 //Write proper segments for each number
  521.                 //
  522.                 switch (pData->sValue) {
  523.  
  524.                     case 0:
  525.                         DrawTop (hdc, xUnit, yUnit, wPenWidth);
  526.                         DrawRTop (hdc, xUnit, yUnit, wPenWidth);
  527.                         DrawRBot (hdc, xUnit, yUnit, wPenWidth);
  528.                         DrawBot (hdc, xUnit, yUnit, wPenWidth);
  529.                         DrawLBot (hdc, xUnit, yUnit, wPenWidth);
  530.                         DrawLTop (hdc, xUnit, yUnit, wPenWidth);
  531.                         break;
  532.  
  533.                     case 1:
  534.                         DrawRTop (hdc, xUnit, yUnit, wPenWidth);
  535.                         DrawRBot (hdc, xUnit, yUnit, wPenWidth);
  536.                         break;
  537.  
  538.                     case 2:
  539.                         DrawTop (hdc, xUnit, yUnit, wPenWidth);
  540.                         DrawRTop (hdc, xUnit, yUnit, wPenWidth);
  541.                         DrawMid (hdc, xUnit, yUnit, wPenWidth);
  542.                         DrawLBot (hdc, xUnit, yUnit, wPenWidth);
  543.                         DrawBot (hdc, xUnit, yUnit, wPenWidth);
  544.                         break;
  545.  
  546.                     case 3:
  547.                         DrawTop (hdc, xUnit, yUnit, wPenWidth);
  548.                         DrawRTop (hdc, xUnit, yUnit, wPenWidth);
  549.                         DrawRBot (hdc, xUnit, yUnit, wPenWidth);
  550.                         DrawMid (hdc, xUnit, yUnit, wPenWidth);
  551.                         DrawBot (hdc, xUnit, yUnit, wPenWidth);
  552.                         break;
  553.  
  554.                     case 4:
  555.                         DrawRTop (hdc, xUnit, yUnit, wPenWidth);
  556.                         DrawRBot (hdc, xUnit, yUnit, wPenWidth);
  557.                         DrawMid (hdc, xUnit, yUnit, wPenWidth);
  558.                         DrawLTop (hdc, xUnit, yUnit, wPenWidth);
  559.                         break;
  560.  
  561.                     case 5:
  562.                         DrawTop (hdc, xUnit, yUnit, wPenWidth);
  563.                         DrawRBot (hdc, xUnit, yUnit, wPenWidth);
  564.                         DrawMid (hdc, xUnit, yUnit, wPenWidth);
  565.                         DrawBot (hdc, xUnit, yUnit, wPenWidth);
  566.                         DrawLTop (hdc, xUnit, yUnit, wPenWidth);
  567.                         break;
  568.  
  569.                     case 6:
  570.                         DrawTop (hdc, xUnit, yUnit, wPenWidth);
  571.                         DrawRBot (hdc, xUnit, yUnit, wPenWidth);
  572.                         DrawMid (hdc, xUnit, yUnit, wPenWidth);
  573.                         DrawBot (hdc, xUnit, yUnit, wPenWidth);
  574.                         DrawLBot (hdc, xUnit, yUnit, wPenWidth);
  575.                         DrawLTop (hdc, xUnit, yUnit, wPenWidth);
  576.                         break;
  577.  
  578.                     case 7:
  579.                         DrawTop (hdc, xUnit, yUnit, wPenWidth);
  580.                         DrawRTop (hdc, xUnit, yUnit, wPenWidth);
  581.                         DrawRBot (hdc, xUnit, yUnit, wPenWidth);
  582.                         break;
  583.  
  584.                     case 8:
  585.                         DrawTop (hdc, xUnit, yUnit, wPenWidth);
  586.                         DrawRTop (hdc, xUnit, yUnit, wPenWidth);
  587.                         DrawRBot (hdc, xUnit, yUnit, wPenWidth);
  588.                         DrawMid (hdc, xUnit, yUnit, wPenWidth);
  589.                         DrawBot (hdc, xUnit, yUnit, wPenWidth);
  590.                         DrawLBot (hdc, xUnit, yUnit, wPenWidth);
  591.                         DrawLTop (hdc, xUnit, yUnit, wPenWidth);
  592.                         break;
  593.  
  594.                     case 9:
  595.                         DrawTop (hdc, xUnit, yUnit, wPenWidth);
  596.                         DrawRTop (hdc, xUnit, yUnit, wPenWidth);
  597.                         DrawRBot (hdc, xUnit, yUnit, wPenWidth);
  598.                         DrawMid (hdc, xUnit, yUnit, wPenWidth);
  599.                         DrawLTop (hdc, xUnit, yUnit, wPenWidth);
  600.                         break;
  601.  
  602.                     case 10:
  603.                         DrawTop (hdc, xUnit, yUnit, wPenWidth);
  604.                         DrawRTop (hdc, xUnit, yUnit, wPenWidth);
  605.                         DrawRBot (hdc, xUnit, yUnit, wPenWidth);
  606.                         DrawMid (hdc, xUnit, yUnit, wPenWidth);
  607.                         DrawLBot (hdc, xUnit, yUnit, wPenWidth);
  608.                         DrawLTop (hdc, xUnit, yUnit, wPenWidth);
  609.                         break;
  610.  
  611.                     case 11:
  612.                         DrawRBot (hdc, xUnit, yUnit, wPenWidth);
  613.                         DrawMid (hdc, xUnit, yUnit, wPenWidth);
  614.                         DrawBot (hdc, xUnit, yUnit, wPenWidth);
  615.                         DrawLBot (hdc, xUnit, yUnit, wPenWidth);
  616.                         DrawLTop (hdc, xUnit, yUnit, wPenWidth);
  617.                         break;
  618.  
  619.                     case 12:
  620.                         DrawTop (hdc, xUnit, yUnit, wPenWidth);
  621.                         DrawBot (hdc, xUnit, yUnit, wPenWidth);
  622.                         DrawLBot (hdc, xUnit, yUnit, wPenWidth);
  623.                         DrawLTop (hdc, xUnit, yUnit, wPenWidth);
  624.                         break;
  625.  
  626.                     case 13:
  627.                         DrawRTop (hdc, xUnit, yUnit, wPenWidth);
  628.                         DrawRBot (hdc, xUnit, yUnit, wPenWidth);
  629.                         DrawMid (hdc, xUnit, yUnit, wPenWidth);
  630.                         DrawBot (hdc, xUnit, yUnit, wPenWidth);
  631.                         DrawLBot (hdc, xUnit, yUnit, wPenWidth);
  632.                         break;
  633.  
  634.                     case 14:
  635.                         DrawTop (hdc, xUnit, yUnit, wPenWidth);
  636.                         DrawMid (hdc, xUnit, yUnit, wPenWidth);
  637.                         DrawBot (hdc, xUnit, yUnit, wPenWidth);
  638.                         DrawLBot (hdc, xUnit, yUnit, wPenWidth);
  639.                         DrawLTop (hdc, xUnit, yUnit, wPenWidth);
  640.                         break;
  641.  
  642.                     case 15:
  643.                         DrawTop (hdc, xUnit, yUnit, wPenWidth);
  644.                         DrawMid (hdc, xUnit, yUnit, wPenWidth);
  645.                         DrawLBot (hdc, xUnit, yUnit, wPenWidth);
  646.                         DrawLTop (hdc, xUnit, yUnit, wPenWidth);
  647.                         break;
  648.                 }
  649.                 DeleteObject (SelectObject (hdc, GetStockObject (BLACK_PEN)));
  650.                 EndPaint (hWnd, &ps);
  651.             }
  652.             LocalUnlock (hData);
  653.             return 0;
  654.  
  655.         case WM_DESTROY:
  656.             LocalFree (hData);
  657.             break;
  658.     }
  659.     return DefWindowProc (hWnd, message, wParam, lParam);
  660. }
  661.  
  662. //------------------------------------------------------------------------
  663. // About box dialog procedure
  664. //------------------------------------------------------------------------
  665. BOOL FAR PASCAL AboutDlgProc (HWND hwnd, WORD message, WORD wParam, 
  666.                                LONG lParam) {
  667.     switch (message) {
  668.         case WM_COMMAND:
  669.             switch (wParam) {
  670.                 case IDOK:
  671.                     EndDialog (hwnd, 1);
  672.                     return TRUE;
  673.             }
  674.             break;
  675.  
  676.         case WM_CLOSE:
  677.             EndDialog (hwnd, 0);
  678.             return TRUE;
  679.     }
  680.     return FALSE;    
  681. }
  682. 
  683.