Autres CreatorRibbonX palette color pour DUDU2

Boostez vos compétences Excel avec notre communauté !

Rejoignez Excel Downloads, le rendez-vous des passionnés où l'entraide fait la force. Apprenez, échangez, progressez – et tout ça gratuitement ! 👉 Inscrivez-vous maintenant !

patricktoulon

XLDnaute Barbatruc
Bonsoir @Dudu2
J’ai pu dézipper une archive et j'ai retrouvé les deux exemples
Le premier avec les images externes et l'autre intégrées
J’ai dû les updater car il n'y avait pas d'events click
Par contre je n'ai plus le code couleur des images j'ai donc mis dans le tag 1,2,3,4,5...10
tu peux faire un array si tu les a encore sans devoir revenir sur le xml
Voilà elles ont le même rendu toutes les deux

je regarde ton xml
 

Pièces jointes

Bonjour @patricktoulon,
Je l'ai fait avec une Shape Rectangle / Carré parce que c'est ce qui m'a paru le plus simple et aussi pour faire un code complètement différent du tien pour les raisons que tu connais (utilisation libre pour moi ou tout autre utilisateur). L'affichage de la palette est immédiat donc a priori ça ne le pénalise pas même si ton code serait a priori plus performant.
 
Bonjour @Dudu2
OK mais ta pas comprit ma remarque en fait
regarde
Pour afficher ce contenu, nous aurons besoin de votre consentement pour définir des cookies tiers.
Pour plus d'informations, consultez notre page sur les cookies.
Donc comme là on fait des ronds j'ai mis le square en optional
à n'utiliser qu’en cas de shapes ne remplissant pas 4 côtés égaux
Et voilà terminé l'usine a gaz pour 10 petits boutons
la fonction CreateIcon16
VB:
Function CreateIcon16(control As IRibbonControl, Optional InSquare As Boolean = False)
    'archive SCR disque 3:CreatorRibbonX imageMso v 2.2 by patricktoulon
   
    Dim Shap As Shape, carre As Shape, grp As ShapeRange, groupedShape As Shape
     Set bt = CommandBars(1).Controls.Add(msoControlButton, , , , True)
    Application.CutCopyMode = False 'vide le clip
    DoEvents
   
    If InSquare Then
    ' Crée un carré blanc
    Set carre = ActiveSheet.Shapes.AddShape(msoShapeRectangle, 0, 0, 17, 17)
    carre.Fill.Transparency = 1
    carre.Line.Visible = msoFalse
    End If
   
    ' Crée un cercle avec la couleur  (la valeur est dans le control.tag injecté)
    Set Shap = ActiveSheet.Shapes.AddShape(msoShapeOval, 0, 0, 16, 16)
    Shap.Fill.ForeColor.RGB = Val(control.Tag)
    Shap.Line.Visible = msoFalse
   
    If InSquare Then
    'centre le rond sur le carré
    x = (carre.Width - Shap.Width) / 2
    y = (carre.Height - Shap.Height) / 2
    Shap.Left = carre.Left + x
    Shap.Top = carre.Top + y
   
   
    ' Regroupe les 2 formes
    Set grp = ActiveSheet.Shapes.Range(Array(Shap.Name, carre.Name))
    Set groupedShape = grp.Group
   
    ' Nomme le groupe
    groupedShape.Name = control.ID
    'les  2 shapes ne fonct plus qu'une  et un group est une shape a part entière
    'on peut donc copier cette shape
    groupedShape.CopyPicture 'pas bitmap sinon on a pas la transparence
   groupedShape.Delete
   Else
   'si on la met pas dans un carré
   Shap.Name = control.ID
   Shap.CopyPicture
   Shap.Delete
   End If
 
   'il nous reste plus qu'a coller sur le bouton temporaire de la commandbars(1)
    'avec la fonction native pasteFace
    On Error Resume Next
    bt.PasteFace
    On Error GoTo 0
   
    ' Retourne le .picture du bouton de la commandbarre
    Set CreateIcon16 = bt.Picture
   
End Function
qu'est-ce que tu veux de plus
 

Pièces jointes

Bonjour,
Mon code est différent (il le faut pour une utilisation libre) et fait l'économie de la mise au carré dans une forme carrée si Shape.Width = Shape.Height. Et dans le cas contraire, si la Shape est temporaire (marquage à la création Shape.AlternativeText = "TEMPORARY"), je ne créé pas de copie avant de la placer dans la Shape carrée. Mon code ShapeToIPicture() est générique et s'applique aussi bien à des Shapes temporaires marquées qu'à des Shapes pré-existantes en feuille.
 

Pièces jointes

Dernière édition:
re
Bien moi aussi tout pareil sauf qu'il n'y a plus d'api
Pour les shapes préexistantes il suffit que le nom soit dans le id ou tag
Et même au pire on peut indexer

Tu as vu ton fichier au bout de 10/ 15 enregistrements?
Chez moi il gonfle d'à peu près 50 kilos
Pourtant j'ai vérifié il n'y a pas de shape restantes

