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


Trucs et astuces pour C++ Builder

Par CGi

Page 1 Page 2 Page 3 Page 4 Page 5



Accès aux événements de l'objet Application :

Exemple : Sur une fiche (Form1) déposer un TShape (Shape1). Il prendra la couleur de la barre de titre en fonction que l'application est active ou pas.

Dans l'Unit1.h déclarer les 2 méthodes AppDeactivate et AppActivate:

private:    // Déclarations de l'utilisateur
     void __fastcall AppDeactivate(TObject *Sender);
     void __fastcall AppActivate(TObject *Sender);

Dans Unit1.cpp sur l'évenement OnCreate de Form1 affecter les 2 méthodes AppDeactivate, AppActivate aux évenements correspondants. Puis définitir les 2 méthodes.

void __fastcall TForm1::FormCreate(TObject *Sender)
{
      Application->OnDeactivate = AppDeactivate;
      Application->OnActivate = AppActivate;
}

void __fastcall TForm1::AppDeactivate(TObject *Sender)
{
  Shape1->Brush->Color = clInactiveCaption;
}

void __fastcall TForm1::AppActivate(TObject *Sender)
{
  Shape1->Brush->Color = clActiveCaption;
}

Le principe est le même pour tous les autres événements de l'objet Application.

Sous BCB6 il existe un composant donnant accès aux événements de Application : ApplicationEvents (Onglet Supplément).





Déplacement d'un TEdit à l'autre avec les touches flêchées :

Nous utiliserons une méthode commune à tous les TEdits qui sera exécutée lors de l'événement OnKeyDown de chaque TEdit.

void __fastcall TForm1::EditKeyDown(TObject *Sender, WORD &Key,
      TShiftState Shift)
{
     TWinControl *x;

     x = FindNextControl((TWinControl *)Sender, true, false, false);
     if(Key == VK_RIGHT) x->SetFocus();

     x = FindNextControl((TWinControl *)Sender, false, false, false);
     if(Key == VK_LEFT) x->SetFocus();
}




Savoir si l'on est connecté à Internet :

Pour cela nous allons utiliser la fonction "InternetGetConnectedState" de la dll "Wininet.dll". Cette façon de faire ne fonctionne pas avec tous les types de connections. A tester avec différentes configurations.

Exemple sur une Form (Form1) poser un Bouton (Button1) et un Label (Label1) :

void __fastcall TForm1::Button1Click(TObject *Sender)
{
 typedef BOOL (WINAPI *PF_INETGETCONNECTEDSTATE)(LPDWORD, DWORD);
 HANDLE hWinInet;
 PF_INETGETCONNECTEDSTATE pfInternetGetConnectedState;
//.............
hWinInet = LoadLibrary("WININET.DLL");  //Chargement de la dll
    if(hWinInet == NULL)
        {
         Label1->Caption = "Impossible de charger Wininet.dll";
         return;
        }
pfInternetGetConnectedState = (PF_INETGETCONNECTEDSTATE) GetProcAddress(
                          hWinInet, "InternetGetConnectedState");
                // affectation du pointeur sur la fonction
    if(pfInternetGetConnectedState == NULL)
        {
         Label1->Caption = "Erreur appel fonction InternetGetConnectedState";
         if(hWinInet) FreeLibrary(hWinInet);
         return;
        }
//.............
DWORD TypeCon ;
if (pfInternetGetConnectedState(&TypeCon, 0)) //appel de la fonction
     Label1->Caption = "Connecté";
else Label1->Caption = "Déconnecté";
//.............
if(hWinInet) FreeLibrary(hWinInet); //libération de la dll
}




Création d'une fenêtre non rectangulaire :

Pour cela nous allons créer un nouveau projet avec une Form (Form1) avec la propriété BorderStyle à bsDialog.

Sur les événements OnCreate et OnPaint de Form1

void __fastcall TForm1::FormCreate(TObject *Sender)
{
       HRGN Region;
       HRGN SubRgn;

       Region = CreateRectRgn(0,0,Width,Height);
       SubRgn = CreateRectRgn(Width/2-100,Height/2-100,
                                       Width/2+300,Height/2+300);
       CombineRgn(Region,Region,SubRgn,RGN_DIFF);
       SetWindowRgn(Handle,Region,true);
       DeleteObject(SubRgn);
}

void __fastcall TForm1::FormPaint(TObject *Sender)
{
      int bordx, bordy;
      HDC dc;
      RECT Rectangl;

      bordx = GetSystemMetrics(SM_CXEDGE);
      bordy = GetSystemMetrics(SM_CYEDGE);
      dc = GetWindowDC(Handle);
      Rectangl.left = Width/2-100-bordx;
      Rectangl.top = Height/2-100-bordy;
      Rectangl.right = Width/2+300+bordx;
      Rectangl.bottom = Height/2+300+bordy;
      DrawEdge(dc, &Rectangl, EDGE_SUNKEN, BF_RECT);
      ReleaseDC(Handle,dc);
}

