Page 1 sur 1

Résolut Theme XP et autres...

Publié : lun. 09/mars/2009 8:55
par MLD
Bonjours a tous
Etant toujours débutant en PB, mais aimant bien réaliser des logiciels hestétiques. J'ai 'remarqués que certains gadgets sont plus jolis en window classique, et d'autres en theme XP.
Ma question est donc! Est'il possible dans un même programme de mélanger des gadgets classiques et des gadgets theme XP et comment?
Merci de vos réponses.
Michel

Publié : lun. 09/mars/2009 9:46
par Kwai chang caine
Bonjour MDD

Je crois en fait que le THEME est choisi pour tout ton windows.
Selon le theme que tu choisiras, tu auras tes fenetres, boutons etc d'une certaine couleur, forme...

Par contre tu peu creer tes propres fenetres, que l'on appelle SKINNéE.
Soit avec des codes de juxtaposition de la fenetre sur une image, meme si celle ci a des bords non rectangulaires et irreguliers

Soit en creant tes fenetres avec du code seulement, ou bien avec du code et des images qui viendront se positionner sur ta fenetre afin de produire l'effet que tu désire.

Il y a pas mal d'exemples sur les forums, fait rechercher, avec les mots SKIN, SKINNAGE, Fenetre bord arrondis, etc

Et dans ce cas ta fenetre et/ou tes gadgets ne seront pas soumis au graphisme de windows, et restera comme tu l'a créé

Voila voila de ce que je sais.........

Theme XP et autres ....

Publié : lun. 09/mars/2009 11:27
par MLD
Merci de ta réponse Kwai Chang Caine
Mais tu as un peu faux, car en bricolant ce code j'ai obtenu ceci.
Mais je voudrai faire pareil avec un stringGadget, un listIconeGadget.

Code : Tout sélectionner

; Title: Frame3DGadgetEx 
; Author: Fluid Byte 
; Date: December 31, 2006 
; Version: PureBasic V4.3 
Global FontID3
FontID3 = LoadFont(3, "Courier New", 12)

Structure FRAME3DEX 
   lpPrevFunc.l 
   clrText.l 
   ;bThemeXP.b 
EndStructure 

