ImageGadgetEx()

Share your advanced PureBasic knowledge/code with the community.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

ImageGadgetEx()

Post by netmaestro »

ImageGadgetEx is a PureBasic image gadget with an enhancement: It can contain a regular image or an image with alpha transparency. It works seamlessly for the programmer, you just use SetGadgetState as usual and pass either a normal image or an alpha image and the gadget does the rest. The DrawAlphaImage() command is not used here as I was able to achieve a faster alternative. iirc, (subject to correction by team) DrawAlphaImage takes a copy of the image, premultiplies the color bytes with the alpha values and passes the premultiplied copy to AlphaBlend_(), all of which takes time. In my solution, I'm keeping a list of previously-rendered images and saving the premultiplied copies. If the procedure receives an image to render that it has drawn before, the premultiplication step is skipped which results in a considerable saving in time. In speed tests where the same image is redrawn many times, my AlphaRender routine is approx. 8x faster than DrawAlphaImage (here, anyway.) It is an ideal approach for this application imho as an imagegadget gets repainted often and the repaints should happen as fast as possible. Another difference between my routine and DrawAlphaImage is that mine will handle a normal image as well. If you use DrawAlphaImage and pass it a 24-bit bmp, you will see nothing. Because I wanted my imagegadget to accept anything, I coded mine so that the AlphaRender routine would detect the lack of alpha values and switch to BitBlt_() where needed.

Use these images for the test: http://www.lloydsplace.com/chessimages.zip

It's early going, so please report any bugs or omissions.

Also, in testing the performance I found a huge difference between the debugger on and debugger off so if you have a large alpha image for the gadget and it feels a bit sluggish make sure you try with the debugger turned off, which is going to be the case for release software anyway.

Here it is:

Code: Select all

;==========================================================
; Library Command:      ImageGadgetEx
; Author:               Lloyd Gallant (netmaestro)
; Date:                 September 24, 2008
; Target OS:            Microsoft Windows all
; Target Compiler:      PureBasic 4.0 and later
; License:              Free, unrestricted, no warranty
;==========================================================

Prototype AlphaBlend(hdcDest,DestX,DestY,DestW,DestH,hdcSrc,SrcX,SrcY,SrcW,SrcH,BLENDFUNCTION)