Explication :

  • Vous créez une région avec la fonction CreateRectRgn qui représente la surface de la Form:
    Region = CreateRectRgn(0,0,Width,Height);

  • Vous créez une seconde région que vous allez combiner avec la première, ici une ronde:
    SubRegion = CreateEllipticRgn(24, 11, 281, 268);

  • Puis vous les combinez ensembles avec la fonction CombineRgn
    CombineRgn(Region,Region,SubRegion,RGN_DIFF);
    prototype: CombineRgn(HRGN destination, HRGN source1, HRGN source2, int Mode);
    Mode et le mode de combinaison valeurs possible : RGN_AND, RGN_COPY, RGN_DIFF, RGN_OR, RGN_XOR

  • puis vous affectez la région à la Form avec : SetWindowRgn(Handle,Region,true);

  • Vous supprimez la 2eme région qui ne sert plus. DeleteObject(SubRegion);

  • Le mieux est de faire quelques essais avec différentes dimensions et modes de combinaisons des 2 régions (vous pouvez même combiner avec une 3ème région ...)

  • Voir aide sur les API Windows CombineRgn, SetWindowRgn, CreateRectRgn, CreateRoundRectRgn, CreateEllipticRgn, CreatePolygonRgn ...

  • La partie du code qui est dans FormPaint ne sert que pour tracer la bordure elle n'est pas nécessaire pour la forme de la fenêtre
Pour ceux qui ont la chance d'avoir BCB6 et Windows 2000 ou XP, on peut faire cela beaucoup plus simplement. Il suffit de mettre la propriété TransparentColor de la Form à true, de poser un TShape ou mieux un TImage sur la Form et d'affecter la couleur du TShape ou l'une des couleurs du Bitmap du TImage à la propriété TransparentColorValue de la Form.





Déplacement d'une fenêtre sans barre de titre :

Le déplacement de la fenêtre (Form1) se fera par maintient du bouton gauche de la souris enfoncé sur une zone quelconque de la surface de la fenêtre.

Dans Unit1.h déclarer les variables :

private:    // Déclarations de l'utilisateur
       bool Deplacement;
       int XPos, YPos;

Dans Unit1.cpp sur les événements OnMouseDown, OnMouseMove et OnMouseUp :

void __fastcall TForm1::FormMouseDown(TObject *Sender, TMouseButton Button,
      TShiftState Shift, int X, int Y)
{
      XPos = X;
      YPos = Y;
      if (Button == mbLeft) Deplacement = true;
}
void __fastcall TForm1::FormMouseMove(TObject *Sender, TShiftState Shift,
      int X, int Y)
{
      if ( Deplacement == true )
     {
       Left += X-XPos;
       Top += Y-YPos;
     }
}
void __fastcall TForm1::FormMouseUp(TObject *Sender, TMouseButton Button,
      TShiftState Shift, int X, int Y)
{
     Deplacement = false;
}



Autre solution beaucoup plus simple : Sur l'événement OnMouseDown de la fiche (Form1)
void __fastcall TForm1::FormMouseDown(TObject *Sender, TMouseButton Button,
      TShiftState Shift, int X, int Y)
{
   ReleaseCapture();
   SendMessage(Handle, WM_SYSCOMMAND, 0xF012, 0);
}




Obtenir les ressources User, System et GDI :

Exemple sur une fiche (Form1) poser un Bouton (Button1) et 3 Labels (Label1, Label2, Label3)

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  typedef LONG (* GETRES)(int);

  HINSTANCE hInst = LoadLibrary("RSRC32.dll");
   if (hInst != NULL)
    {
      GETRES pGetRes = (GETRES) GetProcAddress(hInst,
                                   "_MyGetFreeSystemResources32@4");

      if (pGetRes)
        {
           long lSysRes = pGetRes(0);
           long lGdiRes = pGetRes(1);
           long lUsrRes = pGetRes(2);
           Label1->Caption = "System : " + String(lSysRes) + "%";
           Label3->Caption = "GDI    : " + String(lGdiRes) + "%";
           Label2->Caption = "User   : " + String(lUsrRes) + "%";
        }
      else ShowMessage("Erreur appel fonction");
    }
   else ShowMessage("Erreur chargement dll");

 if (hInst) FreeLibrary(hInst);
}

Ne fonctionne pas sous Windows XP.