Procedure Frame3DExProc(hWnd.l,uMsg.l,wParam.l,lParam.l) 
   Protected hDC.l,ps.PAINTSTRUCT,*frmex.FRAME3DEX,Title.s,fts.SIZE,wrc.RECT,lpBuffer.l;hThemeButton.l 
                
   *frmex = GetWindowLong_(hwnd,#GWL_USERDATA) 
    
    Select uMsg 
       Case #WM_DESTROY 
       *frmex\lpPrevFunc = -1 
        
       ProcedureReturn 0 
        
        Case #WM_PAINT        
      hdc = BeginPaint_(hwnd,ps) 
        
      ;SelectObject_(hdc,SendMessage_(hwnd,#WM_GETFONT,0,0)) ;on peu changer de fonte
      SelectObject_(hdc,SendMessage_(hwnd,FontID3,0,0))  ; comme ici
      Title = GetGadgetText(GetDlgCtrlID_(hwnd))    
      GetTextExtentPoint32_(hdc,Title,Len(Title),fts)    
      GetClientRect_(hWnd,wrc)        
      SetRect_(wrc,wrc\left,wrc\top+fts\cy/2,wrc\right,wrc\bottom) 
        
;        If OSVersion() = #PB_OS_Windows_XP And IsThemeActive_() And IsAppThemed_() And *frmex\bThemeXP 
;          lpBuffer = AllocateMemory(13) : PokeS(lpBuffer,"Button",-1,1)        
;           
;          hThemeButton = OpenThemeData_(WindowID(0),lpBuffer)          
;          DrawThemeBackground_(hThemeButton,hdc,4,1,wrc,0) 
;          CloseThemeData_(hThemeButton) 
;           
;         FreeMemory(lpBuffer)          
;      Else 
         DrawEdge_(hdc,wrc,#EDGE_ETCHED,#BF_RECT) 
     ;EndIf 
    
      SetBkColor_(hdc,GetSysColor_(#COLOR_3DFACE)) ;couleur de fond sous le texte 
      SetTextColor_(hdc,*frmex\clrText) 
      TextOut_(hdc,9,0,Title,Len(Title))  ; placement du texte  

      EndPaint_(hwnd,ps) 

      ProcedureReturn 0 

      Default 
      If *frmex\lpPrevFunc = -1 : FreeMemory(*frmex) : Else 
         ProcedureReturn CallWindowProc_(*frmex\lpPrevFunc,hWnd,uMsg,wParam,lParam)          
      EndIf 
    EndSelect 
EndProcedure 

Procedure Frame3DGadgetEx(GadgetID.w,X.w,Y.w,Width.w,Height.w,Text.s,Color.l=0)        
   Protected *frmex.FRAME3DEX,HINSTANCE.l 
    
   Frame3DGadget(GadgetID,X,Y,Width,Height,Text)    
    
   *frmex = AllocateMemory(SizeOf(FRAME3DEX)) 
   *frmex\lpPrevFunc = SetWindowLong_(GadgetID(GadgetID),#GWL_WNDPROC,@Frame3DExProc()) 
   *frmex\clrText = Color 

;    HINSTANCE = OpenLibrary(#PB_Any,ProgramFilename()) 
;    *frmex\bThemeXP = FindResource_(LibraryID(HINSTANCE),1,24) 
;    CloseLibrary(HINSTANCE) 
    
   SetWindowLong_(GadgetID(GadgetID),#GWL_USERDATA,*frmex) 
    
   ProcedureReturn GadgetID(GadgetID) 
EndProcedure 

OpenWindow(0,0,0,400,300,"Ownerdraw Frame3D Control",#WS_OVERLAPPEDWINDOW | 1) 

SetGadgetFont(#PB_Default,LoadFont(0,"Arial",9)) 

Frame3DGadgetEx(101,10,5,200,90,"Sans theme XP",#Red) 
Frame3DGadgetEx(102,10,100,200,90,"Sans theme XP",RGB(40,180,70)) 
Frame3DGadgetEx(103,10,195,200,90,"Sans theme XP",#Blue) 
ButtonGadget(1, 300, 240, 80, 50, "Theme XP")

While WaitWindowEvent() ! 16 : Wend 
[/code]

Publié : lun. 09/mars/2009 13:04
par Backup
que ce soit a partir de windows classique , ou de windows avec theme Xp

lorsque je lance ton code, et que j'appuie que le bouton, ça ne change rien chez moi :?

que la prise en compte des theme soit activé ou pas !!


bref ton code ne fait rien , chez moi (Xp service pack 3)

Publié : lun. 09/mars/2009 14:09
par Kwai chang caine
que ce soit a partir de windows classique , ou de windows avec theme Xp
lorsque je lance ton code, et que j'appuie que le bouton, ça ne change rien chez moi
que la prise en compte des theme soit activé ou pas !!
bref ton code ne fait rien , chez moi (Xp service pack 3)
Bah si a part la couleur de chaque gadget :lol:

Publié : lun. 09/mars/2009 15:22
par Anonyme2
Voila comment on fait pour supprimer les thème d'un gadget (le sujet a déjà été abordé par le passé).

Comme c'est un code rapide, je n'ai pas fait de tests si le gadget existe etc, à toi de faire une application qui est stable.

Il faut utiliser l'API des thèmes SetWindowTheme doc MS ici
http://msdn.microsoft.com/en-us/library ... S.85).aspx

La doc explique comment faire, mais l'exemple est plus parlant

Code : Tout sélectionner

#Librairie = 1

#Bouton_1 = 1
#Bouton_2 = 2
#Listicon_1 = 3
#Listicon_2 = 4


;-Macros permettant de retrouver l'identifiant système du header de la listicon
Macro HeaderID(GadgetID)
    SendMessage_(GadgetID, #LVM_GETHEADER, 0, 0)
EndMacro


If OpenLibrary(#Librairie, "UxTheme.dll") = 0
    MessageRequester("Error", "Les thèmes ne sont pas disponibles")
    End
EndIf

*SetWindowTheme = GetFunction(#Librairie, "SetWindowTheme")
If *SetWindowTheme = 0
    MessageRequester("Error", "Couldn't find SetWindowTheme")
    End
EndIf

If OpenWindow(0, 100, 100, 300, 450, "SetWindowTheme", #PB_Window_SystemMenu)
     ButtonGadget(#Bouton_1, 20, 20, 100, 60, "Avec thèmes")
     ButtonGadget(#Bouton_2, 180, 20, 100, 60, "Sans thème")
     ListIconGadget(#Listicon_1, 20, 110, WindowWidth(0)-40, 150, "Avec thèmes", 90 )
     ListIconGadget(#Listicon_2, 20, 280, WindowWidth(0)-40, 150, "Sans thème", 90 )

     
     ;// la variable null doit valoir 0
     null.w = 0
     ;// supprime les thèmes du second bouton
     CallFunctionFast(*SetWindowTheme, GadgetID(#Bouton_2), @null, @null)

     ;// supprime les thèmes de la seconde Listicon
     CallFunctionFast(*SetWindowTheme, GadgetID(#Listicon_2), @null, @null)
     
     ;// supprime les thème du header de la listicon (la ligne d'en-tête)
     CallFunctionFast(*SetWindowTheme, HeaderID(GadgetID(#Listicon_2)), @null, @null)
     
     
     Repeat
     Until WaitWindowEvent() = #PB_Event_CloseWindow
     
     CloseLibrary(#Librairie)
EndIf

Publié : lun. 09/mars/2009 15:28
par comtois

Theme XP et autres...

Publié : lun. 09/mars/2009 17:17
par MLD
Merci pour vos réponses
Dobro: Le bouton ne sert a rien c'est pour montrer que l'on peu mélanger les themes XP (le bouton) avec du window classique)
Michel

Publié : lun. 09/mars/2009 17:48
par Backup
arf !! ok :D

Re: Résolut Theme XP et autres...

Publié : lun. 09/mars/2009 17:49
par MLD
Denis: Merci de ton aide. ton code répond parfaitement a mon problème.
Je vois que tu es un grand spécialiste de l' API window.
Michel

Publié : lun. 09/mars/2009 19:34
par comtois
Denis, il y a une raison particulière pour que tu ouvres UxTheme.dll ?

J'ai testé ton code en utilisant la fonction déjà déclarée dans PureBasic, ça fonctionne très bien sur XP.

Code : Tout sélectionner

#Bouton_1 = 1
#Bouton_2 = 2
#Listicon_1 = 3
#Listicon_2 = 4

;-Macros permettant de retrouver l'identifiant système du header de la listicon
Macro HeaderID(GadgetID)
    SendMessage_(GadgetID, #LVM_GETHEADER, 0, 0)
EndMacro


If OpenWindow(0, 100, 100, 300, 450, "SetWindowTheme", #PB_Window_SystemMenu)
     ButtonGadget(#Bouton_1, 20, 20, 100, 60, "Avec thèmes")
     ButtonGadget(#Bouton_2, 180, 20, 100, 60, "Sans thème")
     ListIconGadget(#Listicon_1, 20, 110, WindowWidth(0)-40, 150, "Avec thèmes", 90 )
     ListIconGadget(#Listicon_2, 20, 280, WindowWidth(0)-40, 150, "Sans thème", 90 )

     
     ;// la variable null doit valoir 0
     null.w = 0
     ;// supprime les thèmes du second bouton
     SetWindowTheme_(GadgetID(#Bouton_2), @null, @null)

     ;// supprime les thèmes de la seconde Listicon
     SetWindowTheme_(GadgetID(#Listicon_2), @null, @null)
     
     ;// supprime les thème du header de la listicon (la ligne d'en-tête)
     SetWindowTheme_(HeaderID(GadgetID(#Listicon_2)), @null, @null)
     
     
     Repeat
     Until WaitWindowEvent() = #PB_Event_CloseWindow

EndIf

Publié : lun. 09/mars/2009 19:52
par Anonyme2
comtois a écrit :Denis, il y a une raison particulière pour que tu ouvres UxTheme.dll ?

J'ai testé ton code en utilisant la fonction déjà déclarée dans PureBasic, ça fonctionne très bien sur XP.
On a 3 manières de faire (peut-être 4):
- Les API des thèmes sont déclarées (j'avais fait les fichiers et Fred les a utilisés si je me souviens bien, http://www.purebasic.fr/french/viewtopic.php?t=2561), on utilise avec le _ et ça marche.

- on utilise les import et ça marche aussi

- on utilise le callfunctionfast et ça marche aussi.

La dll des thèmes n'est présente que depuis XP, serveur 2003, Vista et serveur 2008. Si on lance le code sur W2000 par exemple sans tester la dll, on aura un message du linker lorsque le programme s'exécutera, je préfère gérer ce problème et mettre un message personnalisé si les thèmes ne sont pas dispo.

Je crois avoir fait des tests et même en testant si la dll est là et que l'on utilise les import, on aura tout de même le message d'erreur du linker, c'est pour ça que je teste la fonction et que j'utilise callfunctionfast, c'est pas plus difficile, juste une question d'écriture.

On pourrait écrire des macros pour utiliser cette méthode afin de faciliter l'écriture, je vous laisse faire . :D

A+
Denis