[Solved] How to Skin window with PNG (Source Code Available)

Just starting out? Need help? Post your questions and find answers here.
PyroStrex
User
User
Posts: 61
Joined: Mon Mar 22, 2010 3:08 pm

[Solved] How to Skin window with PNG (Source Code Available)

Post by PyroStrex »

Can someone help me with this? I've been searching through the whole purebasic forum but the only skin system i've found that use png is http://forum.purebasic.com/english/view ... 1df2458a77. The problem is, with this code, i can't no longer use all the gadget. I want the window to be skinned and at the same time i still can use all the gadget without problem.
Last edited by PyroStrex on Wed Apr 07, 2010 2:43 am, edited 2 times in total.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4135
Joined: Sun Apr 12, 2009 6:27 am

Re: How to Skin window with PNG ?

Post by RASHAD »

Hi

Code: Select all

UsePNGImageDecoder()
LoadImage(0, "f:\alpha.png")   ;Box filled w Red color in the middle any shape with any no. of colors but the Red( The Red zone will be skinned )

OpenWindow(0,20,20,300,300,"Test",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
HideWindow(0,1)
ButtonGadget(1,100,250,120,20,"Test")
ImageGadget(2,20,20,128,128,ImageID(0))
SetWindowLong_(WindowID(0),#GWL_EXSTYLE,GetWindowLong_(WindowID(0),#GWL_EXSTYLE)|#WS_EX_LAYERED)
SetLayeredWindowAttributes_(WindowID(0),#Red,0,#LWA_COLORKEY)
HideWindow(0,0)
DisableGadget(2, 1)



Repeat
  ev = WaitWindowEvent()
  Select ev
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 1
           MessageRequester("This is a test","OK",#MB_ICONWARNING)
      
      EndSelect
  EndSelect
Until ev = #PB_Event_CloseWindow 
Egypt my love
Nituvious
Addict
Addict
Posts: 956
Joined: Sat Jul 11, 2009 4:57 am
Location: United States

Re: How to Skin window with PNG ?

Post by Nituvious »

Holy crap that is neat!! Throw in a borderless window and you can make it look even cooler!
▓▓▓▓▓▒▒▒▒▒░░░░░
PyroStrex
User
User
Posts: 61
Joined: Mon Mar 22, 2010 3:08 pm

Re: How to Skin window with PNG ?

Post by PyroStrex »

Hehe, its a good code. Thank you. But, what i mean by using PNG is that i can use PNG transparency for the skinning. This is my example of picture i wanna use
Image
Nituvious
Addict
Addict
Posts: 956
Joined: Sat Jul 11, 2009 4:57 am
Location: United States

Re: How to Skin window with PNG ?

Post by Nituvious »

The code he posted makes the color red transparent.
I modified it a little bit, maybe it would be useful for you?
[Edit] Oh I am a dummy, I totally misread your reply. I recall a discussion about that on this board some where, I don't know where the post is though. I am sorry!!

Image

Code: Select all

Enumeration
  #MWindow
  #Skin
  #LoadImg
  #AButton
  #XButton
EndEnumeration

UsePNGImageDecoder()
LoadImage(#LoadImg, "c:\test.png")   ;Box filled w Red color in the middle any shape with any no. of colors but the Red( The Red zone will be skinned )

OpenWindow(#MWindow,20,20,500,500,"Test",#PB_Window_BorderLess|#PB_Window_ScreenCentered)
HideWindow(#MWindow,1)
ImageGadget(#Skin,0,0,128,128,ImageID(#LoadImg))
SetWindowLong_(WindowID(#MWindow),#GWL_EXSTYLE,GetWindowLong_(WindowID(#MWindow),#GWL_EXSTYLE)|#WS_EX_LAYERED)
SetLayeredWindowAttributes_(WindowID(#MWindow),#Red,0,#LWA_COLORKEY)
HideWindow(#MWindow,0)
DisableGadget(#Skin, 1)
ButtonGadget(#AButton,100,250,120,20,"Test")
ButtonGadget(#XButton,320,35,15,15,"X")


Repeat
  EventID = WaitWindowEvent()
  Select EventID
    Case #WM_LBUTTONDOWN
      SendMessage_(WindowID(0), #WM_NCLBUTTONDOWN, #HTCAPTION, 0)
  EndSelect
  
  If EventID = #PB_Event_Gadget
      Select EventGadget()
        Case #AButton
           Debug "clicker"
        Case #XButton
           End
      EndSelect
  EndIf
Until EventID = #PB_Event_CloseWindow 
▓▓▓▓▓▒▒▒▒▒░░░░░
PyroStrex
User
User
Posts: 61
Joined: Mon Mar 22, 2010 3:08 pm

Re: How to Skin window with PNG ?

Post by PyroStrex »

Yeah, it's a very good code and look much more better after you've changed it a bit. But what i want is, the one that looks exactly like the link i've provide on my first post but with the advantage of using the gadget.

Edit:
I forgot to say the magic word. Thanks for helping me :). I really appreciate it.

Edit:
Hmm, this post will never going to end. I've read many information that says there's no way we can add object after using updatelayeredwindow.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4135
Joined: Sun Apr 12, 2009 6:27 am

Re: How to Skin window with PNG ?

Post by RASHAD »

Hi
Transparency and Skinning are different subjects
My first post is for skinning
Now this one for transparency with trick for the gadget to show it with no transparncy

Code: Select all


UsePNGImageDecoder()

Procedure WndProc(hwnd, uMsg, wParam, lParam)
   GetWindowRect_(GadgetID(0), wr.RECT)
   result = #PB_ProcessPureBasicEvents        
   Select uMsg               
      Case #WM_SIZE,#WM_MOVE,#WM_PAINT         
         MoveWindow_(WindowID(1),wr\left+10 ,wr\top+320, 80,25,1)
   EndSelect   
  ProcedureReturn result 
EndProcedure


LoadImage(0, "test.png")  ;Size of image 250 x 350

hwnd=OpenWindow(0,100,100,250,350,"Test",#PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_TitleBar|#PB_Window_ScreenCentered)
ImageGadget(0,0,0,250,350, ImageID(0))
DisableGadget(0,1)
SetWindowLong_(WindowID(0),#GWL_EXSTYLE,#WS_EX_LAYERED)
SetLayeredWindowAttributes_(WindowID(0),0,150,#LWA_ALPHA)
GetWindowRect_(GadgetID(0), wr.RECT)
OpenWindow(1,wr\left+10 ,wr\top+320,80,25,"",#PB_Window_BorderLess|#WS_POPUP,hwnd)
ButtonGadget(1, 0, 0,80,25,"TEST")
SetWindowCallback(@WndProc(),0)


Repeat
  ev = WaitWindowEvent()
  Select ev
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 1
            MessageRequester("Test","Gadeg 1 OK",#MB_ICONINFORMATION)
      
      EndSelect
  EndSelect
Until ev = #PB_Event_CloseWindow
Egypt my love
PyroStrex
User
User
Posts: 61
Joined: Mon Mar 22, 2010 3:08 pm

Re: How to Skin window with PNG ?

Post by PyroStrex »

I've already come up with the solution, just an edited code from the link i provide.

But, there are several things needed to be fixed and i don't know how.
  • Moving the window very fast will cause the window to stuck (means not moving).
  • If you click the button and move your mouse, the window will still moving. (i want to prevent from moving the window even though it was the region for gadget)
  • If you clicked the button, after the message appear, move your mouse and the window is still moving
I hope someone can fix everything here and thanks RASHAD. Your code is very helpful.

Sorry for those people who i copy pasted their code. Just need to get the solution first before cleaning up the code.

Code: Select all

UsePNGImageDecoder()

Procedure SetLayeredWindow2(WindowID) ; Mettre l'attribut WS_EX_LAYERED à la fenêtre
   SetWindowLong_(WindowID, #GWL_EXSTYLE, GetWindowLong_(WindowID, #GWL_EXSTYLE) | #WS_EX_LAYERED) ; Mettre l'attribut WS_EX_LAYERED à la fenêtre
EndProcedure

Procedure AlphaImageWindow2(WindowID, ImageID, Alpha) ; Mettre une image PNG comme fond d'une fenêtre
  Protected Image_HDC, Image_Bitmap.BITMAP, Image_BitmapInfo.BITMAPINFO, ContextOffset.POINT, Blend.BLENDFUNCTION
   Protected xx, yy, x, y, Rouge, Vert, Bleu, AlphaChannel
   
   ; Précalcul
   Protected Dim Echelle.f($FF)
   For x = 0 To $FF
      Echelle(x) = x / $FF
   Next
   
   ; Chargement du HDC
   Image_HDC = CreateCompatibleDC_(#Null)
  Image_Ancienne = SelectObject_(Image_HDC, ImageID)
   
   ; Dimension de l'image
   GetObject_(ImageID, SizeOf(BITMAP), @Image_Bitmap)
   Image_BitmapInfo\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
   Image_BitmapInfo\bmiHeader\biWidth = Image_Bitmap\bmWidth
   Image_BitmapInfo\bmiHeader\biHeight = Image_Bitmap\bmHeight
   Image_BitmapInfo\bmiHeader\biPlanes = 1
   Image_BitmapInfo\bmiHeader\biBitCount = 32
   
   ; Zone mémoire pour copier l'image
   xx = Image_Bitmap\bmWidth - 1
   yy = Image_Bitmap\bmHeight - 1
   Protected Dim Image.l(xx, yy)
   
   ; Copie de l'image en mémoire
   GetDIBits_(Image_HDC, ImageID, 0, Image_Bitmap\bmHeight, @Image(), @Image_BitmapInfo, #DIB_RGB_COLORS)
   
   ; Modification de l'image en mémoire
   For x = 0 To xx
      For y = 0 To yy
         Couleur = Image(x, y)
         AlphaChannel = Couleur >> 24 & $FF
         If AlphaChannel < $FF
            Rouge = (Couleur & $FF) * Echelle(AlphaChannel)
            Vert = (Couleur >> 8 & $FF) * Echelle(AlphaChannel)
            Bleu = (Couleur >> 16 & $FF) * Echelle(AlphaChannel)
            Image(x, y) = Rouge | Vert << 8 | Bleu << 16 | AlphaChannel << 24
         EndIf
      Next
   Next
   
   ; Transfert de la mémoire dans la l'image de base
   SetDIBits_(Image_HDC, ImageID, 0, Image_Bitmap\bmHeight, @Image(), @Image_BitmapInfo, #DIB_RGB_COLORS)
   
   ; L'image est mise en skin de la fenêtre
   Blend\SourceConstantAlpha = Alpha ; niveau de transparence
   Blend\AlphaFormat = 1 ; Support de la couche alpha
   Blend\BlendOp = 0
   Blend\BlendFlags = 0
   UpdateLayeredWindow_(WindowID, 0, 0, @Image_BitmapInfo + 4, Image_HDC, @ContextOffset, 0, @Blend, 2)
   
   ; Fermeture du HDC
   SelectObject_(Image_HDC, Image_Ancienne)
   DeleteDC_(Image_HDC)
  
EndProcedure

Procedure HideFromTaskBar(hWnd, Flag)
  Protected TBL.ITaskbarList

  CoInitialize_(0)
  If CoCreateInstance_(?CLSID_TaskBarList, 0, 1, ?IID_ITaskBarList, @TBL) = #S_OK
    TBL\HrInit()
    If Flag
      TBL\DeleteTab(hWnd)
    Else
      TBL\AddTab(hWnd)
    EndIf
    TBL\Release()
  EndIf
  CoUninitialize_()

  DataSection
    CLSID_TaskBarList:
    Data.l $56FDF344
    Data.w $FD6D, $11D0
    Data.b $95, $8A, $00, $60, $97, $C9, $A0, $90
    IID_ITaskBarList:
    Data.l $56FDF342
    Data.w $FD6D, $11D0
    Data.b $95, $8A, $00, $60, $97, $C9, $A0, $90
  EndDataSection
EndProcedure

Fichier.s = OpenFileRequester("Image", "", "PNG|*.png", 1)
If Fichier
  If LoadImage(0, Fichier)
      
      If OpenWindow(0, 0, 0, ImageWidth(0), ImageHeight(0), "Test", #PB_Window_BorderLess | #PB_Window_ScreenCentered)
         If OpenWindow(1, 0, 0, ImageWidth(0), ImageHeight(0), "", #PB_Window_BorderLess | #PB_Window_ScreenCentered)
         HideFromTaskBar(WindowID(0), #True)
         
         SetLayeredWindow2(WindowID(0))
         SetLayeredWindow2(WindowID(1))
         
         SetWindowColor(1, RGB(255, 0, 0))
         
         AlphaImageWindow2(WindowID(0), ImageID(0), 200)
         SetLayeredWindowAttributes_(WindowID(1),#Red,0,#LWA_COLORKEY)
         
         HideWindow(0, 0)

         ButtonGadget(0, 0, 0, 100, 100, "Test")
         
         Repeat
            Event = WindowEvent()
            EventW = EventWindow()
            
            If Event = #WM_LBUTTONDOWN And EventW = 1 
                initialX = WindowX(1)
                initialY = WindowY(1)
                initialmX = DesktopMouseX()
                initialmY = DesktopMouseY()
                
                startDrag = #True
            ElseIf Event = #WM_MOUSEMOVE And And EventW = 1 
                If startDrag = #True
                    ResizeWindow(0, DesktopMouseX() - (initialmX - initialX), DesktopMouseY() - (initialmY - initialY), #PB_Ignore, #PB_Ignore);
                    ResizeWindow(1, DesktopMouseX() - (initialmX - initialX), DesktopMouseY() - (initialmY - initialY), #PB_Ignore, #PB_Ignore);
                EndIf
            ElseIf Event = #WM_LBUTTONUP And And EventW = 1
                startDrag = #False
            ElseIf Event = #PB_Event_Gadget
                    Gadget = EventGadget()
                    
                    Select Gadget
                        Case 0
                            MessageBox_(0, "test", "", 0)
                    EndSelect
            EndIf
            
         Until Event = #PB_Event_CloseWindow
         EndIf
      EndIf
      
   EndIf
EndIf
PyroStrex
User
User
Posts: 61
Joined: Mon Mar 22, 2010 3:08 pm

Re: How to Skin window with PNG ?

Post by PyroStrex »

Sorry to post two times but. I've finally got the solution! Thanks guys! I post this directly after finishing it so i know it is not a neat code.

Again, sorry for people who i've copy pasted their code.

Code: Select all

UsePNGImageDecoder()

Procedure SetLayeredWindow2(WindowID) ; Mettre l'attribut WS_EX_LAYERED à la fenêtre
   SetWindowLong_(WindowID, #GWL_EXSTYLE, GetWindowLong_(WindowID, #GWL_EXSTYLE) | #WS_EX_LAYERED) ; Mettre l'attribut WS_EX_LAYERED à la fenêtre
EndProcedure

Procedure AlphaImageWindow2(WindowID, ImageID, Alpha) ; Mettre une image PNG comme fond d'une fenêtre
  Protected Image_HDC, Image_Bitmap.BITMAP, Image_BitmapInfo.BITMAPINFO, ContextOffset.POINT, Blend.BLENDFUNCTION
   Protected xx, yy, x, y, Rouge, Vert, Bleu, AlphaChannel
   
   ; Précalcul
   Protected Dim Echelle.f($FF)
   For x = 0 To $FF
      Echelle(x) = x / $FF
   Next
   
   ; Chargement du HDC
   Image_HDC = CreateCompatibleDC_(#Null)
  Image_Ancienne = SelectObject_(Image_HDC, ImageID)
   
   ; Dimension de l'image
   GetObject_(ImageID, SizeOf(BITMAP), @Image_Bitmap)
   Image_BitmapInfo\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
   Image_BitmapInfo\bmiHeader\biWidth = Image_Bitmap\bmWidth
   Image_BitmapInfo\bmiHeader\biHeight = Image_Bitmap\bmHeight
   Image_BitmapInfo\bmiHeader\biPlanes = 1
   Image_BitmapInfo\bmiHeader\biBitCount = 32
   
   ; Zone mémoire pour copier l'image
   xx = Image_Bitmap\bmWidth - 1
   yy = Image_Bitmap\bmHeight - 1
   Protected Dim Image.l(xx, yy)
   
   ; Copie de l'image en mémoire
   GetDIBits_(Image_HDC, ImageID, 0, Image_Bitmap\bmHeight, @Image(), @Image_BitmapInfo, #DIB_RGB_COLORS)
   
   ; Modification de l'image en mémoire
   For x = 0 To xx
      For y = 0 To yy
         Couleur = Image(x, y)
         AlphaChannel = Couleur >> 24 & $FF
         If AlphaChannel < $FF
            Rouge = (Couleur & $FF) * Echelle(AlphaChannel)
            Vert = (Couleur >> 8 & $FF) * Echelle(AlphaChannel)
            Bleu = (Couleur >> 16 & $FF) * Echelle(AlphaChannel)
            Image(x, y) = Rouge | Vert << 8 | Bleu << 16 | AlphaChannel << 24
         EndIf
      Next
   Next
   
   ; Transfert de la mémoire dans la l'image de base
   SetDIBits_(Image_HDC, ImageID, 0, Image_Bitmap\bmHeight, @Image(), @Image_BitmapInfo, #DIB_RGB_COLORS)
   
   ; L'image est mise en skin de la fenêtre
   Blend\SourceConstantAlpha = Alpha ; niveau de transparence
   Blend\AlphaFormat = 1 ; Support de la couche alpha
   Blend\BlendOp = 0
   Blend\BlendFlags = 0
   UpdateLayeredWindow_(WindowID, 0, 0, @Image_BitmapInfo + 4, Image_HDC, @ContextOffset, 0, @Blend, 2)
   
   ; Fermeture du HDC
   SelectObject_(Image_HDC, Image_Ancienne)
   DeleteDC_(Image_HDC)
  
EndProcedure

Procedure HideFromTaskBar(hWnd, Flag)
  Protected TBL.ITaskbarList

  CoInitialize_(0)
  If CoCreateInstance_(?CLSID_TaskBarList, 0, 1, ?IID_ITaskBarList, @TBL) = #S_OK
    TBL\HrInit()
    If Flag
      TBL\DeleteTab(hWnd)
    Else
      TBL\AddTab(hWnd)
    EndIf
    TBL\Release()
  EndIf
  CoUninitialize_()

  DataSection
    CLSID_TaskBarList:
    Data.l $56FDF344
    Data.w $FD6D, $11D0
    Data.b $95, $8A, $00, $60, $97, $C9, $A0, $90
    IID_ITaskBarList:
    Data.l $56FDF342
    Data.w $FD6D, $11D0
    Data.b $95, $8A, $00, $60, $97, $C9, $A0, $90
  EndDataSection
EndProcedure

Procedure WndProc(hwnd, uMsg, wParam, lParam)
   result = #PB_ProcessPureBasicEvents        
   Select uMsg               
      Case #WM_SIZE,#WM_MOVE,#WM_PAINT         
         MoveWindow_(WindowID(0), WindowX(1) ,WindowY(1), ImageWidth(0), ImageHeight(0), 1)
   EndSelect   
  ProcedureReturn result 
EndProcedure

Fichier.s = OpenFileRequester("Image", "", "PNG|*.png", 1)
If Fichier
  If LoadImage(0, Fichier)
      
      If OpenWindow(0, 0, 0, ImageWidth(0), ImageHeight(0), "", #PB_Window_BorderLess | #PB_Window_ScreenCentered)
         If OpenWindow(1, 0, 0, ImageWidth(0), ImageHeight(0), "", #PB_Window_BorderLess | #PB_Window_ScreenCentered, WindowID(0))
         
         SetLayeredWindow2(WindowID(0))
         SetLayeredWindow2(WindowID(1))
         
         SetWindowColor(1, RGB(255, 0, 0))
         
         AlphaImageWindow2(WindowID(0), ImageID(0), 200)
         SetLayeredWindowAttributes_(WindowID(1),#Red,0,#LWA_COLORKEY)
         
         ;HideWindow(0, 0)

         ButtonGadget(0, 0, 0, 100, 100, "Test")
         
         SetWindowCallback(@WndProc(), 1)
         
         Repeat
            Event = WindowEvent()
            EventW = EventWindow()
            
            If Event = #PB_Event_Gadget
                    Gadget = EventGadget()
                    
                    Select Gadget
                        Case 0
                            MessageBox_(0, "test", "", 0)
                    EndSelect
            ElseIf Event = #WM_LBUTTONDOWN And EventW = 1
                SendMessage_(WindowID(1),#WM_NCLBUTTONDOWN, #HTCAPTION,0)
            EndIf            
         Until Event = #PB_Event_CloseWindow
         EndIf
      EndIf
      
   EndIf
EndIf
ricardo
Addict
Addict
Posts: 2312
Joined: Fri Apr 25, 2003 7:06 pm
Location: Argentina

Re: How to Skin window with PNG ?

Post by ricardo »

PyroStrex wrote:Sorry to post two times but. I've finally got the solution! Thanks guys! I post this directly after finishing it so i know it is not a neat code.

Very nice!

Any solution to avoid some flickering when start running?
PyroStrex
User
User
Posts: 61
Joined: Mon Mar 22, 2010 3:08 pm

Re: How to Skin window with PNG ?

Post by PyroStrex »

I don't seem to saw any flickering. I'm using Windows 7 and v4.4x of PureBasic
ricardo
Addict
Addict
Posts: 2312
Joined: Fri Apr 25, 2003 7:06 pm
Location: Argentina

Re: [Solved] How to Skin window with PNG ?

Post by ricardo »

I post this example some years ago.
In this case it shows an animated GIF but can be anything else.
It has a button. Its very simple solution, but very effective.
Its not a skinned GUI, but the idea is more or less the same.

Code: Select all

If OpenWindow(0, 10, 10, 620, 640, "", #PB_Window_BorderLess|#PB_Window_Maximize|#PB_Window_Invisible) 
  SetWindowColor(0, #White) 
  CreateGadgetList(WindowID(0)) 
  WebGadget(0,0,100,WindowWidth(0)+50,WindowHeight(0),"http://publib.boulder.ibm.com/infocenter/radhelp/v6r0m1/topic/com.ibm.etools.animgif.doc/images/skiing.gif") 
  ButtonGadget(1,100,10,100,30,"Click")
  SetWindowLong_(WindowID(0),#GWL_EXSTYLE,GetWindowLong_(WindowID(0),#GWL_EXSTYLE)|#WS_EX_LAYERED) 
  SetLayeredWindowAttributes_(WindowID(0),RGB(255,255,255),0,#LWA_COLORKEY) 
  HideWindow(0, 0) 
  Repeat 
    EventID=WaitWindowEvent() 
    
    Select EventID 
        
      Case #PB_Event_Gadget 
        Select EventGadget() 
          Case 1
            MessageRequester("","Click")
        EndSelect 
        
    EndSelect 
    
  Until GetAsyncKeyState_(#VK_ESCAPE) 
EndIf 
PyroStrex
User
User
Posts: 61
Joined: Mon Mar 22, 2010 3:08 pm

Re: [Solved] How to Skin window with PNG ?

Post by PyroStrex »

Owh, it's a very great code you have there. Thanks for sharing it (again?). Hehe~
Post Reply