Announcement

Collapse

Forum Guidelines

This forum is for finished source code that is working properly. If you have questions about this or any other source code, please post it in one of the Discussion Forums, not here.
See more
See less

Bitmap to region, again...

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Bitmap to region, again...

    ' In answer to a Chris Boss challenge
    '
    ' This code allows you to convert a bitmap to a window region.
    ' It is based on the work from:
    ' Jean-Edouard Lachand-Robert
    ' Semen Matusovski
    ' Patrice Terrier
    '
    ' The function could be used to build a region on the fly
    '
    Code:
    FUNCTION ConvertBitmapToRgn& (BYVAL hBmp&, BYVAL TransColor&) EXPORT
    '
        LOCAL bm AS BITMAP, rc AS RECT
        LOCAL bi AS BITMAPINFO, rdh AS RGNDATAHEADER PTR
        LOCAL os AS OSVERSIONINFO
        LOCAL lpRect AS RECT PTR
    '
        MaxRegions& = 4000
    '
        IF hBmp& THEN
           CALL GetObject(hBmp&, SIZEOF(bm), bm)
           pWidth& = bm.bmWidth
           pHeight& = bm.bmHeight
        END IF
    '
        hDC& = CreateIC ("DISPLAY", BYVAL %NULL, BYVAL %NULL, BYVAL %NULL)
    '
        hMem1DC& = CreateCompatibleDC(hDC&)
        hMem2DC& = CreateCompatibleDC(hDC&)
        hTmpBmp& = CreateCompatibleBitmap(hDC&, pWidth&, pHeight&)
        CALL SelectObject(hMem1DC&, hBmp&)
        CALL SelectObject(hMem2DC&, hTmpBmp&)
        CALL BitBlt(hMem2DC&, 0, 0, pWidth&, pHeight&, hMem1DC&, 0, 0, %SRCCOPY)
    '
        bi.bmiHeader.biSize = SIZEOF(bi.bmiHeader)
        bi.bmiHeader.biWidth = pWidth&
        bi.bmiHeader.biHeight = pHeight&
        bi.bmiHeader.biPlanes = 1
        bi.bmiHeader.biBitCount = 32
        bi.bmiHeader.biCompression = %BI_RGB
    '
        hToDIB& = CreateDIBSection(hMem1DC&, bi, %DIB_RGB_COLORS, 0, 0, 0)
    '
        CALL SelectObject(hMem1DC&, hToDIB&)
        CALL GetObject(hToDIB&, SIZEOF(bm), bm)
        CALL BitBlt(hMem1DC&, 0, 0, pWidth&, pHeight&, hMem2DC&, 0, 0, %SRCCOPY)
    '
        REDIM Ar&(0) AT bm.bmBits: TT& = 0
    '
      ' Set up the transparent color
        IF TransColor& = -1 THEN
           T& = (Ar&((pHeight& - 1) * pWidth&) AND &HFFFFFF)'<--- (0, 0)
        ELSE
           T& = TransColor& ' Common Trancolor is magenta &HFF00FF
        END IF
    '
        RegionData$ = STRING$(LEN(RGNDATAHEADER) + LEN(RECT) * MaxRegions&, 0)
        rdh = STRPTR(RegionData$)
        @rdh.nCount = MaxRegions& + 1
        @rdh.dwSize = LEN(RGNDATAHEADER)
        @rdh.iType = %RDH_RECTANGLES
        @rdh.rcBound.nLeft = 0
        @rdh.rcBound.nTop = 0
        @rdh.rcBound.nRight = pWidth&
        @rdh.rcBound.nBottom = pHeight&
        FOR J& = 0 TO pHeight& - 1
            TT& = pWidth& * (pHeight& - 1 - J&): M& = -1
            FOR I& = 0 TO pWidth&
                IF I& = pWidth& THEN K& = T& ELSE K& = (Ar&(TT&) AND &HFFFFFF): INCR TT&
                IF K& <> T& THEN
                   IF M& = -1 THEN M& = I&
                ELSEIF M& >= 0 THEN
                   IF @rdh.nCount >= MaxRegions& THEN
                      hRgn2& = ExtCreateRegion(BYVAL 0, LEN(RGNDATAHEADER) + (LEN(RECT) * @rdh.nCount), BYVAL rdh)
                      IF hRgn1& = 0 THEN
                         hRgn1& = hRgn2&
                      ELSE
                         CALL CombineRgn(hRgn1&, hRgn1&, hRgn2&, %RGN_OR)
                         CALL DeleteObject(hRgn2&)
                      END IF
                      lpRect = LEN(RGNDATAHEADER) + rdh
                      @rdh.nCount = 0
                   END IF
                   INCR @rdh.nCount
                   @lpRect.nLeft = M&
                   @lpRect.nRight = I&
                   @lpRect.nTop = J&
                   @lpRect.nBottom = J& + 1
                   lpRect = lpRect + LEN(RECT)
                   M& = -1
                END IF
            NEXT
        NEXT
        hRgn2& = ExtCreateRegion(BYVAL 0, LEN(RGNDATAHEADER) + (LEN(RECT) * @rdh.nCount), BYVAL rdh)
        IF hRgn1& = 0 THEN
           hRgn1& = hRgn2&
        ELSE
           CALL CombineRgn(hRgn1&, hRgn1&, hRgn2&, %RGN_OR)
           CALL DeleteObject(hRgn2&)
        END IF
    '
        CALL DeleteDC(hMem1DC&)
        CALL DeleteDC(hMem2DC&)
        CALL DeleteDC(hDC&)
        CALL DeleteObject(hTmpBmp&)
        CALL DeleteObject(hToDIB&)
    '
        FUNCTION = hRgn1&
    '
    END FUNCTION

    ------------------
    Patrice Terrier
    mailto[email protected][email protected]</A>
    http://www.zapsolution.com
    Toolkit: WinLIFT (Skin Engine), GDI+ helper (Graphic package), dvBTree (Index manager)
    Freeware: ZAP Audio Player, ZAP Picture Browser.
    Artwork on demand.

    [This message has been edited by Patrice Terrier (edited March 18, 2004).]
    Patrice Terrier
    www.zapsolution.com
    www.objreader.com
    Addons: GDImage.DLL 32/64-bit (Graphic library), WinLIFT.DLL 32/64-bit (Skin Engine).

  • #2
    And now the complete demo written from scratch
    Code:
    ' REGION.EXE
    ' Create a complex window region from a bitmap 
    '
    ' Author Patrice Terrier
    ' http://www.zapsolution.com 
    '
    ' Use right mouse click to close the window
    ' Hold down left mouse to dragg the window.
    '
    ' You can download the test bitmap from there
    ' http://www.zapsolution.com/preview/test.bmp 
    '
    #COMPILE EXE "REGION.EXE"
    '
    #INCLUDE "WIN32API.INC"
    '
    GLOBAL UseBitmap&
    '
    SUB GetPixmapSize(BYVAL hBmp&, xWidth&, yHeight&) EXPORT
        LOCAL bm AS BITMAP
        IF hBmp& THEN
           CALL GetObject(hBmp&, SIZEOF(bm), bm)
           xWidth& = bm.bmWidth
           yHeight& = bm.bmHeight
        END IF
    END SUB
    '
    FUNCTION ConvertBitmapToRgn& (BYVAL hBmp&, BYVAL TransColor&) EXPORT
    '
        LOCAL bm AS BITMAP, rc AS RECT
        LOCAL bi AS BITMAPINFO, rdh AS RGNDATAHEADER PTR
        LOCAL os AS OSVERSIONINFO
        LOCAL lpRect AS RECT PTR
    '
        MaxRegions& = 4000
    '
        CALL GetPixmapSize(hBmp&, pWidth&, pHeight&)
    '
        hDC& = CreateIC ("DISPLAY", BYVAL %NULL, BYVAL %NULL, BYVAL %NULL)
    '
        hMem1DC& = CreateCompatibleDC(hDC&)
        hMem2DC& = CreateCompatibleDC(hDC&)
        hTmpBmp& = CreateCompatibleBitmap(hDC&, pWidth&, pHeight&)
        CALL SelectObject(hMem1DC&, hBmp&)
        CALL SelectObject(hMem2DC&, hTmpBmp&)
        CALL BitBlt(hMem2DC&, 0, 0, pWidth&, pHeight&, hMem1DC&, 0, 0, %SRCCOPY)
    '
        bi.bmiHeader.biSize = SIZEOF(bi.bmiHeader)
        bi.bmiHeader.biWidth = pWidth&
        bi.bmiHeader.biHeight = pHeight&
        bi.bmiHeader.biPlanes = 1
        bi.bmiHeader.biBitCount = 32
        bi.bmiHeader.biCompression = %BI_RGB
    '
        hToDIB& = CreateDIBSection(hMem1DC&, bi, %DIB_RGB_COLORS, 0, 0, 0)
    '
        CALL SelectObject(hMem1DC&, hToDIB&)
        CALL GetObject(hToDIB&, SIZEOF(bm), bm)
        CALL BitBlt(hMem1DC&, 0, 0, pWidth&, pHeight&, hMem2DC&, 0, 0, %SRCCOPY)
    '
        REDIM Ar&(0) AT bm.bmBits: TT& = 0
    '
      ' Set up the transparent color
        IF TransColor& = -1 THEN
           T& = (Ar&((pHeight& - 1) * pWidth&) AND &HFFFFFF)'<--- (0, 0)
        ELSE
           T& = TransColor& ' Common Trancolor is magenta &HFF00FF
        END IF
    '
        RegionData$ = STRING$(LEN(RGNDATAHEADER) + LEN(RECT) * MaxRegions&, 0)
        rdh = STRPTR(RegionData$)
        @rdh.nCount = MaxRegions& + 1
        @rdh.dwSize = LEN(RGNDATAHEADER)
        @rdh.iType = %RDH_RECTANGLES
        @rdh.rcBound.nLeft = 0
        @rdh.rcBound.nTop = 0
        @rdh.rcBound.nRight = pWidth&
        @rdh.rcBound.nBottom = pHeight&
        FOR J& = 0 TO pHeight& - 1
            TT& = pWidth& * (pHeight& - 1 - J&): M& = -1
            FOR I& = 0 TO pWidth&
                IF I& = pWidth& THEN K& = T& ELSE K& = (Ar&(TT&) AND &HFFFFFF): INCR TT&
                IF K& <> T& THEN
                   IF M& = -1 THEN M& = I&
                ELSEIF M& >= 0 THEN
                   IF @rdh.nCount >= MaxRegions& THEN
                      hRgn2& = ExtCreateRegion(BYVAL 0, LEN(RGNDATAHEADER) + (LEN(RECT) * @rdh.nCount), BYVAL rdh)
                      IF hRgn1& = 0 THEN
                         hRgn1& = hRgn2&
                      ELSE
                         CALL CombineRgn(hRgn1&, hRgn1&, hRgn2&, %RGN_OR)
                         CALL DeleteObject(hRgn2&)
                      END IF
                      lpRect = LEN(RGNDATAHEADER) + rdh
                      @rdh.nCount = 0
                   END IF
                   INCR @rdh.nCount
                   @lpRect.nLeft = M&
                   @lpRect.nRight = I&
                   @lpRect.nTop = J&
                   @lpRect.nBottom = J& + 1
                   lpRect = lpRect + LEN(RECT)
                   M& = -1
                END IF
            NEXT
        NEXT
        hRgn2& = ExtCreateRegion(BYVAL 0, LEN(RGNDATAHEADER) + (LEN(RECT) * @rdh.nCount), BYVAL rdh)
        IF hRgn1& = 0 THEN
           hRgn1& = hRgn2&
        ELSE
           CALL CombineRgn(hRgn1&, hRgn1&, hRgn2&, %RGN_OR)
           CALL DeleteObject(hRgn2&)
        END IF
    '
        CALL DeleteDC(hMem1DC&)
        CALL DeleteDC(hMem2DC&)
        CALL DeleteDC(hDC&)
        CALL DeleteObject(hTmpBmp&)
        CALL DeleteObject(hToDIB&)
    '
        FUNCTION = hRgn1&
    '
    END FUNCTION
    '
    ' Message function
    FUNCTION WndProc&(BYVAL hWnd&, BYVAL Msg&, BYVAL wParam&, BYVAL lParam&)
    '
        SELECT CASE Msg&
    '
        CASE %WM_ERASEBKGND
    '
             hDC& = CreateCompatibleDC(wParam&)
    '
             CALL GetPixmapSize(UseBitmap&, xSize&, ySize&)
             SelectObject hDC&, UseBitmap&
             BitBlt wParam&, 0, 0, xSize&, ySize&, hDC&, 0, 0, %SRCCOPY
    '
             DeleteDC hDC&
    '
             FUNCTION = 1
             EXIT FUNCTION
    '
        CASE %WM_RBUTTONDOWN
             CALL PostQuitMessage(0)
             FUNCTION = 0: EXIT FUNCTION
    '
        CASE %WM_LBUTTONDOWN
             CALL ReleaseCapture
             CALL SendMessage(hWnd&, %WM_NCLBUTTONDOWN, %HTCAPTION, BYVAL %NULL)
             FUNCTION = 1: EXIT FUNCTION
    '
        END SELECT
    '
        FUNCTION = DefWindowProc(hWnd&, Msg&, wParam&, lParam&)
    '
        EXIT FUNCTION
    '
    END FUNCTION
    '
    FUNCTION WinMain&(BYVAL hInstance&, _
            BYVAL hPrevInstance&, _
            BYVAL lpCmdLine AS ASCIIZ PTR, _
            BYVAL iCmdShow&)
    '
        LOCAL Msg     AS tagMsg
        LOCAL WC      AS WndClassEx
        LOCAL zClass  AS ASCIIZ * 7
    '
        IF LEN(Command$) = 0 THEN 
           BmpFile$ = "TEST.BMP"
        ELSE
           BmpFile$ = Command$
        END IF
        IF LEN(DIR$(BmpFile$)) = 0 THEN EXIT FUNCTION
    '
        zClass = "REGION"
    '
        wc.cbSize        = SIZEOF(wc)
        wc.style         = %CS_HREDRAW OR %CS_VREDRAW
        wc.lpfnWndProc   = CODEPTR(WndProc)
        wc.cbClsExtra    = 0
        wc.cbWndExtra    = 0
        wc.hInstance     = hInstance&
        wc.hIcon         = %NULL 'LoadIcon(hInstance&, "PROGRAM")
        wc.hCursor       = LoadCursor(%NULL, BYVAL %IDC_ARROW)
        wc.hbrBackground = GetStockObject( %LTGRAY_BRUSH )
        wc.lpszMenuName  = %NULL
        wc.lpszClassName = VARPTR(zClass)
        wc.hIconSm       = 0
        CALL RegisterClassEx(wc)
    '
        Style& = %WS_POPUP OR %WS_VISIBLE  OR %WS_SYSMENU 'OR %WS_CLIPCHILDREN
    '
        UseBitmap& = LoadImage(BYVAL 0&, (BmpFile$), %IMAGE_BITMAP, 0, 0, %LR_LOADFROMFILE) 
        CALL GetPixmapSize(UseBitmap&, Xout&, Yout&)
    '
        Style& = %WS_POPUP OR %WS_SYSMENU 
        StyleEx& = 0
        hFrame&  = CreateWindowEx( _
                   StyleEx&, _                ' window EXstyle
                   zClass, _                  ' window class name
                   zClass, _                  ' window title
                   Style&, _                  ' window style
                   x&, _                      ' initial x position
                   y&, _                      ' initial y position
                   Xout&, _                   ' initial x size
                   Yout&, _                   ' initial y size
                   %NULL, _                   ' parent window handle
                   %NULL, _                   ' window menu handle
                   hInstance&, _              ' program instance handle
                   BYVAL %NULL)               ' creation parameters
    '
        IF hFrame& THEN
    '
           IF UseBitmap& THEN
              hRgnClip& = ConvertBitmapToRgn(UseBitmap&, -1)
              IF hRgnClip& THEN CALL SetWindowRgn(hFrame&, hRgnClip&, %True)
           END IF
    '
           CALL ShowWindow(hFrame&, %SW_SHOW)
           CALL UpdateWindow(hFrame&)
    '
           WHILE GetMessage(Msg, %NULL, 0, 0)
              TranslateMessage Msg
              DispatchMessage Msg
           WEND
    '
           IF UseBitmap& THEN CALL DeleteObject(UseBitmap&)
    '
           FUNCTION = msg.wParam
        END IF
    '
    END FUNCTION
    ------------------
    Patrice Terrier
    mailto[email protected][email protected]</A>
    http://www.zapsolution.com
    Toolkit: WinLIFT (Skin Engine), GDI+ helper (Graphic package), dvBTree (Index manager)
    Freeware: ZAP Audio Player, ZAP Picture Browser.
    Artwork on demand.

    [This message has been edited by Patrice Terrier (edited March 18, 2004).]
    Patrice Terrier
    www.zapsolution.com
    www.objreader.com
    Addons: GDImage.DLL 32/64-bit (Graphic library), WinLIFT.DLL 32/64-bit (Skin Engine).

    Comment


    • #3
      Ok,
      Now done with EZGUI All I did was use the Designer, select the bitmap, placed a button on the form, then clicked "Generate". Much easier to do IMHO.

      Code:
      #COMPILE EXE
      #DIM ALL  
      #INCLUDE "ezgui30.inc" 
      
      DECLARE SUB Form1_Display(BYVAL Parent$)
      DECLARE SUB Form1_Design()
      DECLARE SUB Form1_Events(CID&, CMsg&, CVal&, Cancel&)
      ' ----------------------------------------------------------
      %FILE                                   = 4000
      ' ----------------------------------------------------------
      %NEWFILE                                = 4005
      %OPENFILE                               = 4010
      %SAVEFILE                               = 4015
      %SAVEAS                                 = 4020
      %SEPARATOR_4025                         = 4025
      %EXIT                                   = 4030
      ' ----------------------------------------------------------
      %EDIT                                   = 4100
      ' ----------------------------------------------------------
      %CUT                                    = 4105
      %COPY                                   = 4110
      %PASTE                                  = 4115
      ' ----------------------------------------------------------
      %HELP                                   = 4200
      ' ----------------------------------------------------------
      %HELP1                                  = 4205
      %BUTTON_CLOSE       = 100
      %STATUSBAR           = 110
      ' ------------------------------------------------
      DECLARE SUB BUTTON_CLOSE_Click()
      
      
      ' Global Handles for menus
      GLOBAL hMenu0&
      GLOBAL hMenu1&
      GLOBAL hMenu2&
      GLOBAL hMenu3&
      
      ' --------------------
      #INCLUDE "C:\Development\ezgui30\includes\ezwmain.inc"                          ' EZGUI Include file for WinMain
      ' --------------------
      
      SUB EZ_Main(VerNum&)
          EZ_DEFFONT 6, "Arial", 10, "V"
          EZ_DEFFONT 7, "Courier New", 10, "F"
          EZ_DEFFONT 8, "Times New Roman", 10, "V"
          EZ_DEFFONT 9, "Modern", 10, "V"
          Form1_Display ""
      END SUB
      
      SUB EZ_DesignWindow(FormName$)
          SELECT CASE FormName$
              CASE "FORM1"
                  Form1_Design
              CASE ELSE
          END SELECT
      END SUB
      
      ' -------------------------------------------------------------------------------------
      
      SUB EZ_Events(FormName$, CID&, CMsg&, CVal&, Cancel&)
          '      - NOTE:   EZGUI passes back Form Name in uppercase letters
          SELECT CASE FormName$
              CASE "FORM1"
                  Form1_Events CID&, CMsg&, CVal&, Cancel&
              CASE ELSE
          END SELECT
      END SUB
      
      ' -------------------------------------------------------------------------------------
      
      SUB Form1_Display(BYVAL Parent$)
          LOCAL PN$
          hMenu0&=EZ_DEFMAINMENU( %FILE, "&File", "")
          PN$=EZ_LOADPICTURE("C:\Development\Projects\Membership DB\family.bmp")
          EZ_SHAPEFORMTOPICTURE PN$, -1
          EZ_COLOR -1, -1
          EZ_FORM "FORM1", Parent$, "Your Dialog", 0, 0, 15.875, 5.5, "^_CRK"
          EZ_FREEIMAGE PN$
      END SUB
      ' ------------------------------------------------
      
      GLOBAL Form1_FF&
      
      SUB Form1_Design()
          LOCAL FF&
          '---------------------------------------------------------------
          FF& =  9              '          -  Offset for Font Numbers
          Form1_FF& = FF&          ' Global for ODButtons Draw code
          '---------------------------------------------------------------
          EZ_COLOR-1,-1
          EZ_USEFONT -1
          EZ_USEFONT 4
          EZ_BUTTON %BUTTON_CLOSE, 5.25, 2, 7.375, 1.5, "Close", "T"
          ' --------------------------------------------------------------
          EZ_USEFONT 4
          EZ_STATUSBAR %STATUSBAR, "", ""
      END SUB
      ' ------------------------------------------------
      
      SUB Form1_Events(CID&, CMsg&, CVal&, Cancel&)
          SELECT CASE CID&
              CASE %EZ_Window
                  IF CMsg&=%EZ_Close THEN
                  END IF
                  IF CMsg&=%EZ_LButtonDown THEN
                      EZ_DRAGFORM "Form1"
                  END IF
              CASE  %BUTTON_CLOSE
                  IF CMsg&=%EZ_Click THEN
                      BUTTON_CLOSE_Click
                  END IF
              CASE ELSE
          END SELECT
      END SUB
      
      SUB BUTTON_CLOSE_Click()
        EZ_Unload "FORM1"
      END SUB
      ------------------
      Joe Byrne
      mailto:[email protected]
      [email protected]
      </A>
      Software makes Hardware Happen

      Comment


      • #4
        Joe

        You can use cut and paste from my code into yours.
        I can't from yours



        ------------------
        Patrice Terrier
        mailto[email protected][email protected]</A>
        http://www.zapsolution.com
        Toolkit: WinLIFT (Skin Engine), GDI+ helper (Graphic package), dvBTree (Index manager)
        Freeware: ZAP Audio Player, ZAP Picture Browser.
        Artwork on demand.
        Patrice Terrier
        www.zapsolution.com
        www.objreader.com
        Addons: GDImage.DLL 32/64-bit (Graphic library), WinLIFT.DLL 32/64-bit (Skin Engine).

        Comment


        • #5
          Of course not. What's your point. I am simply showing how easy it is to do this with EZGUI, and the amount of code it takes to do so. If you had EZGUI, you certainly could use this code.

          The context of this thread is to show how one 3rd party application works, that's all, plain and simple.

          ------------------
          Joe Byrne
          mailto:[email protected]
          [email protected]
          </A>
          Software makes Hardware Happen

          Comment

          Working...
          X