home *** CD-ROM | disk | FTP | other *** search
/ On Hand / On_Hand_From_Softbank_1994_Release_2_Disc_2_1994.iso / 00202 / s / disk3 / pix.c_ / pix.bin
Text File  |  1993-04-28  |  23KB  |  689 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. // Pix.c
  10. //---------------------------------------------------------------------------
  11. // Contains control procedure for PIX control
  12. //---------------------------------------------------------------------------
  13.  
  14. #include <windows.h>
  15. #include <vbapi.h>
  16. #include "pictblt.h"
  17. #include "pix.h"
  18. #include "pixvb1.h"
  19.  
  20.  
  21. //---------------------------------------------------------------------------
  22. // Global Variables
  23. //---------------------------------------------------------------------------
  24. HANDLE hmodDLL;
  25.  
  26.  
  27. //---------------------------------------------------------------------------
  28. // Standard Error Values
  29. //---------------------------------------------------------------------------
  30. #define ERR_None        0
  31. #define ERR_OutOfMemory     7   // Error$(7) = "Out of memory"
  32. #define ERR_BadIndex          381   // Error$(381) = "Invalid property array index"
  33. #define ERR_BadPixFmt        32000   // User-defined error
  34.  
  35.  
  36. //---------------------------------------------------------------------------
  37. // Local Prototypes
  38. //---------------------------------------------------------------------------
  39. ERR ErrCopyHlstr(HLSTR FAR *lphlstrDest, HLSTR hlstrSrc);
  40. VOID NEAR PaintPix(HCTL hctl, HDC hdc, LPRECT lprect);
  41. #define LppixDEREF(hctl)  ((PPIX)VBDerefControl(hctl))
  42.  
  43.  
  44. //---------------------------------------------------------------------------
  45. // Private macros
  46. //---------------------------------------------------------------------------
  47. #define SETOPAQUE(hctl)      VBSetControlFlags(hctl, CTLFLG_GRAPHICALOPAQUE, CTLFLG_GRAPHICALOPAQUE)
  48. #define SETTRANSLUCENT(hctl) VBSetControlFlags(hctl, CTLFLG_GRAPHICALTRANSLUCENT, CTLFLG_GRAPHICALTRANSLUCENT)
  49. #define SETTRANSPARENT(hctl) VBSetControlFlags(hctl, CTLFLG_GRAPHICALOPAQUE|CTLFLG_GRAPHICALTRANSLUCENT, 0)
  50.  
  51.  
  52. //---------------------------------------------------------------------------
  53. // Pix Control Procedure
  54. //---------------------------------------------------------------------------
  55. LONG FAR PASCAL _export PixCtlProc
  56. (
  57.     HCTL   hctl,
  58.     HWND   hwnd,
  59.     USHORT msg,
  60.     USHORT wp,
  61.     LONG   lp
  62. )
  63. {
  64.     PPIX ppix = NULL;
  65.  
  66.     switch (msg)
  67.     {
  68.     // *** NOTE: Only windowed controls receive WM_PAINT
  69.     case WM_PAINT:
  70.         {
  71.         RECT rect;
  72.  
  73.         GetClientRect(hwnd, &rect);
  74.             if (wp)
  75.         PaintPix(hctl, (HDC)wp, &rect);
  76.         else
  77.         {
  78.                 PAINTSTRUCT ps;
  79.  
  80.         BeginPaint(hwnd, &ps);
  81.         PaintPix(hctl, ps.hdc, &rect);
  82.         EndPaint(hwnd, &ps);
  83.         }
  84.         return 0L;
  85.         }
  86.  
  87.     // *** NOTE: Only Graphical controls receive VBM_PAINT
  88.     case VBM_PAINT:
  89.         PaintPix(hctl, (HDC)wp, (LPRECT)lp);
  90.         return 0L;
  91.  
  92.     // *** NOTE: Both Graphical and windowed controls receive WM_NCCREATE
  93.     case WM_NCCREATE:
  94.         // When being created, let's clear the CTLFLG_GRAPHICALTRANSLUCENT
  95.         // which is set by default for Graphical controls.
  96.         if (VBGetVersion() >= VB200_VERSION)
  97.         {
  98.         VBSetControlFlags(hctl, CTLFLG_GRAPHICALTRANSLUCENT, 0);
  99.         VBSetControlFlags(hctl, CTLFLG_USESPALETTE, CTLFLG_USESPALETTE);
  100.         }
  101.         break;
  102.  
  103.     // *** NOTE: Both Graphical and windowed controls receive WM_NCDESTROY
  104.     case WM_NCDESTROY:
  105.         ppix = (PPIX)VBDerefControl(hctl);
  106.         VBFreePic(ppix->hpicPict);
  107.         ppix = (PPIX)VBDerefControl(hctl);
  108.         if (ppix->hlstrMyTag)
  109.           VBDestroyHlstr(ppix->hlstrMyTag);
  110.         ppix = (PPIX)VBDerefControl(hctl);
  111.         if (ppix->hlstrMyTagMsg)
  112.           VBDestroyHlstr(ppix->hlstrMyTagMsg);
  113.         break;
  114.  
  115.         case VBM_GETPROPERTY:
  116.         switch (wp)
  117.         {
  118.         case IPROP_PIX_LIST:    // Get element of List prop array
  119.                     {
  120.             LONG     i;
  121.             LPDATASTRUCT lpds = (LPDATASTRUCT)lp;
  122.             LPSTR     lpstr;
  123.  
  124.             i = lpds->index[0].data;
  125.                     if (i < 0 || i >= ARRMAX)
  126.             return ERR_BadIndex;
  127.  
  128.             ppix = (PPIX)VBDerefControl(hctl);
  129.             if (ppix->List[i] == NULL)
  130.             {
  131.             lpds->data = (LONG)VBCreateHsz((_segment)hctl,"");
  132.             // *** ppix may now be invalid due to call to VB API ***
  133.             return ERR_None;
  134.                         }
  135.                     lpstr = VBDerefHsz(ppix->List[i]);
  136.             lpds->data = (LONG)VBCreateHsz((_segment)hctl, lpstr);
  137.             // *** ppix may now be invalid due to call to VB API ***
  138.             return ERR_None;
  139.             }
  140.  
  141.         case IPROP_PIX_MYTAG:
  142.             // WARNING: For DT_HLSTR properties which use PF_fGetData,
  143.             // WARNING: we must ensure that NULL is never returned!
  144.             // WARNING: So, if *lp is NULL, let's create a zero-
  145.             // WARNING: length hlstr, and return that!
  146.             if (*(HLSTR FAR *)lp == NULL)
  147.               {
  148.               *(HLSTR FAR *)lp = VBCreateHlstr(NULL, 0);
  149.               if (*(HLSTR FAR *)lp == NULL)
  150.             return ERR_OutOfMemory;
  151.               }
  152.             return ERR_None;
  153.  
  154.         case IPROP_PIX_MYTAGMSG:
  155.             {
  156.             HLSTR  hlstr = LppixDEREF(hctl)->hlstrMyTagMsg;
  157.             USHORT cb = VBGetHlstrLen(hlstr);
  158.             HLSTR  hlstrNew = VBCreateHlstr(NULL, cb);
  159.             ERR    err;
  160.  
  161.             if (!hlstrNew)
  162.               return ERR_OutOfMemory;
  163.  
  164.             err = VBSetHlstr(&hlstrNew, VBDerefHlstr(hlstr), cb);
  165.             if (err)
  166.               {
  167.               if (hlstrNew)
  168.             VBDestroyHlstr(hlstrNew);
  169.               return err;
  170.               }
  171.             *(HLSTR FAR *)lp = hlstrNew;
  172.             return ERR_None;
  173.             }
  174.                 }
  175.             break;
  176.  
  177.         case VBM_SETPROPERTY:
  178.         switch (wp)
  179.         {
  180.         case IPROP_PIX_LIST:    // Set element of List prop array
  181.                     {
  182.             LONG     i;
  183.             LPDATASTRUCT lpds =(LPDATASTRUCT)lp;
  184.             HSZ      hsz;
  185.  
  186.             i = lpds->index[0].data;
  187.                     if (i < 0 || i >= ARRMAX)
  188.             return ERR_BadIndex;
  189.  
  190.             ppix = (PPIX)VBDerefControl(hctl);
  191.                     if (ppix->List[i])
  192.             VBDestroyHsz(ppix->List[i]);
  193.             hsz = VBCreateHsz((_segment)hctl, (LPSTR)(lpds->data));
  194.             // *** ppix may now be invalid due to call to VB API ***
  195.             ppix = (PPIX)VBDerefControl(hctl);
  196.                     ppix->List[i] = hsz;
  197.  
  198.             return ERR_None;
  199.                     }
  200.  
  201.                 case IPROP_PIX_PICT:
  202.             if (VBGetVersion() >= VB200_VERSION)
  203.                         VBLinkPostAdvise(hctl);
  204.                     return ERR_None;
  205.  
  206.         case IPROP_PIX_MYTAGMSG:
  207.             // WARNING: We must never call VBGetHlstr() in response
  208.             // WARNING: to VBM_SETPROPERTY, since this VB API
  209.             // WARNING: has the side affect of freeing the hlstr
  210.             // WARNING: passed in, if it was a temp hlstr.
  211.             // WARNING: Since we do not own the hlstr, we are
  212.             // WARNING: forbidden to free it, and hence must not
  213.             // WARNING: call VBGetHlstr() or VBDestroyHlstr()
  214.             // WARNING: on the hlstr passed in lp.  We also cannot
  215.             // WARNING: call VBSetHlstr(xx,lp,-1), since this form
  216.             // WARNING: of VBSetHlstr() will also free lp if it is a
  217.             // WARNING: temp string.
  218.             return ErrCopyHlstr(&LppixDEREF(hctl)->hlstrMyTagMsg, (HLSTR)lp);
  219.                 }
  220.             break;
  221.  
  222.     case VBM_CHECKPROPERTY:
  223.         switch (wp)
  224.         {
  225.                 case IPROP_PIX_PICT:
  226.                     {
  227.             PIC pic;
  228.  
  229.             if (VBGetVersion() >= VB200_VERSION)
  230.             {
  231.             // Need to call VBGetPicEx to get the
  232.             // hpal field to be filled in
  233.             VBGetPicEx((HPIC)lp, &pic, VB_VERSION);
  234.  
  235.             // Mark palette aware, as necessary
  236.             VBSetControlFlags(hctl, CTLFLG_HASPALETTE,
  237.                 (pic.picType == PICTYPE_BITMAP &&
  238.                  pic.picData.bmp.hpal != NULL)
  239.                           ? CTLFLG_HASPALETTE
  240.                           : 0);
  241.             }
  242.             else
  243.             VBGetPic((HPIC)lp, &pic);
  244.  
  245.             switch (pic.picType)
  246.             {
  247.             case PICTYPE_BITMAP:
  248.                 if (VBGetVersion() >= VB200_VERSION)
  249.                 {
  250.                 VBInvalidateRect(hctl, NULL, TRUE);
  251.                 VBSetControlFlags(hctl,
  252.                           CTLFLG_GRAPHICALOPAQUE,
  253.                           CTLFLG_GRAPHICALOPAQUE);
  254.                 }
  255.                 else
  256.                 InvalidateRect(hwnd, NULL, TRUE);
  257.                 return ERR_None;
  258.  
  259.                         case PICTYPE_NONE:
  260.                 if (VBGetVersion() >= VB200_VERSION)
  261.                 {
  262.                 VBInvalidateRect(hctl, NULL, TRUE);
  263.                 VBSetControlFlags(hctl,
  264.                           CTLFLG_GRAPHICALOPAQUE|CTLFLG_GRAPHICALTRANSLUCENT,
  265.                           0);
  266.                 }
  267.                 else
  268.                 InvalidateRect(hwnd, NULL, TRUE);
  269.                 return ERR_None;
  270.  
  271.             // *** NOTE: If we supported PICTYPE_ICON, we would
  272.             // *** NOTE: have to set CTLFLG_GRAPHICALTRANSLUCENT!
  273.                         }
  274.             return VBSetErrorMessage(ERR_BadPixFmt,
  275.                          "Picture format not supported.");
  276.                     }
  277.                 }
  278.         break;
  279.  
  280.  
  281.     case VBM_GETPALETTE:
  282.         {
  283.         PIC pic;
  284.  
  285.         // Note that this message will only be sent under
  286.         // VB 2.0 or higher.  Therefore there is no need
  287.         // to check the VB version in processing this message.
  288.  
  289.         ppix = (PPIX)VBDerefControl(hctl);
  290.         VBGetPicEx(ppix->hpicPict, &pic, VB_VERSION);
  291.  
  292.         if (pic.picType == PICTYPE_BITMAP)
  293.           return (LONG)(SHORT)pic.picData.bmp.hpal;
  294.         else
  295.           return NULL;
  296.         }
  297.         case VBM_LINKENUMFORMATS:
  298.             if (LOWORD(lp) == 0)
  299.                 return CF_BITMAP;
  300.             return NULL;
  301.  
  302.         case VBM_LINKGETDATA:
  303.             {
  304.             HPIC     hpic;
  305.             PIC      pic;
  306.  
  307.             // Bitmaps and DIB's and metafiles are special cases for DDE.
  308.             // HBITMAPS, DIB's and metafiles are not passed directly, but
  309.             // instead are passed in a block of memory which contains the
  310.             // HBITMAP, handles to DIBs or metafiles.  All other formats are
  311.             // passed directly.  CF_TEXT, for instance, can be accessed
  312.             // directly as (LPSZ)GlobalLock(((LPLINKDATA)lp)->hData).
  313.  
  314.             // Note that DIB's are the preferred format for DDE: when
  315.             // bitmaps are passed between applications, palette information
  316.             // is not included, leading to problems when transferring 256
  317.             // bitmaps.
  318.  
  319.             if (wp != CF_BITMAP)
  320.                 return LINK_DATA_FORMATBAD;
  321.  
  322.             hpic = ((PPIX)VBDerefControl(hctl))->hpicPict;
  323.             VBGetPicEx(hpic, &pic, VB_VERSION);
  324.  
  325.             if (pic.picType == PICTYPE_BITMAP)
  326.                 {
  327.                 BITMAP   bmp;
  328.                 LONG     lDataLen;
  329.                 HANDLE   hData, hDdeData;
  330.                 LPHANDLE lphnd;
  331.                 char FAR *pch;
  332.  
  333.                 // All data allocated, regardless of format, must be
  334.                 // GMEM_MOVEABLE and GMEM_DDESHARE.
  335.  
  336.                 hDdeData = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,
  337.                                   sizeof(pic.picData.bmp.hbitmap) + 1);
  338.                 if (!hDdeData)
  339.                     return LINK_DATA_OOM;
  340.  
  341.                 // Copy the bitmap
  342.                 if (!GetObject(pic.picData.bmp.hbitmap, sizeof(BITMAP),
  343.                               (LPSTR)&bmp))
  344.                   return LINK_DATA_OOM;
  345.  
  346.                 lDataLen = (LONG)bmp.bmHeight * bmp.bmWidthBytes *
  347.                               bmp.bmPlanes;
  348.                 hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,
  349.                              lDataLen);
  350.  
  351.                 if (!hData)
  352.                   return LINK_DATA_OOM;
  353.  
  354.                 pch = GlobalLock(hData);
  355.                 if (!GetBitmapBits((HBITMAP)pic.picData.bmp.hbitmap,
  356.                               lDataLen, pch))
  357.                   return LINK_DATA_OOM;
  358.  
  359.                 lphnd = (LPHANDLE) GlobalLock(hDdeData);
  360.                 *lphnd = CreateBitmap(bmp.bmWidth, bmp.bmHeight,
  361.                                       bmp.bmPlanes, bmp.bmBitsPixel,
  362.                                       pch);
  363.  
  364.                 GlobalUnlock(hData);
  365.                 GlobalFree(hData);
  366.                 GlobalUnlock(hDdeData);
  367.  
  368.                 ((LPLINKDATA)lp)->cb = sizeof(hDdeData);
  369.                 ((LPLINKDATA)lp)->hData = hDdeData;
  370.                 return LINK_DATA_OK;
  371.                 }
  372.               else
  373.                 return LINK_DATA_FORMATBAD;
  374.             }
  375.  
  376.         case VBM_LINKSETDATA:
  377.             {
  378.             HPIC   hpic;
  379.             LPVOID lpv;
  380.  
  381.             // Bitmaps and DIB's and metafiles are special cases for DDE.
  382.             // HBITMAPS, DIB's and metafiles are not passed directly, but
  383.             // instead are passed in a block of memory which contains the
  384.             // HBITMAP, handles to DIBs or metafiles.  All other formats are
  385.             // passed directly.  CF_TEXT, for instance, can be accessed
  386.             // directly as (LPSZ)GlobalLock(((LPLINKDATA)lp)->hData).
  387.  
  388.             // Note that DIB's are the preferred format for DDE: when
  389.             // bitmaps are passed between applications, palette information
  390.             // is not included, leading to problems when transferring 256
  391.             // bitmaps.
  392.  
  393.             // Assure that the clipboard format is of type text.
  394.             if (wp != CF_BITMAP)
  395.                 return LINK_DATA_FORMATBAD;
  396.  
  397.             lpv = GlobalLock(((LPLINKDATA)lp)->hData);
  398.  
  399.             VBPicFromCF((HPIC FAR *) &hpic, *(HANDLE far *)lpv, wp);
  400.             GlobalUnlock(((LPLINKDATA)lp)->hData);
  401.  
  402.             if (VBSetControlProperty(hctl, IPROP_PIX_PICT, (LONG)hpic))
  403.                 return LINK_DATA_SETFAILED;
  404.  
  405.             return LINK_DATA_OK;
  406.             }
  407.  
  408.         case VBM_QPASTEOK:
  409.             if (wp == PT_PASTELINK)
  410.                 return VBPasteLinkOk(NULL, hctl);
  411.             break;
  412.     }
  413.  
  414.     return VBDefControlProc(hctl, hwnd, msg, wp, lp);
  415.  
  416. }
  417.  
  418.  
  419. //---------------------------------------------------------------------------
  420. // Paint the bitmap into the Pix control.
  421. //---------------------------------------------------------------------------
  422. VOID NEAR PaintPix
  423. (
  424.     HCTL   hctl,
  425.     HDC    hdc,
  426.     LPRECT lprect
  427. )
  428. {
  429.     HPIC     hpic;
  430.     PIC      pic;
  431.     BITMAP   bmp;
  432.     HDC      hdcMem;
  433.     HPEN     hpen, hpenOld;
  434.     HPALETTE hpalSave = NULL;
  435.     HPALETTE hpalOld = NULL;
  436.  
  437.     // Draw a border
  438.     hpen = CreatePen(0, 1, COLOR_DEFBITON | COLOR_WINDOWFRAME);
  439.     if (hpen)
  440.       hpenOld = SelectObject(hdc, (HANDLE)hpen);
  441.     Rectangle(hdc, lprect->left, lprect->top, lprect->right, lprect->bottom);
  442.     if (hpen && hpenOld)
  443.       {
  444.       SelectObject(hdc, (HANDLE)hpenOld);
  445.       DeleteObject((HANDLE)hpen);
  446.       }
  447.  
  448.     // Paint the bitmap, if there is one
  449.     hpic = ((PPIX)VBDerefControl(hctl))->hpicPict;
  450.  
  451.     if (VBGetVersion() >= VB200_VERSION)
  452.     VBGetPicEx(hpic, &pic, VB_VERSION);
  453.     else
  454.     {
  455.     // Initialize the hpal field to NULL since VBGetPic will not
  456.     // do it.
  457.     pic.picData.bmp.hpal = NULL;
  458.     VBGetPic(hpic, &pic);
  459.     }
  460.  
  461.     switch (pic.picType)
  462.     {
  463.     case PICTYPE_BITMAP:
  464.         GetObject(pic.picData.bmp.hbitmap, sizeof(BITMAP), (LPSTR)&bmp);
  465.         hdcMem = CreateCompatibleDC(hdc);
  466.  
  467.         if (pic.picData.bmp.hpal)
  468.           {
  469.           if (!PictFMemDC(hdc))
  470.         {
  471.         // If the hdc is a memory DC, then PictStretchBlt will use
  472.         // the palette of the destination DC correctly.
  473.         // One condition that the hdc will be a memory dc is when
  474.         // the control is being printed.  In that case, a rainbow
  475.         // palette has already been selected into the hdc and
  476.         // will be used for the printing.
  477.         // NOTE: If this control was a windowed control under
  478.         // NOTE: VB 2.0 of higher, then there is no need to
  479.         // NOTE: select the palette into the destination DC
  480.         // NOTE: because VB will already have done so.
  481.         hpalOld = SelectPalette(hdc, pic.picData.bmp.hpal, TRUE);
  482.         RealizePalette(hdc);
  483.         }
  484.           // If the bitmap has a palette, select it into the memory dc
  485.           hpalSave = SelectPalette(hdcMem, pic.picData.bmp.hpal, FALSE);
  486.           RealizePalette(hdcMem);
  487.           }
  488.  
  489.         SelectObject(hdcMem, pic.picData.bmp.hbitmap);
  490.         // Note that since we drew a border, the area into which we
  491.         // PictStretchBlt the bitmap is two pixels smaller.
  492.         // NOTE: We must use PictStretchBlt instead of StretchBlt
  493.         // NOTE: to handle printing 256-color bitmaps!
  494.         PictStretchBlt(hdc, lprect->left+1, lprect->top+1,
  495.                lprect->right  - lprect->left - 2,
  496.                lprect->bottom - lprect->top  - 2,
  497.                hdcMem, 0, 0,
  498.                bmp.bmWidth, bmp.bmHeight, SRCCOPY);
  499.  
  500.         if (hpalOld)
  501.           {
  502.           SelectPalette(hdc, hpalOld, TRUE);
  503.           RealizePalette(hdc);
  504.           }
  505.         if (hpalSave)
  506.           {
  507.           SelectPalette(hdcMem, hpalSave, FALSE);
  508.           RealizePalette(hdcMem);
  509.           }
  510.  
  511.         DeleteDC(hdcMem);
  512.             break;
  513.  
  514.     case PICTYPE_NONE:
  515.         // Remain totally transparent if we don't have a picture
  516.         break;
  517.     }
  518. }
  519.  
  520.  
  521. //---------------------------------------------------------------------------
  522. // Make a copy of hlstrSrc, and store the resulting hlstr in *lphlstrDest.
  523. // On entry *lphlstrDest may be NULL or a valid hlstr.    If NULL, a new hlstr
  524. // will be allocated to hold hlstrSrc, and then this handle will be stored
  525. // in *lphlstrDest.  If *lphlstrDest was originally non-NULL, then we try
  526. // resizing *lphlstrDest to fit hlstrSrc, and failing that, we free the
  527. // hlstr at *lphlstrDest, and allocate a new hlstr, storing that new handle
  528. // back into *lphlstrDest.
  529. //---------------------------------------------------------------------------
  530. // WARNING: This routine is called from VBM_SETPROPERTY!!!!  We must never
  531. // WARNING: call VBGetHlstr() in response to VBM_SETPROPERTY, since this VB
  532. // WARNING: API has the side affect of freeing the hlstr passed in, if it was
  533. // WARNING: a temp hlstr.  Since we do not own the hlstr, we are forbidden to
  534. // WARNING: free it, and hence must not call VBGetHlstr() or VBDestroyHlstr()
  535. // WARNING: on the hlstr passed in lp.    We also cannot call
  536. // WARNING: VBSetHlstr(xx,lp,-1), since this form of VBSetHlstr() will also
  537. // WARNING: free lp if it is a temp string.
  538. //---------------------------------------------------------------------------
  539. ERR ErrCopyHlstr
  540. (
  541.   HLSTR FAR *lphlstrDest,
  542.   HLSTR      hlstrSrc
  543. )
  544. {
  545.     ERR    err;
  546.     HLSTR  hlstrOld = *lphlstrDest;
  547.     USHORT cb = VBGetHlstrLen(hlstrSrc);
  548.     HLSTR  hlstrNew;
  549.  
  550.     // To prevent using excessive amts of memory, let's just try re-allocate
  551.     // this hlstr in place.
  552.     if (hlstrOld)
  553.       {
  554.       err = VBResizeHlstr(hlstrOld, cb);
  555.       if (!err)
  556.     {
  557.     // Successful, so lets copy the string data and return
  558.     return VBSetHlstr(lphlstrDest, VBDerefHlstr(hlstrSrc), cb);
  559.     }
  560.       }
  561.  
  562.     // Unsuccessful at re-allocating in place.    So, we'll now try allocating
  563.     // a *new* hlstr to contain lp, since VBResizeHlstr() didn't try
  564.     // allocating in a new segment.  Note we cannot do
  565.     // VBCreateHlstr(VBDerefHlstr(hlstrSrc), cb), since the create might
  566.     // cause hlstrSrc to move after we've already Deref'd it.
  567.     hlstrNew = VBCreateHlstr(NULL, cb);
  568.     if (!hlstrNew)
  569.       return ERR_OutOfMemory;
  570.  
  571.     // Successful, so lets copy the string data
  572.     err = VBSetHlstr(&hlstrNew, VBDerefHlstr(hlstrSrc), cb);
  573.     if (err)
  574.       {
  575.       // Failed, so let's clean up and return the error
  576.       if (hlstrNew)
  577.     VBDestroyHlstr(hlstrNew);
  578.       return err;
  579.       }
  580.  
  581.     // Success.  Let's keep the new value, and free the old
  582.     *lphlstrDest = hlstrNew;
  583.     if (hlstrOld)
  584.       VBDestroyHlstr(hlstrOld);
  585.     return ERR_None;
  586. }
  587.  
  588.  
  589. //---------------------------------------------------------------------------
  590. // Register custom control.  This routine is called by VB when the custom
  591. // control DLL is loaded for use.
  592. //---------------------------------------------------------------------------
  593. BOOL FAR PASCAL _export VBINITCC
  594. (
  595.     USHORT usVersion,
  596.     BOOL   fRuntime
  597. )
  598. {
  599.     // Avoid warnings on unused (but required) formal parameters
  600.     fRuntime  = fRuntime;
  601.  
  602.     // Register control(s)
  603.     if (usVersion < VB_VERSION)
  604.       return VBRegisterModel(hmodDLL, &modelPix_Vb1);
  605.     else
  606.       return VBRegisterModel(hmodDLL, &modelPix);
  607. }
  608.  
  609.  
  610. //---------------------------------------------------------------------------
  611. // Provide custom control model information to host environment.
  612. //---------------------------------------------------------------------------
  613. LPMODELINFO FAR PASCAL _export VBGetModelInfo
  614. (
  615.     USHORT usVersion
  616. )
  617. {
  618.     if (usVersion < VB_VERSION)
  619.     return &modelinfoPix_Vb1;
  620.     else
  621.     return &modelinfoPix;
  622. }
  623.  
  624.  
  625. //---------------------------------------------------------------------------
  626. // Initialize library.    This routine is called when the first client loads
  627. // the DLL.
  628. //---------------------------------------------------------------------------
  629. int FAR PASCAL LibMain
  630. (
  631.     HANDLE hModule,
  632.     WORD   wDataSeg,
  633.     WORD   cbHeapSize,
  634.     LPSTR  lpszCmdLine
  635. )
  636. {
  637.     // Avoid warnings on unused (but required) formal parameters
  638.     wDataSeg    = wDataSeg;
  639.     cbHeapSize    = cbHeapSize;
  640.     lpszCmdLine = lpszCmdLine;
  641.  
  642.     hmodDLL = hModule;
  643.  
  644.     return 1;
  645. }
  646.  
  647.  
  648. //---------------------------------------------------------------------------
  649. // WEP
  650. //---------------------------------------------------------------------------
  651. // C7 and QCWIN provide default a WEP:
  652. //---------------------------------------------------------------------------
  653. #if (_MSC_VER < 610)
  654.  
  655. int FAR PASCAL WEP(int fSystemExit);
  656.  
  657. //---------------------------------------------------------------------------
  658. // For Windows 3.0 it is recommended that the WEP function reside in a
  659. // FIXED code segment and be exported as RESIDENTNAME.  This is
  660. // accomplished using the alloc_text pragma below and the related EXPORTS
  661. // and SEGMENTS directives in the .DEF file.
  662. //
  663. // Read the comments section documenting the WEP function in the Windows
  664. // 3.1 SDK "Programmers Reference, Volume 2: Functions" before placing
  665. // any additional code in the WEP routine for a Windows 3.0 DLL.
  666. //---------------------------------------------------------------------------
  667. #pragma alloc_text(WEP_TEXT,WEP)
  668.  
  669. //---------------------------------------------------------------------------
  670. // Performs cleanup tasks when the DLL is unloaded.  WEP() is
  671. // called automatically by Windows when the DLL is unloaded (no
  672. // remaining tasks still have the DLL loaded).    It is strongly
  673. // recommended that a DLL have a WEP() function, even if it does
  674. // nothing but returns success (1), as in this example.
  675. //---------------------------------------------------------------------------
  676. int FAR PASCAL WEP
  677. (
  678.     int fSystemExit
  679. )
  680. {
  681.     // Avoid warnings on unused (but required) formal parameters
  682.     fSystemExit = fSystemExit;
  683.  
  684.     return 1;
  685. }
  686. #endif
  687.  
  688. //---------------------------------------------------------------------------
  689.