Page 1 of 1

Can this be done in PB?

Posted: Wed Jun 15, 2011 11:27 pm
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.

Re: Can this be done in PB?

Posted: Thu Jun 16, 2011 2:06 am
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.

Re: Can this be done in PB?

Posted: Thu Jun 16, 2011 5:46 am
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. ;)

Re: Can this be done in PB?

Posted: Thu Jun 16, 2011 9:13 am
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 :-)

Re: Can this be done in PB?

Posted: Fri Jun 17, 2011 5:13 am
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

Re: Can this be done in PB?

Posted: Fri Jun 17, 2011 11:56 pm
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

Re: Can this be done in PB?

Posted: Sat Jun 18, 2011 3:26 am
by RASHAD
Hi spongehammer
You are welcome
Glad to know that you got what you need

Re: Can this be done in PB?

Posted: Sat Jun 18, 2011 11:49 am
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

Re: Can this be done in PB?

Posted: Sat Jun 18, 2011 1:11 pm
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


Re: Can this be done in PB?

Posted: Sat Jun 18, 2011 1:29 pm
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