Exemple #1
0
void loadTransparent( HAB hab, HDC hdc, HPS hps, XBITMAP *x, PSZ FileName)
{
   BITMAPINFOHEADER2    bmih;
   HBITMAP              base            = LoadBitmap(hab,hdc,hps,FileName);
   BITMAPINFOHEADER     pbmpData;       /* bit-map information header           */
   POINTL               aptlPoints[4];

//   DBGMessage(FileName);

   if(x->masc)
      GpiDeleteBitmap(x->masc);

   if(x->image)
      GpiDeleteBitmap(x->image);

   memset(x,0,sizeof(XBITMAP));

   GpiQueryBitmapParameters(base, &pbmpData);

   memset(&bmih,0, sizeof(BITMAPINFOHEADER2));
   bmih.cbFix        = sizeof(bmih);
   bmih.cx           = pbmpData.cx;
   bmih.cy           = pbmpData.cy;
   bmih.cPlanes      = 1;
   bmih.cBitCount    = 1;

   x->masc        = GpiCreateBitmap(   hps,
                                       &bmih,
                                       0L,
                                       NULL,
                                       NULL);

   GpiSetBitmap(hps,x->masc);

   aptlPoints[0].x=0;
   aptlPoints[0].y=0;
   aptlPoints[1].x=aptlPoints[0].x+pbmpData.cx-1;
   aptlPoints[1].y=aptlPoints[0].y+pbmpData.cy-1;
   aptlPoints[2].x=0;
   aptlPoints[2].y=0;
   aptlPoints[3].x=aptlPoints[2].x+pbmpData.cx;
   aptlPoints[3].y=aptlPoints[2].y+pbmpData.cy;

   GpiSetColor(hps,CLR_WHITE);
   GpiSetBackColor(hps,CLR_PINK);

   GpiWCBitBlt( hps,
                base,
                4,
                aptlPoints,
                ROP_NOTSRCCOPY,
                BBO_IGNORE);



   bmih.cbFix        = sizeof(bmih);
   bmih.cx           = pbmpData.cx;
   bmih.cy           = pbmpData.cy;
   bmih.cPlanes      = 1;
   bmih.cBitCount    = 24;

   x->image        = GpiCreateBitmap(  hps,
                                       &bmih,
                                       0L,
                                       NULL,
                                       NULL);

   GpiSetBitmap(hps,x->image);
   GpiSetColor(hps,CLR_WHITE);
   GpiSetBackColor(hps,CLR_BLACK);

   GpiWCBitBlt( hps,
                x->masc,
                4,
                aptlPoints,
                ROP_NOTSRCCOPY,
                BBO_IGNORE);

   GpiWCBitBlt( hps,
                base,
                4,
                aptlPoints,
                ROP_SRCAND,
                BBO_IGNORE);

   GpiSetBitmap(hps,NULLHANDLE);
   GpiDeleteBitmap(base);

}
Exemple #2
0
HBITMAP LoadBitmap ( HAB hab,
                     HDC hdc,
                     HPS hps,
                     PSZ pszFileName )
{
    HBITMAP       hbm;
    MMIOINFO      mmioinfo;
    MMFORMATINFO  mmFormatInfo;
    HMMIO         hmmio;
    ULONG         ulImageHeaderLength;
    MMIMAGEHEADER mmImgHdr;
    ULONG         ulBytesRead;
    ULONG         dwNumRowBytes;
    PBYTE         pRowBuffer;
    ULONG         dwRowCount;
    SIZEL         ImageSize;
    ULONG         dwHeight, dwWidth;
    SHORT         wBitCount;
    FOURCC        fccStorageSystem;
    ULONG         dwPadBytes;
    ULONG         dwRowBits;
    ULONG         ulReturnCode;
    ULONG         dwReturnCode;
    HBITMAP       hbReturnCode;
    LONG          lReturnCode;
    FOURCC        fccIOProc;

//    DBGMessage(pszFileName);

    ulReturnCode = mmioIdentifyFile ( pszFileName,
                                      0L,
                                      &mmFormatInfo,
                                      &fccStorageSystem,
                                      0L,
                                      0L);

    /*
     *  If this file was NOT identified, then this function won't
     *  work, so return an error by indicating an empty bitmap.
     */

    if ( ulReturnCode == MMIO_ERROR )
    {
         DBGMessage("Erro em mmioIdentifyFile");
         return (0L);
    }

    /*
     *  If mmioIdentifyFile did not find a custom-written IO proc which
     *  can understand the image file, then it will return the DOS IO Proc
     *  info because the image file IS a DOS file.
     */

    if( mmFormatInfo.fccIOProc == FOURCC_DOS )
    {

         WinMessageBox( HWND_DESKTOP,
                        HWND_DESKTOP,
                        "Image file could not be interpreted by any permanently or temporarily installed IO procedures.",
                        pszFileName,
                        (HMODULE) NULL,
                        (ULONG) MB_OK | MB_MOVEABLE |
                                MB_ERROR );
         return ( 0L );
    }

    /*
     *  Ensure this is an IMAGE IOproc, and that it can read
     *  translated data
     */

    if ( (mmFormatInfo.ulMediaType != MMIO_MEDIATYPE_IMAGE) ||
         ((mmFormatInfo.ulFlags & MMIO_CANREADTRANSLATED) == 0) )
    {

         WinMessageBox( HWND_DESKTOP,
                        HWND_DESKTOP,
                        "No IMAGE IO Procedures exist which can translate the data in the image file specified.",
                        pszFileName,
                        (HMODULE) NULL,
                        (ULONG) MB_OK | MB_MOVEABLE |
                                MB_ERROR );
         return (0L);
    }
    else
    {
         fccIOProc = mmFormatInfo.fccIOProc;
    }

    /* Clear out and initialize mminfo structure */

    memset ( &mmioinfo,
             0L,
             sizeof ( MMIOINFO ) );

    mmioinfo.fccIOProc = fccIOProc;
    mmioinfo.ulTranslate = MMIO_TRANSLATEHEADER | MMIO_TRANSLATEDATA;

    hmmio = mmioOpen ( (PSZ) pszFileName,
                       &mmioinfo,
                       MMIO_READ | MMIO_DENYWRITE | MMIO_NOIDENTIFY );

    if ( ! hmmio )
    {
         /* If file could not be opened, return with error */
         DBGMessage("Erro em mmioOpen");
         return (0L);
    }

    dwReturnCode = mmioQueryHeaderLength ( hmmio,
                                         (PLONG)&ulImageHeaderLength,
                                           0L,
                                           0L);

    if ( ulImageHeaderLength != sizeof ( MMIMAGEHEADER ) )
    {
         /* We have a problem.....possibly incompatible versions */

         ulReturnCode = mmioClose (hmmio, 0L);

         return (0L);
    }

    ulReturnCode = mmioGetHeader ( hmmio,
                                   &mmImgHdr,
                                   (LONG) sizeof ( MMIMAGEHEADER ),
                                   (PLONG)&ulBytesRead,
                                   0L,
                                   0L);

    if ( ulReturnCode != MMIO_SUCCESS )
    {
         /* Header unavailable */
         DBGMessage("Erro em mmioGetHeader");
         ulReturnCode = mmioClose (hmmio, 0L);

         return (0L);
    }

    /*
     *  Determine the number of bytes required, per row.
     *      PLANES MUST ALWAYS BE = 1
     */

    dwHeight = mmImgHdr.mmXDIBHeader.BMPInfoHeader2.cy;
    dwWidth = mmImgHdr.mmXDIBHeader.BMPInfoHeader2.cx;
    wBitCount = mmImgHdr.mmXDIBHeader.BMPInfoHeader2.cBitCount;
    dwRowBits = dwWidth * mmImgHdr.mmXDIBHeader.BMPInfoHeader2.cBitCount;
    dwNumRowBytes = dwRowBits >> 3;

    /*
     *  Account for odd bits used in 1bpp or 4bpp images that are
     *  NOT on byte boundaries.
     */

    if ( dwRowBits % 8 )
    {
         dwNumRowBytes++;
    }

    /*
     *  Ensure the row length in bytes accounts for byte padding.
     *  All bitmap data rows must are aligned on LONG/4-BYTE boundaries.
     *  The data FROM an IOProc should always appear in this form.
     */

    dwPadBytes = ( dwNumRowBytes % 4 );

    if ( dwPadBytes )
    {
         dwNumRowBytes += 4 - dwPadBytes;
    }

    /* Allocate space for ONE row of pels */

    if ( DosAllocMem( (PPVOID)&pRowBuffer,
                      (ULONG)dwNumRowBytes,
                      fALLOC))
    {
         ulReturnCode = mmioClose (hmmio, 0L);
         DBGMessage("Erro de alocacao de memoria");
         return(0L);
    }

    /* ***************************************************
       Create a memory presentation space that includes
       the memory device context obtained above.
       ***************************************************/

    ImageSize.cx = dwWidth;
    ImageSize.cy = dwHeight;

    /* ***************************************************
       Create an uninitialized bitmap.  This is where we
       will put all of the bits once we read them in.
       ***************************************************/

    hbm = GpiCreateBitmap ( hps,
                            &mmImgHdr.mmXDIBHeader.BMPInfoHeader2,
                            0L,
                            NULL,
                            NULL);

    if ( !hbm )
    {
         ulReturnCode = mmioClose (hmmio, 0L);
         DBGMessage("Erro ao criar bitmap");

         return(0L);
    }

    /* ***************************************************
       Select the bitmap into the memory device context.
       *************************************************** */

    hbReturnCode = GpiSetBitmap ( hps,
                                  hbm );

    /****************************************************************
        LOAD THE BITMAP DATA FROM THE FILE
            One line at a time, starting from the BOTTOM
     *************************************************************** */

    for ( dwRowCount = 0; dwRowCount < dwHeight; dwRowCount++ )
    {
         ulBytesRead = (ULONG) mmioRead ( hmmio,
                                          pRowBuffer,
                                          dwNumRowBytes );

         if ( !ulBytesRead )
         {
              break;
         }

         /*
          *  Allow context switching while previewing.. Couldn't get
          *  it to work. Perhaps will get to it when time is available...
          */

         lReturnCode = GpiSetBitmapBits ( hps,
                                          (LONG) dwRowCount,
                                          (LONG) 1,
                                          (PBYTE) pRowBuffer,
                                          (PBITMAPINFO2) &mmImgHdr.mmXDIBHeader.BMPInfoHeader2);

    }

    ulReturnCode = mmioClose (hmmio, 0L);

    DosFreeMem(pRowBuffer);

//    DBGTracex(hbm);

    return(hbm);
}
MRESULT EXPENTRY ClientWndProc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
     {
     static BITMAPINFOHEADER2 bmp ;
     static BOOL              fButton1Down, fButton2Down ;
     static HBITMAP           hbm ;
     static HDC               hdcMemory ;
     static HPS               hpsMemory ;
     static POINTL            ptlPointerPos, aptl [3] ;
     HPS                      hpsWindow ;
     LONG                     cxFullScrn, cyFullScrn ;
     SIZEL                    sizl ;

     switch (msg)
          {
          case WM_CREATE:
               cxFullScrn = WinQuerySysValue (HWND_DESKTOP, SV_CXFULLSCREEN) ;
               cyFullScrn = WinQuerySysValue (HWND_DESKTOP, SV_CYFULLSCREEN) ;

                         // Create Memory DC and PS

               hdcMemory = DevOpenDC (hab, OD_MEMORY, "*", 0L, NULL, 0) ;

               sizl.cx = 0 ;
               sizl.cy = 0 ;
               hpsMemory = GpiCreatePS (hab, hdcMemory, &sizl,
					PU_PELS    | GPIF_DEFAULT |
                                        GPIT_MICRO | GPIA_ASSOC) ;

                         // Create monochrome bitmap, return 1 if cannot

               bmp.cbFix     = sizeof (BITMAPINFOHEADER2) ;
               bmp.cx        = cxFullScrn ;
               bmp.cy        = cyFullScrn ;
               bmp.cPlanes   = 1 ;
               bmp.cBitCount = 1 ;

               hbm = GpiCreateBitmap (hpsMemory, &bmp, 0L, 0L, NULL) ;

               if (hbm == 0)
                    {
                    GpiDestroyPS (hpsMemory) ;
                    DevCloseDC (hdcMemory) ;
                    return MRFROMSHORT (1) ;
                    }

                         // Set bitmap in memory PS and clear it

               GpiSetBitmap (hpsMemory, hbm) ;

               aptl[1].x = cxFullScrn ;
               aptl[1].y = cyFullScrn ;
               GpiBitBlt (hpsMemory, 0, 2L, aptl, ROP_ZERO, BBO_OR) ;
               return 0 ;

          case WM_BUTTON1DOWN:
               if (!fButton2Down)
                    WinSetCapture (HWND_DESKTOP, hwnd) ;

               ptlPointerPos.x = MOUSEMSG(&msg)->x ;
               ptlPointerPos.y = MOUSEMSG(&msg)->y ;

               fButton1Down = TRUE ;
               break ;                       // do default processing

          case WM_BUTTON1UP:
               if (!fButton2Down)
                    WinSetCapture (HWND_DESKTOP, NULLHANDLE) ;

               fButton1Down = FALSE ;
               return 0 ;

          case WM_BUTTON2DOWN:
               if (!fButton1Down)
                    WinSetCapture (HWND_DESKTOP, hwnd) ;

               ptlPointerPos.x = MOUSEMSG(&msg)->x ;
               ptlPointerPos.y = MOUSEMSG(&msg)->y ;

               fButton2Down = TRUE ;
               break ;                       // do default processing

          case WM_BUTTON2UP:
               if (!fButton1Down)
                    WinSetCapture (HWND_DESKTOP, NULLHANDLE) ;

               fButton2Down = FALSE ;
               return 0 ;

          case WM_MOUSEMOVE:
               if (!fButton1Down && !fButton2Down)
                    break ;

               hpsWindow = WinGetPS (hwnd) ;

               GpiSetColor (hpsMemory, fButton1Down ? CLR_TRUE : CLR_FALSE) ;
               GpiSetColor (hpsWindow,
                            fButton1Down ? CLR_NEUTRAL : CLR_BACKGROUND) ;

               GpiMove (hpsMemory, &ptlPointerPos) ;
               GpiMove (hpsWindow, &ptlPointerPos) ;

               ptlPointerPos.x = MOUSEMSG(&msg)->x ;
               ptlPointerPos.y = MOUSEMSG(&msg)->y ;

               GpiLine (hpsMemory, &ptlPointerPos) ;
               GpiLine (hpsWindow, &ptlPointerPos) ;

               WinReleasePS (hpsWindow) ;
               break ;                       // do default processing

          case WM_PAINT:
               hpsWindow = WinBeginPaint (hwnd, NULLHANDLE, (PRECTL) aptl) ;

               aptl[2] = aptl[0] ;

               GpiBitBlt (hpsWindow, hpsMemory, 3L, aptl, ROP_SRCCOPY,
                          BBO_OR) ;

               WinEndPaint (hpsWindow) ;
               return 0 ;

          case WM_DESTROY:
               GpiDestroyPS (hpsMemory) ;
               DevCloseDC (hdcMemory) ;
               GpiDeleteBitmap (hbm) ;
               return 0 ;
          }
     return WinDefWindowProc (hwnd, msg, mp1, mp2) ;
     }
