home *** CD-ROM | disk | FTP | other *** search
/ On Hand / On_Hand_From_Softbank_1994_Release_2_Disc_2_1994.iso / 00202 / s / disk1 / cntr.c_ / cntr.bin
Text File  |  1993-04-28  |  14KB  |  489 lines

  1. //---------------------------------------------------------------------------
  2. //        Copyright (C) 1991-93, Microsoft Corporation
  3. //
  4. // You have a royalty-free right to use, modify, reproduce and distribute
  5. // the Sample Custom Control Files (and/or any modified version) in any way
  6. // you find useful, provided that you agree that Microsoft has no warranty,
  7. // obligation or liability for any Custom Control File.
  8. //---------------------------------------------------------------------------
  9. // Cntr.c
  10. //---------------------------------------------------------------------------
  11. // Cntr Display Control
  12. //---------------------------------------------------------------------------
  13.  
  14. #include <windows.h>
  15. #include <vbapi.h>
  16. #include "cntr.h"
  17.  
  18. //---------------------------------------------------------------------------
  19. // Global Variables
  20. //---------------------------------------------------------------------------
  21. HANDLE hmodDLL;
  22.  
  23.  
  24. //---------------------------------------------------------------------------
  25. // Standard Error Values
  26. //---------------------------------------------------------------------------
  27. #define ERR_None          0
  28. #define ERR_InvPropVal        380     // Error$(380) = "Invalid property value"
  29.  
  30.  
  31. //---------------------------------------------------------------------------
  32. // Local Prototypes
  33. //---------------------------------------------------------------------------
  34. VOID NEAR DeleteBitMaps(BPCNTR bpcntr);
  35. VOID NEAR PaintCntr(BPCNTR bpcntr, HWND hwnd, HDC hdc);
  36. ERR  NEAR ErrSetCntrVal(BPCNTR bpcntr, HWND hwnd, float Val);
  37. VOID NEAR SizeCntr(BPCNTR bpcntr, HWND hwnd);
  38.  
  39.  
  40. //---------------------------------------------------------------------------
  41. // Cntr Control Procedure
  42. //---------------------------------------------------------------------------
  43. LONG FAR PASCAL _export CntrCtlProc
  44. (
  45.     HCTL   hctl,
  46.     HWND   hwnd,
  47.     USHORT msg,
  48.     USHORT wp,
  49.     LONG   lp
  50. )
  51. {
  52.     BPCNTR bpcntr = NULL;
  53.  
  54.     segCntr = (_segment)hctl;
  55.  
  56.     // Message pre-processing
  57.     switch (msg)
  58.     {
  59.     case WM_NCDESTROY:
  60.         bpcntr = BpcntrDEREF(hctl);
  61.         DeleteBitMaps(bpcntr);
  62.         break;
  63.  
  64.     case WM_NCCREATE:
  65.         bpcntr = BpcntrDEREF(hctl);
  66.         bpcntr->hFont = NULL;
  67.         ErrSetCntrVal(bpcntr, hwnd, (float)0.0);
  68.         bpcntr->DigitsLeft = 3;
  69.         bpcntr->DigitsRight = 0;
  70.         bpcntr->colorBackRight = COLOR_HIGHLIGHT | 0x80000000;
  71.         bpcntr->colorForeRight = COLOR_HIGHLIGHTTEXT | 0x80000000;
  72.         break;
  73.  
  74.     case WM_GETMINMAXINFO:
  75.         ((LPPOINT)lp)[3].x = 4;
  76.         ((LPPOINT)lp)[3].y = 4;
  77.         return 1L;
  78.  
  79.     case WM_SIZE:
  80.         SizeCntr(BpcntrDEREF(hctl), hwnd);
  81.         break;
  82.  
  83.     case WM_SETFONT:
  84.         bpcntr = BpcntrDEREF(hctl);
  85.         bpcntr->hFont = (HFONT)wp;
  86.         DeleteBitMaps(bpcntr);
  87.         break;
  88.  
  89.     case WM_GETFONT:
  90.         return BpcntrDEREF(hctl)->hFont;
  91.  
  92.     case WM_ERASEBKGND:
  93.         return TRUE;
  94.  
  95.     case WM_PAINT:
  96.         if (wp)
  97.         PaintCntr(BpcntrDEREF(hctl), hwnd, (HDC)wp);
  98.         else
  99.         {
  100.         PAINTSTRUCT ps;
  101.  
  102.         BeginPaint(hwnd, &ps);
  103.         PaintCntr(BpcntrDEREF(hctl), hwnd, ps.hdc);
  104.         EndPaint(hwnd, &ps);
  105.         }
  106.         break;
  107.  
  108.     case VBM_SETPROPERTY:
  109.         switch (wp)
  110.         {
  111.         case IPROP_CNTR_DIGITSLEFT:
  112.             if ((SHORT)lp < 1 || (SHORT)lp > 6)
  113.             return ERR_InvPropVal;
  114.             bpcntr = BpcntrDEREF(hctl);
  115.             bpcntr->DigitsLeft = (SHORT)lp;
  116.             SizeCntr(bpcntr, hwnd);
  117.             InvalidateRect(hwnd, NULL, FALSE);
  118.             return ERR_None;
  119.  
  120.         case IPROP_CNTR_DIGITSRIGHT:
  121.             if ((SHORT)lp < 0 || (SHORT)lp > 5)
  122.             return ERR_InvPropVal;
  123.             bpcntr = BpcntrDEREF(hctl);
  124.             bpcntr->DigitsRight = (SHORT)lp;
  125.             SizeCntr(bpcntr, hwnd);
  126.             InvalidateRect(hwnd, NULL, FALSE);
  127.             // reset value to reevaluate roll factors
  128.             ErrSetCntrVal(BpcntrDEREF(hctl), hwnd, bpcntr->Value);
  129.             return ERR_None;
  130.  
  131.         case IPROP_CNTR_VALUE:
  132.             return ErrSetCntrVal(BpcntrDEREF(hctl), hwnd,
  133.                      *(float FAR *)&(lp));
  134.  
  135.         case IPROP_CNTR_BACKCOLORRIGHT:
  136.         case IPROP_CNTR_FORECOLORRIGHT:
  137.         case IPROP_CNTR_BACKCOLOR:
  138.         case IPROP_CNTR_FORECOLOR:
  139.             InvalidateRect(hwnd, NULL, FALSE);
  140.             DeleteBitMaps(BpcntrDEREF(hctl));
  141.             return ERR_None;
  142.         }
  143.         break;
  144.     }
  145.  
  146.     // Default processing:
  147.     return VBDefControlProc(hctl, hwnd, msg, wp, lp);
  148. }
  149.  
  150.  
  151. //---------------------------------------------------------------------------
  152. // Delete currently cached bitmaps.  Called when control size, font, or
  153. // color has changed.  Bitmaps will be recalculated next time they are
  154. // needed.
  155. //---------------------------------------------------------------------------
  156. VOID NEAR DeleteBitMaps
  157. (
  158.     BPCNTR bpcntr
  159. )
  160. {
  161.     if (bpcntr->hbmp[0])
  162.     {
  163.     DeleteObject(bpcntr->hbmp[0]);
  164.     bpcntr->hbmp[0] = NULL;
  165.     }
  166.     if (bpcntr->hbmp[1])
  167.     {
  168.     DeleteObject(bpcntr->hbmp[1]);
  169.     bpcntr->hbmp[1] = NULL;
  170.     }
  171. }
  172.  
  173.  
  174. //---------------------------------------------------------------------------
  175. // Caluculate new bitmaps.  We will create and paint a new bitmap which looks
  176. // like:
  177. //    -+
  178. //    0|
  179. //    -+
  180. //    1|
  181. //    -+
  182. //    2|
  183. //    -+
  184. //    :
  185. //    -+
  186. //    9|
  187. //    -+
  188. //    0|
  189. //    -+
  190. // using the correct colors and font.
  191. //---------------------------------------------------------------------------
  192. HBITMAP NEAR GetBitMap
  193. (
  194.     BPCNTR bpcntr,
  195.     HWND   hwnd,
  196.     SHORT  inx
  197. )
  198. {
  199.     static  CHAR szDig[] = "01234567890";
  200.     RECT    rcClient;
  201.     RECT    rcDigit;
  202.     SHORT   digit;
  203.     SHORT   DigitHeight;
  204.     HDC     hdcScr;
  205.     HDC     hdcMem;
  206.     HBITMAP hbmp;
  207.     HBITMAP hbmpOld;
  208.     HBRUSH  hbr;
  209.     HFONT   hfontOld = NULL;
  210.  
  211.     if (bpcntr->hbmp[inx])
  212.     return bpcntr->hbmp[inx];
  213.     GetClientRect(hwnd, &rcClient);
  214.  
  215.     DigitHeight = rcClient.bottom + 1;
  216.     rcDigit = rcClient;
  217.     rcDigit.right = rcClient.right = bpcntr->DigitWidth - 1;
  218.     rcClient.bottom = DigitHeight * 11;
  219.     hdcScr = GetDC(NULL);
  220.     hdcMem = CreateCompatibleDC(hdcScr);
  221.     hbmp = CreateCompatibleBitmap(hdcScr, rcClient.right+1, rcClient.bottom+1);
  222.     ReleaseDC(NULL, hdcScr);
  223.     if (!hbmp)
  224.     {
  225.     DeleteDC(hdcMem);
  226.     return NULL;
  227.     }
  228.     bpcntr->hbmp[inx] = hbmp;
  229.     hbmpOld = SelectObject(hdcMem, hbmp);
  230.     // set up colors, etc.
  231.     if (!inx)
  232.     hbr = (HBRUSH)SendMessage(GetParent(hwnd), WM_CTLCOLOR, hdcMem, MAKELONG(hwnd, 0));
  233.     else
  234.     {
  235.     LONG BackColor = RGBCOLOR(bpcntr->colorBackRight);
  236.     LONG ForeColor = RGBCOLOR(bpcntr->colorForeRight);
  237.  
  238.     hbr = CreateSolidBrush(BackColor);
  239.     SetTextColor(hdcMem, ForeColor);
  240.     }
  241.     if (hbr)
  242.     {
  243.     FillRect(hdcMem, &rcClient, hbr);
  244.     if (inx)
  245.         DeleteObject(hbr);
  246.     }
  247.     SetBkMode(hdcMem, TRANSPARENT);
  248.     if (bpcntr->hFont)
  249.     hfontOld = SelectObject(hdcMem, bpcntr->hFont);
  250.     MoveTo(hdcMem, rcClient.right, 0);
  251.     LineTo(hdcMem, rcClient.right, rcClient.bottom);
  252.  
  253.     for (digit = 0; digit <= 10; ++digit)
  254.     {
  255.     MoveTo(hdcMem, 0, rcDigit.bottom);
  256.     LineTo(hdcMem, rcDigit.right, rcDigit.bottom);
  257.     DrawText(hdcMem, &szDig[digit], 1, &rcDigit,
  258.          DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_NOCLIP);
  259.     rcDigit.top += DigitHeight;
  260.     rcDigit.bottom += DigitHeight;
  261.     }
  262.     if (hfontOld)
  263.     SelectObject(hdcMem, hfontOld);
  264.     SelectObject(hdcMem, hbmpOld);
  265.     DeleteDC(hdcMem);
  266.     return bpcntr->hbmp[inx];
  267. }
  268.  
  269.  
  270. //---------------------------------------------------------------------------
  271. // Handle the resizing.  Calculate new width for digits and the size of the
  272. // gap.  Delete the old bitmaps, so that new ones will be created on the next
  273. // paint.
  274. //---------------------------------------------------------------------------
  275. VOID NEAR SizeCntr
  276. (
  277.     BPCNTR bpcntr,
  278.     HWND   hwnd
  279. )
  280. {
  281.     RECT  rcClient;
  282.     SHORT digits;
  283.  
  284.     GetClientRect(hwnd, &rcClient);
  285.     digits = bpcntr->DigitsLeft + bpcntr->DigitsRight;
  286.     bpcntr->DigitWidth = (rcClient.right + 1) / digits;
  287.     bpcntr->Gap = rcClient.right + 1 - digits * bpcntr->DigitWidth;
  288.     DeleteBitMaps(bpcntr);
  289. }
  290.  
  291.  
  292. //---------------------------------------------------------------------------
  293. // Handle setting a new value.
  294. //---------------------------------------------------------------------------
  295. ERR NEAR ErrSetCntrVal
  296. (
  297.     BPCNTR bpcntr,
  298.     HWND   hwnd,
  299.     float  Val
  300. )
  301. {
  302.     LONG  ValInt;
  303.     LONG  ValFrac;
  304.     SHORT digit;
  305.     SHORT last;
  306.     SHORT StartRoll;
  307.     CHAR  szVal[13];
  308.  
  309.     if (Val < (float)0.0)
  310.     return ERR_InvPropVal;
  311.     if (Val > (float)999999.0)
  312.     return ERR_InvPropVal;
  313.     bpcntr->Value = Val;
  314.     ValInt = (LONG)Val;
  315.     ValFrac = (LONG)((Val - (float)ValInt) * 1000000.0);
  316.     wsprintf(szVal, "%06ld%06ld", ValInt, ValFrac);
  317.     last = 6 + bpcntr->DigitsRight;
  318.     StartRoll = last - 1;
  319.     for (digit = last; digit >= 6 - bpcntr->DigitsLeft; --digit)
  320.     if (digit == StartRoll - 1 && szVal[StartRoll] == '9')
  321.         --StartRoll;
  322.     bpcntr->StartRoll = StartRoll;
  323.     bpcntr->RollVal = (szVal[last] - '0') * 10;
  324.     if (last < 11)
  325.     bpcntr->RollVal += (szVal[last+1] - '0');
  326.     lstrcpy(bpcntr->szVal, szVal);
  327.     InvalidateRect(hwnd, NULL, FALSE);
  328.     return ERR_None;
  329. }
  330.  
  331.  
  332. //---------------------------------------------------------------------------
  333. // Handle painting.  Blit the correct portion of the stashed bitmaps for
  334. // each digit.
  335. //---------------------------------------------------------------------------
  336. VOID NEAR PaintCntr
  337. (
  338.     BPCNTR bpcntr,
  339.     HWND   hwnd,
  340.     HDC    hdc
  341. )
  342. {
  343.     RECT    rcDigit;
  344.     SHORT   digit;
  345.     HBRUSH  hbr;
  346.     SHORT   roll;
  347.     SHORT   top;
  348.     HDC     hdcMem;
  349.     HBITMAP hbmp;
  350.     HBITMAP hbmpOld = NULL;
  351.  
  352.     hdcMem = CreateCompatibleDC(hdc);
  353.     if (!hdcMem)
  354.     return;
  355.  
  356.     // size the situation
  357.     GetClientRect(hwnd, &rcDigit);
  358.  
  359.     hbr = (HBRUSH)SendMessage(GetParent(hwnd), WM_CTLCOLOR, hdc, MAKELONG(hwnd, 0));
  360.     rcDigit.right = bpcntr->Gap;
  361.     FillRect(hdc, &rcDigit, hbr);
  362.     rcDigit.left  = rcDigit.right;
  363.     rcDigit.right = rcDigit.left + bpcntr->DigitWidth;
  364.  
  365.     roll = (bpcntr->RollVal * rcDigit.bottom) / 100;
  366.     for (digit = 6 - bpcntr->DigitsLeft; digit <= 5 + bpcntr->DigitsRight; ++digit)
  367.     {
  368.     hbmp = GetBitMap(bpcntr, hwnd, digit >= 6);
  369.     if (!hbmp)
  370.         {
  371.         if (hbmpOld)
  372.         SelectObject(hdcMem, hbmpOld);
  373.         DeleteDC(hdcMem);
  374.         return;
  375.         }
  376.     hbmpOld = SelectObject(hdcMem, hbmp);
  377.     if (RectVisible(hdc, &rcDigit))
  378.         {
  379.         top = (bpcntr->szVal[digit] - '0') * (rcDigit.bottom + 1);
  380.         if (digit >= bpcntr->StartRoll)
  381.         top += roll;
  382.         BitBlt(hdc, rcDigit.left, 0, bpcntr->DigitWidth, rcDigit.bottom + 1,
  383.            hdcMem, 0, top, SRCCOPY);
  384.         }
  385.     rcDigit.left  = rcDigit.right;
  386.     rcDigit.right = rcDigit.left + bpcntr->DigitWidth;
  387.     }
  388.     if (hbmpOld)
  389.     SelectObject(hdcMem, hbmpOld);
  390.     DeleteDC(hdcMem);
  391. }
  392.  
  393.  
  394. //---------------------------------------------------------------------------
  395. // Register custom control.  This routine is called by VB when the custom
  396. // control DLL is loaded for use.
  397. //---------------------------------------------------------------------------
  398. BOOL FAR PASCAL _export VBINITCC
  399. (
  400.     USHORT usVersion,
  401.     BOOL   fRuntime
  402. )
  403. {
  404.     // Avoid warnings on unused (but required) formal parameters
  405.     fRuntime  = fRuntime;
  406.     usVersion = usVersion;
  407.  
  408.     // Register control(s)
  409.     return VBRegisterModel(hmodDLL, &modelCntr);
  410. }
  411.  
  412.  
  413. //---------------------------------------------------------------------------
  414. // Provide custom control model information to host environment.
  415. //---------------------------------------------------------------------------
  416. LPMODELINFO FAR PASCAL _export VBGetModelInfo
  417. (
  418.     USHORT usVersion
  419. )
  420. {
  421.     return &modelinfoCntr;
  422. }
  423.  
  424.  
  425. //---------------------------------------------------------------------------
  426. // Initialize library. This routine is called when the first client loads
  427. // the DLL.
  428. //---------------------------------------------------------------------------
  429. int FAR PASCAL LibMain
  430. (
  431.     HANDLE hModule,
  432.     WORD   wDataSeg,
  433.     WORD   cbHeapSize,
  434.     LPSTR  lpszCmdLine
  435. )
  436. {
  437.     // Avoid warnings on unused (but required) formal parameters
  438.     wDataSeg    = wDataSeg;
  439.     cbHeapSize    = cbHeapSize;
  440.     lpszCmdLine = lpszCmdLine;
  441.  
  442.     hmodDLL = hModule;
  443.  
  444.     return 1;
  445. }
  446.  
  447.  
  448. //---------------------------------------------------------------------------
  449. // WEP
  450. //---------------------------------------------------------------------------
  451. // C7 and QCWIN provide default a WEP:
  452. //---------------------------------------------------------------------------
  453. #if (_MSC_VER < 610)
  454.  
  455. int FAR PASCAL WEP(int fSystemExit);
  456.  
  457. //---------------------------------------------------------------------------
  458. // For Windows 3.0 it is recommended that the WEP function reside in a
  459. // FIXED code segment and be exported as RESIDENTNAME.  This is
  460. // accomplished using the alloc_text pragma below and the related EXPORTS
  461. // and SEGMENTS directives in the .DEF file.
  462. //
  463. // Read the comments section documenting the WEP function in the Windows
  464. // 3.1 SDK "Programmers Reference, Volume 2: Functions" before placing
  465. // any additional code in the WEP routine for a Windows 3.0 DLL.
  466. //---------------------------------------------------------------------------
  467. #pragma alloc_text(WEP_TEXT,WEP)
  468.  
  469. //---------------------------------------------------------------------------
  470. // Performs cleanup tasks when the DLL is unloaded.  WEP() is
  471. // called automatically by Windows when the DLL is unloaded (no
  472. // remaining tasks still have the DLL loaded).    It is strongly
  473. // recommended that a DLL have a WEP() function, even if it does
  474. // nothing but returns success (1), as in this example.
  475. //---------------------------------------------------------------------------
  476. int FAR PASCAL WEP
  477. (
  478.     int fSystemExit
  479. )
  480. {
  481.     // Avoid warnings on unused (but required) formal parameters
  482.     fSystemExit = fSystemExit;
  483.  
  484.     return 1;
  485. }
  486. #endif // C6
  487.  
  488. //---------------------------------------------------------------------------
  489.