Notez bien que je ne revendique en aucun cas la paternité de ces codes! Il s'agit souvent de petites choses que j'ai récupérées et modifiées pour qu'elles correspondent plus à mes besoins. Si vous reconnaissez un de vos codes là dedans, n'hésitez pas à me prévenir pour que je vous donne le crédit ou que je le supprime (à votre choix)!
- 1] Skinner une fenêtre
 
Code : Tout sélectionner
Procedure SkinWindow(Window,Skin,Transparent_Color = #Magenta)
  Define Region,x1,y1,y2,Region_Temp,brush
  
  Region = CreateRectRgn_(0, 0, WindowWidth(Window) + 1, WindowHeight(Window) + 1)
  StartDrawing( ImageOutput (Skin))
    For x1 = 0 To WindowWidth(Window)-1
      For y1 = 0 To WindowHeight(Window)-1
        If Point(x1, y1) = Transparent_Color
          y2 = y1
          While y2 < WindowHeight(Window)-1 And Point(x1, y2 + 1) = Transparent_Color
            y2 + 1
          Wend
          Region_Temp = CreateRectRgn_(x1, y1, x1 + 1, y2 + 1)
          CombineRgn_ (Region, Region, Region_Temp, #RGN_DIFF )
          y1 = y2
        EndIf
      Next
    Next
  StopDrawing()
  SetWindowRgn_(WindowID(Window), Region, #True )
  brush=CreatePatternBrush_(ImageID(Skin))
  SetClassLong_(WindowID(Window),#GCL_HBRBACKGROUND,brush)
  InvalidateRect_(WindowID(Window),0,1)
EndProcedurePetit exemple pour l'utiliser:
Code : Tout sélectionner
#Skin = 0
#Window = 0
If LoadImage(#Skin,OpenFileRequester("Selection du skin","","Bitmap|*.bmp",0))
  OpenWindow(#Window,0,0,ImageWidth(0),ImageHeight(0),"Fenêtre skinée",#PB_Window_ScreenCentered|#PB_Window_BorderLess)
  SkinWindow(#Window,#Skin)
  Repeat
    
  Until WaitWindowEvent() = #PB_Event_CloseWindow
  FreeImage(0)
EndIf Informations supplémentaires a écrit :Testé sur PB 4.30; c'est probablement incompatible avec le chanel Alpha des PNG qu'apporte PB4.40; je me pencherais dessus à l'occasion.
- 2] Skinner des boutons
 
Code : Tout sélectionner
#Enter           = #WM_APP+$100
#Leave           = #WM_APP+$101
#CB_Button_Click = #WM_APP+$102
#CB_SolidBrush   = -2
Procedure Monitor(hwnd)
  Protected cp1.POINT
  Protected cp2.POINT
  Define hRgn,lastbutton
  
  Repeat
    If IsWindowEnabled_(hwnd)
      If GetProp_(hwnd,"cb_status") = 2
        SetProp_(hwnd,"cb_status",0)
        If IsImage(GetProp_(hwnd,"cb_disab"))
          SetGadgetState(GetDlgCtrlID_(hwnd),ImageID(GetProp_(hwnd,"cb_cold")))
        EndIf
      EndIf
      hRgn = GetProp_(hwnd,"cb_region")
      GetCursorPos_(@cp1)
      GetCursorPos_(@cp2)
      MapWindowPoints_(0,hwnd,@cp1,1)
      If WindowFromPoint_(cp2\x|cp2\y<<32) = hwnd
        If PtInRegion_(hRgn,cp1\x,cp1\y)
          If GetProp_(hwnd,"cb_status") = 0 
            SetProp_(hwnd,"cb_status", 1)
            If lastbutton = 0 Or lastbutton = hwnd Or GetAsyncKeyState_(#VK_LBUTTON) & 32768 = 0
              PostMessage_(hwnd,#Enter,0,0)
              lastbutton = 0
            EndIf
          EndIf
        Else
          If GetProp_(hwnd,"cb_status") = 1
            SetProp_(hwnd,"cb_status", 0)
            PostMessage_(hwnd,#Leave,0,0)
            If GetAsyncKeyState_(#VK_LBUTTON) & 32768
              If lastbutton = 0
                lastbutton = hwnd
              EndIf
            Else
              lastbutton = 0
            EndIf
          EndIf
        EndIf
      Else
        If GetProp_(hwnd,"cb_status") = 1
          SetProp_(hwnd,"cb_status", 0)
          PostMessage_(hwnd,#Leave,0,0)
          If GetAsyncKeyState_(#VK_LBUTTON) & 32768
            If lastbutton = 0
              lastbutton = hwnd
            EndIf
          Else
            lastbutton = 0
          EndIf
        EndIf
      EndIf     
    Else
      If IsWindow_(hwnd)
        If IsWindowEnabled_(hwnd)=0
          SetProp_(hwnd,"cb_status",2)
          If IsImage(GetProp_(hwnd,"cb_disab"))
            SetGadgetState(GetDlgCtrlID_(hwnd),ImageID(GetProp_(hwnd,"cb_disab")))
          EndIf
        EndIf 
      EndIf 
    EndIf
    Delay(10)
  ForEver
EndProcedure
Procedure CustomButtonProc(hwnd, msg, wParam, lParam)
  Protected cp1.POINT
  Protected oldproc = GetProp_(hwnd,"cb_oldproc")
  Protected monitor_tid = GetProp_(hwnd, "cb_monitor_tid")
  Define hRgn, lastbutton
  hRgn = GetProp_(hwnd, "cb_region")
  GetCursorPos_(@cp1)
  MapWindowPoints_(0,hwnd,@cp1,1)   
  Select msg
    Case #WM_NCDESTROY
      If IsThread(monitor_tid)
        KillThread(monitor_tid)
        WaitThread(monitor_tid)
      EndIf
      RemoveProp_(hwnd, "cb_status")
      RemoveProp_(hwnd, "cb_disab")
      RemoveProp_(hwnd, "cb_cold")
      RemoveProp_(hwnd, "cb_warm")
      RemoveProp_(hwnd, "cb_hot")
      RemoveProp_(hwnd, "cb_parent")
      RemoveProp_(hwnd, "cb_oldproc")
      RemoveProp_(hwnd, "cb_region")
      RemoveProp_(hwnd, "cb_monitor_tid")
    Case #WM_LBUTTONDOWN
      If PtInRegion_(hRgn,cp1\x,cp1\y) 
        SetGadgetState(GetDlgCtrlID_(hwnd),ImageID(GetProp_(hwnd,"cb_hot")))
      EndIf
    Case #WM_LBUTTONUP
      If PtInRegion_(hRgn,cp1\x,cp1\y) 
        SetGadgetState(GetDlgCtrlID_(hwnd),ImageID(GetProp_(hwnd,"cb_warm")))
        If lastbutton = 0 Or lastbutton= hwnd
          PostMessage_(GetProp_(hwnd,"cb_parent"), #CB_Button_Click, GetDlgCtrlID_(hwnd), 0)
        EndIf
        lastbutton = 0
      EndIf
    Case #Enter
      If GetAsyncKeyState_(#VK_LBUTTON) & 32768
        SetGadgetState(GetDlgCtrlID_(hwnd),ImageID(GetProp_(hwnd,"cb_hot")))
      Else
        SetGadgetState(GetDlgCtrlID_(hwnd),ImageID(GetProp_(hwnd,"cb_warm")))
      EndIf
    Case #Leave
      SetGadgetState(GetDlgCtrlID_(hwnd),ImageID(GetProp_(hwnd,"cb_cold")))
  EndSelect
  ProcedureReturn CallWindowProc_(oldproc,hwnd,msg,wParam,lParam)
EndProcedure
Procedure GrabRegion(ImageID, TransColor)
  
  Structure RECTARRAY
    rect.RECT[0]
  EndStructure
  
  Protected bmp.BITMAP,width.l,height.l,hVisibleRgn.l,combineresult.l=0, returnvalue.l = 0
  Protected BmiInfo.BITMAPINFOHEADER,rowbytes.l,*ColorBits,hdc.l,iRes.l,Structure_Max.l
  Protected *Buffer.RGNDATAHEADER,*rd.RECTARRAY,rectcount.l,y.l,x.l,pxcount.l,*px.Long
  Protected transcount.l,firsttrans.l,RegionSize.l,hTransparentRgn.l
  
  If GetObject_(ImageID, SizeOf(BITMAP), @bmp.BITMAP) And bmp
    width = bmp\bmWidth
    height = bmp\bmHeight
    hVisibleRgn=CreateRectRgn_(0, 0, width, height)
    If hVisibleRgn
      With BmiInfo
        \biSize         = SizeOf(BITMAPINFOHEADER)
        \biWidth        = width
        \biHeight       = -height
        \biPlanes       = 1
        \biBitCount     = 32
        \biCompression  = #BI_RGB
      EndWith   
      rowbytes =  SizeOf(Long)*width
      *ColorBits = AllocateMemory(rowbytes*height)
      If *ColorBits
        hdc   = GetWindowDC_(#Null)
        If hdc
          iRes  = GetDIBits_(hdc, ImageID, 0, height, *ColorBits, @BmiInfo, #DIB_RGB_COLORS)
          If iRes
            ReleaseDC_(#Null, hdc)
            Structure_Max=(width*height*16)+SizeOf(RGNDATAHEADER)
            *Buffer=AllocateMemory(Structure_Max)
            If *Buffer
              *rd=*Buffer+SizeOf(RGNDATAHEADER)
              rectcount = 0
              For y=0 To height-1
                pxcount=0
                For x=0 To rowbytes-1 Step 4
                  *px = *ColorBits + rowbytes * y + x
                  If *px\l = TransColor
                    transcount = 1 : firsttrans = pxcount
                    x+SizeOf(Long) : *px.Long = *ColorBits + rowbytes * y + x
                    While *px\l = TransColor And x <= rowbytes-1
                      transcount+1 : pxcount+1 : x+SizeOf(Long)
                      *px = *ColorBits + rowbytes * y + x
                    Wend
                    x-SizeOf(Long) : *px.Long = *ColorBits + rowbytes * y + x
                    With *rd\rect[rectcount]
                      \left   = firsttrans           
                      \top    = y                     
                      \right  = firsttrans+transcount
                      \bottom = y+1     
                    EndWith
                    rectcount+1
                  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_(0, RegionSize, *Buffer)
              If hTransparentRgn
                combineresult = CombineRgn_(hVisibleRgn, hVisibleRgn, hTransparentRgn, #RGN_XOR)
                If combineresult = #SIMPLEREGION Or combineresult = #COMPLEXREGION
                  returnvalue = hVisibleRgn
                Else
                  returnvalue = 0
                EndIf
                DeleteObject_(hTransparentRgn)
              EndIf
              FreeMemory(*Buffer)
            EndIf
          EndIf
        EndIf
        FreeMemory(*ColorBits)
      EndIf
    EndIf
    DeleteObject_(bmp)
  EndIf
  ProcedureReturn returnvalue
EndProcedure
Procedure CustomButton(parent, button, x, y, w, h, image)
  Define disab, cold, warm, hot, mask, Region, tmp1, tmp2, dc, CustomButtonID, Handle, old, monitor_tid
  disab=GrabImage(image,#PB_Any, 0,   0, w, h)
  cold=GrabImage(image,#PB_Any, w,   0, w, h)
  warm=GrabImage(image, #PB_Any, w*2, 0, w, h)
  hot=GrabImage(image, #PB_Any, w*3, 0, w, h) 
  
  If w*5 = ImageWidth(image)
    mask=GrabImage(image, #PB_Any, w*4, 0, w, h)
    Region = GrabRegion(ImageID(mask), #Black)
  EndIf
  If Not Region
    Region = CreateRectRgn_(0,0,w,h)
  EndIf
  
  CustomButtonID = ImageGadget(button,x,y,w,h,ImageID(cold))
  If button=#PB_Any
    Handle = GadgetID(CustomButtonID)
  Else
    Handle = CustomButtonID
  EndIf
  
  old = SetWindowLong_(Handle, #GWL_WNDPROC, @CustomButtonProc())
  
  SetProp_(Handle,"cb_oldproc", old)
  SetProp_(Handle,"cb_status",0)
  SetProp_(Handle,"cb_disab",disab) 
  SetProp_(Handle,"cb_cold",cold)
  SetProp_(Handle,"cb_warm",warm)
  SetProp_(Handle,"cb_hot",hot)
  SetProp_(Handle,"cb_parent",parent)
  SetProp_(Handle,"cb_region",Region)
  
  monitor_tid = CreateThread(@Monitor(),Handle)
  SetProp_(Handle,"cb_monitor_tid",monitor_tid)
  
  ProcedureReturn CustomButtonID
  
EndProcedure
Petit exemple pour l'utiliser:
Code : Tout sélectionner
#Image_Buttons = 0
#Button_0 = 0
#Button_1 = 1
#Button_2 = 2
UsePNGImageDecoder()
If LoadImage(#Image_Buttons,OpenFileRequester("Selection du button","","PNG|*.png",0))
  OpenWindow(0,0,0,400,150,"Test boutons",#PB_Window_ScreenCentered)
  
  CustomButton(WindowID(0),#Button_0,40,20,48,48,#Image_Buttons)
  CustomButton(WindowID(0),#Button_1,120,20,48,48,#Image_Buttons)
  CustomButton(WindowID(0),#Button_2,200,20,48,48,#Image_Buttons)
  DisableGadget(0,1)
  
  Repeat
    Select WaitWindowEvent()
      Case #CB_Button_Click
        Select EventwParam()
          Case #Button_1
            Debug "Bouton 1!"
          Case #Button_2
            Debug "Bouton 2!"
        EndSelect
      Case #WM_CLOSE
        FreeImage(#Image_Buttons)
        End
    EndSelect
  ForEver
EndIf
Informations supplémentaires a écrit :Uniquement PB4.40 et plus: on a besoin du support du chanel Alpha. Il est tout à fait utilisable avec le skin windows, il a même été pensé dans ce sens.
Autre détail: les boutons réagissent bizarrement dans un environnement multi-écran, quand ils sont ouvert dans un écran aillant des coordonnées négatives. Je comprends bien le pourquoi, mais je n'arrive pas à régler le problème...
- 3]Skinner une Progress Bar
 
Bon, j'ai un gros bug sur celle là, je la règlerais prochainement et on passe à la suite en attendant
- 4]Progresse Circle
 
Code : Tout sélectionner
Procedure ProgressCircle(gadgetNumber.l,x.l,y.l,Size.l,segments.l,bg.l)
  Protected radius.l,n.l,x2.l,y2.l,img.l, beta_in_rad.d
  
  img = CreateImage(#PB_Any,Size,Size)
  StartDrawing(ImageOutput(img))
    Box(0,0,Size,Size,bg)
    radius = Size/2
    Circle(radius,radius,radius)
    Circle(radius,radius,radius-8,bg)   
    
    For n = 0 To segments-1
      beta_in_rad = (2*#PI*n)/segments
      x2.l = radius *(1 + Cos(beta_in_rad))
      y2.l = radius *(1 + Sin(beta_in_rad))
      LineXY(radius,radius,x2,y2,bg)
    Next
    
  StopDrawing()
  ImageGadget(gadgetNumber,x,y,Size,Size,ImageID(img))
  SetGadgetData(gadgetNumber, img)
EndProcedure
Procedure SetProgressCircleState(progressbar.l,segments.l, State.l, color.l, bg.l)
  Static progCirc_font.l
  Protected IW2.l,TW2.l,TH2.l,x.l,y.l,sp_to_clear.l
  Protected img.l = GetGadgetData(progressbar)
  Protected beta_in_rad.d
  
  
  StartDrawing(ImageOutput(img))
    
    IW2.l = ImageWidth(img)/2
    State - 1
    beta_in_rad.d = (2*#PI*State)/segments - #PI/2
    x = IW2 + (IW2 - 4)*Cos(beta_in_rad)
    y = IW2 + (IW2 - 4)*Sin(beta_in_rad)
    If State < segments/4
      x + 2
      y + 2
    ElseIf State < segments/2
      x - 2
      y + 2
    ElseIf State < 3*segments/4
      x - 2
      y - 2
    Else
      x + 2
      y - 2
    EndIf
    
    FillArea(x,y,bg,color)
    
  StopDrawing()
  SetGadgetState(progressbar,ImageID(img))
  
  While WindowEvent():Wend
  ProcedureReturn 1
EndProcedurePetit exemple pour s'en servir:
Code : Tout sélectionner
#Window_Processing = 0
#ProgressCircle = 0
#ProgressText = 1
OpenWindow(#Window_Processing,0,0,200,60,"Test du progress Circle",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
ProgressCircle(#ProgressCircle,5,5,50,8,$F1F1F1)
TextGadget(#ProgressText,60,22,135,15,"Processing",#PB_Text_Center)
      
temp$ = EventDropFiles()
      
r=10
g=150
b=10
Repeat
  For m= 1 To 8
    SetProgressCircleState(#ProgressCircle,8,m,RGB(r, g, b),$F1F1F1)
    Delay(100)
    WindowEvent()
  Next
  
  r+20
  g+25
  b+10
  If g>240
    r=10
    g=150
    b=10
  EndIf
ForEverInformations supplémentaires a écrit :Niveau intégration dans une fenêtre skinnée, c'est pas encore ça, faudrait que je bosse la dessus (mais en ce moment, c'est pas ma priorité, faudra attendre un peu :p)
Aussi, mon exemple est un peu foireux. Pour l'utiliser correctement, il faut plaquer l'avancement du progress circle dans un thread; cela dit, je pense que l'exemple est assez parlant en soit et que vous saurez broder autour.