Visiblement avec le mien le fait de deleter les shape et le reset de la commandbars erase bien tout.
Peut-être est-ce le fait que les adresses mémoire des copies picture ne sont plus au même endroit avec la cmb

bon en tout cas maintenant tu sais faire hein 😉
 
Y a un truc, chez moi, qui m'emm*** et auquel je ne trouve pas de solution.
Lorsque je force le ActiveWorkbook.Saved = True pour ignorer la création des Shapes temporaires, à la fermeture du classeur, le processus EXCEL ne se termine pas et impossible de relancer un fichier EXCEL quelconque, il ne s'ouvre pas à cause de ce processus non terminé. Faut que je mette un Auto_Close():
VB:
Sub Auto_Close()
    'Quit or Close
    If ActiveWorkbook.Saved Then
        With Application
            If .Workbooks.Count = 1 Then .Quit Else ActiveWorkbook.Close
        End With
    End If
End Sub
 
Dernière édition:
tiens regarde je te parlais de la qualité des image hier
1762514940541.png

Dans le ruban on voit bien la bavure au dessus le oval les autres c'est moins évident mais bon c'est visible.
Et ça, ce sont les data qui ne sont pas bonnes
et pourtant tu travailles en bitmap en plus

c'est bien pour ca que je corrige avec les outils( GDI et GDI+) au départ dans ma version.
Je connais parfaitement le phénomène ,ce que tu utilises est un ersatz de la méthode stephen bullen( je l'ai longtemps utilisé).
Je dois même avoir encore ses modules originaux dans mes archives au complet
Mais ils ne sont plus assez précis et c'est bourré de fuite mémoire
Cette méthode était valable sur XP(et encore) mais sur nos windows d'aujourd'hui c'est un peu léger.

Intéresse-toi à ces apis et savoir comment elles travaillent
 
J'ai gardé ton code avec ton module fonctions_image et sa Function IpictureInSquare qui utilise tes API GDI.

Le problème c'est qu'en comparant ta méthode (API GDI) et le mienne, je trouve exactement les mêmes approximations des icônes du ruban lorsqu'on les grossit (ce qui est peu visible à l'état non grossi du ruban):

Grossissement Méthode @patricktoulon---------------------Grossissement Méthode @Dudu2
1762516721763.png
1762516632154.png


Je pense que c'est dû à EXCEL qui réduit ce qu'on lui donne en IPicture et n'est pas très précis.
 

Pièces jointes

j'ai mis tes boutons en gros pour mieux voir
en fait c'est bien ca c'est même pas du bitmap car normalement même sans square l'image devrait être carrée
si tu regardes bien tu insères du xlpicture(donc emf) dans un conteneur xlbitmap avec des data erronées

du coup ca enleve un peu de blanc mais ca en laisse un peu car le xlbitmap n'a pas de drowmooth comme avec gdi et gdi+
demo4.gif

Sur mon modèle, c'est normal que les images ne soient pas zoomables. Elles mesurent seulement 16(rellement puisque c'est la limite des commandbars), ce qui est vraiment petit. tandis que toi cu copie la shape et adapte le carrée a elle donc elle font plus que 16

la méthode de stephen bullen a tellement voyagé au fil des années tout le monde y a mis son grain de sel et c'est devenu n'importe quoi en fait
Tiens j'ai retrouvé la version qu'il a publiée au en 2000 je vais essayer de le retrouver dans mes archives la version initiale complète (elle était plus longue avant ) on voit bien que les data dans le guid sont les mêmes
VB:
Option Explicit
Option Compare Text
Private Type GUID
    Data1 As Long
    Data2 As Integer
    Data3 As Integer
    Data4(0 To 7) As Byte
End Type
Private Type uPicDesc
    Size As Long
    Type As Long
    hPic As Long
    hPal As Long
End Type
Private Declare Function IsClipboardFormatAvailable Lib "user32" (ByVal wFormat As Integer) As Long
Private Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function GetClipboardData Lib "user32" (ByVal wFormat As Integer) As Long
Private Declare Function CloseClipboard Lib "user32" () As Long
Private Declare Function OleCreatePictureIndirect Lib "olepro32.dll" (PicDesc As uPicDesc, RefIID As GUID, ByVal fPictureOwnsHandle As Long, IPic As IPicture) As Long
Declare Function CopyEnhMetaFile Lib "gdi32" Alias "CopyEnhMetaFileA" (ByVal hemfSrc As Long, ByVal lpszFile As String) As Long
Declare Function CopyImage Lib "user32" (ByVal handle As Long, ByVal un1 As Long, ByVal n1 As Long, ByVal n2 As Long, ByVal un2 As Long) As Long
Const CF_BITMAP = 2
Const CF_PALETTE = 9
Const CF_ENHMETAFILE = 14
Const IMAGE_BITMAP = 0
Const LR_COPYRETURNORG = &H4
' 30 Oct 98 Stephen Bullen Created
Function PastePicture(Optional lXlPicType As Long = xlPicture) As IPicture
    Dim h As Long, hPicAvail As Long, hPtr As Long, hPal As Long, lPicType As Long, hCopy As Long
    lPicType = IIf(lXlPicType = xlBitmap, CF_BITMAP, CF_ENHMETAFILE)
    hPicAvail = IsClipboardFormatAvailable(lPicType)
    If hPicAvail <> 0 Then
        h = OpenClipboard(0&)
        If h > 0 Then
            hPtr = GetClipboardData(lPicType)
            If lPicType = CF_BITMAP Then
                hCopy = CopyImage(hPtr, IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG)
            Else
                hCopy = CopyEnhMetaFile(hPtr, vbNullString)
            End If
            h = CloseClipboard
            If hPtr <> 0 Then Set PastePicture = CreatePicture(hCopy, 0, lPicType)
        End If
    End If