HBITMAP PSBMBLTToSize(HAB hab, HPS hps, HBITMAP hbm, float fScale, ULONG ulOptions)
{
    BITMAPINFOHEADER2 bif2Before;
    BITMAPINFOHEADER2 bif2After;
    SIZEL slAfter;
    ULONG ulScreenWidth;
    ULONG ulScreenHeight;
    HDC hdcAfter;
    HPS hpsAfter;
    HBITMAP hbmAfter;
    POINTL aptl[4];
    float fAspect;
    HBITMAP hbmOld;

    if ((hbmOld = GpiSetBitmap(hps, hbm)) == HBM_ERROR)
    {
        return (NULLHANDLE);
    }

    memset(&bif2Before, 0, sizeof(bif2Before));  // get current info

    bif2Before.cbFix = sizeof(bif2Before);
    if (GpiQueryBitmapInfoHeader(hbm, &bif2Before) != TRUE)
    {
        GpiSetBitmap(hps, hbmOld);
        return (NULLHANDLE);
    }

    ulScreenWidth = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);  // screen width

    ulScreenHeight = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);  // screen height

    fAspect = (bif2Before.cx * 1.0) / (bif2Before.cy * 1.0);  // calculate aspect ratio

    if (ulOptions & SCALE_LARGEST)
    {
        if (bif2Before.cx > bif2Before.cy)
        {
            slAfter.cx = (LONG) (ulScreenWidth * fScale);
            slAfter.cy = (LONG) (slAfter.cx / fAspect);
        }
        else
        {
            slAfter.cy = (LONG) (ulScreenHeight * fScale);
            slAfter.cx = (LONG) (slAfter.cy * fAspect);
        }
    }
    else if (ulOptions & SCALE_SMALLEST)
    {
        if (bif2Before.cx < bif2Before.cy)
        {
            slAfter.cx = (LONG) (ulScreenWidth * fScale);
            slAfter.cy = (LONG) (slAfter.cx / fAspect);
        }
        else
        {
            slAfter.cy = (LONG) (ulScreenHeight * fScale);
            slAfter.cx = (LONG) (slAfter.cy * fAspect);
        }
    }
    else if (ulOptions & SCALE_HORIZONTAL)
    {
        slAfter.cx = (LONG) (ulScreenWidth * fScale);
        if (ulOptions & SCALE_VERTICAL)  // basically, screw the aspect

        {
            slAfter.cy = (LONG) (ulScreenHeight * fScale);
        }
        else
        {
            slAfter.cy = (LONG) (slAfter.cx / fAspect);
        }
    }
    else if (ulOptions & SCALE_VERTICAL)
    {
        slAfter.cy = (LONG) (ulScreenHeight * fScale);
        slAfter.cx = (LONG) (slAfter.cy * fAspect);
    }
    else
    {
        GpiSetBitmap(hps, hbmOld);
        return (NULLHANDLE);
    }

    if ((hdcAfter = DevOpenDC(hab, OD_MEMORY, "*", 0L, (PDEVOPENDATA) NULL, NULLHANDLE))
            == NULLHANDLE)
    {
        GpiSetBitmap(hps, hbmOld);
        return (NULLHANDLE);
    }
    if ((hpsAfter = GpiCreatePS(hab,
                                hdcAfter,
                                &slAfter,
           PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC)) == NULLHANDLE)
    {
        DevCloseDC(hdcAfter);
        GpiSetBitmap(hps, hbmOld);
        return (NULLHANDLE);
    }

    memset(&bif2After, 0, sizeof(bif2After));
    bif2After.cbFix = sizeof(bif2After);
    bif2After.cx = slAfter.cx;
    bif2After.cy = slAfter.cy;
    bif2After.cBitCount = bif2Before.cBitCount;
    bif2After.cPlanes = bif2Before.cPlanes;

    if ((hbmAfter = GpiCreateBitmap(hpsAfter,  // create bitmap
                                     (PBITMAPINFOHEADER2) & (bif2After),
                                    (ULONG) FALSE,
                                    NULL,
                                    NULL)) == NULLHANDLE)
    {
        GpiDestroyPS(hpsAfter);
        DevCloseDC(hdcAfter);
        GpiSetBitmap(hps, hbmOld);
        return (NULLHANDLE);
    }

    if (GpiSetBitmap(hpsAfter, hbmAfter) == HBM_ERROR)
    {
        GpiDeleteBitmap(hbmAfter);
        GpiDestroyPS(hpsAfter);
        DevCloseDC(hdcAfter);
        GpiSetBitmap(hps, hbmOld);
        return (NULLHANDLE);
    }

    aptl[0].x = 0;
    aptl[0].y = 0;
    aptl[1].x = slAfter.cx;
    aptl[1].y = slAfter.cy;
    aptl[2].x = 0;
    aptl[2].y = 0;
    aptl[3].x = bif2Before.cx;
    aptl[3].y = bif2Before.cy;

    if (GpiBitBlt(hpsAfter,
                  hps,
                  4L,
                  aptl,
                  ROP_SRCCOPY,
                  BBO_IGNORE) == GPI_ERROR)
    {
        GpiSetBitmap(hpsAfter, NULLHANDLE);
        GpiDeleteBitmap(hbmAfter);
        GpiDestroyPS(hpsAfter);
        DevCloseDC(hdcAfter);
        GpiSetBitmap(hps, hbmOld);
        return (NULLHANDLE);
    }

    GpiSetBitmapDimension(hbmAfter, &slAfter);

    GpiSetBitmap(hpsAfter, NULLHANDLE);
    GpiDestroyPS(hpsAfter);
    DevCloseDC(hdcAfter);
    GpiSetBitmap(hps, hbmOld);

    return (hbmAfter);
}
Exemple #5
0
static void draw_stuff( HWND hwnd )
{
    HPS                 win_dc;
    RECTL               paint;
    RECTL               intersect;
#ifdef DRAW_ALL_AT_ONCE
    int                 old_top;
    int                 width, height;
    SIZEL               sizl = { 0, 0 };
    BITMAPINFOHEADER2   bmih;
    LONG                formats[24];
    POINTL              pts[3];
    LONG                old_cursor;
    LONG                hour_glass_cur;
    RECTL               interior;
    DEVOPENSTRUC        dop = { 0L, "DISPLAY", NULL, 0L,
                                0L, 0L, 0L, 0L, 0L };
#endif


    win_dc = WinBeginPaint( hwnd, 0, &paint );
    GpiCreateLogColorTable( win_dc, 0L, LCOLF_RGB, 0L, 0L, NULL );
#ifdef DRAW_ALL_AT_ONCE
    old_top = paint.yBottom;
    paint.yBottom = Draw_area.yTop;
#endif
    WinFillRect( win_dc, &paint, SYSCLR_WINDOW );
#ifdef DRAW_ALL_AT_ONCE
    paint.yBottom = old_top;
#endif
    if( WinIntersectRect( Main_hab, &intersect, &paint, &Draw_area ) ) {

#ifdef DRAW_ALL_AT_ONCE
        width = Draw_area.xRight - Draw_area.xLeft;
        height = Draw_area.yTop - Draw_area.yBottom;
        interior.xLeft = 0;
        interior.yBottom = 0;
        interior.xRight = width;
        interior.yTop = height;
        if( Draw_bitmap == NULLHANDLE ) {
            Hdc = DevOpenDC( Main_hab, OD_MEMORY, "*", 5L,
                                            (PDEVOPENDATA)&dop, NULLHANDLE );
            Mem_dc = GpiCreatePS( Main_hab, Hdc, &sizl, PU_PELS | GPIA_ASSOC );
            memset( &bmih, 0, sizeof( BITMAPINFOHEADER2 ) );
            GpiQueryDeviceBitmapFormats( Mem_dc, 24L, formats );
            bmih.cbFix = sizeof( BITMAPINFOHEADER2 );
            bmih.cx = width;
            bmih.cy = height;
            bmih.cPlanes = (USHORT) formats[0];
            bmih.cBitCount = (USHORT) formats[1];
            Draw_bitmap = GpiCreateBitmap( Mem_dc, &bmih, 0L, NULL, NULL );
            Old_bitmap = GpiSetBitmap( Mem_dc, Draw_bitmap );
            GpiCreateLogColorTable( Mem_dc, 0, LCOLF_RGB, 0, 0, NULL );
            WinFillRect( Mem_dc, &interior, SYSCLR_WINDOW );

            hour_glass_cur = WinQuerySysPointer( HWND_DESKTOP, SPTR_WAIT, FALSE );
            old_cursor = WinQueryPointer( HWND_DESKTOP );
            WinSetPointer( HWND_DESKTOP, hour_glass_cur );

            hThree_d = three_d_begin( Mem_dc, &interior );
            draw_room();
            three_d_draw( hThree_d );
            three_d_end( hThree_d );

            WinSetPointer( HWND_DESKTOP, old_cursor );
        }

        pts[0].x = Draw_area.xLeft;
        pts[0].y = Draw_area.yBottom;
        pts[1].x = Draw_area.xLeft + width;
        pts[1].y = Draw_area.yBottom + height;
        pts[2].x = 0;
        pts[2].y = 0;
        GpiBitBlt( win_dc, Mem_dc, 3, pts, ROP_SRCCOPY, BBO_IGNORE );
#else
        hThree_d = three_d_begin( win_dc, &Draw_area );
        draw_room();
        three_d_draw( hThree_d );
        three_d_end( hThree_d );
#endif

    }
    WinEndPaint( win_dc );
}
// *******************************************************************************
// FUNCTION:     DuplicateBitmap
//
// FUNCTION USE: Duplicates a bitmap
//
// DESCRIPTION:  Uses GpiBitBlt to make a copy of a bitmap by bit-bliting the
//               contents of the source PS containing the bitmap, to the target
//               presentation space.
//
// PARAMETERS:   HBITMAP    source bitmap handle to copy
//
// RETURNS:      HBITMAP    target bitmap handle
//
// HISTORY:
//
// *******************************************************************************
HBITMAP DuplicateBitmap (HBITMAP hbmSource, HPS hpsSource)
{
 HAB                hab;
 HBITMAP            hbmTarget;
 HBITMAP            hbmOld;
 HDC                hdcSource = NULLHANDLE;
 HDC                hdcTarget = NULLHANDLE;
 HPS                hpsTarget;
 SIZEL              sizl;
 POINTL             aptl[3];
 BOOL               bError = FALSE;
 BITMAPINFOHEADER2  bmp2;

 ERRORID            errorid;
 CHAR               szBuffer[CCHMAXPATH];
 PSZ                pszDevData[9] = {0, "MEMORY", 0, 0, 0, 0, 0, 0, 0};        

 // --------------------------------------------------------------------------
 // Get an anchor block handle
 // --------------------------------------------------------------------------
 hab = WinQueryAnchorBlock(HWND_DESKTOP);

 // --------------------------------------------------------------------------
 // Create memory device context handles and presentation space handles
 // --------------------------------------------------------------------------
 hdcSource = DevOpenDC (hab, OD_MEMORY, "*", 0L, NULL, NULLHANDLE);

 if (!hdcSource)                                               
  DisplayMessages(NULLHANDLE, "no hdcSource", MSG_INFO);       

  hdcTarget = DevOpenDC (hab, OD_MEMORY, "*", 0L, NULL, NULLHANDLE);

 if (!hdcTarget)                                               
  DisplayMessages(NULLHANDLE, "no hdcSource", MSG_INFO);       

 // --------------------------------------------------------------------------
 // Set presentation space size
 // --------------------------------------------------------------------------
 sizl.cx = 0;
 sizl.cy = 0;

 // --------------------------------------------------------------------------
 // If we don't have a source PS get one
 // --------------------------------------------------------------------------
 if (!hpsSource) 
  {
   hpsSource = GpiCreatePS (hab,
                            hdcSource,
                            &sizl,
                            PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC);

   if (!hpsSource) 
    DisplayMessages(NULLHANDLE, "no hpsSource", MSG_INFO);
  }


 // --------------------------------------------------------------------------
 // Create our target presentation space
 // --------------------------------------------------------------------------
 hpsTarget = GpiCreatePS (hab,
                          hdcTarget,
                          &sizl,
                          PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC);

 if (!hpsTarget)                                               
  DisplayMessages(NULLHANDLE, "no hpsTarget", MSG_INFO);       

 // --------------------------------------------------------------------------
 // Initialize the bitmap info header structure
 // --------------------------------------------------------------------------
 memset(&bmp2, 0, sizeof(BITMAPINFOHEADER2));

 // --------------------------------------------------------------------------
 // Set the size of the structure
 // --------------------------------------------------------------------------
 bmp2.cbFix = sizeof (BITMAPINFOHEADER2);

 // --------------------------------------------------------------------------
 // Get the bitmap information header from the source bitmap
 // --------------------------------------------------------------------------
 GpiQueryBitmapInfoHeader (hbmSource, &bmp2);

 // --------------------------------------------------------------------------
 // Create our target bitmap using the bitmap information header from
 // our source bitmap.
 // --------------------------------------------------------------------------
 hbmTarget = GpiCreateBitmap (hpsTarget, &bmp2, 0L, NULL, NULL);

 if (hbmTarget == GPI_ERROR) 
  {
   // --------------------------------------------------------------------------           
   // If we get an error creating the bitmap set the bError flag to TRUE                   
   // so we can return GPI_ERROR telling the caller that the function failed.              
   // --------------------------------------------------------------------------           
   bError = TRUE;                                                                        
  }                                                                                      

 // --------------------------------------------------------------------------
 // If everything is cool, set the bitmaps into our presentation spaces.
 // --------------------------------------------------------------------------
 else
  {
   hbmOld = GpiSetBitmap (hpsSource, hbmSource);

   if (hbmOld == HBM_ERROR) 
    {
     errorid = WinGetLastError(hab);                  
     sprintf(szBuffer, "GpiSetBitmap failed setting hbmSource into hpsSource\nLast Error = %8.8x", errorid);    
     DisplayMessages(NULLHANDLE, szBuffer, MSG_INFO); 
    }

   hbmOld = GpiSetBitmap (hpsTarget, hbmTarget);

   if (hbmOld == HBM_ERROR) 
    {
     errorid = WinGetLastError(hab);                  
     sprintf(szBuffer, "GpiSetBitmap failed setting hbmTarget into hpsTarget\nLast Error = %8.8x", errorid);    
     DisplayMessages(NULLHANDLE, szBuffer, MSG_INFO); 
    }

   aptl[0].x = 0;
   aptl[0].y = 0;
   aptl[1].x = bmp2.cx;
   aptl[1].y = bmp2.cy;
   aptl[2].x = 0;
   aptl[2].y = 0;

   // --------------------------------------------------------------------------
   // Bit blit the contents of the source presentation space into our target
   // presentation space.  This is how we copy the bitmap from the source to
   // the target.
   // --------------------------------------------------------------------------
   bError = GpiBitBlt (hpsTarget,      //  Target presentation space handle
                       hpsSource,      //  Source presentation space handle
                       3L,             //  Number of Points
                       aptl,           //  Array of Points
                       ROP_SRCCOPY,    //  Mixing function (source copy)
                       BBO_IGNORE);    //  Options

   // --------------------------------------------------------------------------
   // If we get an error copying from our source PS to our target PS
   // set the error flag to TRUE so that we can return GPI_ERROR back
   // to the caller.
   // --------------------------------------------------------------------------
   if (bError == GPI_ERROR)
    {
     bError = TRUE;
     errorid = WinGetLastError(hab);
     sprintf(szBuffer, "Error on BitBlt is %8.8x", errorid);
     DisplayMessages(NULLHANDLE, szBuffer, MSG_INFO);
    }

   // --------------------------------------------------------------------------
   // If we got a value back from GpiBitBlt reset our error flag since
   // bError would be TRUE.
   // --------------------------------------------------------------------------
   else
    {
     bError = FALSE;
    }
  }

 // --------------------------------------------------------------------------
 // Regardless of what happens, we will free all of our graphics engine
 // resources by destroying our presentation spaces and device context
 // handles.
 // --------------------------------------------------------------------------
 // GpiDestroyPS (hpsSource);
 GpiDestroyPS (hpsTarget);
 DevCloseDC (hdcSource);
 DevCloseDC (hdcTarget);

 // --------------------------------------------------------------------------
 // If we get an error trying to duplicate the bitmap, return GPI_ERROR.
 // --------------------------------------------------------------------------
 if (bError)
  {
   return GPI_ERROR;
  }

 // --------------------------------------------------------------------------
 // If everthing worked like a champ, return the bitmap handle.
 // --------------------------------------------------------------------------
 else
  {
   return hbmTarget;
  }
}