Page 1 sur 1

Dessin sur le bureau

Publié : dim. 07/août/2022 11:30
par SPH
Salut,

je me suis penché sur un code de ollivier. Et je voudrais comprendre comment ça marche.
Quelqu'un pourrait faire un code MINIMALISTE avec (par exemple) une boule sur le bureau ?

Merci

Code : Tout sélectionner

Define tempWin = OpenWindow(#PB_Any, ExamineDesktops(), 0, 0, 0, "", #PB_Window_Maximize | #PB_Window_BorderLess | #PB_Window_Invisible)
If DesktopWidth(0) <> WindowWidth(tempWin) * DesktopResolutionX()
    If #PB_Compiler_OS = #PB_OS_Windows And OSVersion() > 70
        MessageRequester("Don't forget to...", "switch the user option ! (menu Compiler)")
        End
    EndIf
    MessageRequester("Please switch...", "the dpi option on ! (menu Compiler)")
    End
EndIf
CloseWindow(tempWin)
Global Dim win.i(2047)
Global Dim hid.i(2047)
hid(3) = 1     
hid(7) = 1     
hid(8) = 1     
hid(10) = 1    
hid(11) = 1    
hid(13) = 1    
hid(15) = 1    
hid(19) = 1    
hid(22) = 1    
hid(25) = 1    
hid(28) = 1    
hid(32) = 1    
hid(34) = 1     
hid(37) = 1     
hid(39) = 1     
hid(44) = 1     
hid(50) = 1     
hid(52) = 1     
hid(53) = 1     
hid(55) = 1     
hid(67) = 1     
hid(76) = 1     
hid(77) = 1     
hid(79) = 1     
hid(84) = 1     
hid(85) = 1     
hid(86) = 1     
hid(89) = 1     
hid(91) = 1     
hid(92) = 1     
hid(100) = 1    
hid(103) = 1    
hid(107) = 1    
hid(110) = 1    
hid(111) = 1    

Procedure.i unscaX(x.i)
    ProcedureReturn DesktopUnscaledX(x)
EndProcedure

Procedure.i unscaY(y.i)
    ProcedureReturn DesktopUnscaledY(y)
EndProcedure

Global.I ctlWin = OpenWindow(#PB_Any, 16, 16, UnscaX(400), UnscaY(300), "", #PB_Window_SystemMenu | #PB_Window_Invisible ! #PB_Window_Invisible)

Procedure coloredBox(x, y, w, h, color)
    Define.i window
    window = OpenWindow(#PB_Any, UnscaX(x), UnscaY(y), unscax(w), UnscaY(h), "", #PB_Window_BorderLess | #PB_Window_NoGadgets | #PB_Window_NoActivate | #PB_Window_Invisible ! #PB_Window_Invisible, WindowID(ctlWin) )
    SetWindowColor(window, color)
    StickyWindow(window, 1)
    ProcedureReturn window
EndProcedure

ExamineDesktops()
Global dw = DesktopWidth(0)
Global dh = DesktopHeight(0)
Global gw = 16
Global gh = 9
Global cw = dw / gw
Global ch = dh / gh
Global Dim gx.d(2)
Global Dim gy.d(3)
Global Dim xx.d(2)
Global Dim yy.d(3)
 gx(0) = 1 / 8
 gy(0) = 1 / 10
 gx(1) = gx(0)
 gx(2) = 1 - gx(0)
 gy(1) = gy(0)
 gy(2) = 1 / 2
 gy(3) = 1 - gy(0)
Global Dim x.d(3)
Global Dim y.d(4)

Procedure bcd()
thi.d = 12
thi2.d = thi / 2
y = 4 * ch
id = 0
Repeat
    x = 0
    Repeat             
        For yy = 1 To 3
            For xx = 1 To 2                
                xx(xx) = x + cw * gx(xx)
                yy(yy) = y + ch * gy(yy)
            Next
        Next        
        cc = RGB((x * 255) / dw, ((dw - x) * 255) / dw, 0)
        For yy = 1 To 3
            For xx = 1 To 2                
                If xx < 2
                    If hid(id) = 0 And win(id) = 0
                        win(id) = coloredBox(xx(xx) + thi2, yy(yy) - thi2, xx(xx + 1) - xx(xx) - thi, thi, cc)
                    EndIf
                    If hid(id) And win(id)
                        CloseWindow(win(id) )
                        win(id) = 0
                    EndIf
                    id + 1
                EndIf
                If yy < 3
                    If hid(id) = 0 And win(id) = 0
                        win(id) = coloredBox(xx(xx) - thi2, yy(yy) + thi2, thi, yy(yy + 1) - yy(yy) - thi, cc)
                    EndIf
                    If hid(id) And win(id)
                        CloseWindow(win(id) )
                        win(id) = 0
                    EndIf
                    id + 1
                EndIf
            Next
        Next        
        x + cw
    Until x >= dw
    y + ch
Until y >= dh / 2
EndProcedure
dmx = DesktopMouseX()
Repeat
    t = ElapsedMilliseconds()
    If t > lap
        lap = t + 1000
        bcd()
        For i = 0 To 7
            hid(i + 16*7) = hid(i)
        Next
        For i = 0 To 16 * 7 - 1 Step 1
            hid(i) = hid((i + 7) )
        Next
    EndIf
    Delay(33)
    ev = WindowEvent()
    dmx0 = dmx
    dmx = DesktopMouseX()
Until ev = #PB_Event_CloseWindow ; dmx <> dmx0

Re: Dessin sur le bureau

Publié : dim. 07/août/2022 13:46
par Ollivier
Si tu veux une boule, tu n'est plus dans la forme rectangulaire orthogonale (pas oblique, juste avec des côtés horizontaux et verticaux).

Dans ce cas, tu dois utiliser une fonction de la bibliothèque GDI (il me semble) : UpdateLayeredWindow(), ou son équivalent sous Linux.

Ça te permet de faire des "skins" de fenêtre (tableaux de bord, décoration hi-fi, etc... ). Il y a pas mal d'exemples pour Windows depuis près de 20 ans.

Ce qui est intéressant avec ce code, c'est qu'il te permet de chercher les limites d'affichage. Windows (Linux doit réagir un peu pareil) traite pleins d'informations (peu utiles ici) autour de chaque fenêtre (segment), et donc est très lent et crée parfois des artifacts.

Un disque mettrait un temps fou, avec une lenteur et une prise de ressources énormes.

Re: Dessin sur le bureau

Publié : lun. 08/août/2022 22:22
par Ar-S
Pour pouvoir fermer ta fenêtre avec la croix j'ai modifié les lignes 145 et 146

Code : Tout sélectionner

    Delay(33)
    ev = WindowEvent()
par

Code : Tout sélectionner

;     Delay(33)
    ev = WaitWindowEvent(33)
Pour ton histoire de boule SPH j'ai rien pipé au code.
note : Tu commenterais tes codes Ollivier ce serait pas dégueux. :mrgreen:

Re: Dessin sur le bureau

Publié : mar. 09/août/2022 13:30
par case
j'ai compris certain trucs de ce code, mais pas tout, notamment comment il crée les chiffres & lettres hexa.
ollivier m’étonnera toujours :)
l'affichage ensuite utilise des fenêtres colores a la place des fonctions de dessins.

donc effectivement une boule ca risque d'etre tendu du slip puisque chaque segment est une fenetre dans ce cas ci :)

Re: Dessin sur le bureau

Publié : mar. 09/août/2022 16:37
par SPH
Il me semble me rappeler que LSI savait faire des fenêtres non carrées. :idea:

Donc, je demandais une boule :arrow: :?

Re: Dessin sur le bureau

Publié : mar. 09/août/2022 21:08
par Ar-S
@SPH
Une partie de la lib de LSI et je t'ai fait un exemple de skin rond
Le topic avec la lib complète est là.
https://www.purebasic.fr/french/viewtop ... hilit=skin

Code : Tout sélectionner


Procedure SkinWindow(WindowID, ImageID) ; Mettre une forme sur une fenêtre a partir d'une image
    ; Parti de la libe SKINWINDIW de LSI
    Protected bmi.BITMAPINFO, Region_Temp, Region_Totale, Largeur, Hauteur
  
  GetObject_(ImageID, SizeOf(BITMAP), @bm.BITMAP)
  
  bmi\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
  bmi\bmiHeader\biWidth = bm\bmWidth
  bmi\bmiHeader\biHeight = bm\bmHeight
  bmi\bmiHeader\biPlanes = 1
  bmi\bmiHeader\biBitCount = 32
  bmi\bmiHeader\biCompression = #BI_RGB
  
  Region_Totale = CreateRectRgn_(0, 0, bm\bmWidth, bm\bmHeight)
  
  mem = AllocateMemory(bm\bmWidth * bm\bmHeight * 4)
  If mem
    
    hdc = CreateCompatibleDC_(GetDC_(ImageID))
    If hdc
      GetDIBits_(hdc, ImageID, 0, bm\bmHeight, mem, @bmi, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
      DeleteDC_(hdc)
    EndIf
    
    ; On convertit la liste dans le bon format
    Largeur = bm\bmWidth - 1
    Hauteur = bm\bmHeight - 1
    Point = mem
    For y1 = 0 To Hauteur
      For x1 = 0 To Largeur
        If PeekL(Point) = $FF00FF
          x2 = x1
          While x2 < Largeur And PeekL(Point + 4) = $FF00FF
            x2 + 1
            Point + 4
          Wend
          Region_Temp = CreateRectRgn_(x1, Hauteur - y1, x2 + 1, Hauteur - y1 + 1) ; On retire le point de la region
          CombineRgn_(Region_Totale, Region_Totale, Region_Temp, #RGN_DIFF)
          DeleteObject_(Region_Temp)
          x1 = x2
        EndIf
        Point + 4
      Next
    Next
    
    FreeMemory(mem)
  EndIf
  
  SetWindowRgn_(WindowID, Region_Totale, 1) ; On applique la region
  DeleteObject_(Region_Totale) ; On efface la region
  
EndProcedure



; Création de la fenêtre et de la GadgetList
If OpenWindow(0, 0, 0, 300, 300, "Skin", #PB_Window_BorderLess | #PB_Window_ScreenCentered) = 0
  End
EndIf
; La fenêtre doit obligatoirement être avec le style #PB_Window_BorderLess

SetWindowColor(0, RGB(255, 0, 0))

; On crée une image qui va servir de skin (elle doit avoir la taille de la fenêtre)
CreateImage(0, 300, 300)
StartDrawing(ImageOutput(0))
  ; La couleur mauve $FF00FF ou RGB(255, 0, 255) représente la partie transparente de la fenêtre
  Box(0, 0, 300, 300, $FF00FF)
  Circle(150, 150, 100, $00CCFF)
  StopDrawing()

Temps = ElapsedMilliseconds()

SkinWindow(WindowID(0), ImageID(0))

Temps = (ElapsedMilliseconds() - Temps)

; On place un bouton pour quitter
ButtonGadget(0, 120, 120, 100, 25, "Quitter")

Repeat
  Event = WaitWindowEvent()
  
  If Event = #WM_LBUTTONDOWN
    SendMessage_(WindowID(0), #WM_NCLBUTTONDOWN, #HTCAPTION, 0)
  EndIf
  
  If Event = #PB_Event_Gadget
    Select EventGadget() ; boutons, zone de texte, ...
      Case 0 ; On quitte le programme
        Event = #PB_Event_CloseWindow
    EndSelect
  EndIf
  
Until Event = #PB_Event_CloseWindow

End

Re: Dessin sur le bureau

Publié : mar. 09/août/2022 22:11
par SPH
Haaaa, excellent. C'est exactement ce que je voulais. Comme quoi, c'était possible ! 😍

Re: Dessin sur le bureau

Publié : mer. 10/août/2022 1:16
par Ollivier
Comme dit le proverbe chinois : la politique de la boule unique...

Code : Tout sélectionner

OpenWindow(1,100,100,200,200,"Redimensionnable",#PB_Window_SizeGadget|#PB_Window_SystemMenu)
SetWindowColor(1,$efface)
wId = WindowID(1)
SetWindowLongPtr_(wId,-20,GetWindowLongPtr_(wId,-20)|$80000)
SetLayeredWindowAttributes_(wId,$efface,0,1)
Repeat
 ev=WaitWindowEvent()
 If ev=#PB_Event_Repaint Or ev=#PB_Event_SizeWindow
  StartDrawing(WindowOutput(1))
  w=OutputWidth()
  h=OutputHeight()
  Box(0,0,w,h,#White)
  Ellipse(w/2,h/2,w/2,h/2,$efface)
  StopDrawing()
 EndIf
Until ev=#PB_Event_CloseWindow
Et le canvas ça marche pareil, canvasOuput au lieu de windowOutput !

Re: Dessin sur le bureau

Publié : mer. 10/août/2022 9:26
par SPH
Extra Ollivier !

Court et très compréhensible !!! 🥰