Can this be done in PB?

Just starting out? Need help? Post your questions and find answers here.
spongehammer
User
User
Posts: 84
Joined: Sat Jul 19, 2003 6:45 pm
Location: UK

Can this be done in PB?

Post by spongehammer »

Hi all,
i would appreciate some ideas on where to start with this:

I need to create a Window which has an image for a background. This image should be able to have it's opacity adjusted via a slider from 0 - 100%. When transparent i need whatever is underneath (windows, applications, video etc) to be visible.

Any ideas very welcome :-)

Thanks.
I looked up 'paranoid' in the dictionary this morning.
It said, 'what do you want to know that for?'
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: Can this be done in PB?

Post by netmaestro »

Sure, it's not difficult but you pretty much have to skin the window, for reasons I don't have time to explain right now.

Assuming you want the frame & caption to be unaffected, the method is as follows:

Create a borderless window, draw your caption and attach such sysmenu buttons as you wish to the caption area, then translate #wm_lbuttondown into #wm_nclbuttondown with hcaption for wparam in your callback. Now you have a window with basic control functions.

Create a rect region the size of your window and use CombineRgn() to cut the client area out altogether except for a bar high enough to accommodate a trackbar or whatever you want to control transparency with . Use SetWindowRgn_() to apply this region to your window. Now your window is just a frame & caption with a big transparent hole in it.

Open a second window, #fakeclient, borderless and layered, the size of your hole. Remove this window from the taskbar with simple COM (do a forum search if you need to). In the frame window callback, have this window continually positioned at the x,y of where the client area of the frame window used to be by responding to wm_move, wm_moving, etc.

For your background, use SetClassLong_() with a brush for your image. Add such gadgets as you want, wire them up to be functional, and you're done.

Respond to your trackbar movements with SetLayeredWindowAttributes(WindowID(#fakeclient),#Null,<opacity 0-255>,#LWA_ALPHA) and your whole "client area" (which is really a separate window but the user can't tell) will fade in and out as you like.

Of course if you don't mind the whole window fading, client,frame,caption and all, it's remarkably simple- just layer the window with LWA_ALPHA alone, control this with your trackbar and you don't need all the fancy tricks and second windows.
BERESHEIT
MachineCode
Addict
Addict
Posts: 1482
Joined: Tue Feb 22, 2011 1:16 pm

Re: Can this be done in PB?

Post by MachineCode »

netmaestro wrote:Sure, it's not difficult but you pretty much have to skin the window, for reasons I don't have time to explain right now.
:lol: Your explanation of how to do it was probably longer to type than just posting some code. ;)
Microsoft Visual Basic only lasted 7 short years: 1991 to 1998.
PureBasic: Born in 1998 and still going strong to this very day!
spongehammer
User
User
Posts: 84
Joined: Sat Jul 19, 2003 6:45 pm
Location: UK

Re: Can this be done in PB?

Post by spongehammer »

Hi netmaestro,

thanks for the reply.. you make it sound so easy! :D

Seriously that has given me a direction at least.
Of course if you don't mind the whole window fading, client,frame,caption and all, it's remarkably simple- just layer the window with LWA_ALPHA alone, control this with your trackbar and you don't need all the fancy tricks and second windows.
Would this mean the trackbar would disappear too? MIght be a bit difficult to control after that :-)
I looked up 'paranoid' in the dictionary this morning.
It said, 'what do you want to know that for?'
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4955
Joined: Sun Apr 12, 2009 6:27 am

Re: Can this be done in PB?

Post by RASHAD »

Hi

Code: Select all