Procedure PreMultiply(image)
  ; netmaestro 2008
  ; Helper function for AlphaRender
  
  imgout = CopyImage_(image, #IMAGE_BITMAP, 0, 0, #LR_CREATEDIBSECTION)
  
  GetObject_(imgout, SizeOf(BITMAP), bmp.BITMAP) 
  If bmp\bmBitsPixel <> 32
    ProcedureReturn image
  ElseIf bmp\bmBits = 0
    ProcedureReturn 0
  EndIf
  alphasfound=#False
  *bits.RGBQUAD = bmp\bmBits 
  For i=0 To bmp\bmHeight-1 
    For j=0 To bmp\bmWidthBytes-1 Step 4 
      *px.RGBQUAD = *bits + bmp\bmWidthBytes * i + j 
      If *px\rgbReserved > 0: alphasfound=#True : EndIf
      *px\rgbBlue = *px\rgbBlue & $FF * *px\rgbReserved & $FF / $FF      
      *px\rgbGreen = *px\rgbGreen & $FF * *px\rgbReserved & $FF / $FF
      *px\rgbRed = *px\rgbRed & $FF * *px\rgbReserved & $FF / $FF
    Next 
  Next 
  If alphasfound
    ProcedureReturn imgout
  Else
    DeleteObject_(imgout)
    ProcedureReturn image
  EndIf
EndProcedure

Procedure AlphaRender(imgIn, imgDest, x, y)
  ; netmaestro 2008
  ; Alternative to DrawAlphaImage()
  
  Structure Index 
    original.l   ; contains handles of all previously-rendered images
    premult.l    ; contains handles of premultiplied copies
  EndStructure
  
  Static firstrun = 1
  If firstrun
    Static NewList image.Index()
    firstrun = 0
  EndIf
  imgSrc = 0
  ForEach image()
    If image()\original = ImgIn
      ImgSrc = image()\premult
      Break
    EndIf
  Next
  If Not imgSrc
    imgSrc = Premultiply(imgIn)
    AddElement(image())
    image()\original = imgIn
    image()\premult = imgSrc
  EndIf
  
  hdcScreen = CreateDC_("DISPLAY",0,0,0)
  hdcDest = CreateCompatibleDC_(hdcScreen)
  hdcSrc  = CreateCompatibleDC_(hdcScreen)
  SelectObject_(hdcSrc, imgSrc)
  SelectObject_(hdcDest, imgDest)
  
  GetObject_(imgSrc, SizeOf(BITMAP), bmpSrc.BITMAP) 
  
  msimg32 = OpenLibrary(#PB_Any, "msimg32.dll")
  AlphaBlend_.AlphaBlend = GetFunction(msimg32, "AlphaBlend")
  
  If msimg32=0 Or bmpSrc\bmBitsPixel < 32 Or imgIn = image()\premult
    BitBlt_(hdcDest,x,y,bmpSrc\bmWidth,bmpSrc\bmHeight,hdcSrc,0,0,#SRCCOPY)
    result = 2
  Else
    result=AlphaBlend_(hdcDest,x,y,bmpSrc\bmWidth,bmpSrc\bmHeight,hdcSrc,0,0,bmpSrc\bmWidth,bmpSrc\bmHeight,$1FF0000)
  EndIf
  
  DeleteObject_(bmpSrc)
  DeleteDC_(hdcScreen)
  DeleteDC_(hdcSrc)
  DeleteDC_(hdcDest)
  If IsLibrary(msimg32)
    CloseLibrary(msimg32)
  EndIf
  
  ProcedureReturn result
  
EndProcedure

Procedure ige_ImageProc(hwnd, msg, wparam, lparam) 

  oldproc = GetProp_(hwnd, "ige_oldproc")
  ctrlid  = GetDlgCtrlID_(hwnd)

  Select msg 
     Case #WM_NCDESTROY
      RemoveProp_(hwnd, "ige_oldproc")
      
    Case #WM_PAINT 
      dcParent = GetDC_(GetParent_(hwnd))
      hdc = BeginPaint_(hwnd, ps.PAINTSTRUCT) 
      If GetGadgetState(ctrlid)
        GetObject_(GetGadgetState(ctrlid),SizeOf(BITMAP), bmp.BITMAP)
        w = bmp\bmWidth
        h = bmp\bmHeight
        base = CreateImage(#PB_Any,w,h,#PB_Image_DisplayFormat)
        dcOut = StartDrawing(ImageOutput(base)) 
          ; take a snapshot of the window background where the image will show 
          If GetWindowLong_(hwnd, #GWL_EXSTYLE) & #WS_EX_CLIENTEDGE 
            offset = GetSystemMetrics_(#SM_CXEDGE)
          Else
            offset = 0
          EndIf
          BitBlt_(dcOut, 0,0,ImageWidth(base),ImageHeight(base),dcParent,GadgetX(ctrlid)+offset,GadgetY(ctrlid)+offset,#SRCCOPY) 
        StopDrawing()
        ReleaseDC_(GetParent_(hwnd), dcParent)
        ; draw the alpha image onto it 
        AlphaRender(GetGadgetState(ctrlid),ImageID(base),0,0)
        ; render background & image together on the window 
        dcIn = StartDrawing(ImageOutput(base)) 
          BitBlt_(hdc, 0,0,ImageWidth(base),ImageHeight(base),dcIn,0,0,#SRCCOPY) 
        StopDrawing() 
        FreeImage(base)
      EndIf
      EndPaint_(hwnd, ps) 
      ProcedureReturn 0 
  EndSelect 
  
  ProcedureReturn CallWindowProc_(oldproc, hwnd, msg, wparam, lparam)
  
EndProcedure 

Procedure ImageGadgetEx(gadgetnumber,x,y,width,height,imageID=0,flags=0)
  If gadgetnumber = #PB_Any
    ige_ctrlid = ImageGadget(#PB_Any,x,y,width,height,0,flags)
    ige_hwnd = GadgetID(ige_ctrlid)
    result = ige_ctrlid
  Else
    ige_hwnd = ImageGadget(gadgetnumber,x,y,width,height,0,flags)
    ige_ctrlid = gadgetnumber
    result = ige_hwnd
  EndIf

  oldproc = SetWindowLong_(ige_hwnd,#GWL_WNDPROC,@ige_ImageProc())
  SetProp_(ige_hwnd, "ige_oldproc", oldproc)
  
  SetGadgetState(ige_ctrlid,imageID)
  
  ProcedureReturn result
EndProcedure
Test program:

Code: Select all

IncludeFile "imagegadgetex.pbi" 

#offset = 34 
#size   = 64 

Structure SQUARE 
  ctrlid.l      ; gadget number 
  x.l           ; x coordinate 
  y.l           ; y coordinate 
  name.s{2}     ; square name, e.g. "A1", etc. 
EndStructure 

Global rgn_bishop = ExtCreateRegion_(0,?rgn_bishopend-?rgn_bishop, ?rgn_bishop) 
Global rgn_knight = ExtCreateRegion_(0,?rgn_knightend-?rgn_knight, ?rgn_knight) 

Global hand = LoadCursor_(0, #IDC_HAND), arrow = LoadCursor_(0, #IDC_ARROW) 
Global activeimage, activeregion, move_active, offs_x, offs_y, boardimage_in, boardimage_out, tid 

boardimage_in = CreateImage(#PB_Any, 580, 580, #PB_Image_DisplayFormat) 

UsePNGImageDecoder() 

Global bkg    = CatchImage(#PB_Any, ?bkg, ?bkgend-?bkg) 
bishop = CatchImage(#PB_Any, ?bishop, ?bishopend-?bishop) 
knight = CatchImage(#PB_Any, ?knight, ?knightend-?knight) 

Global NewList squares.SQUARE() 

For j=7 To 0 Step -1 
  For i=0 To 7 
    AddElement(squares()) 
    With squares() 
      \ctrlid = 0 
      \x = #offset + (i*64) 
      \y = #offset + ((7-j)*64) 
      \name = Chr(65+i)+Chr(49+j) 
    EndWith 
  Next 
Next 

Procedure FindSquare(square$) 
  ForEach squares() 
    If squares()\name = square$ 
      ProcedureReturn @squares() 
    EndIf 
  Next 
  ProcedureReturn -1 
EndProcedure 

Procedure GrabBoard(ctrlid) 
  tmp = GrabImage(bkg,#PB_Any,GadgetX(ctrlid),GadgetY(ctrlid),64,64)
  hdcIn  = GetDC_(WindowID(0)) 
  hdcOut = StartDrawing(ImageOutput(boardimage_in)) 
    BitBlt_(hdcOut,0,0,580,580,hdcIn,0,0,#SRCCOPY) 
    DrawImage(ImageID(tmp),GadgetX(ctrlid),GadgetY(ctrlid))
  StopDrawing() 
  FreeImage(tmp)
  ReleaseDC_(WindowID(0),hdcIn)
EndProcedure 

Procedure PieceMove_Thread(ctrlid) 
  ExamineDesktops() 
  OptimalDelay = 1000/DesktopFrequency(0) 
  timeGetDevCaps_(tc.TIMECAPS, SizeOf(TIMECAPS)) 
  timeBeginPeriod_(tc\wPeriodMin) 
  With boardrect.RECT 
    \left = WindowX(0)+#offset+5 
    \top  = WindowY(0)+#offset+25 
    \right = \left+506 
    \bottom = \top+506 
  EndWith 
  ClipCursor_(boardrect) 
  SetGadgetState(ctrlid, 0)
  While move_active 
    t1 = timeGetTime_() 
    mouse_x = lparam>>16 
    mouse_y = lparam&$FFFF 
    boardimage_out = GrabImage(boardimage_in,#PB_Any,0,0,580,580) 
    AlphaRender(activeimage,ImageID(boardimage_out),WindowMouseX(0)-offs_x,WindowMouseY(0)-offs_y) 
    StartDrawing(WindowOutput(0)) 
      DrawImage(ImageID(boardimage_out),0,0) 
    StopDrawing() 
    FreeImage(boardimage_out) 
    drawingtime = timeGetTime_()-t1 
    Delay(Int(Abs(OptimalDelay-drawingtime))) 
  Wend 
  timeEndPeriod_(tc\wPeriodMin) 
EndProcedure 

Procedure ImageProc(hwnd, msg, wparam, lparam) 
  oldproc = GetProp_(hwnd, "oldproc") 
  ctrlid = GetDlgCtrlID_(hwnd) 
  
  Select msg 
    Case #WM_NCDESTROY 
      RemoveProp_(hwnd, "oldproc") 
      
    Case #WM_SETCURSOR 
      rgn = GetProp_(hwnd, "region") 
      GetCursorPos_(cp.point) 
      MapWindowPoints_(0,hwnd, cp,1) 
      If PtInRegion_(rgn, cp\x+4, cp\y) 
        SetCursor_(hand) 
        ProcedureReturn #True 
      Else 
        SetCursor_(arrow) 
      EndIf 
      
    Case #WM_LBUTTONDOWN 
      rgn = GetProp_(hwnd, "region")          ; get the square's region for hittesting 
      GetCursorPos_(cp.point)                 ; do the hittest 
      MapWindowPoints_(0,hwnd, cp,1)          ;      " 
      If PtInRegion_(rgn, cp\x+4, cp\y)       ;      " 
        SetCapture_(WindowID(0))              ; transfer mouse messages to parent window for the move      
        offs_x = cp\x : offs_y = cp\y         ; store cursor offsets for when parent draws the moved piece 
        activeimage  = GetGadgetState(ctrlid) ; save imageid to drop on target square 
        activeregion = rgn                    ; save region to store in target square 
        SetProp_(hwnd, "region", 0)           ; remove region from this square 
        GrabBoard(ctrlid)                     ; get current board image minus the moving piece 
        move_active = #True                   ; set global var to indicate a move in progress 
        tid = CreateThread(@PieceMove_Thread(),ctrlid) ; start the move thread 
        ThreadPriority(tid, 17)                   ; give it above-normal priority 
      EndIf 
      ProcedureReturn 0 
      
  EndSelect 
  ProcedureReturn CallWindowProc_(oldproc, hwnd, msg, wparam, lparam) 
EndProcedure 

Procedure WindowProc(hwnd, msg, wparam, lparam) 
  result = #PB_ProcessPureBasicEvents 
  
  Select msg 
    Case #WM_SETCURSOR 
      If move_active 
        SetCursor_(hand) 
        ProcedureReturn #True 
      EndIf 

    Case #WM_LBUTTONUP 
      If move_active 
        ReleaseCapture_() 
        move_active = #False 
        ClipCursor_(0) 
        targetsquare = GetDlgCtrlID_(ChildWindowFromPoint_(WindowID(0),WindowMouseX(0),WindowMouseY(0))) 
        WaitThread(tid) 
        StartDrawing(WindowOutput(0)) 
          DrawImage(ImageID(boardimage_in),0,0) 
        StopDrawing() 
        SetGadgetState(targetsquare, 0) 
        SetGadgetState(targetsquare, activeimage) 
        SetProp_(GadgetID(targetsquare), "region", activeregion) 
      EndIf 
      
  EndSelect 
  
  ProcedureReturn result 
  
EndProcedure 

hBrush = CreatePatternBrush_(ImageID(bkg)) 
OpenWindow(0,0,0,580,580,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu|#PB_Window_Invisible) 
SetWindowCallback(@WindowProc()) 
CompilerIf #PB_Compiler_Version <= 420 : CreateGadgetList(WindowID(0)) : CompilerEndIf 
SetClassLong_(WindowID(0),#GCL_HBRBACKGROUND,hBrush) 
InvalidateRect_(WindowID(0),0,1) 

ForEach squares() 
  cc+1 
  With squares() 
    \ctrlid = cc: ImageGadgetEx(cc, \x, \y, #size, #size, 0) 
    SetProp_(GadgetID(cc), "oldproc", SetWindowLong_(GadgetID(cc),#GWL_WNDPROC,@ImageProc())) 
  EndWith 
Next 

; Place a bishop on C1 
FindSquare("C1") 
SetGadgetState(squares()\ctrlid, ImageID(bishop)) 
SetProp_(GadgetID(squares()\ctrlid), "region", rgn_bishop) 

; Place a knight on B1 
FindSquare("B1") 
SetGadgetState(squares()\ctrlid, ImageID(knight)) 
SetProp_(GadgetID(squares()\ctrlid), "region", rgn_knight) 

HideWindow(0,0) 

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow 

DeleteObject_(hBrush) 

DataSection 
  ; Images 
    bishop: IncludeBinary "bishop.png"      : bishopend: 
    knight: IncludeBinary "knight.png"      : knightend: 
    bkg: IncludeBinary    "board_grain.png" : bkgend: 
  
  ; Regions 
    rgn_bishop: 
    Data.b $20,$00,$00,$00,$01,$00,$00,$00,$3D,$00,$00,$00,$D0,$03,$00,$00 
    Data.b $07,$00,$00,$00,$05,$00,$00,$00,$3E,$00,$00,$00,$3A,$00,$00,$00 
    Data.b $20,$00,$00,$00,$05,$00,$00,$00,$25,$00,$00,$00,$06,$00,$00,$00 
    Data.b $1F,$00,$00,$00,$06,$00,$00,$00,$26,$00,$00,$00,$07,$00,$00,$00 
    Data.b $1E,$00,$00,$00,$07,$00,$00,$00,$27,$00,$00,$00,$09,$00,$00,$00 
    Data.b $1D,$00,$00,$00,$09,$00,$00,$00,$28,$00,$00,$00,$0A,$00,$00,$00 
    Data.b $1E,$00,$00,$00,$0A,$00,$00,$00,$28,$00,$00,$00,$0B,$00,$00,$00 
    Data.b $1E,$00,$00,$00,$0B,$00,$00,$00,$27,$00,$00,$00,$0E,$00,$00,$00 
    Data.b $1D,$00,$00,$00,$0E,$00,$00,$00,$28,$00,$00,$00,$0F,$00,$00,$00 
    Data.b $1B,$00,$00,$00,$0F,$00,$00,$00,$1C,$00,$00,$00,$10,$00,$00,$00 
    Data.b $1D,$00,$00,$00,$0F,$00,$00,$00,$28,$00,$00,$00,$10,$00,$00,$00 
    Data.b $29,$00,$00,$00,$0F,$00,$00,$00,$2A,$00,$00,$00,$10,$00,$00,$00 
    Data.b $1B,$00,$00,$00,$10,$00,$00,$00,$2A,$00,$00,$00,$11,$00,$00,$00 
    Data.b $18,$00,$00,$00,$11,$00,$00,$00,$2C,$00,$00,$00,$12,$00,$00,$00 
    Data.b $18,$00,$00,$00,$12,$00,$00,$00,$2D,$00,$00,$00,$13,$00,$00,$00 
    Data.b $17,$00,$00,$00,$13,$00,$00,$00,$2E,$00,$00,$00,$14,$00,$00,$00 
    Data.b $16,$00,$00,$00,$14,$00,$00,$00,$2F,$00,$00,$00,$15,$00,$00,$00 
    Data.b $14,$00,$00,$00,$15,$00,$00,$00,$30,$00,$00,$00,$16,$00,$00,$00 
    Data.b $14,$00,$00,$00,$16,$00,$00,$00,$31,$00,$00,$00,$17,$00,$00,$00 
    Data.b $13,$00,$00,$00,$17,$00,$00,$00,$31,$00,$00,$00,$18,$00,$00,$00 
    Data.b $14,$00,$00,$00,$18,$00,$00,$00,$31,$00,$00,$00,$1A,$00,$00,$00 
    Data.b $13,$00,$00,$00,$1A,$00,$00,$00,$32,$00,$00,$00,$1B,$00,$00,$00 
    Data.b $14,$00,$00,$00,$1B,$00,$00,$00,$32,$00,$00,$00,$1C,$00,$00,$00 
    Data.b $14,$00,$00,$00,$1C,$00,$00,$00,$31,$00,$00,$00,$1D,$00,$00,$00 
    Data.b $13,$00,$00,$00,$1D,$00,$00,$00,$31,$00,$00,$00,$1E,$00,$00,$00 
    Data.b $14,$00,$00,$00,$1E,$00,$00,$00,$31,$00,$00,$00,$1F,$00,$00,$00 
    Data.b $15,$00,$00,$00,$1F,$00,$00,$00,$31,$00,$00,$00,$20,$00,$00,$00 
    Data.b $14,$00,$00,$00,$20,$00,$00,$00,$30,$00,$00,$00,$21,$00,$00,$00 
    Data.b $16,$00,$00,$00,$21,$00,$00,$00,$30,$00,$00,$00,$22,$00,$00,$00 
    Data.b $16,$00,$00,$00,$22,$00,$00,$00,$2F,$00,$00,$00,$23,$00,$00,$00 
    Data.b $18,$00,$00,$00,$23,$00,$00,$00,$2E,$00,$00,$00,$24,$00,$00,$00 
    Data.b $18,$00,$00,$00,$24,$00,$00,$00,$2D,$00,$00,$00,$25,$00,$00,$00 
    Data.b $19,$00,$00,$00,$25,$00,$00,$00,$2C,$00,$00,$00,$26,$00,$00,$00 
    Data.b $18,$00,$00,$00,$26,$00,$00,$00,$2D,$00,$00,$00,$27,$00,$00,$00 
    Data.b $16,$00,$00,$00,$27,$00,$00,$00,$2E,$00,$00,$00,$29,$00,$00,$00 
    Data.b $17,$00,$00,$00,$29,$00,$00,$00,$2F,$00,$00,$00,$2C,$00,$00,$00 
    Data.b $17,$00,$00,$00,$2C,$00,$00,$00,$2E,$00,$00,$00,$2D,$00,$00,$00 
    Data.b $0D,$00,$00,$00,$2D,$00,$00,$00,$0E,$00,$00,$00,$2E,$00,$00,$00 
    Data.b $12,$00,$00,$00,$2D,$00,$00,$00,$14,$00,$00,$00,$2E,$00,$00,$00 
    Data.b $19,$00,$00,$00,$2D,$00,$00,$00,$2D,$00,$00,$00,$2E,$00,$00,$00 
    Data.b $0C,$00,$00,$00,$2E,$00,$00,$00,$15,$00,$00,$00,$2F,$00,$00,$00 
    Data.b $1C,$00,$00,$00,$2E,$00,$00,$00,$2A,$00,$00,$00,$2F,$00,$00,$00 
    Data.b $30,$00,$00,$00,$2E,$00,$00,$00,$39,$00,$00,$00,$2F,$00,$00,$00 
    Data.b $09,$00,$00,$00,$2F,$00,$00,$00,$17,$00,$00,$00,$30,$00,$00,$00 
    Data.b $1B,$00,$00,$00,$2F,$00,$00,$00,$3B,$00,$00,$00,$30,$00,$00,$00 
    Data.b $09,$00,$00,$00,$30,$00,$00,$00,$3C,$00,$00,$00,$31,$00,$00,$00 
    Data.b $08,$00,$00,$00,$31,$00,$00,$00,$3D,$00,$00,$00,$32,$00,$00,$00 
    Data.b $08,$00,$00,$00,$32,$00,$00,$00,$3E,$00,$00,$00,$33,$00,$00,$00 
    Data.b $07,$00,$00,$00,$33,$00,$00,$00,$3D,$00,$00,$00,$34,$00,$00,$00 
    Data.b $09,$00,$00,$00,$34,$00,$00,$00,$3D,$00,$00,$00,$35,$00,$00,$00 
    Data.b $08,$00,$00,$00,$35,$00,$00,$00,$3C,$00,$00,$00,$36,$00,$00,$00 
    Data.b $0A,$00,$00,$00,$36,$00,$00,$00,$22,$00,$00,$00,$37,$00,$00,$00 
    Data.b $24,$00,$00,$00,$36,$00,$00,$00,$3C,$00,$00,$00,$37,$00,$00,$00 
    Data.b $09,$00,$00,$00,$37,$00,$00,$00,$11,$00,$00,$00,$38,$00,$00,$00 
    Data.b $16,$00,$00,$00,$37,$00,$00,$00,$21,$00,$00,$00,$38,$00,$00,$00 
    Data.b $25,$00,$00,$00,$37,$00,$00,$00,$2F,$00,$00,$00,$38,$00,$00,$00 
    Data.b $35,$00,$00,$00,$37,$00,$00,$00,$3B,$00,$00,$00,$38,$00,$00,$00 
    Data.b $0B,$00,$00,$00,$38,$00,$00,$00,$0F,$00,$00,$00,$39,$00,$00,$00 
    Data.b $19,$00,$00,$00,$38,$00,$00,$00,$1E,$00,$00,$00,$39,$00,$00,$00 
    Data.b $27,$00,$00,$00,$38,$00,$00,$00,$2C,$00,$00,$00,$39,$00,$00,$00 
    Data.b $37,$00,$00,$00,$38,$00,$00,$00,$3B,$00,$00,$00,$39,$00,$00,$00 
    Data.b $0B,$00,$00,$00,$39,$00,$00,$00,$0E,$00,$00,$00,$3A,$00,$00,$00 
    Data.b $38,$00,$00,$00,$39,$00,$00,$00,$3A,$00,$00,$00,$3A,$00,$00,$00 
    rgn_bishopend: 
    rgn_knight: 
    Data.b $20,$00,$00,$00,$01,$00,$00,$00,$43,$00,$00,$00,$30,$04,$00,$00 
    Data.b $08,$00,$00,$00,$04,$00,$00,$00,$3E,$00,$00,$00,$3A,$00,$00,$00 
    Data.b $14,$00,$00,$00,$04,$00,$00,$00,$15,$00,$00,$00,$05,$00,$00,$00 
    Data.b $1F,$00,$00,$00,$04,$00,$00,$00,$21,$00,$00,$00,$05,$00,$00,$00 
    Data.b $13,$00,$00,$00,$05,$00,$00,$00,$18,$00,$00,$00,$06,$00,$00,$00 
    Data.b $1E,$00,$00,$00,$05,$00,$00,$00,$23,$00,$00,$00,$06,$00,$00,$00 
    Data.b $13,$00,$00,$00,$06,$00,$00,$00,$19,$00,$00,$00,$07,$00,$00,$00 
    Data.b $1D,$00,$00,$00,$06,$00,$00,$00,$24,$00,$00,$00,$07,$00,$00,$00 
    Data.b $13,$00,$00,$00,$07,$00,$00,$00,$1A,$00,$00,$00,$08,$00,$00,$00 
    Data.b $1D,$00,$00,$00,$07,$00,$00,$00,$23,$00,$00,$00,$08,$00,$00,$00 
    Data.b $12,$00,$00,$00,$08,$00,$00,$00,$1B,$00,$00,$00,$09,$00,$00,$00 
    Data.b $1C,$00,$00,$00,$08,$00,$00,$00,$25,$00,$00,$00,$09,$00,$00,$00 
    Data.b $12,$00,$00,$00,$09,$00,$00,$00,$24,$00,$00,$00,$0A,$00,$00,$00 
    Data.b $13,$00,$00,$00,$0A,$00,$00,$00,$28,$00,$00,$00,$0B,$00,$00,$00 
    Data.b $13,$00,$00,$00,$0B,$00,$00,$00,$29,$00,$00,$00,$0C,$00,$00,$00 
    Data.b $2A,$00,$00,$00,$0B,$00,$00,$00,$2C,$00,$00,$00,$0C,$00,$00,$00 
    Data.b $14,$00,$00,$00,$0C,$00,$00,$00,$2E,$00,$00,$00,$0D,$00,$00,$00 
    Data.b $13,$00,$00,$00,$0D,$00,$00,$00,$30,$00,$00,$00,$0E,$00,$00,$00 
    Data.b $12,$00,$00,$00,$0E,$00,$00,$00,$31,$00,$00,$00,$0F,$00,$00,$00 
    Data.b $11,$00,$00,$00,$0F,$00,$00,$00,$32,$00,$00,$00,$10,$00,$00,$00 
    Data.b $11,$00,$00,$00,$10,$00,$00,$00,$33,$00,$00,$00,$11,$00,$00,$00 
    Data.b $10,$00,$00,$00,$11,$00,$00,$00,$33,$00,$00,$00,$12,$00,$00,$00 
    Data.b $10,$00,$00,$00,$12,$00,$00,$00,$34,$00,$00,$00,$13,$00,$00,$00 
    Data.b $10,$00,$00,$00,$13,$00,$00,$00,$35,$00,$00,$00,$14,$00,$00,$00 
    Data.b $0F,$00,$00,$00,$14,$00,$00,$00,$36,$00,$00,$00,$16,$00,$00,$00 
    Data.b $0F,$00,$00,$00,$16,$00,$00,$00,$37,$00,$00,$00,$17,$00,$00,$00 
    Data.b $0F,$00,$00,$00,$17,$00,$00,$00,$38,$00,$00,$00,$19,$00,$00,$00 
    Data.b $0E,$00,$00,$00,$19,$00,$00,$00,$39,$00,$00,$00,$1A,$00,$00,$00 
    Data.b $0D,$00,$00,$00,$1A,$00,$00,$00,$39,$00,$00,$00,$1C,$00,$00,$00 
    Data.b $0C,$00,$00,$00,$1C,$00,$00,$00,$3A,$00,$00,$00,$1D,$00,$00,$00 
    Data.b $0B,$00,$00,$00,$1D,$00,$00,$00,$3A,$00,$00,$00,$1E,$00,$00,$00 
    Data.b $0B,$00,$00,$00,$1E,$00,$00,$00,$3B,$00,$00,$00,$1F,$00,$00,$00 
    Data.b $0A,$00,$00,$00,$1F,$00,$00,$00,$3B,$00,$00,$00,$20,$00,$00,$00 
    Data.b $09,$00,$00,$00,$20,$00,$00,$00,$3B,$00,$00,$00,$21,$00,$00,$00 
    Data.b $09,$00,$00,$00,$21,$00,$00,$00,$3C,$00,$00,$00,$22,$00,$00,$00 
    Data.b $08,$00,$00,$00,$22,$00,$00,$00,$23,$00,$00,$00,$23,$00,$00,$00 
    Data.b $24,$00,$00,$00,$22,$00,$00,$00,$3C,$00,$00,$00,$23,$00,$00,$00 
    Data.b $08,$00,$00,$00,$23,$00,$00,$00,$21,$00,$00,$00,$24,$00,$00,$00 
    Data.b $24,$00,$00,$00,$23,$00,$00,$00,$3C,$00,$00,$00,$24,$00,$00,$00 
    Data.b $08,$00,$00,$00,$24,$00,$00,$00,$1F,$00,$00,$00,$25,$00,$00,$00 
    Data.b $24,$00,$00,$00,$24,$00,$00,$00,$3D,$00,$00,$00,$25,$00,$00,$00 
    Data.b $09,$00,$00,$00,$25,$00,$00,$00,$1D,$00,$00,$00,$26,$00,$00,$00 
    Data.b $23,$00,$00,$00,$25,$00,$00,$00,$3D,$00,$00,$00,$26,$00,$00,$00 
    Data.b $09,$00,$00,$00,$26,$00,$00,$00,$1C,$00,$00,$00,$27,$00,$00,$00 
    Data.b $1D,$00,$00,$00,$26,$00,$00,$00,$1F,$00,$00,$00,$27,$00,$00,$00 
    Data.b $23,$00,$00,$00,$26,$00,$00,$00,$3D,$00,$00,$00,$27,$00,$00,$00 
    Data.b $09,$00,$00,$00,$27,$00,$00,$00,$1B,$00,$00,$00,$28,$00,$00,$00 
    Data.b $1C,$00,$00,$00,$27,$00,$00,$00,$1D,$00,$00,$00,$28,$00,$00,$00 
    Data.b $21,$00,$00,$00,$27,$00,$00,$00,$3D,$00,$00,$00,$28,$00,$00,$00 
    Data.b $08,$00,$00,$00,$28,$00,$00,$00,$1C,$00,$00,$00,$29,$00,$00,$00 
    Data.b $20,$00,$00,$00,$28,$00,$00,$00,$3D,$00,$00,$00,$29,$00,$00,$00 
    Data.b $08,$00,$00,$00,$29,$00,$00,$00,$1A,$00,$00,$00,$2A,$00,$00,$00 
    Data.b $1F,$00,$00,$00,$29,$00,$00,$00,$3D,$00,$00,$00,$2A,$00,$00,$00 
    Data.b $09,$00,$00,$00,$2A,$00,$00,$00,$19,$00,$00,$00,$2B,$00,$00,$00 
    Data.b $1E,$00,$00,$00,$2A,$00,$00,$00,$3E,$00,$00,$00,$2B,$00,$00,$00 
    Data.b $0B,$00,$00,$00,$2B,$00,$00,$00,$18,$00,$00,$00,$2C,$00,$00,$00 
    Data.b $1D,$00,$00,$00,$2B,$00,$00,$00,$3E,$00,$00,$00,$2C,$00,$00,$00 
    Data.b $0B,$00,$00,$00,$2C,$00,$00,$00,$17,$00,$00,$00,$2D,$00,$00,$00 
    Data.b $18,$00,$00,$00,$2C,$00,$00,$00,$19,$00,$00,$00,$2D,$00,$00,$00 
    Data.b $1C,$00,$00,$00,$2C,$00,$00,$00,$3E,$00,$00,$00,$2D,$00,$00,$00 
    Data.b $0C,$00,$00,$00,$2D,$00,$00,$00,$16,$00,$00,$00,$2E,$00,$00,$00 
    Data.b $1B,$00,$00,$00,$2D,$00,$00,$00,$3E,$00,$00,$00,$2E,$00,$00,$00 
    Data.b $0F,$00,$00,$00,$2E,$00,$00,$00,$14,$00,$00,$00,$2F,$00,$00,$00 
    Data.b $1A,$00,$00,$00,$2E,$00,$00,$00,$3E,$00,$00,$00,$2F,$00,$00,$00 
    Data.b $1A,$00,$00,$00,$2F,$00,$00,$00,$3E,$00,$00,$00,$31,$00,$00,$00 
    Data.b $19,$00,$00,$00,$31,$00,$00,$00,$3E,$00,$00,$00,$33,$00,$00,$00 
    Data.b $18,$00,$00,$00,$33,$00,$00,$00,$3E,$00,$00,$00,$37,$00,$00,$00 
    Data.b $17,$00,$00,$00,$37,$00,$00,$00,$3E,$00,$00,$00,$39,$00,$00,$00 
    Data.b $18,$00,$00,$00,$39,$00,$00,$00,$3E,$00,$00,$00,$3A,$00,$00,$00 
    rgn_knightend: 
  
EndDataSection 
Last edited by netmaestro on Sat Jun 12, 2010 5:58 pm, edited 5 times in total.
BERESHEIT
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Brilliant! :)

Looks great on Vista!
I may look like a mule, but I'm not a complete ass.
Little John
Addict
Addict
Posts: 4791
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Post by Little John »

When I run "test.pb" with PureBasic 4.20 on Windows XP SP3, the GUI opens the file "imagegadgetex.pbi" and shows an error on line 147:

Code: Select all

ige_ctrlid = ImageGadget(#PB_Any,x,y,width,height,0,flags)
The error message is:
There is no current GadgetList.
Regards, Little John
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

The code is written for PB 4.3. For 4.2 just add a CreateGadgetList(...) after the OpenWindow() command in the test program.
I may look like a mule, but I'm not a complete ass.
Little John
Addict
Addict
Posts: 4791
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Post by Little John »

srod wrote:The code is written for PB 4.3.
That was actually my first guess, but
ImageGadgetEx.pbi wrote:; Target Compiler: PureBasic 4.0 and later
:o
srod wrote:For 4.2 just add a CreateGadgetList(...) after the OpenWindow() command in the test program.
Works fine now, thank you! And thanks to netmaestro for sharing!

Regards, Little John
akj
Enthusiast
Enthusiast
Posts: 668
Joined: Mon Jun 09, 2003 10:08 pm
Location: Nottingham

Post by akj »

@netmaestro

Thank you very much for this contribution. I will certainly find it useful.
However there is one minor problem:

When I run the test program and then close it by clicking the X at the top right of the window, it always crashes within the procedure ImageProc() at the line

Code: Select all

ProcedureReturn CallWindowProc_(oldproc, hwnd, msg, wparam, lparam)
with the error: Invalid memory access (read error at address 4294967295)

I am using Windows ME (the 32-bit version in case you were unsure).
Anthony Jordan
milan1612
Addict
Addict
Posts: 894
Joined: Thu Apr 05, 2007 12:15 am
Location: Nuremberg, Germany
Contact:

Post by milan1612 »

Works fine here on XP, nice work! :P
Windows 7 & PureBasic 4.4
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

@akj : try changing #WM_DESTROY in the window proc to #WM_NCDESTROY.
I may look like a mule, but I'm not a complete ass.
akj
Enthusiast
Enthusiast
Posts: 668
Joined: Mon Jun 09, 2003 10:08 pm
Location: Nottingham

Post by akj »

@srod: Thanks. #WM_NCDESTROY solved it.

@netmaestro: Is it possible to download images of the remaining chess pieces?
Anthony Jordan
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

Good one, srod I don't know how I overlooked that. Typing too fast I guess.

@akj: On the graphics, they're going into a commercial project so I can't accomodate you there, sorry. You're welcome to the board though.
BERESHEIT
User avatar
NoahPhense
Addict
Addict
Posts: 1999
Joined: Thu Oct 16, 2003 8:30 pm
Location: North Florida

Re: ImageGadgetEx()

Post by NoahPhense »

Damn.. I wanted to move the chess piece and watch it snap into place. :)

- np
User avatar
Demivec
Addict
Addict
Posts: 4270
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Post by Demivec »

@netmaestro: I am working at becoming more familiar with API, please forgive me if this is a naive observation.

In looking at ImageGadgetEx.pbi it shows:

Code: Select all

;as part of procedure AlphaRender()
GetObject_(imgSrc, SizeOf(BITMAP), bmpSrc.BITMAP) ;Line 80
;
;
DeleteObject_(bmpSrc);Line 91
You seem to be treating bmpSrc as both an object and as a buffer. Is the code correct?
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

No, the DeleteObject is just a mistake. It isn't appropriate for that variable.
BERESHEIT
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

For a bit more advanced test program, see: http://www.greatlakescode.com/test2.pb

(if you already have the library download in the first post)
BERESHEIT
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Post by ts-soft »

netmaestro wrote:For a bit more advanced test program, see: http://www.greatlakescode.com/test2.pb

(if you already have the library download in the first post)
will not work :cry:
duplicate procedure line 80

:D good code
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
Post Reply