Charger un fichier wav en mémoire puis le jouer:

  #include <mmsystem.h>

  //.......

  TMemoryStream *MSt = new(TMemoryStream);
  MSt->LoadFromFile("son.wav");
  sndPlaySound((const char *)MSt->Memory,SND_MEMORY | SND_ASYNC);
  delete MSt;




Son wave depuis une ressource :

fichier.rc à ajouter au projet

  TONWAVE WAVE "fichier.wav"

Unit.cpp

   #include <mmsystem.h>

   //.........

   sndPlaySound("TONWAVE",SND_RESOURCE | SND_ASYNC);




ToolBar détachable :

Poser un TPanel (Panel1) sur la fiche (Form1) avec les propriétés :

  • Align = alTop
  • AutoSize = True ( A faire après avoir posé la ToolBar)
  • BevelOuter = bvNone
  • UseDockManager = False
  • DockSite = True

Sur Panel1 poser une ToolBar (ToolBar1) avec les propriétés:

  • BorderWidth = 1
  • DragKind = dkDock
  • DragMode = dmAutomatic
  • Indent = 2

Evénement OnCreate de Form1(Taille de la ToolBar quand elle est flottante):

void __fastcall TForm1::FormCreate(TObject *Sender)
{
      ToolBar1->UndockHeight = 60;
      ToolBar1->UndockWidth = 128;
}

Evénement OnDockDrop de Panel1:

void __fastcall TForm1::Panel1DockDrop(TObject *Sender,
      TDragDockObject *Source, int X, int Y)
{
      ToolBar1->Align = alTop;
}

Evénement OnDockOver de Panel1 (dessin du rectangle de déplacement sur Panel1):

void __fastcall TForm1::Panel1DockOver(TObject *Sender,
      TDragDockObject *Source, int X, int Y, TDragState State,
      bool &Accept)
{
      TRect ARect;

      ARect.Left = Panel1->ClientOrigin.x;
      ARect.Top = Panel1->ClientOrigin.y;
      ARect.Bottom = Panel1->ClientOrigin.y + 30; //30 hauteur
      ARect.Right = Panel1->ClientOrigin.x+Panel1->Width;

      Source->DockRect = ARect;
}

La ToolBar pouvant être rendu invisible avec le bouton fermeture. prévoir de la rendre à nouveau visible avec le code suivant: ToolBar1->Visible = true; (par exemple dans un menu.)

Les ControlBar permettent de faire cela beaucoup plus facilement. Cet exemple démontre plus le docking de contrôles.





Créer un raccourci:

Exemple un raccourci de la calculatrice sur le bureau au click d'un bouton:

#include <shlobj.h>

//.........

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    HRESULT hres;
    IShellLink* psl;
    WORD wsz[MAX_PATH];

    CoInitialize(NULL);
    hres = CoCreateInstance(CLSID_ShellLink, NULL,CLSCTX_INPROC_SERVER,
                                 IID_IShellLink, (LPVOID *)&psl);

    if (SUCCEEDED(hres))
       {
        IPersistFile* ppf;

        psl->SetPath("C:\\Windows\\calc.exe");
        psl->SetDescription("Calculatrice");

        psl->QueryInterface(IID_IPersistFile,(LPVOID *)&ppf);

        MultiByteToWideChar(CP_ACP, 0,"C:\\Windows\\Bureau\\Calc.lnk", -1,
                                              (LPWSTR)wsz, MAX_PATH);

       ppf->Save((LPWSTR)wsz, TRUE);
       ppf->Release();
       }
     psl->Release();
     CoUninitialize();
}

Pour ne pas surcharger l'exemple je n'ai pas employer les fonctions adéquates pour chercher le chemin de Windows et du bureau.


J'ai tester la compilation avec BCB6. Pour ne pas avoir les messages d'erreurs sur le fichier "shlobj.h", il faut déclarer la constante NO_WIN32_LEAN_AND_MEAN au tout début du fichier ".cpp" avant #include <vcl.h>

 #define NO_WIN32_LEAN_AND_MEAN

 #include <vcl.h>
 #include <shlobj.h>
 #pragma hdrstop

 //.......




Exemple d'utilisation de TPerformanceGraph :

Sur une Form (Form1) poser un composant TPerformanceGraph (PerformanceGraph1) et un Timer (Timer1) avec sa propriété Interval à 100. Sur l'événement OnTimer de Timer1 mettre le code suivant:

#include <stdlib.h> //Pour la fonction rand()

//.............

void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
    static int x = 40;
    x = x + rand()%5 - rand()%5;

    PerformanceGraph1->DataPoint(clRed,x);
    PerformanceGraph1->Update();
}

On peut dessiner plusieurs tracé en appelant plusieurs fois la méthode DataPoint, avec des couleurs différentes en changeant son premier argument. C'est la méthode Update qui provoque le dessin du tracé et le fait avancer d'un pas.