CreateImage(0, 620,340)
StartDrawing(ImageOutput(0))
  Box(0,0,620,340,#Blue)
  DrawingMode(#PB_2DDrawing_Outlined)
  Box(0,0,620,340,RGB(0, 0, 0))
StopDrawing()

CreateImage(1,618,338)
  StartDrawing(ImageOutput(1))
      DrawingMode(#PB_2DDrawing_Gradient)      
      LinearGradient(0, 0, 500, 0)
      GradientColor(0.00, $03FEFC)
      GradientColor(0.25, $83FD7C)
      GradientColor(0.50, $FA8C05)
      GradientColor(0.75, $0593FA)
      GradientColor(1.00, $0803F7)
      Box(0,0,618,338)
  StopDrawing()
  
  hBrush = CreatePatternBrush_(ImageID(1))


Procedure WndProc(hwnd, uMsg, wParam, lParam)
   
   result = #PB_ProcessPureBasicEvents        
   Select uMsg               
      Case #WM_MOVE,#WM_PAINT
         ClientToScreen_(WindowID(0), c.POINT)
         MoveWindow_(WindowID(1),c\x+11,c\y+11,618,338,1)
         
   EndSelect   
  ProcedureReturn result 
EndProcedure

hWin=OpenWindow(0, 0, 0,640,480, "Window_0",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)

hMenu = CreateMenu(#PB_Any, hWin)

MenuTitle("MenuChoice")
    OpenSubMenu("SubChoice")
        MenuItem(0101, "Choice1")
        MenuBar()
        MenuItem(0111, "Choice2")
        MenuItem(0112, "Choice3")
        MenuItem(0113, "Choice4")
        MenuItem(0114, "Choice5")
        MenuBar()
        MenuItem(0121, "Choice6")
        MenuItem(0122, "Choice7")
        MenuItem(0123, "Choice8")
        MenuItem(0124, "Choice9")
    CloseSubMenu()

      ButtonGadget(1,10,430,60,20,"TEST 1")
      ButtonGadget(2,570,430,60,20,"TEST 2")
      TrackBarGadget(3, 10, 380, 620, 30, 0,255,#PB_TrackBar_Ticks)
      SetWindowLongPtr_(WindowID(0),#GWL_EXSTYLE,#WS_EX_LAYERED)
      SetLayeredWindowAttributes_(WindowID(0),#Blue,0,#LWA_COLORKEY)
      ImageGadget(0,10,10,620,340,ImageID(0))    

      OpenWindow(1,0,0,0,0,"",#WS_POPUP,hWin)      
      SetClassLongPtr_(WindowID(1), #GCL_HBRBACKGROUND, hBrush)

      SetWindowCallback(@WndProc())      
      SetActiveWindow(0)
      
      SetWindowLong_(WindowID(1),#GWL_EXSTYLE,#WS_EX_LAYERED)
      SetLayeredWindowAttributes_(WindowID(1),0,255,#LWA_ALPHA)
      
    Repeat
       EventID = WaitWindowEvent()
       
       Select EventID

        Case #PB_Event_Gadget
       
         Select EventGadget()
         
               Case 1
                MessageRequester("","Button 1 is pressed")

               Case 2
                MessageRequester("","Button 2 is pressed")
                
               Case 3
                  Result = GetGadgetState(3) ! 255                  
                  SetLayeredWindowAttributes_(WindowID(1),0,Result,#LWA_ALPHA)
                   
         EndSelect
         
              Case #PB_Event_CloseWindow
              Quit = 1
             
           
      EndSelect
         
    Until Quit = 1
    End

Edit :Improved a little
Egypt my love
spongehammer
User
User
Posts: 84
Joined: Sat Jul 19, 2003 6:45 pm
Location: UK

Re: Can this be done in PB?

Post by spongehammer »

Hi RASHAD,

thanks so much for the code. Much as i enjoy trying to code, it's not my job and i do struggle getting my head around some stuff.

This is exactly what i need :-)

Chris
I looked up 'paranoid' in the dictionary this morning.
It said, 'what do you want to know that for?'
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4955
Joined: Sun Apr 12, 2009 6:27 am

Re: Can this be done in PB?

Post by RASHAD »

Hi spongehammer
You are welcome
Glad to know that you got what you need
Egypt my love
spongehammer
User
User
Posts: 84
Joined: Sat Jul 19, 2003 6:45 pm
Location: UK

Re: Can this be done in PB?

Post by spongehammer »

Just another question based on the same topic.

Is it possible with this code to load and change the background image whilst the program is running?

thanks
I looked up 'paranoid' in the dictionary this morning.
It said, 'what do you want to know that for?'
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4955
Joined: Sun Apr 12, 2009 6:27 am

Re: Can this be done in PB?

Post by RASHAD »

Hi

Code: Select all

CreateImage(0, 620,340)
  StartDrawing(ImageOutput(0))
      Box(0,0,620,340,#Blue)
      DrawingMode(#PB_2DDrawing_Outlined)
      Box(0,0,620,340,RGB(0, 0, 0))
  StopDrawing()

CreateImage(1,618,338)
  StartDrawing(ImageOutput(1))
      DrawingMode(#PB_2DDrawing_Gradient)     
      LinearGradient(0, 0, 500, 0)
      GradientColor(0.00, $03FEFC)
      GradientColor(0.25, $83FD7C)
      GradientColor(0.50, $FA8C05)
      GradientColor(0.75, $0593FA)
      GradientColor(1.00, $0803F7)
      Box(0,0,618,338)
  StopDrawing()
  
hBrush = CreatePatternBrush_(ImageID(1))   
  
CreateImage(2,618,338)
      hdc = StartDrawing(ImageOutput(2))
      For X = 0 To 617
        For Y = 0 To 337
          Plot(X, Y, RGB(X, Y, X*Y/20))
        Next
      Next
StopDrawing()

hBrush2 = CreatePatternBrush_(ImageID(2))   

Procedure WndProc(hwnd, uMsg, wParam, lParam)
   
   result = #PB_ProcessPureBasicEvents       
   Select uMsg               
      Case #WM_MOVE,#WM_PAINT
         ClientToScreen_(WindowID(0), c.POINT)
         MoveWindow_(WindowID(1),c\x+11,c\y+11,618,338,1)
         
   EndSelect   
  ProcedureReturn result
EndProcedure

hWin=OpenWindow(0, 0, 0,640,480, "Window_0",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)

hMenu = CreateMenu(#PB_Any, hWin)

MenuTitle("MenuChoice")
    OpenSubMenu("SubChoice")
        MenuItem(0101, "Choice1")
        MenuBar()
        MenuItem(0111, "Choice2")
        MenuItem(0112, "Choice3")
        MenuItem(0113, "Choice4")
        MenuItem(0114, "Choice5")
        MenuBar()
        MenuItem(0121, "Choice6")
        MenuItem(0122, "Choice7")
        MenuItem(0123, "Choice8")
        MenuItem(0124, "Choice9")
    CloseSubMenu()

      ButtonGadget(1,10,430,60,20,"IMAGE 1")
      ButtonGadget(2,570,430,60,20,"IMAGE 2")
      TrackBarGadget(3, 10, 380, 620, 30, 0,255,#PB_TrackBar_Ticks)
      SetWindowLongPtr_(WindowID(0),#GWL_EXSTYLE,#WS_EX_LAYERED)
      SetLayeredWindowAttributes_(WindowID(0),#Blue,0,#LWA_COLORKEY)
      ImageGadget(0,10,10,620,340,ImageID(0))   

      OpenWindow(1,0,0,0,0,"",#WS_POPUP,hWin)
      hBrush = CreatePatternBrush_(ImageID(1))     
      SetClassLongPtr_(WindowID(1), #GCL_HBRBACKGROUND, hBrush)

      SetWindowCallback(@WndProc())     
      SetActiveWindow(0)
     
      SetWindowLongPtr_(WindowID(1),#GWL_EXSTYLE,#WS_EX_LAYERED)
      SetLayeredWindowAttributes_(WindowID(1),0,255,#LWA_ALPHA)
     
    Repeat
       EventID = WaitWindowEvent()
       
       Select EventID

        Case #PB_Event_Gadget
       
         Select EventGadget()
         
               Case 1   
                   SetClassLongPtr_(WindowID(1), #GCL_HBRBACKGROUND, hBrush2)
                   InvalidateRect_(WindowID(1),0,1)                   

               Case 2    
                   SetClassLongPtr_(WindowID(1), #GCL_HBRBACKGROUND, hBrush)
                   InvalidateRect_(WindowID(1),0,1)  
                   
               
               Case 3
                   Result = GetGadgetState(3) ! 255                 
                   SetLayeredWindowAttributes_(WindowID(1),0,Result,#LWA_ALPHA)
                   
         EndSelect
         
              Case #PB_Event_CloseWindow
              Quit = 1
             
           
      EndSelect
         
    Until Quit = 1
    End

Egypt my love
spongehammer
User
User
Posts: 84
Joined: Sat Jul 19, 2003 6:45 pm
Location: UK

Re: Can this be done in PB?

Post by spongehammer »

Thank you so much RASHAD.

I must admit to feeling a certain guilt though.
When i asked the original question I sincerely intended to write this myself.
Your code has done exactly what i need, something which would have taken me a long time.
I feel humbled by the people on this forum who go out of their way to help, and although i doubt it, i would do the same if i could.

Thanks again :D
I looked up 'paranoid' in the dictionary this morning.
It said, 'what do you want to know that for?'
Post Reply