|
Obtention de la taille de la Ram en Mo
MEMORYSTATUS X;
X.dwLength = sizeof(X);
GlobalMemoryStatus(&X);
TailleDeLaRam = (X.dwTotalPhys+524288)/1024/1024;
Dans le fichier Unit.h on définit une constante pour la commande CM_MONMSG.
On déclare la fonction ReponseMessage et le Handle de menu MyMenu.
Puis on dirige le message WM_SYSCOMMAND vers la fonction ReponseMessage.
#define CM_MONMSG 401
class TForm1 : public TForm
{
__published: // Composants gérés par l'EDI
void __fastcall FormCreate(TObject *Sender);
private: // Déclarations de l'utilisateur
HMENU MyMenu;
void __fastcall ReponseMessage(TMessage &Msg);
public: // Déclarations de l'utilisateur
__fastcall TForm1(TComponent* Owner);
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_SYSCOMMAND, TMessage, ReponseMessage);
END_MESSAGE_MAP(TForm)
};
Dans le fichier Unit.cpp on crée la commande de menu du menu système sur
l'événement OnCreate de la Form (Form1).
On définit la fonction ReponseMessage
void __fastcall TForm1::FormCreate(TObject *Sender)
{
MyMenu = GetSystemMenu(Handle,FALSE);
AppendMenu(MyMenu,MF_SEPARATOR ,NULL,NULL);//ajoute un séparateur
AppendMenu(MyMenu,NULL ,CM_MONMSG , "A Propos !");
}
void __fastcall TForm1::ReponseMessage(TMessage &Msg)
{
if (Msg.WParam == CM_MONMSG)
ShowMessage("Message Reçu");
else TForm::Dispatch(&Msg);
}
Par exemple nous allons envoyer tous les fichiers textes "*.txt" du dossier
"C:\\tmp" dans la corbeille à l'aide de la fonction SHFileOperation.
#include <shellapi.h>
//................................
SHFILEOPSTRUCT FileOpStr;
ZeroMemory(&FileOpStr, sizeof(FileOpStr));
FileOpStr.hwnd = Application->Handle;
FileOpStr.fFlags = FOF_ALLOWUNDO;
FileOpStr.wFunc = FO_DELETE;
FileOpStr.pFrom = "C:\\tmp\\*.txt\0";
SHFileOperation(&FileOpStr);
Cette fonction peut aussi servir à renommer, copier, déplacer des fichiers.
FileOpStr.wFunc: FO_RENAME, FO_COPY, FO_MOVE.
Dossier de destination : FileOpStr.pTo = "C:\\ici"
Les chaînes pointées par FileOpStr.pFrom et FileOpStr.pTo peuvent contenir
plusieurs fichiers ils doivent être séparer par des caractères NULL '\0'
et les chaînes doivent se terminer par un double '\0'.
Les chaînes contenant les noms de fichiers doivent contenir des chemins complets.
Exemple :
Copie du dossier Source et tout son contenu dans le dossier Destination :
#include <shellapi.h>
//................................
SHFILEOPSTRUCT FileOpStr;
ZeroMemory(&FileOpStr, sizeof(FileOpStr));
FileOpStr.hwnd = Application->Handle;
FileOpStr.wFunc = FO_COPY;
FileOpStr.pFrom = "C:\\Source\0";
FileOpStr.pTo = "C:\\Destination\0";
SHFileOperation(&FileOpStr);
Déplassement des fichiers du dossier Source dans le dossier Destination :
#include <shellapi.h>
//................................
SHFILEOPSTRUCT FileOpStr;
ZeroMemory(&FileOpStr, sizeof(FileOpStr));
FileOpStr.hwnd = Application->Handle;
FileOpStr.wFunc = FO_MOVE;
FileOpStr.pFrom = "C:\\Source\\*.*\0";
FileOpStr.pTo = "C:\\Destination\0";
SHFileOperation(&FileOpStr);
Dans Unit.h déclaration de la méthode réagissant au message (WM_DISPLAYCHANGE)
envoyé par windows à toutes les applications quand la résolution de l'écran change.
private: // Déclarations de l'utilisateur
void __fastcall ChgtResolutionEcran(TMessage &Msg);
public: // Déclarations de l'utilisateur
__fastcall TForm1(TComponent* Owner);
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_DISPLAYCHANGE, TMessage, ChgtResolutionEcran);
END_MESSAGE_MAP(TForm)
Dans Unit.cpp définition de la fonction. C'est là
que l'on met les actions à éffectuer.
void __fastcall TForm1::ChgtResolutionEcran(TMessage &Msg)
{
ShowMessage("La résolution écran a changé.");
}
Dans cet exemple nous allons appeller la boîte de dialogue
de changement d'icônes. (Celle qui sert à changer les icônes
des raccourcis) Puis nous afficherons l'icône sélectionnée sur la fiche.
Sur une Form (Form1) poser un bouton (Button1) et 2 Labels (Label1 et Label2).
Sur Unit.h déclaration du Handle d'icône:
private: // Déclarations de l'utilisateur
HICON MonIcone;
Sur Unit.cpp événement OnClick de Button1 et OnPaint de Form1:
#include <shellapi.h>
//................
void __fastcall TForm1::Button1Click(TObject *Sender)
{
typedef LONG (CALLBACK *SHCHANGEICONDIALOG)(HWND hWnd, LPCSTR szFilename,
LONG Size, int *IconIndex);
SHCHANGEICONDIALOG SHChangeIconDialog = NULL;
char szFilename[MAX_PATH];
int IconIndex;
HANDLE hInst;
hInst=LoadLibrary("SHELL32.DLL");
if(hInst)
{
SHChangeIconDialog=(SHCHANGEICONDIALOG)GetProcAddress(hInst,(LPCSTR)62);
szFilename[0]='\0';
SHChangeIconDialog(Handle,szFilename,sizeof(szFilename),&IconIndex);
Label1->Caption = IconIndex;
Label2->Caption = szFilename;
MonIcone = ExtractIcon(HInstance, szFilename, IconIndex);
Refresh();
}
if(hInst) FreeLibrary(hInst);
}
void __fastcall TForm1::FormPaint(TObject *Sender)
{
DrawIcon(Canvas->Handle, 200, 10, MonIcone);
}
Exemple: l'extension des fichiers de l'application exemple sera ".mon"
se seront des fichiers textes qui se chargeront dans un Memo (Memo1)
qui a été posé sur la fiche (Form1).
Pour cela il suffit de mettre ce code dans l'événement OnCreate de Form1
void __fastcall TForm1::FormCreate(TObject *Sender)
{
if ( ParamCount() > 0 )
Memo1->Lines->LoadFromFile(ParamStr(1));
}
ParamCount() renvoie le nombre de paramètres.
ParamStr(1) renvoie une AnsiString contenant le 1er paramètre.
Mais pour que cela fonctionne, il faut associer le type de fichiers ".mon"
à l'application.
On peut faire l'association par programme :
Unit.h :
#include <Registry.hpp>
Unit.cpp
TRegistry *Reg = new TRegistry;
Reg->RootKey = HKEY_CLASSES_ROOT;
Reg->OpenKey("\\.mon",true);//Extention du fichier
Reg->WriteString("","Mon_Fichier");//nom de la clé suivante
Reg->CloseKey();
Reg->OpenKey("\\Mon_Fichier",true);
Reg->WriteString("","Fichier Mon");
//nom qui apparait dans l'explorateur de fichier
Reg->CloseKey();
Reg->OpenKey("\\Mon_Fichier\\shell\\open\\command",true);
Reg->WriteString("","\"C:\\dossier\\mon.exe\" \"%1\"");
//Chemin et nom du programme associé suivie de "%1"
Reg->CloseKey();
delete Reg;
ATTENTION aux écritures dans la base de registre. Les erreurs ne
sont pas permises.
Ce code a été testé sous Windows 95, 98 et XP.
Pour le tester il faudra créer un fichier texte avec l'extension ".mon"
Dans cet exemple nous allons utiliser la classe TRegistry pour sauvegarder et
restaurer la taille et la position de la dernière utilisation avant fermeture
de notre fiche (Form1).
Unit.h :
#include <Registry.hpp>
Sauvegarde: à la fermeture de la fiche sur l'événement OnClose de Form1.
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
TRegistry *Reg = new TRegistry;
Reg->OpenKey("\\Software\\Votre_Societe\\Votre_Application",true);
if ( WindowState == wsNormal )
{
Reg->WriteBool("Agrandie",false);
Reg->WriteInteger("Pos_X",Left);
Reg->WriteInteger("Pos_Y",Top);
Reg->WriteInteger("Largeur",Width);
Reg->WriteInteger("Hauteur",Height);
}
else Reg->WriteBool("Agrandie",true);
Reg->CloseKey();
delete Reg;
}
Restauration: à l'ouverture de la fiche sur l'événement OnCreate de Form1.
void __fastcall TForm1::FormCreate(TObject *Sender)
{
TRegistry *Reg = new TRegistry;
if ( Reg->OpenKey("\\Software\\Votre_Societe\\Votre_Application",false))
{
try
{
Left = Reg->ReadInteger("Pos_X");
Top = Reg->ReadInteger("Pos_Y");
Width = Reg->ReadInteger("Largeur");
Height = Reg->ReadInteger("Hauteur");
}
catch(...) {}
if ( Reg->ReadBool("Agrandie") ) WindowState = wsMaximized;
}
Reg->CloseKey();
delete Reg;
}
Les données de taille et position peuvent ne pas être dans la base de registre
si lors des premiéres utilisations la fiche a été fermée en position Maximised.
D'où le bloc try catch pour éviter le message d'erreur en ce cas.
La clé par défaut de TRegistry est HKEY_CURRENT_USER. Donc dans notre exemple
les données seront écrites dans :
HKEY_CURRENT_USER\Software\Votre_Societe\Votre_Application
ATTENTION aux écritures dans la base de registre. Les erreurs ne
sont pas permises.
Comme l'exemple précédent nous allons sauvegarder et
restaurer la taille et la position de la dernière utilisation avant fermeture
de notre fiche (Form1), mais cette fois dans un fichier profil ".ini" à l'aide
de la classe TIniFile.
Unit.h :
#include <Inifiles.hpp>
Sauvegarde: à la fermeture de la fiche sur l'événement OnClose de Form1.
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
TIniFile *Ini = new TIniFile("App.ini");
if ( WindowState == wsNormal )
{
Ini->WriteInteger("Position", "Pos_X", Left);
Ini->WriteInteger("Position", "Pos_Y", Top);
Ini->WriteInteger("Position", "Largeur", Width);
Ini->WriteInteger("Position", "Hauteur", Height);
Ini->WriteBool("Position", "Agrandie",false);
}
else Ini->WriteBool("Position", "Agrandie",true);
delete Ini;
}
Restauration: à l'ouverture de la fiche sur l'événement OnCreate de Form1.
void __fastcall TForm1::FormCreate(TObject *Sender)
{
TIniFile *Ini = new TIniFile("App.ini");
Left = Ini->ReadInteger("Position", "Pos_X", Left);
Top = Ini->ReadInteger("Position", "Pos_Y", Top);
Width = Ini->ReadInteger("Position", "Largeur", Width);
Height = Ini->ReadInteger("Position", "Hauteur", Height);
if ( Ini->ReadBool("Position", "Agrandie", false) ) WindowState = wsMaximized;
delete Ini;
}
Utilisation des fonctions de lectures et écritures :
Valeur = ReadInteger("Section", "Clé", ValeurParDéfaut);
WriteInteger("Section", "Clé", Valeur);
Dans cet exemple le fichier "App.ini" est enregistré dans le dossier Windows.
Si vous voulez l'enregistrer ailleurs il faut mettre le chemin avec le nom de fichier.
Pour plus d'information voir Aide C++ Builder Rubrique TIniFile.
Pour cela nous utiliserons la fonction SystemParametersInfo.
SystemParametersInfo(SPI_SETDESKWALLPAPER,
0,"C:\\Dossier\\Dessin.bmp",NULL );
Cette fonction permet d'obtenir ou de changer de nombreux paramètres
de configuration de Windows. (voir aide API Windows)
Par exemple désactiver l'écran de veille:
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, false, NULL, 0);
Réactiver l'écran de veille:
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, true, NULL, 0);
Dans cet exemple le code va être inséré dans le fichier principal
de notre application "Project1.cpp". Nous y créons un Mutex
avec un nom qui n'a aucune chance d'exister dans une autre application.
Au lancement de la deuxième instance de l'application le Mutex avec
ce nom existant déjà provoque une erreur sur la fonction CreateMutex.
Erreur que l'on teste pour quitter la deuxième instance de l'application
le cas échéant.
#include <vcl.h>
#pragma hdrstop
USEFORM("Unit1.cpp", Form1);
//---------------------------------------------------------------------------
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
HANDLE hMutex;
try
{
hMutex = CreateMutex (NULL,FALSE,"Mon application");
if (GetLastError() == ERROR_ALREADY_EXISTS) return 0;
Application->Initialize();
Application->CreateForm(__classid(TForm1), &Form1);
Application->Run();
CloseHandle(hMutex);
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
return 0;
}
Dans cet exemple nous allons créer un bouton dynamiquement puis créer une méthode
pour gérer son événement OnClick.
Dans Unit1.h déclaration du pointeur sur le bouton et de la méthode :
private: // Déclarations de l'utilisateur
TButton *MonBouton;
void __fastcall MonBoutonClick(TObject *Sender);
Sur l'événement OnCreate de Form1 création du bouton et affectation de la méthode
MonBoutonClick à l'événement OnClick du bouton :
void __fastcall TForm1::FormCreate(TObject *Sender)
{
MonBouton = new TButton(this);
MonBouton->Left = 20;
MonBouton->Top = 20;
MonBouton->Caption = "Bouton";
MonBouton->Parent = Form1;
MonBouton->OnClick = MonBoutonClick;
}
Définition de la méthode :
void __fastcall TForm1::MonBoutonClick(TObject *Sender)
{
ShowMessage("Tu viens de cliquer sur MonBouton");
}
Pour l'exemple nous allons poser un Label (Label1) sur une fiche (Form1).
Nous passerons le texte du label en rouge quand le curseur viendra
au dessus puis en bleu quand il en sortira.
Unit1.h :
déclaration d'une variable TWndMethod pour mémoriser la procédure
de fenêtre de Label1 et la méthode de la nouvelle procédure de fenêtre.
private: // Déclarations de l'utilisateur
Controls::TWndMethod OldLabelWP;
void __fastcall NewLabelWP(TMessage &Msg);
Unit1.cpp :
événement OnCreate de Form1, sauvegarde de l'ancienne procédure
de fenêtre de Label1 et affectation de la nouvelle.
void __fastcall TForm1::FormCreate(TObject *Sender)
{
OldLabelWP = Label1->WindowProc;
Label1->WindowProc = NewLabelWP;
}
Nouvelle procédure de fenêtre de Label1: traitement des commandes
CM_MOUSELEAVE et CM_MOUSEENTER sinon appel de l'ancienne procédure de fenêtre
si autre message.
void __fastcall TForm1::NewLabelWP(TMessage &Msg)
{
if (Msg.Msg == CM_MOUSELEAVE) //OnMouseExit
{
Label1->Font->Color = clBlue;
}
else if (Msg.Msg == CM_MOUSEENTER) //OnMouseEnter
{
Label1->Font->Color = clRed;
}
else OldLabelWP(Msg);
}
Cette façon de faire est obsolète sur BCB6, on a accés à ces événements
dans l'inspecteur d'objets (OnMouseEnter et OnMouseLeave).
Pour que la propriété Hint s'affiche sur plusieurs ligne.
Il faut l'affecter à l'éxécution par exemple sur l'événement OnCreate de la Form.
void __fastcall TForm1::FormCreate(TObject *Sender)
{
Hint = "Bonjour\nMonsieur";
}
Exemple : passer la couleur de ProgressBar1 en rouge.
SendMessage(ProgressBar1->Handle, PBM_SETBARCOLOR, 0, clRed);
Dans cet exemple nous allons copier les noms et chemins des fichiers glissés
depuis l'explorateur Windows vers une ListBox (ListBox1) qui a été posé sur
la Form (Form1).
Unit.h déclaration de la méthode DropFiles réagissant au message WM_DROPFILES
private: // Déclarations de l'utilisateur
void DropFiles(TMessage &Message);
public: // Déclarations de l'utilisateur
__fastcall TForm1(TComponent* Owner);
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_DROPFILES, TMessage, DropFiles);
END_MESSAGE_MAP(TForm);
Unit.cpp sur l'événement OnCreate de Form1 appel de la fonction DragAcceptFiles
pour autoriser l'application à recevoir les noms fichiers depuis l'explorateur.
Puis définition de la méthode DropFiles dans laquelle le premier appel de la
fonction DragQueryFile nous retourne le nombre de fichiers glissés et
les appels suivants leurs noms et chemins.
La fonction DragFinish libère la mémoire.
#include <shellapi.h>
//..........
void __fastcall TForm1::FormCreate(TObject *Sender)
{
DragAcceptFiles(Handle, true);
}
void TForm1::DropFiles(TMessage &Message)
{
int nFiles;
char buffer[256];
nFiles = DragQueryFile((HDROP)Message.WParam, 0xFFFFFFFF, NULL, 0);
for (int i = 0; i < nFiles; i++)
{
DragQueryFile((HDROP)Message.WParam, i, buffer, 256);
ListBox1->Items->Add((AnsiString)buffer);
}
DragFinish((HDROP)Message.WParam);
}
|