End Function
' 30 Oct 98 Stephen Bullen Created
Private Function CreatePicture(ByVal hPic As Long, ByVal hPal As Long, ByVal lPicType) As IPicture
    Dim R As Long, uPicInfo As uPicDesc, IID_IDispatch As GUID, IPic As IPicture
    Const PICTYPE_BITMAP = 1
    Const PICTYPE_ENHMETAFILE = 4
    With IID_IDispatch
        .Data1 = &H7BF80980
        .Data2 = &HBF32
        .Data3 = &H101A
        .Data4(0) = &H8B
        .Data4(1) = &HBB
        .Data4(2) = &H0
        .Data4(3) = &HAA
        .Data4(4) = &H0
        .Data4(5) = &H30
        .Data4(6) = &HC
        .Data4(7) = &HAB
    End With
    With uPicInfo
        .Size = Len(uPicInfo)                                                   ' Length of structure.
        .Type = IIf(lPicType = CF_BITMAP, PICTYPE_BITMAP, PICTYPE_ENHMETAFILE)  ' Type of Picture
        .hPic = hPic                                                            ' Handle to image.
        .hPal = IIf(lPicType = CF_BITMAP, hPal, 0)                              ' Handle to palette (if bitmap).
    End With
    R = OleCreatePictureIndirect(uPicInfo, IID_IDispatch, True, IPic)
    If R <> 0 Then Debug.Print "Create Picture: " & fnOLEError(R)
    Set CreatePicture = IPic
End Function
' 30 Oct 98 Stephen Bullen Created
Private Function fnOLEError(lErrNum As Long) As String
    Const E_ABORT = &H80004004
    Const E_ACCESSDENIED = &H80070005
    Const E_FAIL = &H80004005
    Const E_HANDLE = &H80070006
    Const E_INVALIDARG = &H80070057
    Const E_NOINTERFACE = &H80004002
    Const E_NOTIMPL = &H80004001
    Const E_OUTOFMEMORY = &H8007000E
    Const E_POINTER = &H80004003
    Const E_UNEXPECTED = &H8000FFFF
    Const S_OK = &H0
    Select Case lErrNum
        Case E_ABORT
            fnOLEError = " Aborted"
        Case E_ACCESSDENIED
            fnOLEError = " Access Denied"
        Case E_FAIL
            fnOLEError = " General Failure"
        Case E_HANDLE
            fnOLEError = " Bad/Missing Handle"
        Case E_INVALIDARG
            fnOLEError = " Invalid Argument"
        Case E_NOINTERFACE
            fnOLEError = " No Interface"
        Case E_NOTIMPL
            fnOLEError = " Not Implemented"
        Case E_OUTOFMEMORY
            fnOLEError = " Out of Memory"
        Case E_POINTER
            fnOLEError = " Invalid Pointer"
        Case E_UNEXPECTED
            fnOLEError = " Unknown Error"
        Case S_OK
            fnOLEError = " Success!"
    End Select
End Function
 
Bon, je te confirme c'est bien un emf que tu encapsules en bitmap
en fait la différence est ici
hCopy = CopyImage(GetClipboardData(&H2), 0, 0, 0, &H4) '&H8 pour le fond opaque
&h4 c'est pour le emf et &H8 c'est bitmap
en fait tu crée un bitmap avec des trous (du vide à la place du blanc )
du coup le renderer n'identifie pas bien les couleurs c'est ce qui explique les bavures
en gros c'est un hybride
 
En réduisant la taille des Shapes en feuille de 2cm à 0,5cm on obtient (avec les 2 méthodes) une amélioration du résultat grossi ~4 fois.
Ce qui tend à montrer que la réduction Excel de IPicture à Icône n'est pas optimale.
1762527298441.png
1762527872849.png
 
Dernière édition:
à ça c'est intéressant @Dudu2

un exemple des plus flagrant avec mon module ou j'envoie la shape dans des controls images de userform ou je strech
dans cette demo on voit bien que le fond qui reste transparent dans le ruban ne l'ai plus dans un control image
par contre on vois bien que ma fonction copyxlpicture dans un contenanir hybride est largement de meilleur qualité
demo4.gif
 
- Navigue sans publicité
- Accède à Cléa, notre assistante IA experte Excel... et pas que...
- Profite de fonctionnalités exclusives
Ton soutien permet à Excel Downloads de rester 100% gratuit et de continuer à rassembler les passionnés d'Excel.
Je deviens Supporter XLD
Retour