Draggable image on transparent window

Just starting out? Need help? Post your questions and find answers here.
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4789
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

@srod

Post by Fangbeast »

You wondered what use a drop target is (apart from the download manager I mentioned)

Just a small example. Most of the people I know of do genealogy and they either subscribe to a genealogical database or share packets between them by email (called "tiny tafels").

Not all of them can afford expensive programs that can do download and import direct through the program interface, most of them have fairly simple software.

I'm thinking of a simple tafel packet importer where they drag the packet onto the drag target as it comes in (I know they could wait until they have many packets and do a mass import but these people work in real time) and it immediately adds it to their database.

Just one of my useless ideas.
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

I think your latest request requires a different approach (truth be told I'm not very experienced with layered windows).

Here's one way using a routine of Netmaestro's which alters the window region to match that part of the image which is not declared as transparent (white in this example).

Code: Select all

Global gTranscolor=#White ;Alter to match your own transparent colour.

Procedure ScanRegion(image) 
  Protected width, height 
  width = ImageWidth(image) 
  height = ImageHeight(image) 
  hRgn = CreateRectRgn_(0, 0, Width, Height) 
  StartDrawing(ImageOutput(image)) 
    For y=0 To ImageHeight(image) 
      For x=0 To ImageWidth(image) 
        color = Point(x,y) 
        If color = gTranscolor
          hTmpRgn = CreateRectRgn_(x,y,x+1,y+1) 
          CombineRgn_(hRgn, hRgn, hTmpRgn, #RGN_XOR) 
          DeleteObject_(hTmpRgn) 
        EndIf 
      Next 
    Next 
  StopDrawing() 
  ProcedureReturn hRgn; 
EndProcedure 

LoadImage(0, "bmd1.bmp") 
mainrgn = ScanRegion(0) 

OpenWindow(0, 250, 250, 512, 384, "", #PB_Window_BorderLess | #PB_Window_Invisible) 
SetWindowLong_(WindowID(0), #GWL_EXSTYLE, GetWindowLong_(WindowID(0), #GWL_EXSTYLE) | #WS_EX_TOOLWINDOW) 
;Change the window region to remove the transparent portion of the image.
  SetWindowRgn_(WindowID(0),mainrgn,1) 
;Set the window background to the image.
  hBrush = CreatePatternBrush_(ImageID(0)) 
  SetClassLong_(WindowID(0),#GCL_HBRBACKGROUND,hBrush) 
;Show the window.
HideWindow(0,0)

Repeat 
  Select WaitWindowEvent() 
    Case #PB_Event_CloseWindow 
      Break 
    Case #WM_RBUTTONUP 
      CreatePopupMenu(0) 
      MenuItem(0, "Close") 
      DisplayPopupMenu(0, WindowID(0)) 
    Case #PB_Event_Menu 
      Break
    Case #WM_LBUTTONDOWN 
      SendMessage_(WindowID(0), #WM_NCLBUTTONDOWN, #HTCAPTION, 0) 
  EndSelect 
ForEver 
You'll probably want to switch the scan region procedure above for Netmaestro's latest offering in the tricks and tips forum as it looks very very fast indeed.
I may look like a mule, but I'm not a complete ass.
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4789
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Hmm, no drag (No, I am not wearing drag!)

Post by Fangbeast »

I have put NetMaestro's fast region scan in on your advice but it also replaces most of your lines so I am at a loss to figure out what allows the dragging around of the image?

Thought I had the essentials down but obviously lot. What a tiny brain!

Code: Select all

;============================================================================================================================
; 
;============================================================================================================================

Declare GrabRegion(ImageID, transcolor)

;============================================================================================================================
; Very fast bitmap -> region creator, By netmaestro, Contributors: eesau, nico, June 26, 2007
;============================================================================================================================

ProcedureDLL GrabRegion(ImageID, transcolor) ; HBITMAP ImageID, COLORREF transcolor

  Structure RGBTRIPLEC
    rgbtBlue.c
    rgbtGreen.c
    rgbtRed.c
  EndStructure

  GetObject_(ImageID, SizeOf(BITMAP), @bmp.BITMAP)
  Protected width       = bmp\bmWidth
  Protected height      = bmp\bmHeight
  Protected hVisibleRgn = CreateRectRgn_(0, 0, width, height)
  Protected tred        = Red(transcolor)
  Protected tgreen      = Green(transcolor)
  Protected tblue       = Blue(transcolor)
 
  BmiInfo.BITMAPINFOHEADER
  With BmiInfo
    \biSize         = SizeOf(BITMAPINFOHEADER)
    \biWidth        = width
    \biHeight       = -height
    \biPlanes       = 1
    \biBitCount     = 24
    \biCompression  = #BI_RGB
  EndWith   
 
  bytesperrow = 4 * ((3 * width + 3) / 4)

  *ColorBits = AllocateMemory(bytesperrow * height)
  hDC   = GetWindowDC_(#Null)
  iRes  = GetDIBits_(hDC, ImageID, 0, height, *ColorBits, @bmiInfo, #DIB_RGB_COLORS)
  ReleaseDC_(#Null, hDC)
 
  Structure_Max = (width * height * 16) + SizeOf(RGNDATAHEADER)
  *Buffer.RGNDATAHEADER = AllocateMemory(Structure_Max)
  *rd.LONG = *Buffer + SizeOf(RGNDATAHEADER)

  bufferloc = 0
  rectcount = 0
  
  For y = 0 To height - 1
    pxcount = 0
    For x = 0 To bytesperrow - 1 Step 3
      *px.RGBTRIPLEC = *ColorBits + bytesperrow * y + x
      If *px\rgbtRed = tred And *px\rgbtGreen = tgreen And *px\rgbtBlue = tblue
        transcount = 1
        firsttrans = pxcount
        While *px\rgbtRed = tred And *px\rgbtGreen = tgreen And *px\rgbtBlue = tblue And x <= bytesperrow - 4
          transcount + 1
          pxcount + 1
          x + 3     
          *px = *ColorBits + bytesperrow * y + x
        Wend
        rectcount + 1
        *rd\l = firsttrans              : *rd + 4
        *rd\l = y                       : *rd + 4
        *rd\l = firsttrans + transcount : *rd + 4
        *rd\l = y + 1                   : *rd + 4
      EndIf
      pxcount + 1
    Next
  Next
 
  With *Buffer
    \dwSize         = SizeOf(RGNDATAHEADER)
    \iType          = #RDH_RECTANGLES
    \nCount         = rectcount
    \nRgnSize       = rectcount * SizeOf(RECT)
    \rcBound\left   = 0
    \rcBound\top    = 0
    \rcBound\right  = width
    \rcBound\bottom = height
  EndWith
 
  RegionSize = SizeOf(RGNDATAHEADER) + (rectcount * SizeOf(RECT))
  hTransparentRgn = ExtCreateRegion_(#Null, RegionSize, *Buffer)
  CombineRgn_(hVisibleRgn, hVisibleRgn, hTransparentRgn, #RGN_XOR)
   
  FreeMemory(*Buffer)
  FreeMemory(*ColorBits)
  DeleteObject_(hTransparentRgn)
 
  ProcedureReturn hVisibleRgn
 
EndProcedure

;============================================================================================================================
; 
;============================================================================================================================

LoadImage(0, "girl.bmp")

OpenWindow(0, 0 ,0, ImageWidth(0), ImageHeight(0), "", #PB_Window_ScreenCentered | #PB_Window_BorderLess | #PB_Window_Invisible)

CreateGadgetList(WindowID(0))

ImageGadget(0, 0, 0, 0, 0, ImageID(0))

region = GrabRegion(ImageID(0), #White)

SetWindowRgn_(WindowID(0), region, #True)

HideWindow(0, 0)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #WM_RBUTTONUP
      CreatePopupMenu(0)
      MenuItem(0, "Close")
      DisplayPopupMenu(0, WindowID(0))
    Case #PB_Event_Menu
      Break
    Case #WM_LBUTTONDOWN
      SendMessage_(WindowID(0), #WM_NCLBUTTONDOWN, #HTCAPTION, 0)
  EndSelect
ForEver 

;--------------------------------------------------------------------------------------------

Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Get rid of the imagegadget and insert the lines:

Code: Select all

;Set the window background to the image.
  hBrush = CreatePatternBrush_(ImageID(0)) 
  SetClassLong_(WindowID(0),#GCL_HBRBACKGROUND,hBrush) 
just before the HideWindow() command.
I may look like a mule, but I'm not a complete ass.
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4789
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Post by Fangbeast »

Oi!! You!! Yes you!!! Aren't you supposed to be eating?? You look awfully skinny from here!!

/me falls off the chair laughing
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Fangbeast wrote:You look awfully skinny from here!!

/me falls off the chair laughing
That'll be because you're over 6000 miles away from me!
I may look like a mule, but I'm not a complete ass.
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4789
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Arrr, that she blows!!!

Post by Fangbeast »

That's a nice bit of code. Can't wait to Fanglize it. Now to add drag and drop and see what happens (MWUAHAHAHA)

Thanks Trond, NetMaestro and Srod.

srod, go and eat!!! Stay away from the keyboard!!

Oi!! none of that!! I saw you inch closer to the keyboard now stop it!!!
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4789
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Post by Fangbeast »

How do I make it a toolwindow?

This command is different to where you added the #WS_EX_TOOLWINDOW style before. Where should it go now?

SetClassLong_(WindowID(#Window_draggy), #GCL_HBRBACKGROUND, hBrush)

P.s. I posted an article in tips and tricks with all the combined code you all gave me. The beginnings of a stand-alone, draggable, transparent, drop target which could be easily incorporated into another window with minor mods. And the picture is included in a datasection.
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Place

Code: Select all

SetWindowLong_(WindowID(0), #GWL_EXSTYLE, GetWindowLong_(WindowID(0), #GWL_EXSTYLE) | #WS_EX_TOOLWINDOW) 
after your OpenWindow() command.
I may look like a mule, but I'm not a complete ass.
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4789
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Post by Fangbeast »

srod wrote:Place

Code: Select all

SetWindowLong_(WindowID(0), #GWL_EXSTYLE, GetWindowLong_(WindowID(0), #GWL_EXSTYLE) | #WS_EX_TOOLWINDOW) 
after your OpenWindow() command.
Wheee, thanks. Can't wait to see how I screw this up wen I add it into a real application and not just by itself:):):)
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
ebs
Enthusiast
Enthusiast
Posts: 557
Joined: Fri Apr 25, 2003 11:08 pm

Post by ebs »

Borrowing code from everyone who contributed to this thread, as well as some great transparent window code, how about this?

Code: Select all

; create window
LoadImage(0, "girl.bmp")
OpenWindow(0,0,0,ImageWidth(0),ImageHeight(0),"", #PB_Window_ScreenCentered|#PB_Window_BorderLess|#PB_Window_Invisible)

; display image
hBrush.l = CreatePatternBrush_(ImageID(0))
SetClassLong_(WindowID(0), #GCL_HBRBACKGROUND, hBrush) 

; add #WS_EX_LAYERED style and set transparent color
SetWindowLong_(WindowID(0), #GWL_EXSTYLE, GetWindowLong_(WindowID(0), #GWL_EXSTYLE) | #WS_EX_LAYERED)
SetLayeredWindowAttributes_(WindowID(0), #White, 0, #LWA_COLORKEY) 

; show window
HideWindow(0,0)

Repeat
  Event.l = WaitWindowEvent()
  Select Event
    Case #WM_LBUTTONDOWN
      SendMessage_(WindowID(0), #WM_NCLBUTTONDOWN, #HTCAPTION, 0)
  EndSelect
Until GetAsyncKeyState_(#VK_SPACE) & 32768 
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4789
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Wheeee

Post by Fangbeast »

I like how everybody comes up with interesting ways of doing the same thing, makes for great reading (and playing).

Now, how can I draw extra text on that image? (Wanting to use it as a file counter as well. Tried the 2d commands and whipped up an example but it didn't seem to want to draw on it for some reason)
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
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 »

You have to make a new brush and set the class backgroundbrush again each time. Or draw to WindowOutput() would work too. That's with LWA_COLORKEY only, if you're also using the LWA_ALPHA flag for semi-transparency, you'll have to use the trick in this thread:

http://www.purebasic.fr/english/viewtopic.php?t=27708

else your text will be fully transparent, which usually isn't desired.
BERESHEIT
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4789
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Post by Fangbeast »

As usual, I understood only the English words out of that. But thanks for that, will have to study and play some more.
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4789
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Post by Fangbeast »

Okay, this didn't work as I don't understand graphics at all. When I drag and drop files onto my drop taget, I wanted a file counter to be implemented on it in real time.

I just did the test of your code with (what I thought was the correct way by following your original example) and it appears to do nothing but make the hourglass appear and sit there for the 50,000 microseconds.

Code: Select all

For stuffaduck = 1 To 50000
  StartDrawing(ImageOutput(0))
    DrawingFont(FontID(0))
    DrawText(0, 0, Str(stuffaduck), #Red, RGB(230,0,0))
  StopDrawing()

  StartDrawing(ImageOutput(1))
    DrawAlphaImage(ImageID(0), 110, 160)
  StopDrawing()

  SetGadgetState(1, ImageID(0))
Next stuffaduck
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
Post Reply