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

  1. //---------------------------------------------------------------------------
  2. //        Copyright (C) 1992-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. // Pal.c
  10. //---------------------------------------------------------------------------
  11. // PALette Control
  12. //---------------------------------------------------------------------------
  13.  
  14. #include <windows.h>
  15. #include <string.h>
  16. #include <vbapi.h>
  17. #include "pal.h"
  18.  
  19. extern  MODEL modelPal;
  20.  
  21. VOID   PaintPalette(HCTL hctl, HWND hwnd, HDC hdc);
  22. HPALETTE CopyPalette(HPALETTE hpal);
  23.  
  24. HANDLE    hmodDLL;    // Module handle for the DLL
  25.  
  26. #define ERR_OOM 7   // Out of memory error
  27.  
  28. //---------------------------------------------------------------------------
  29. // PAL control function
  30. //---------------------------------------------------------------------------
  31. LONG _export FAR PASCAL PalCtlProc
  32. (
  33.   HCTL    hctl,
  34.   HWND    hwnd,
  35.   USHORT  msg,
  36.   USHORT  wp,
  37.   LONG    lp
  38. )
  39. {
  40.   LONG    lResult;
  41.  
  42.   // Message pre-processing
  43.   switch(msg)
  44.     {
  45.     case WM_NCCREATE:
  46.       // For convenience, mark this control as always using a palette,
  47.       // but for windowed controls this will only take effect if we later
  48.       // also set CTLFLG_HASPALETTE.
  49.       VBSetControlFlags(hctl, CTLFLG_USESPALETTE, CTLFLG_USESPALETTE);
  50.       break;
  51.  
  52.     case WM_PAINT:
  53.       if (wp)
  54.     // Handle "subclass paint", where wp == hdc
  55.     PaintPalette(hctl, hwnd, (HDC)wp);
  56.       else
  57.         {
  58.         PAINTSTRUCT ps;
  59.  
  60.         BeginPaint(hwnd, &ps);
  61.     PaintPalette(hctl, hwnd, ps.hdc);
  62.         EndPaint(hwnd, &ps);
  63.         }
  64.       break;
  65.  
  66.     case VBM_GETPALETTE:
  67.       // Return the palette we want realized.
  68.       // Turning off our palette awareness with VBSetControlFlags()
  69.       // when we have no palette will prevent us from returning NULL here.
  70.       return PALDEREF(hctl)->hpal;
  71.  
  72.     case VBM_GETPROPERTY:
  73.       switch (wp)
  74.         {
  75.     case IPROP_PAL_PICTURE:
  76.       // For the Picture property we build an HPIC value composed
  77.       // of a 0 by 0 bitmap and a copy of our current HPALETTE
  78.       {
  79.       PPAL        ppal;
  80.       PIC        pic;
  81.       HPIC        hpic;
  82.       HPALETTE  hpal;
  83.       HBITMAP   hbmp;
  84.       HDC        hdcScr;
  85.  
  86.       ppal = PALDEREF(hctl);
  87.  
  88.       if (!ppal->hpal)
  89.         {
  90.         // No palette - no picture
  91.         *(HPIC FAR *)lp = HPIC_NULL;
  92.         return 0;
  93.         }
  94.  
  95.       // Make a copy of the palette we're using
  96.       hpal = CopyPalette(ppal->hpal);
  97.       if (!hpal)
  98.         return ERR_OOM;
  99.  
  100.       // Create a 1x1 bitmap to go with the palette
  101.       hdcScr = GetDC(NULL);
  102.       hbmp = CreateBitmap(1, 1,
  103.                   (BYTE)GetDeviceCaps(hdcScr, PLANES),
  104.                   (BYTE)GetDeviceCaps(hdcScr, BITSPIXEL),
  105.                   NULL);
  106.       ReleaseDC(NULL, hdcScr);
  107.       if (!hbmp)
  108.         {
  109.         DeleteObject(hpal);
  110.         return ERR_OOM;
  111.         }
  112.  
  113.       // Create HPIC from HBMP and HPAL
  114.       pic.picType = PICTYPE_BITMAP;
  115.       pic.picData.bmp.hbitmap = hbmp;
  116.       pic.picData.bmp.hpal = hpal;
  117.       hpic = VBAllocPicEx(&pic, VB_VERSION);
  118.       if (!hpic)
  119.         {
  120.         DeleteObject(hpal);
  121.         DeleteObject(hbmp);
  122.         return ERR_OOM;
  123.         }
  124.  
  125.       // Return the HPIC but don't call VBRefPic because we're
  126.       // not holding a reference to this picture
  127.       *(HPIC FAR *)lp = hpic;
  128.       return 0;
  129.       }
  130.  
  131.     case IPROP_PAL_LENGTH:
  132.       // The Length property just returns the palette length
  133.       {
  134.       PPAL        ppal;
  135.       HPALETTE  hpal;
  136.       SHORT     palNumEntries;
  137.  
  138.       ppal = PALDEREF(hctl);
  139.  
  140.       hpal = ppal->hpal;
  141.       if (!hpal)
  142.         // Fall back to the default palette
  143.         hpal = GetStockObject(DEFAULT_PALETTE);
  144.       GetObject((HANDLE)hpal, sizeof(WORD), (LPSTR)&palNumEntries);
  145.       *(SHORT FAR *)lp = palNumEntries;
  146.       return 0;
  147.       }
  148.  
  149.     case IPROP_PAL_ENTRY:
  150.       // The Entry array property returns the color RGB value
  151.       // of the palette entry at the given index
  152.       {
  153.       PPAL        ppal;
  154.       HPALETTE  hpal;
  155.       PALETTEENTRY palentry;
  156.       LPDATASTRUCT pds = (LPDATASTRUCT)lp;
  157.       SHORT index = (SHORT)(pds->index[0].data);
  158.  
  159.       ppal = PALDEREF(hctl);
  160.  
  161.       hpal = ppal->hpal;
  162.       if (!hpal)
  163.         hpal = GetStockObject(DEFAULT_PALETTE);
  164.       if (!GetPaletteEntries(hpal, index, 1, &palentry))
  165.         return VBSetErrorMessage(32000, "invalid palette index");
  166.       pds->data = RGB(palentry.peRed, palentry.peGreen, palentry.peBlue);
  167.       return 0;
  168.       }
  169.     }
  170.       break;
  171.  
  172.     case VBM_SETPROPERTY:
  173.       switch (wp)
  174.         {
  175.     case IPROP_PAL_PICTURE:
  176.       // For the Picture we just copy the palette from the HPIC
  177.       {
  178.       PIC  pic;
  179.       PPAL ppal;
  180.  
  181.       ppal = PALDEREF(hctl);
  182.  
  183.       // Get the picture information and validate the type
  184.       VBGetPicEx((HPIC)lp, &pic, VB_VERSION);
  185.       switch (pic.picType)
  186.         {
  187.         case PICTYPE_NONE:
  188.         case PICTYPE_BITMAP:
  189.           // Free old HPAL
  190.           if (ppal->hpal)
  191.         DeleteObject(ppal->hpal);
  192.           if (pic.picType == PICTYPE_NONE)
  193.         ppal->hpal = NULL;
  194.           else
  195.         ppal->hpal = CopyPalette(pic.picData.bmp.hpal);
  196.           InvalidateRect(hwnd, NULL, TRUE);
  197.           VBSetControlFlags(hctl, CTLFLG_HASPALETTE,
  198.           (ppal->hpal != NULL) ? CTLFLG_HASPALETTE : 0);
  199.           return 0;
  200.         }
  201.       return VBSetErrorMessage(32001, "bitmaps only");
  202.       }
  203.  
  204.     case IPROP_PAL_LENGTH:
  205.       // The Length property causes the palette to be extended
  206.       // (with black entries) or truncated to a specific length
  207.       {
  208.       PPAL       ppal;
  209.       HPALETTE hpal;
  210.  
  211.       ppal = PALDEREF(hctl);
  212.  
  213.       hpal = ppal->hpal;
  214.       if (!hpal)
  215.         {
  216.         // Fall back to the default palette
  217.         hpal = CopyPalette(GetStockObject(DEFAULT_PALETTE));
  218.         if (!hpal)
  219.           return ERR_OOM;
  220.         ppal->hpal = hpal;
  221.         }
  222.       // Windows does all the real work here!!
  223.       if (!ResizePalette(hpal, (WORD)lp))
  224.         return VBSetErrorMessage(32002, "can't resize palette");
  225.       InvalidateRect(hwnd, NULL, TRUE);
  226.       VBSetControlFlags(hctl, CTLFLG_HASPALETTE, CTLFLG_HASPALETTE);
  227.       return 0;
  228.       }
  229.  
  230.     case IPROP_PAL_ENTRY:
  231.       // The Entry array property sets the color RGB value
  232.       // of the palette entry at the given index
  233.       {
  234.       PPAL        ppal;
  235.       HPALETTE    hpal;
  236.       PALETTEENTRY    palentry;
  237.       LPDATASTRUCT    pds = (LPDATASTRUCT)lp;
  238.       SHORT     index = (SHORT)(pds->index[0].data);
  239.       // Use RGBCOLOR macro to translate SysColors
  240.       COLOR     color = RGBCOLOR(pds->data);
  241.  
  242.       ppal = PALDEREF(hctl);
  243.  
  244.       hpal = ppal->hpal;
  245.       if (!hpal)
  246.         {
  247.         // Fall back to the default palette
  248.         hpal = CopyPalette(GetStockObject(DEFAULT_PALETTE));
  249.         if (!hpal)
  250.           return ERR_OOM;
  251.         ppal->hpal = hpal;
  252.         }
  253.       // Build an entry and set it
  254.       palentry.peRed   = GetRValue(color);
  255.       palentry.peGreen = GetGValue(color);
  256.       palentry.peBlue  = GetBValue(color);
  257.       palentry.peFlags = 0;
  258.       if (!SetPaletteEntries(hpal, index, 1, &palentry))
  259.         return VBSetErrorMessage(32003, "invalid palette index");
  260.       InvalidateRect(hwnd, NULL, TRUE);
  261.       VBSetControlFlags(hctl, CTLFLG_HASPALETTE, CTLFLG_HASPALETTE);
  262.       return 0;
  263.       }
  264.         }
  265.       break;
  266.     }
  267.  
  268.   // Default processing:
  269.   lResult = VBDefControlProc(hctl, hwnd, msg, wp, lp);
  270.  
  271.   // Message post-processing:
  272.   switch (msg)
  273.     {
  274.     case WM_DESTROY:
  275.       {
  276.       PPAL  ppal;
  277.  
  278.       ppal = PALDEREF(hctl);
  279.       // Free old HPAL
  280.       if (ppal->hpal)
  281.     {
  282.     DeleteObject(ppal->hpal);
  283.     ppal->hpal = NULL;
  284.     }
  285.       }
  286.       break;
  287.     }
  288.   return lResult;
  289. }
  290.  
  291.  
  292. //---------------------------------------------------------------------------
  293. // Handle the painting of the window.
  294. //---------------------------------------------------------------------------
  295. VOID PaintPalette
  296. (
  297.   HCTL hctl,
  298.   HWND hwnd,
  299.   HDC  hdc
  300. )
  301. {
  302.   RECT       rect;
  303.   HPALETTE hpal;
  304.   HPALETTE hpalOld;
  305.   int       i;
  306.   int       stripe;
  307.   HBRUSH   hbr;
  308.   int       palNumEntries;
  309.  
  310.   hpal = PALDEREF(hctl)->hpal;
  311.   if (!hpal)
  312.     hpal = GetStockObject(DEFAULT_PALETTE);
  313.  
  314.   GetClientRect(hwnd, &rect);
  315.  
  316.   hpalOld = SelectPalette(hdc, hpal, TRUE);
  317.   RealizePalette(hdc);
  318.  
  319.   GetObject((HANDLE)hpal, sizeof(WORD), (LPSTR)&palNumEntries);
  320.   stripe = rect.right / (int)palNumEntries;
  321.   if (stripe == 0)
  322.     stripe = 1;
  323.   ++stripe;
  324.   for (i = 0; i < palNumEntries; i++)
  325.     {
  326.     // A palette-relative brush is used for drawing.
  327.     hbr = CreateSolidBrush(PALETTEINDEX(i));
  328.     if (hbr)
  329.       {
  330.       hbr = SelectObject(hdc, hbr);
  331.       PatBlt(hdc, i*stripe, 0, stripe, rect.bottom, PATCOPY);
  332.       hbr = SelectObject(hdc, hbr);
  333.       DeleteObject(hbr);
  334.       }
  335.     }
  336.   SelectPalette(hdc, hpalOld, TRUE);
  337.   RealizePalette(hdc);
  338. }
  339.  
  340.  
  341. //---------------------------------------------------------------------------
  342. // Makes a copy of a GDI logical palette.  Returns a handle to the new
  343. // palette.
  344. //---------------------------------------------------------------------------
  345. HPALETTE CopyPalette
  346. (
  347.     HPALETTE hpal
  348. )
  349. {
  350.     PLOGPALETTE ppal;
  351.     int         nNumEntries;
  352.  
  353.     if (!hpal)
  354.         return NULL;
  355.  
  356.     GetObject(hpal,sizeof(int),(LPSTR)&nNumEntries);
  357.  
  358.     if (nNumEntries == 0)
  359.         return NULL;
  360.  
  361.     ppal = (PLOGPALETTE)LocalAlloc(LPTR, (WORD)(sizeof(LOGPALETTE) +
  362.     nNumEntries * sizeof(PALETTEENTRY)));
  363.  
  364.     if (!ppal)
  365.         return NULL;
  366.  
  367.     ppal->palVersion  = 0x300;
  368.     ppal->palNumEntries = (WORD)nNumEntries;
  369.  
  370.     GetPaletteEntries(hpal,0, (WORD)nNumEntries, ppal->palPalEntry);
  371.  
  372.     hpal = CreatePalette(ppal);
  373.  
  374.     LocalFree((HANDLE)ppal);
  375.     return hpal;
  376. }
  377.  
  378.  
  379. //---------------------------------------------------------------------------
  380. // Register custom control.  This routine is called by VB when the custom
  381. // control DLL is loaded for use.
  382. //---------------------------------------------------------------------------
  383. BOOL FAR PASCAL _export VBINITCC
  384. (
  385.   USHORT usVersion,
  386.   BOOL     fRuntime
  387. )
  388. {
  389.   // Avoid warnings on unused (but required) formal parameters
  390.   fRuntime = fRuntime;
  391.  
  392.   // Avoid loading under earlier version of VB
  393.   if (usVersion < VB200_VERSION)
  394.     {
  395.     MessageBox(NULL,
  396.            "Requires Visual Basic 2.0",
  397.            "Palette Control",
  398.            MB_OK | MB_TASKMODAL);
  399.     return FALSE;
  400.     }
  401.  
  402.   // Register control(s)
  403.   return VBRegisterModel(hmodDLL, &modelPal);
  404. }
  405.  
  406.  
  407. //---------------------------------------------------------------------------
  408. // Provide custom control model information to host environment.
  409. //---------------------------------------------------------------------------
  410. LPMODELINFO FAR PASCAL _export VBGetModelInfo
  411. (
  412.   USHORT usVersion
  413. )
  414. {
  415.   // Avoid warnings on unused (but required) formal parameters
  416.   usVersion = usVersion;
  417.  
  418.   return &modelinfoPal;
  419. }
  420.  
  421.  
  422. //---------------------------------------------------------------------------
  423. // Initialize library. This routine is called when the first client loads
  424. // the DLL.
  425. //---------------------------------------------------------------------------
  426. int FAR PASCAL LibMain
  427. (
  428.   HANDLE hModule,
  429.   WORD     wDataSeg,
  430.   WORD     cbHeapSize,
  431.   LPSTR  lpszCmdLine
  432. )
  433. {
  434.   // Avoid warnings on unused (but required) formal parameters
  435.   wDataSeg    = wDataSeg;
  436.   cbHeapSize  = cbHeapSize;
  437.   lpszCmdLine = lpszCmdLine;
  438.  
  439.   hmodDLL = hModule;
  440.  
  441.   return 1;
  442. }
  443.  
  444.  
  445. //---------------------------------------------------------------------------
  446. // WEP
  447. //---------------------------------------------------------------------------
  448. // C7 and QCWIN provide default a WEP:
  449. //---------------------------------------------------------------------------
  450. #if (_MSC_VER < 610)
  451.  
  452. int FAR PASCAL WEP(int fSystemExit);
  453.  
  454. //---------------------------------------------------------------------------
  455. // For Windows 3.0 it is recommended that the WEP function reside in a
  456. // FIXED code segment and be exported as RESIDENTNAME.  This is
  457. // accomplished using the alloc_text pragma below and the related EXPORTS
  458. // and SEGMENTS directives in the .DEF file.
  459. //
  460. // Read the comments section documenting the WEP function in the Windows
  461. // 3.1 SDK "Programmers Reference, Volume 2: Functions" before placing
  462. // any additional code in the WEP routine for a Windows 3.0 DLL.
  463. //---------------------------------------------------------------------------
  464. #pragma alloc_text(WEP_TEXT,WEP)
  465.  
  466. //---------------------------------------------------------------------------
  467. // Performs cleanup tasks when the DLL is unloaded.  WEP() is
  468. // called automatically by Windows when the DLL is unloaded (no
  469. // remaining tasks still have the DLL loaded).    It is strongly
  470. // recommended that a DLL have a WEP() function, even if it does
  471. // nothing but returns success (1), as in this example.
  472. //---------------------------------------------------------------------------
  473. int FAR PASCAL WEP
  474. (
  475.   int fSystemExit
  476. )
  477. {
  478.   // Avoid warnings on unused (but required) formal parameters
  479.   fSystemExit = fSystemExit;
  480.  
  481.   return 1;
  482. }
  483. #endif // C6
  484.  
  485. //---------------------------------------------------------------------------
  486.