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

C++Builder Discussion :

Composant LCD avec TShape


Sujet :

C++Builder

  1. #1
    Membre actif
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 27
    Par défaut Composant LCD avec TShape
    Bonjour à tous,

    Pour notre logiciel disponible sur notre site http://sites.google.com/site/outilsobdfacile/

    Je travaille sur un composant graphique qui simulera un afficheur LCD.. Mais voilà j'experimente quelque soucis de lenteur..

    Le principe est le suivant je créer un TShape vert et j'ajoute x pixels qui sont eux des TShape (noir) et après je joue sur la propriété visible pour afficher du texte. Celà donne le résultat suivant



    Uploaded with ImageShack.us

    Jusqu'ici tout va bien, vous me direz, sauf que l'affichage initiale du composant prends environ 10s... ET c'est très long 10s sans rien qui se passe pour un programme

    Voici le code qui prends un temps fou
    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
     
    void __fastcall TForm1::FormCreate(TObject *Sender)
    {
       //Create the green background
       TShape *ShapeBack = new TShape(NULL);
       ShapeBack->Parent = Form1;
       ShapeBack->Top = LCD_TOP_POSITION;
       ShapeBack->Left = LCD_LEFT_POSITION;
       ShapeBack->Width = LCD_PIXEL_WIDTH * LCD_PIXEL_DOT;
       ShapeBack->Height = LCD_PIXEL_HEIGHT * LCD_PIXEL_DOT;
       ShapeBack->Brush->Color = LCD_BACK_COLOR;
       //ShapeBack->Visible = TRUE;
     
       //Now create each pixel
       for(int x = 0; x < LCD_PIXEL_WIDTH ; x++)
       {
          for(int y = 0; y < LCD_PIXEL_HEIGHT ; y++)
          {
             Pixels[x][y] = new TShape(NULL);
             Pixels[x][y]->Parent = Form1;
             Pixels[x][y]->Width = LCD_PIXEL_DOT;
             Pixels[x][y]->Height = LCD_PIXEL_DOT;
             Pixels[x][y]->Top = LCD_TOP_POSITION + (y * LCD_PIXEL_DOT);
             Pixels[x][y]->Left = LCD_LEFT_POSITION + (x * LCD_PIXEL_DOT);
             Pixels[x][y]->Brush->Color = LCD_PIXEL_COLOR;
             //Pixels[x][y]->Visible = TRUE;
          }
       }
     
    }
    La ligne suivante Pixels[x][y]->Parent = Form1; me semble louche mais je suis un pro du C embarqué et de l'OBD.. mais le C++ je me debrouille, mais sans plus

    Je vous remercie d'avance pour votre expertise
    Salutations

  2. #2
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2005
    Messages
    401
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2005
    Messages : 401
    Par défaut
    Hello,

    Ce n'est pas déconnant. Pixels[x][y]->Parent = Form1 te permets d'"intégrer" le TShape dans le TForm, normal.

    Cependant je te conseillerais de créer toi-même un composant dérivé de TGraphicControl. Tu trouveras assez facilement des infos là dessus (ah, google).
    Par exemple: http://docwiki.embarcadero.com/RADSt...les_graphiquesOu dans l'aide de Builder (avec un peu de chance ), ou dans les exemples de projets fournis avec.

  3. #3
    Membre actif
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 27
    Par défaut
    Merci totoche76,

    Oui, faut que je me crée un "TShape allegé" en partant de TGraphicControl. Comme je ne suis pas un pro du C++ et de la programmation objet, je pense que je vais procédé ainsi :

    Récupérer la définition de TShape et enlever tout ce qui me sert pas et renommer le tout en TShapeLight

    Ma question est la suivante :
    Ou puis-je trouver la defintion du composant TShape?

    Autre remarque, mis à part la création du composant qui est longue, j'ai fait quelques calcul et la mise à jour de l'affichage est lente aussi (de l'ordre de 100ms) pour le texte "Test". La création de ma propre classe résoudra se problème aussi?

  4. #4
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2005
    Messages
    401
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2005
    Messages : 401
    Par défaut
    Je ne pensais à refaire le TShape sous forme de TGraphicControl, mais carrément ta matrice LCD.
    Dans ton exemple, ça fait un sacré paquet de TShape qui doivent se redessiner individuellement...

    Imagine faire quelque chose comme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    //monComposant: la matrice LCD
    monComposant->Allumer(x, y); 
    monComposant->Eteindre(x, y);
    ou
    monComposant->EtatON[x][y] = true;
    monComposant->EtatON[x][y] = false;
    Et c'est le composant qui s'occupe de redessiner chaque point de la matrice.

    Dans les exemples de composants fournis avec Builder, tu trouveras TCGauge et TPerformanceGraph, ça peut donner des idées (en fonction de ta version de Builder, soit dans C:\Program Files\Borland\<Version Builder>\Examples\Controls\Source, soit dans C:\Documents and Settings\All Users\Documents\RAD Studio\<Version>\Demos\CPP\Controls)

  5. #5
    Membre chevronné

    Profil pro
    Inscrit en
    Juin 2005
    Messages
    351
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2005
    Messages : 351
    Par défaut
    Salut,

    Je pense que tu vas gagner autant en facilité qu'en vitesse en travaillant directement sur le canevas d'une image. Tu dois juste créer une fonction qui converti les coordonnées de ton point dans l'écran LCD en coordonnées dans l'image (une simple multiplication par la taille des points).

    Voici un exemple qui marche assez bien (il dessine un ersatz d'ellipse). Il est constitué d'une fiche avec les éléments suivants:

    - Trois TEdit avec le événement OnChange dirigé sur la même fonction: LCDSizeChange():
    1) txtWidth pour changer le nombre de point horizontaux de l'écran LCD
    2) txtHeight pour changer le nombre de point verticaux de l'écran LCD
    3) txtSize pour la taille (en pixels) de chaque point de ll'écran LCD
    - Un TButton (cmdAddCircle) qui ajoute une ellipse
    - Un TImage (imaLCD) qui est la simulation de l'écran LCD

    .h
    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
     
    //---------------------------------------------------------------------------
     
    #ifndef FTestLCDH
    #define FTestLCDH
    //---------------------------------------------------------------------------
    #include <Classes.hpp>
    #include <Controls.hpp>
    #include <StdCtrls.hpp>
    #include <Forms.hpp>
    #include <ExtCtrls.hpp>
    #include "Math.h"
    //---------------------------------------------------------------------------
    class TTestLCD : public TForm
    {
    __published:	// IDE-managed Components
    TImage *imaLCD;
    TPanel *Panel1;
    TLabeledEdit *txtWidth;
    TLabeledEdit *txtHeight;
    TLabeledEdit *txtSize;
    TButton *cmdAddCircle;
    void __fastcall LCDSizeChange(TObject *Sender);
    void __fastcall cmdAddCircleClick(TObject *Sender);
    void __fastcall FormCreate(TObject *Sender);
    private:	// User declarations
    public:		// User declarations
    __fastcall TTestLCD(TComponent* Owner);
     
      // Fonction pretexte pour dessiner un cercle
      void PaintLCD();
     
      // Primitives
      void ClearLCD();
      void SetDotState(unsigned int x,unsigned int y,bool on);
     
      // Variables
      int LCD_PIXEL_WIDTH;
      int LCD_PIXEL_DOT;
      int LCD_PIXEL_HEIGHT;
      TColor LCD_BACK_COLOR;
      TColor LCD_DOT_COLOR;
     
    };
    //---------------------------------------------------------------------------
    extern PACKAGE TTestLCD *TestLCD;
    //---------------------------------------------------------------------------
    #endif
    .cpp
    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
    //---------------------------------------------------------------------------
     
    #include <vcl.h>
    #pragma hdrstop
     
    #include "FTestLCD.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TTestLCD *TestLCD;
     
    //---------------------------------------------------------------------------
    __fastcall TTestLCD::TTestLCD(TComponent* Owner)
    : TForm(Owner)
    {
     
      LCD_BACK_COLOR = clGreen;
      LCD_DOT_COLOR  = clBlack;
     
    }
    //---------------------------------------------------------------------------
    void __fastcall TTestLCD::LCDSizeChange(TObject *Sender)
    {
     
      LCD_PIXEL_WIDTH =StrToInt(txtWidth->Text);
      LCD_PIXEL_HEIGHT=StrToInt(txtHeight->Text);
      LCD_PIXEL_DOT   =StrToInt(txtSize->Text);
     
      imaLCD->Width =LCD_PIXEL_WIDTH *LCD_PIXEL_DOT;
      imaLCD->Height=LCD_PIXEL_HEIGHT*LCD_PIXEL_DOT;
     
      ClearLCD();
      PaintLCD();
     
    }
    //---------------------------------------------------------------------------
    // Fonction pretexte pour dessiner un cercle
    void TTestLCD::PaintLCD() {
     
      int centerX=LCD_PIXEL_WIDTH/2;
      int centerY=LCD_PIXEL_HEIGHT/2;
      int radiusX=random(centerX);
      int radiusY=random(centerY);
     
      for (int x=0; x<radiusX; ++x) {
        // Compute position
        int y=sin(acos((double)x/(double)radiusX))*radiusY;
        // Turn dots on
        SetDotState(centerX+x,centerY+y,true);
        SetDotState(centerX+x,centerY-y,true);
        SetDotState(centerX-x,centerY+y,true);
        SetDotState(centerX-x,centerY-y,true);
      }
     
    }
     
    //---------------------------------------------------------------------------
    // Primitives
    void TTestLCD::ClearLCD() {
     
      imaLCD->Canvas->Brush->Color=LCD_BACK_COLOR;
      imaLCD->Canvas->FillRect(imaLCD->ClientRect);
     
    }
    //---------------------------------------------------------------------------
    void TTestLCD::SetDotState(unsigned int x,unsigned int y,bool on) {
     
      // Ignore if out of range
      if ((x>=LCD_PIXEL_WIDTH)||(y>=LCD_PIXEL_HEIGHT)) return;
     
      // Find the position (in bitmap coordinates) of the LCD dot
      int top =y*LCD_PIXEL_DOT;
      int left=x*LCD_PIXEL_DOT;
      int size=LCD_PIXEL_DOT;
     
      // Draw the LCD dot
      imaLCD->Canvas->Brush->Color=(on?LCD_DOT_COLOR:LCD_BACK_COLOR);
      imaLCD->Canvas->FillRect(TRect(left,top,left+size,top+size));
     
    }
     
     
    void __fastcall TTestLCD::cmdAddCircleClick(TObject *Sender)
    {
      PaintLCD();
    }
    //---------------------------------------------------------------------------
     
    void __fastcall TTestLCD::FormCreate(TObject *Sender)
    {
      LCDSizeChange(Sender);
    }
    //---------------------------------------------------------------------------

  6. #6
    Membre actif
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 27
    Par défaut
    Merci,

    J'avance tout doucement, je vais organiser le code avec une class que je nomme LCDComponent qui sera la gestion des pixels graphiques (la méthode la plus rapide est à definir) et une class qui encapuslera LCDComponent que je vais appeler LCD..
    POur le moment je travaille sur l'écriture des méthodes qui permette de transformer du texte en image, ca fonctionne plutot bien, cf ci dessous



    Le principe est le même que les afficheurs LCD électronique du commerce, un curseur qui définit la position et on écrit..

    Y a encore pas mal de boulot, et le support du logiciel OB2Diag me prends aussi du temps, si y a des personnes intéressé pour co-developper le composant avec nous, elles sont plus que les bienvenues

    Patrick, je vais tester avec ta methode qui me semble pas mal!! Pour le moment pour "limiter" le temps de rafraichissement je ne redessinais que les pixels qui change en passant par un buffer temporaire et une methode "ReDraw"

    Tout ca va finir par bien se goupiller, je vous tiens au courant de toute manière

    Merci

  7. #7
    Invité de passage
    Inscrit en
    Décembre 2008
    Messages
    1
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 1
    Par défaut Cnavas, ou pourquoi ne pas utiliser Label?
    Bonjour,
    Tout à fait d'accord avec Patrick pour l'utilisation de la propriété Canvas qui peut être liée à Form1 ou à un objet Image (TImage).

    Mais pourquoi ne pas tout simplement utiliser Label (TLabel) qui fait déjà tout ça de manière très efficace? :



    Le code:
    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
     
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Button_Label1Click(TObject *Sender)
    {
      Label1->Color = clOlive;         // couleur de fond
      Label1->Font->Color = clBlack;  // couleur du texte
      Label1->Font->Name = "Courier"; // Police
      Label1->Font->Height = 55;      // taille
     
      Label1->Caption = Edit1->Text;
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Button_CanvasClick(TObject *Sender)
    {
      Form1->Canvas->TextHeight(40);
      Form1->Canvas->TextWidth(28);
      Form1->Canvas->Font->Color = clBlack;
      Form1->Canvas->Font->Name = "Courier";
      Form1->Canvas->Font->Size = 40;
     
      TRect TheRect;
      TheRect = Rect(150,50,400,100);
      Canvas->TextRect(TheRect, 150, 50, Edit1->Text);
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormPaint(TObject *Sender)
    {
      Button_CanvasClick(Sender);
    }

Discussions similaires

  1. Connaitre le Composant survolé avec la souris
    Par Hauwke dans le forum Composants VCL
    Réponses: 3
    Dernier message: 12/10/2005, 19h22
  2. [Composant] BDD avec Delphi 6 Perso
    Par Manopower dans le forum Bases de données
    Réponses: 5
    Dernier message: 17/02/2005, 09h47
  3. Ajouter des composants à chaud avec Swing
    Par raj dans le forum AWT/Swing
    Réponses: 7
    Dernier message: 02/12/2004, 10h34
  4. [Débutant] SWT: composant Texte avec \n
    Par bonnefr dans le forum SWT/JFace
    Réponses: 3
    Dernier message: 18/05/2004, 11h44

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