Lancer l'économiseur d'écran :

Par exemple sur l'événement OnClick d'un bouton.

void __fastcall TForm1::Button1Click(TObject *Sender)
{
      SendMessage(Handle,WM_SYSCOMMAND,SC_SCREENSAVE,0);
}




Tapisser une Form avec un Bitmap :

Pour l'exemple nous allons mettre dans le même dossier que l'exécutable un fichier Bitmap nommé: "fond.bmp". Puis sur l'événement OnPaint de la Form (Form1) le code suivant:

void __fastcall TForm1::FormPaint(TObject *Sender)
{
  Graphics::TBitmap *Bitmap1 = new Graphics::TBitmap();
  Bitmap1->LoadFromFile("fond.bmp");
  for(int x=0 ; x < Width ; x+=Bitmap1->Width)
     {
      for (int y=0 ; y < Height ; y+=Bitmap1->Height)
                                   Canvas->Draw(x,y,Bitmap1);
     }
  delete Bitmap1;
}

On peut mettre le fichier Bitmap dans une ressource. Cela a l'avantage de ne pas avoir de fichier à joindre avec l'application.





Extraire les mots d'une AnsiString :

Sur une fiche poser un TMemo (Memo1) un TEdit (Edit1) et un bouton (Button1) A l'événement OnClick de Button1 les mots de la phrase contenue dans Edit1 s'afficheront sur différentes lignes de Memo1.

void __fastcall TForm1::Button1Click(TObject *Sender)
{
   int x;
   AnsiString st = Edit1->Text;
   st = st.Trim();
   while ((x=st.Pos(" ")) > 0 )
   {
     Memo1->Lines->Add(st.SubString(1,x));
     st.Delete(1,x);
     st = st.TrimLeft();
   }
   Memo1->Lines->Add(st);
}




Compiler une unité Delphi :

Pour compiler une unité Delphi :

  • Il vous faut les fichiers ".pas" et ".dfm" par exemple "Unit1.pas" et "Unit1.dfm".
  • Vous les copiez dans le dossier où vous allez créer votre projet.
  • Puis vous créez un nouveau projet.
  • Vous retirez du projet la fiche (Form1) crée automatiquement:
    MENU: "Projet" -> "Retirer du projet" -> "Unit1.cpp Form1" -> "Ok"
  • Vous ajouter au projet la fiche Delphi:
    MENU: "Projet" -> "Ajouter au projet" -> "Unit1.pas" -> "Ok"
  • Si la fiche n'apparaît pas automatiquement faire "Voir une fiche"
  • Maintenant vous avez la fiche et son code source à l'écran vous pouvez compiler le projet.
Par contre, il n'est pas possible d'ajouter des composants visuellement. Il faut le faire en mode texte.





Précédant Index Suivant





C/C++
  Les pointeurs du C/C++.   Les listes chaînées.             Liste simple.             Liste triée.             Liste double.   Les arbres.   Les tas.   Le C orienté objets ?

  1 - La fenêtre principale.   2 - Contrôles et messages.   3 - Les commandes.   4 - Dialogue std.   5 - Contexte de périph.   6 - Dessiner.   7 - Les ressources.   8 - Dialogue perso.   9 - Dialogue comm.   10 - Les accélérateurs.

Assembleur
  Assembleur sous Visual C++.

C++ BUILDER
  Trucs et astuces.   Composant.   TRichEdit.   TDrawGrid.   Application MDI.   TThread.   wxWidgets.   Style Win XP.

  Première application.   Construire un menu.   Dessiner.   Sisers, Timers...   Dialogues standards.   Dialogues perso.

DotNet
  Composant C# Builder.   Contrôle WinForm.   Application MDI.

Java
  Applet java.





Copyright 2002-2020 CGi - Tous droits réservés CGi. Toutes reproduction, utilisation ou diffusion de ce document par quelque moyen que ce soit autre que pour un usage personnel doit faire l'objet d'une autorisation écrite de la part de l'auteur, propriétaire des droits intellectuels.
Les codes sources de ce document sont fournis en l'état. L'utilisateur les utilise à ses risques et périls, sans garantie d'aucune sorte de la part de l'auteur. L'auteur n'est responsable d'aucun dommage subi par l'utilisateur pouvant résulter de l'utilisation ou de la distribution des codes sources de ce document.
De la même façon, l'auteur n'est en aucun cas responsable d'une quelconque perte de revenus ou de profits, ou de données, ou de tous dommages directs ou indirects, susceptibles de survenir du fait de l'utilisation des codes sources de ce document, quand bien même l'auteur aurait été averti de la possibilité de tels dommages. L'utilisation des codes sources de ce document vaut acceptation par l'utilisateur des termes de la licence ci-dessus.