IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macros et VBA Excel Discussion :

[Windows API GDI] Dessiner un rectangle dans un userform


Sujet :

Macros et VBA Excel

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Ingénieur aéronautique
    Inscrit en
    Octobre 2018
    Messages
    216
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur aéronautique

    Informations forums :
    Inscription : Octobre 2018
    Messages : 216
    Par défaut [Windows API GDI] Dessiner un rectangle dans un userform
    Bonjour,

    Je souhaite dessiner un rectangle sans remplissage dans un userform pour entourer des contrôles. Jadis, je m'en serais sorti avec plusieurs MSForms.Frame de faible hauteur.

    Ci-desous un exemple basique sensé juste dessiner trait oblique, sauf que ça n'affiche rien...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    Option Explicit
     
    '
    Private Sub UserForm_Initialize()
     
        Left = 0
        Top = 0
     
        Dim hwnd As LongPtr: hwnd = API.GetActiveWindow
     
        Dim hdc As LongPtr: hdc = API.GetDC(hwnd:=hwnd)
     
        Dim lppt(1 To 2) As API.POINTAPI 'dans cet exemple, je ne prend que 2 points (MoveToEx et LineTo seraient probablement plus adaptés)
     
        lppt(1).x = Left 'à vrai dire, j'ignore s'il faille effectuer la translation de l'origine, peut-être utilisé MoveToEx ?
        lppt(1).y = Top
     
        lppt(2).x = Left + Width
        lppt(2).y = Top + Height
     
        'converti les coordonnées logiques en pixels
        Dim ind As Integer: For ind = LBound(lppt) To UBound(lppt)
     
            'conversion en coordonnées pixel
            lppt(ind).x = API.GetDeviceCaps(hdc:=hdc, nIndex:=API.LOGPIXELSX) * lppt(ind).x / API.POINTSPERINCH
            lppt(ind).y = API.GetDeviceCaps(hdc:=hdc, nIndex:=API.LOGPIXELSY) * lppt(ind).y / API.POINTSPERINCH
     
        Next ind
     
        API.PolylineTo hdc:=hdc, lppt:=lppt(1), cCount:=UBound(lppt) - LBound(lppt) + 1
     
        'j'imagine qu'il n'y a pas de brush à spécifier, vu que je ne souhaite pas de remplissage
        'mais qu'en est-il de l'epaisseur du trait, du moins s'il y en a un ?
     
        API.ReleaseDC hwnd:=hwnd, hdc:=hdc
     
    End Sub
    Déclarations de l'API Windows:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    Option Explicit
     
    Public Declare PtrSafe Function GetActiveWindow Lib "user32" () As LongPtr
     
    Public Declare PtrSafe Function GetDC Lib "user32" (ByVal hwnd As LongPtr) As LongPtr
    Public Declare PtrSafe Function ReleaseDC Lib "user32" (ByVal hwnd As LongPtr, ByVal hdc As LongPtr) As Long
     
    Public Declare PtrSafe Function LineTo Lib "gdi32" (ByVal hdc As LongPtr, ByVal x As Long, ByVal y As Long) As Long
    Public Declare PtrSafe Function MoveToEx Lib "gdi32" (ByVal hdc As LongPtr, ByVal x As Long, ByVal y As Long, lpPoint As POINTAPI) As Long
    Public Declare PtrSafe Function PolylineTo Lib "gdi32" (ByVal hdc As LongPtr, lppt As POINTAPI, ByVal cCount As Long) As Long
     
    Public Declare PtrSafe Function GetDeviceCaps Lib "gdi32" (ByVal hdc As LongPtr, ByVal nIndex As Long) As Long
     
    Public Type POINTAPI
        x As Long
        y As Long
    End Type
     
    Public Const LOGPIXELSX                 As Long = &H58&
    Public Const LOGPIXELSY                 As Long = &H5A&
    Public Const POINTSPERINCH            As Long = &H48&
    A ce sujet, je suis entrain de lire le livre Programming Windows de Charles Petzold (1998) sur l'API Windows. J'ai rencontré de nombreux exemples où ça implique des coordonées logiques de ce que je me rappelle (bon autant dire, j'ai fait les exercices sans vraiment comprendre... ) De plus, je n'ai entrevu des exemple que ce servent des object Excel.Shape, mais celà ne me convient pas, car le formulaire est en réalité implémenté sous CATIA (même si je fais des appels vers Excel).

    Pouvez-vous s'il vous plaît m'aider à ce sujet ?

    Merci

  2. #2
    Expert confirmé
    Avatar de Arkham46
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    5 865
    Détails du profil
    Informations personnelles :
    Localisation : France, Loiret (Centre)

    Informations forums :
    Inscription : Septembre 2003
    Messages : 5 865
    Par défaut
    Bonjour,

    Que s'est il passé entre jadis et aujourd'hui ?
    Pourquoi vouloir dessiner avec gdi ?
    Pour dessiner sur un userform, il faut le dc non pas de la fenêtre principale, mais d'une sous fenêtre ; celle sur laquelle office y dessine ses contrôles.
    Vu le besoin, je ne comprends pas trop l'idée d'utiliser gdi.

  3. #3
    Membre éclairé
    Homme Profil pro
    Ingénieur aéronautique
    Inscrit en
    Octobre 2018
    Messages
    216
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur aéronautique

    Informations forums :
    Inscription : Octobre 2018
    Messages : 216
    Par défaut
    Merci pour toutes ces questions... A vrai dire, je me forme tout simplement. Pour l'instant, je commence avec les bases de GDI. Ensuite, je verrai avec GDI+, Direct2D et problament bien d'autres.

    Effectivement le handle que je récupère correspond à celui du ThunderDFrame. La zone graphique d'emplacement des contrôles est de classe F3 Server XXX. Bon, j'ai fait les modilfs pour pourvoir y récupérer son handle (j'ai encapsulé une bonne partie des appels de l'API dans des classes pour m'astreindre la gestion des handles), mais ça n'a pas résolu le problème (vu l'heure qu'il est... )

  4. #4
    Expert confirmé
    Avatar de Arkham46
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    5 865
    Détails du profil
    Informations personnelles :
    Localisation : France, Loiret (Centre)

    Informations forums :
    Inscription : Septembre 2003
    Messages : 5 865
    Par défaut
    Je fais des choses du genre dans clGdi32 :
    https://arkham46.developpez.com/arti...ffice/clgdi32/

    Le sujet n'est pas simple.

  5. #5
    Membre éclairé
    Homme Profil pro
    Ingénieur aéronautique
    Inscrit en
    Octobre 2018
    Messages
    216
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur aéronautique

    Informations forums :
    Inscription : Octobre 2018
    Messages : 216
    Par défaut
    Merci pour cet example de classe, je vais donc essayer de m'y inspirer .

    Pour infos, j'ai lu et pratiqué (c'est-à-dire recopié et adapté les exemples en C++) les 2 / 3 du livre Windows programming de Charles Petzold (5ème édition de 1998), mais j'avoue ne pas encore être en mesure de coder avec autonomie.. En tout cas, c'est sûr qu'il faille avoir une bonne dose de courage..

  6. #6
    Expert confirmé
    Avatar de Arkham46
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    5 865
    Détails du profil
    Informations personnelles :
    Localisation : France, Loiret (Centre)

    Informations forums :
    Inscription : Septembre 2003
    Messages : 5 865
    Par défaut
    Effectivement bon courage

    Ce qu'il faut bien comprendre, c'est qu'un userform c'est office qui le gère.
    Si on veut modifier son comportement standard, ce n'est pas aisé.
    C'est bien différent d'un dessin sur une fenêtre qu'on crée nous mêmes (ce qu'on voit souvent en exemple dans d'autres langages).

Discussions similaires

  1. Réponses: 2
    Dernier message: 26/06/2019, 16h03
  2. Réponses: 0
    Dernier message: 24/12/2012, 21h32
  3. Réponses: 0
    Dernier message: 21/12/2012, 22h50
  4. Dessiner un rectangle dans la console
    Par Akastras dans le forum Langage
    Réponses: 2
    Dernier message: 02/12/2010, 15h55
  5. [MFC]dessiner un rectangle dans ma fenetre
    Par jiraya43 dans le forum MFC
    Réponses: 13
    Dernier message: 15/05/2006, 13h57

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo