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

Windows Discussion :

Pseudo-terminaux et graphique sous API Windows


Sujet :

Windows

  1. #1
    Membre régulier Avatar de loupapet
    Homme Profil pro
    Retraité d'Eurocopter
    Inscrit en
    Janvier 2009
    Messages
    69
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 83
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité d'Eurocopter
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2009
    Messages : 69
    Points : 72
    Points
    72
    Par défaut Pseudo-terminaux et graphique sous API Windows
    Bonjour à tous,

    Je reviens sur le forum car, dans un petit développement, je bloque depuis plus d'une semaine sur la gestion graphique avec les API Windows. J'ai choisi de développer sous MinGW dans un terminal MinGW/Cygwin. Cependant, les programmes générés fonctionnent aussi dans un terminal Windows.

    Le but du développement

    Un processus-père jouant le rôle de serveur (Back-end) capture des sorties "stdout" d'un processus-fils (Front-end), codées pour permettre au processus-père de gérer une visualisation graphique. On retrouve exactement le principe donné par les pseudo-terminaux d'UNIX en plus simple !... L'application est résumée par le logigramme ci-dessous :

    Nom : Logigramme_apiptgr.png
Affichages : 474
Taille : 116,8 Ko

    Comme toute la phase d'encapsulation a été réalisée avec les API Windows, pour en apprendre un peu plus, j'ai décidé de traiter la partie graphique avec ces API. Au départ, j'envisageais plutôt la SDL.

    Comme on peut le voir sur le logigramme, l'application n'a besoin que de l'affichage graphique puisque toutes les actions graphiques sont déclenchées par une commande reçue du processus-fils.

    Dans le programme source de test qui suit, j'ai repris l'exemple de programmation proposé dans le cours "Developpez.com" "6 - Dessiner" que j'ai adapté pour illustrer mon problème.

    Le programme arrive à afficher un texte au tout début du dialogue juste après la création de la fenêtre avec ShowWindow puis UpdateWindow et seulement la première saisie au clavier. Je ne sais pas comment faire ni qu'elle fonction utiliser pour que ce soit répétitif.

    J'ai laissé en commentaire quelques essais que j'ai effectués sans succès. Je n'ai pas pu les laisser tous et je ne vois pas comment il faut faire. Je cherchais en particulier le moyen de donner la main à la MainWndProc pour exécuter la case WM_PAINT après chaque lecture du clavier avec SendMessage() par exemple. Mais rien n'y a fait.

    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    #include <windows.h>
    
    char st[512] = "Bienvenue sur Developpez.com (éèçàùôûîêöïëä) ABCDEFGHIJKLMNOPQRSTUVWXYZ" ;
    
    HANDLE mon_stdout ;                                                // Les trois ...
    HANDLE mon_stdin  ;                                                // ... fichiers standard
    HANDLE mon_stderr ;                                                // ... du programme
    
    /*==============================================================================================================================
    
                             Fonction qui dessine le texte dans ST et qui le souligne en dessinant un trait
    
    ===============================================================================================================================*/
    void dessine(HWND hwnd)
    {
      LOGFONT      lf ;
      HFONT        NewFont, OldFont ;
      HDC          hdc ;
    
      HBRUSH       hbRed, hbGreen, hbrOld ;
      HPEN         hp2px, hpOld ;
      PAINTSTRUCT  ps;
    
      hdc = BeginPaint(hwnd, &ps) ;
    
      //*** Tracé d'une chaîne de caractères avec lettres accentuées :
        SetBkMode(hdc, TRANSPARENT) ;                // le fond du texte est transparent
    
        ZeroMemory(&lf, sizeof(LOGFONT)) ;
    
        lf.lfHeight         = 30 ;                   // définition de la hauteur des caractères
        lf.lfWidth          = 0  ;                   // largeur moyenne des caractères du texte
        lf.lfEscapement     = 50 ;                   // angle (1/10émes de degré) du vecteur échappement / l'axe des x  (???)
        lf.lfOrientation    = 0  ;                   // angle (1/10émes de degré) du       texte         / l'axe des x
        lf.lfWeight         = FW_BOLD ;              // définition de la graisse des caractères (700 pour FW_BOLD)
        lf.lfItalic         = TRUE ;                 // définition du type de texte : italique
        lf.lfUnderline      = FALSE ;                // soulignement du texte (non anticrénelé comme les caractères !!!!...)
        lf.lfStrikeOut      = FALSE ;                // texte non barré
        lf.lfCharSet        = DEFAULT_CHARSET ;      // jeu de caractères par défaut en fonction de la zone locale
        lf.lfOutPrecision   = OUT_DEFAULT_PRECIS ;   // précision de sortie                                             (???)
        lf.lfClipPrecision  = CLIP_DEFAULT_PRECIS ;  // précision d'écrêtage                                            (???)
        lf.lfQuality        = CLEARTYPE_QUALITY   ;  // qualité d'affichage CLEARTYPE_QUALITY / ANTIALIASED_QUALITY
        lf.lfPitchAndFamily = DEFAULT_PITCH ;        // pitch = la + proche distance entre luminophores (résolution) 
        lstrcpy(lf.lfFaceName,"Times New Roman") ;   // définition du nom de la police de caractères
    
        NewFont = CreateFontIndirect(&lf) ;          // création de la police
        OldFont = SelectObject(hdc,NewFont) ;        // sélection de la police avec sauvegarde de la précédente
        SetTextColor(hdc, RGB(255,0,0)) ;            // définition de la couleur des caractères (rouge)
        TextOut(hdc, 10, 40, st, lstrlen(st)) ;      // tracé de la chaîne de caractères
        SelectObject(hdc,OldFont) ;                  // restauration de la police précédente
        DeleteObject(NewFont) ;                      // libération de police créée
    
      //*** tracé du soulignement non anticrénélé par la fonction TextOut :
        hp2px = CreatePen(PS_SOLID, 2, RGB(0,0,255)) ; // création d'un crayon pour ligne continue, épaisseur et couleur
        hpOld = SelectObject(hdc,hp2px) ;              // sélection du crayon avec sauvegarde du crayon précédent
        MoveToEx(hdc, 10, 75, NULL) ;                  // déplacement du crayon en position haute (pas de tracé)
        LineTo(hdc, 545, 30) ;                         // déplacement du crayon en position basse (tracé)
        SelectObject(hdc,hbrOld) ;                     // restauration du crayon précéent
        DeleteObject(hp2px) ;                          // libération du crayon
    
      EndPaint(hwnd, &ps) ;
    
      return ;
    }
    
    /*============================================================================================================================
    
                                       La procédure de traitement des messgaes du système
    
    ============================================================================================================================*/
    LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
      switch (uMsg)
      {
        case WM_PAINT :
            dessine(hwnd) ;
            return 0;
    
        case WM_DESTROY :                // traitement du click sur la croix blanche sur fond rouge en haut à droite de la fenêtre
            PostQuitMessage(0);
            return 0;
    
        default :
            return DefWindowProc(hwnd, uMsg, wParam, lParam);
      }
    }
    
    /*****************************************************************************************************************************
    
                                                       Le maillon principal
    
    *****************************************************************************************************************************/
    int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
      HWND       hwnd ;
      MSG        msg ;
      WNDCLASS   wc ;
    
      mon_stdout = GetStdHandle(STD_OUTPUT_HANDLE) ;         // On récupère .....
      mon_stdin  = GetStdHandle(STD_INPUT_HANDLE)  ;         //     .... les fichiers
      mon_stderr = GetStdHandle(STD_ERROR_HANDLE)  ;         //           ..... standard du programme
    
      wc.style         = 0 ;                                 // définit le comportement de la fenêtre
      wc.lpfnWndProc   = MainWndProc ;                       // procédure de traitement des messages du système
      wc.cbClsExtra    = 0 ;                                 // Allocation supplémentaire derrière la structure window-class    (???) 
      wc.cbWndExtra    = 0 ;                                 // allocation supplémentaire derrière la structure window-instance (???)
      wc.hInstance     = hinstance ;                         // définit que la fenêtre appartient au programme ici
      wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION) ;   // icon à utiliser en haut à gauche de la fenêtre (pas d'icon)
      wc.hCursor       = LoadCursor(NULL, IDC_ARROW) ;       // curseur par défaut dans Windows pour cette fenêtre
      wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1) ;        // définit la couleur du fond de la fenêtre
      wc.lpszMenuName  =  NULL ;                             // pas de menu par défaut
      wc.lpszClassName = "MaWinClass" ;                      // nom attribué à la classe de fenêtre
    
      if(!RegisterClass(&wc)) return FALSE ;
    
      hwnd = CreateWindow( "MaWinClass"
                         , "apitest.exe"                     // titre de la fenêtre
                         ,   WS_OVERLAPPEDWINDOW             // -+
                           | WS_VSCROLL                      //  |   les ascenseurs : une partie du dessin peut être cachée
                           | WS_HSCROLL                      // -+
                         , 0, 0                              // position de la fenêtre
                         , 700, 150                          // taille de la fenêtre
                         , NULL
                         , NULL
                         , hinstance
                         , NULL
                         ) ;
    
      if (!hwnd) return FALSE ;
     /*
      ShowWindow(hwnd, nCmdShow) ;
      UpdateWindow(hwnd) ;
    */ 
      while(1)
      {
        DWORD n ;
    
    //  dessine(hwnd) ;
    
        ShowWindow(hwnd, nCmdShow) ;
        UpdateWindow(hwnd) ;
    
        WriteFile(mon_stdout, "? : ", 4         , &n, NULL) ;
        ReadFile (mon_stdin , st    , sizeof(st), &n, NULL) ;                                // On saisie une commande au clavier :
        st[n] = '\0' ;
    
        PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) ;
    //  GetMessage(&msg, NULL, 0, 0) ;
        TranslateMessage(&msg) ;
        DispatchMessage(&msg) ;
    
        if (st[0] == 'q') break ;
      }
    /*
      while (GetMessage(&msg, NULL, 0, 0) )
      {
        TranslateMessage(&msg) ;
        DispatchMessage(&msg) ;
      }
    */
      return msg.wParam ;
    }
    Ma question est donc le suivante, probablement toute simple pour celui qui maîtrise les API :

    COMMENT mettre à jour la fenêtre pour que chaque saisie au clavier soit traduite graphiquement ?

    Une deuxième petite question

    De manière très classique, l'espace graphique d'un dessin peut très bien être plus grand que la surface de visualisation. Je souhaiterais donc dessiner dans une pixelmap parcourue par la fenêtre de visualisation grâce à une fonction de contrôle par scrollbars et/ou souris, d'un pivot et d'une copie partielle de la pixelmap dans celle de la fenêtre.

    - Où pourrais-je trouver les outils qu'il faut ?

    - Comment faut-il procéder dans la philosophie des API Windows ?


    En espérant votre aide.
    Bien cordialement

    Lou Papet

    Un petit P.S. : Je voudrais tout simplement dire à Hiko-seijuro que je n'ai jamais cherché à faire faire mon travail par les autres comme il me l'avait reproché injustement le 22 janvier 2009 en me gratifiant d'une pénalité. Quand je ne sais pas, je suis malheureusement incapable d'inventer. De plus, si, à l'approche des 80 ans, je continue à faire un peu d'informatique qui a été mon métier, c'est pour mon plaisir et ma distraction et.... accessoirement pour prévenir Alzheimer !....

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Je ne pense pas que tu puisses faire tout ça dans le même thread.
    Tu vas avoir besoin de deux threads différents: Un pour l'affichage, un pour la communication avec le processus fils.
    Le thread de communication pourra commander le thread d'affichage avec des SendMessage() (ou des PostMessage(), mais la gestion de la durée de vie des allocations mémoire est plus facile avec SendMessage() vu qu'on n'a pas besoin d'un transfert de propriété).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre régulier Avatar de loupapet
    Homme Profil pro
    Retraité d'Eurocopter
    Inscrit en
    Janvier 2009
    Messages
    69
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 83
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité d'Eurocopter
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2009
    Messages : 69
    Points : 72
    Points
    72
    Par défaut En effet, deux threads....
    Bonjour Médinoc,

    Merci pour votre réponse, je dirais enfin car mon sujet n'est pas porteur d'intérêt à voir les 135 affichages. Il faut dire qu'un affichage n'est pas forcément une lecture complète !...

    Pourtant le sujet est un bon exercice d'apprentissage des API Windows. Il oblige à travailler sur pas mal de fonctions, les threads, les timers, le graphique en bitmap, les fenêtres, les messages. On peut alors avoir une bonne petite idée, je crois, de la philosophie de fonctionnement de Windows.

    Finalement, avec patience, je suis quand même arrivé à me débrouiller tout seul à force de puiser dans les documentations en ligne et en effectuant des mixages de quelques exemples pas toujours explicites. Quand j'ai lu votre message, j'étais sur le point de marquer le sujet comme résolu ce que je vais faire maintenant.

    Vous avez raison, ma petite application fonctionne avec 2 threads : le premier est le maillon principal, le processus-père, le deuxième est la fonction de dialogue processus-père/processus-fils suivant la méthode des pseudo-terminaux que j'avais utilisée il y a plus d'une dizaine d'années sous LINUX. J'ai eu la grosse surprise de voir qu'avec les API, c'est beaucoup plus simple.

    En principe, je vais pouvoir continuer maintenant à développer l'aspect graphique avec des processus-fils écrits en C et en Fortran. J'essaierai peut-être avec d'autres langages pour voir, ce n'est pas sûr car il faut en télécharger sans grand besoin par ailleurs.

    Salutations. À une prochaine fois peut-être !...

    Lou Papet

  4. #4
    Membre habitué
    Homme Profil pro
    007
    Inscrit en
    Octobre 2014
    Messages
    119
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : 007

    Informations forums :
    Inscription : Octobre 2014
    Messages : 119
    Points : 188
    Points
    188
    Par défaut
    Salut,

    Renseigne-toi sur gnuplot, ça va immensément te simplifier la tâche.
    En plus, sans trop exagérer, je dirais que 99% de ce que tu cherches
    à faire (https://www.developpez.net/forums/d1...api-s-windows/) est
    déjà fait, et tout le reste c'est que du bonus. Ainsi, tu gagneras en
    flexibilité et portabilité, et tes graphiques auront plus de classe tout
    en ayant la possibilité de changer la forme, le fond, tout ce que tu
    veux, à la volée.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Logiciel graphique sous Windows
    Par Jiraiya42 dans le forum PyQt
    Réponses: 1
    Dernier message: 26/06/2006, 17h26
  2. Stocker un imprim ecran sous bmp avec l'api windows
    Par Tofalu dans le forum Windows
    Réponses: 7
    Dernier message: 04/05/2005, 11h32
  3. Ressource graphique sous Windows
    Par c.steph dans le forum Windows
    Réponses: 3
    Dernier message: 22/12/2004, 12h35
  4. [TP]Problème de modes graphiques sous Windows XP
    Par Gabi dans le forum Turbo Pascal
    Réponses: 11
    Dernier message: 04/04/2004, 17h25
  5. Quel langage pour un application graphique sous windows
    Par ipeteivince dans le forum Langages de programmation
    Réponses: 7
    Dernier message: 06/06/2003, 17h00

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