| auteur : Farscape |
LPVOID lpMsgBuf;
FormatMessage (
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL ,
GetLastError (),
0 ,
(LPTSTR) & lpMsgBuf,
0 ,
NULL
);
AfxMessageBox ((LPCTSTR)lpMsgBuf, MB_OK | MB_ICONINFORMATION );
LocalFree ( lpMsgBuf );
|
|
| auteur : Farscape | Avec la fonction GetComputerName.
char szBuffer[MAX_COMPUTERNAME_LENGTH + 1 ];
if (GetComputerName (szBuffer,MAX_COMPUTERNAME_LENGTH))
{
AfxMessageBox (szBuffer);
}
|
|
| auteur : Farscape | Il faut déclarer dans la base de registre une zone de type chaîne correspondant au nom de l'application à l'emplacement suivant :
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
Ensuite on placera dans la zone le chemin complet de l'exécutable.
Exemple :
Valeur chaîne (type REG_SZ) : MonProg
Contenu : C:\Program Files\MonProg\MonProg.exe
|
| auteur : nico-pyright(c) | Utiliser les API : QueryPerformanceFrequency et QueryPerformanceCounter qui donnent respectivement la fréquence du compteur et sa valeur.
voici une classe qui permet de l'utiliser simplement
MesurePrecision.h
# ifndef _MESURE_PRECISION_H
# define _MESURE_PRECISION_H
# include <windows.h>
class CMesurePrecision
{
public :
CMesurePrecision ();
virtual ~ CMesurePrecision ();
bool Start ();
double GetTimeFromStart ();
char * GetLastError ();
private :
LARGE_INTEGER frequence,debut,fin;
char lastError[264 ];
} ;
# endif
|
MesurePrecision.cpp
# include "MesurePrecision.h"
CMesurePrecision:: CMesurePrecision ()
{
strcpy (lastError," Pas d'erreur " );
}
CMesurePrecision:: ~ CMesurePrecision (){ }
bool CMesurePrecision:: Start ()
{
if (! QueryPerformanceFrequency (& frequence))
{
LPVOID lpMsgBuf;
FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL ,
:: GetLastError (), 0 , (LPTSTR) & lpMsgBuf, 0 , NULL );
strcpy (lastError,(LPCSTR)lpMsgBuf);
LocalFree ( lpMsgBuf );
return false ;
}
if (! QueryPerformanceCounter (& debut))
{
LPVOID lpMsgBuf;
FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL , :: GetLastError (), 0 , (LPTSTR) & lpMsgBuf, 0 , NULL );
strcpy (lastError,(LPCSTR)lpMsgBuf);
LocalFree ( lpMsgBuf );
return false ;
}
strcpy (lastError," Pas d'erreur " );
return true ;
}
double CMesurePrecision:: GetTimeFromStart ()
{
if (! QueryPerformanceCounter (& fin))
{
LPVOID lpMsgBuf;
FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL ,
:: GetLastError (), 0 , (LPTSTR) & lpMsgBuf, 0 , NULL );
strcpy (lastError,(LPCSTR)lpMsgBuf);
LocalFree ( lpMsgBuf );
return 0 ;
}
strcpy (lastError," Pas d'erreur " );
return ((double )((__int64)fin.QuadPart)- ((__int64)debut.QuadPart)) /
(double )frequence.QuadPart;
}
char * CMesurePrecision:: GetLastError ()
{
return lastError;
}
|
Remarque : travaillant sur des entiers de 64 bits, on a malheureusement besoin de se risquer à faire une conversion en nombres à virgules
(double).
Exemple d'utilisation CMesurePrecision compteur;
if (! compteur.Start ())
MessageBox (NULL ,compteur.GetLastError ()," " ,MB_ICONSTOP);
for (long k= 0 ;k< 1000000 ;k+ + );
double temps_execution = compteur.GetTimeFromStart ();
if (temps_execution= = 0 )
MessageBox (NULL ,compteur.GetLastError ()," " ,MB_ICONSTOP);
|
L'utilisation de GetTickCount() aurait donné 0 (précis à la milliseconde seulement)
|
| auteur : Farscape | Pour une application réalisée en Visual 6.0 il suffit d'avoir un fichier "manifest" et de procéder comme suit:
- Remplacer MYAppName par le nom de votre application.
- Le fichier soit se nommer MyAppName.exe.manifest.
- Placer le fichier dans le répertoire d'exécution.
Ci-dessous le modèle du fichier manifest
< ?xml version= " 1.0 " encoding= " UTF-8 " standalone= " yes " ?>
< assembly xmlns= " urn:schemas-microsoft-com:asm.v1 " manifestVersion= " 1.0 " >
< assemblyIdentity
version= " 1.0.0.0 "
processorArchitecture= " X86 "
name= " MYAppName "
type= " win32 "
/ >
< description> Your app description here< / description>
< dependency>
< dependentAssembly>
< assemblyIdentity
type= " win32 "
name= " Microsoft.Windows.Common-Controls "
version= " 6.0.0.0 "
processorArchitecture= " X86 "
publicKeyToken= " 6595b64144ccf1df "
language= " * "
/ >
< / dependentAssembly>
< / dependency>
< / assembly>
|
|
| auteur : Farscape | Avec le post Comment appliquer le style XP aux fenêtres ?
Nous avons vu comment générer un fichier manifest pour donner le style XP à nos applications.
Pour intégrer directement ce fichier dans les ressources procéder comme suit :
Editer le fichier ressource .h du projet et rajouter ces deux lignes :
# define IDR_MANIFEST 1
# define RT_MANIFEST 24
|
éditer le fichier .rc2 situé dans le volume /res de votre application avec notepad ,et rajouter la ligne suivante :
IDR_MANIFEST RT_MANIFEST MOVEABLE PURE
" res\\MyAppManifestFile "
|
Ou MyAppManifestFile représente le nom du fichier manifest décrit précédemment enregistré dans le volume /res de votre application avec ce nom.
Recompiler les ressources et procéder à l'édition des liens de votre programme.
Note: Si le SDK est installé et les chemins de recherche de VC mis à jour, la ligne :
devra être mise en commentaire pour éviter le warning à la compilation.
|
| auteur : Farscape | En premier lieu au procédera à la création de notre fichier manifeste pour le style XP comme expliqué ici Comment appliquer le style XP aux fenêtres ?
Puis on rajoutera ce manifeste au manifeste principal comme suit :
Sur les propriétés du projet dans :
configuration properties ou propriétés de configuration
Manifest tool ou Outil Manifeste
Input and OutPut ou Entrée et Sortie
Enfin dans additional manifest file ou Fichiers manifestes supplémentaires
On indiquera le fichier manifeste précédemment pour disposer du style xp.
Note : le fichier manifeste que Visual génère n'a donc rien à voir avec le style XP ,il permet de préciser quelles versions de DLL l'application va utiliser ?
|
lien : Comment appliquer le style XP aux fenêtres ?
|
| auteur : Farscape | Il suffit de déclarer un projet « win32 application » puis de sélectionner l'option « a simple win32 application ».
On obtient le code suivant :
# include "stdafx.h"
int APIENTRY WinMain (HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
return 0 ;
}
|
|
| auteur : Farscape | La fonction la plus simple MessageBeep :
BOOL MessageBeep (
UINT uType);
|
Valeurs possibles avec le Paramètre uType :
- 0xFFFFFFFF
- MB_ICONASTERISK
- MB_ICONEXCLAMATION
- MB_ICONHAND
- MB_ICONQUESTION
- MB_OK
Une solution plus évoluée :
Utiliser la fonction sndPlaySound qui permet de jouer des fichiers au format .wav.
BOOL sndPlaySound (
LPCTSTR lpszSoundName,
UINT fuSound );
|
Deux manières de l'exploiter :
Lecture d'un fichier externe au programme a un emplacement donné :
sndPlaySound (" C:\\WINDOWS\\Media\\notify.wav " ,SND_SYNC);
|
Jouer un son à partir des ressources du programme :
Première phase insérer le fichier dans les ressources :
Cliquer dans les ressources sur le dossier le plus haut exemple :"TestMdi Ressources"
avec le bouton droit de la souris sélectionner l'option import .
Mettre .wav dans le filtre fichier.
Maintenant on a une section "WAVE" avec l'id IDR_WAVE1
sur IDR_WAVE1 faire click droit propriétés et mettre le nom entre "" on doit avoir
"IDR_WAVE1 " .
Deuxième phase lecture du son à partir des ressources :
# include "Mmsystem.h"
bool PlaySound (LPCTSTR lpszName)
{
BOOL bRet= FALSE;
LPSTR lpRes;
HANDLE hRes;
HRSRC hRsrc;
HINSTANCE hinstance= AfxGetInstanceHandle ();
if (! (hRsrc= FindResource (hinstance,lpszName," WAVE " )))return false ;
if (! (hRes = LoadResource (hinstance, hRsrc))) return false ;
if ((lpRes= (LPSTR)LockResource (hRes)))
{
bRet = sndPlaySound (lpRes, SND_MEMORY | SND_SYNC);
}
FreeResource (hRes);
return (bRet > FALSE );
}
PlaySound (" IDR_WAVE1 " );
|
Note:il faudra inclure la librairie Winmm.lib. au link.
|
| auteur : nico-pyright(c) | Des touches comme la touche windows, ou la combinaison de ctrl+echap permettent d'afficher le menu démarrer, une touche comme impr écran envoie un bitmap dans le presse-papiers.
Ces touches sont gérées automatiquement par Windows, comment faire pour empêcher leur fonctionnement ?
En installant un hook global clavier et en interceptant les touches de bas niveau.
Un hook est installé obligatoirement dans une dll.
Pour plus de détails sur les hooks, voir SetWindowsHookEx dans MSDN.
Le message à intercepter est le suivant : WH_KEYBOARD_LL, pour le low level keyboard.
En construisant une structure de hook clavier, on peut récupérer le code de la touche, sa répétition, etc ... KBDLLHOOKSTRUCT kbStruct = * ((KBDLLHOOKSTRUCT * )lParam);
|
Puis sur un message de type WM_KEYDOWN, on intercepte les touches VK_LWIN ou VK_RWIN ou VK_SNAPSHOT, etc ... en renvoyant 1 à la procédure de callback du hook clavier.
Pour avoir un comportement normal du clavier, il faut appeler la fonction CallNextHookEx.
Ne pas oublier d'arrêter le hook clavier à la fin en appelant UnhookWindowsHookEx.
Un exemple de dll qui installe un hook ainsi qu'un programme pour le tester est disponible ici http://farscape.developpez.com/Samples/demoHook.zip
[extrait]
LRESULT CALLBACK fonctionIntercepteClavierLowLevel (int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode = = HC_ACTION)
{
KBDLLHOOKSTRUCT kbStruct = * ((KBDLLHOOKSTRUCT * )lParam);
switch (wParam)
{
case WM_KEYDOWN:
if (kbStruct.vkCode = = VK_LWIN | | kbStruct.vkCode = = VK_RWIN)
return 1 ;
if (kbStruct.vkCode = = VK_ESCAPE & & GetAsyncKeyState (VK_CONTROL))
return 1 ;
if (kbStruct.vkCode = = VK_SNAPSHOT)
return 1 ;
}
}
return CallNextHookEx (hookClavier, nCode, wParam, lParam);
}
|
Note : Le hook WH_KEYBOARD_LL ne fonctionne que pour les systèmes d'exploitation NT/2000/XP ou supérieur
|
| auteur : nico-pyright(c) | En utilisant l'API FlashWindowEx
Exemple : FLASHWINFO flashInfo;
flashInfo.cbSize = sizeof (FLASHWINFO);
flashInfo.dwFlags = FLASHW_TRAY;
flashInfo.uCount = 5 ;
flashInfo.dwTimeout = 0 ;
flashInfo.hwnd = hwnd;
FlashWindowEx (& flashInfo);
|
Le membre dwFlags est FLASHW_TRAY pour faire clignoter la barre des tâches, il peut être FLASHW_CAPTION pour faire clignoter le caption (ou les deux : FLASHW_ALL). (plus de détails dans msdn)
Le membre uCount précise le nombre de répétitions et dwTimeout la fréquence (0 pour celle par défaut).
Bien évidemment, le membre hwnd correspond au handle de la fenêtre à faire clignoter.
|
| auteur : Aurelien.Regat-Barrel | Un process Win32 n'est rattaché à aucune console à sa création. Il est possible d'en obtenir une au moyen de AllocConsole, mais les flux standards de la bibliothèque C/C++ (stdout, cout, ...) n'y sont pas connectés. Le code suivant montre comment corriger cela:
# include <windows.h>
# include <cstdio>
# include <iostream>
void InitializeConsoleStdIO ()
{
# if _MSC_VER > = 1400 / / VC + + 8
{
FILE * stream;
freopen_s ( & stream, " CONIN$ " , " r " , stdin );
freopen_s ( & stream, " CONOUT$ " , " w " , stdout );
freopen_s ( & stream, " CONOUT$ " , " w " , stderr );
}
# else
std:: freopen ( " CONIN$ " , " r " , stdin );
std:: freopen ( " CONOUT$ " , " w " , stdout );
std:: freopen ( " CONOUT$ " , " w " , stderr );
# endif
std:: ios_base:: sync_with_stdio ();
}
int WINAPI WinMain (
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
)
{
:: AllocConsole ();
InitializeConsoleStdIO ();
std:: cout < < " Hello World!\n " ;
std:: cout < < " Appuyez sur Entree pour quitter... " ;
std:: cin.ignore ();
}
|
|
| auteur : nico-pyright(c) | Version Win32 :
Dans la callback, lors du message WM_CREATE, initialiser la structure et ajouter l'icône
static NOTIFYICONDATA TrayIcon;
|
la variable est définie en static dans la callback TrayIcon.cbSize = sizeof (NOTIFYICONDATA);
TrayIcon.hWnd = hwnd;
TrayIcon.uID = 0 ;
TrayIcon.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
TrayIcon.uCallbackMessage = WM_MOUSEMOVE;
TrayIcon.hIcon = LoadIcon (hinst, (LPCTSTR) IDI_ICON1);
strcpy (TrayIcon.szTip, " Mon info bulle " );
Shell_NotifyIcon (NIM_ADD, & TrayIcon);
|
Dans cet exemple, le message à traiter est redirigé vers le message WM_MOUSEMOVE, c'est celui là qu'il faudra traiter.
Dans le traitement de WM_MOUSEMOVE, c'est ici qu'on va vérifier si c'est le bouton droit et afficher un menu
case WM_MOUSEMOVE:
if (lParam = = WM_RBUTTONDOWN)
{
POINT pt;
GetCursorPos (& pt);
SetForegroundWindow (hwnd);
TrackPopupMenu (GetSubMenu (LoadMenu (hinst, (LPCTSTR) IDR_MENU1), 0 ),
TPM_LEFTALIGN, pt.x, pt.y, 0 , hwnd, 0 );
}
|
Le traitement du clic sur le menu se fera de manière classique dans le traitement du message WM_COMMAND
case WM_COMMAND:
switch (wParam)
{
case ID_QUITTER:
PostMessage (hwnd, WM_DESTROY, 0 , 0 );
}
|
(ici, en admettant que ID_QUITTER soit associé à un item du menu)
Il ne restera plus qu'à enlever l'icône de la barre des tâches système (par exemple, au moment du WM_DESTROY) avec un Shell_NotifyIcon (NIM_DELETE, & TrayIcon);
|
Version MFC :
Dans la classe MainFrame, déclarer un attribut privé Le plus simple ici est d'associer un message personnalisé pour le traitement du click sur l'icone.
Rajouter la définition du message privé # define WM_TRAY_MESSAGE ( WM_USER + 1 )
|
Rajouter le prototype de la fonction qui va traiter ce message afx_msg void OnTrayNotify (WPARAM wParam, LPARAM lParam);
|
Et dans le MESSAGE_MAP ON_MESSAGE (WM_TRAY_MESSAGE,OnTrayNotify)
|
Créer la structure et l'icone (par exemple dans le OnCreate) TrayIcon.cbSize = sizeof (NOTIFYICONDATA);
TrayIcon.hWnd = this - > m_hWnd;
TrayIcon.uID = 1 ;
TrayIcon.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
TrayIcon.uCallbackMessage = WM_TRAY_MESSAGE;
TrayIcon.hIcon = LoadIcon (AfxGetInstanceHandle (), MAKEINTRESOURCE (IDI_ICON1));
strcpy (TrayIcon.szTip, " Mon info bulle " );
Shell_NotifyIcon (NIM_ADD, & TrayIcon);
|
Rajouter l'implémentation de la méthode qui va gérer le clic droit
afx_msg void CMainFrame:: OnTrayNotify (WPARAM wParam, LPARAM lParam)
{
if ((UINT)wParam ! = 1 )
return ;
POINT pt;
switch (lParam)
{
case WM_RBUTTONDOWN:
case WM_CONTEXTMENU:
GetCursorPos (& pt);
CMenu myMenu;
myMenu.LoadMenu (IDR_MENU1);
myMenu.GetSubMenu (0 )- > TrackPopupMenu (TPM_BOTTOMALIGN| TPM_LEFTBUTTON| TPM_RIGHTBUTTON,
pt.x, pt.y, this );
break ;
}
return ;
}
|
Ensuite, le traitement du message d'un menu se fera de manière classique, à l'aide du classWizard
Enfin, il ne faudra pas oublier de supprimer l'icône (par exemple à la fermeture de l'application)
void CMainFrame:: OnSysCommand (UINT nID, LPARAM lParam)
{
if (nID= = SC_CLOSE)
{
Shell_NotifyIcon (NIM_DELETE, & TrayIcon);
}
CFrameWnd:: OnSysCommand (nID, lParam);
}
|
NB : Bien souvent, l'iconification se fait lors d'un minimise, il suffit de faire son traitement dans le OnSize pour le type SIZE_MINIMIZED
NB2 : Pour un menu pop-up, il faut créer un (et un seul) menu pop-up, et utiliser GetSubMenu(0) pour avoir le sous-menu
|
| auteur : nico-pyright(c) | En utilisant les api FindFirstUrlCacheEntry, FindNextUrlCacheEntry, etc ...
ex :
# define _WIN32_WINNT 0x0501
# define _WIN32_IE 0x0501
# include <windows.h>
# include <wininet.h>
# pragma comment ( lib , " wininet . lib " )
# define MEMDISPO ( MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN )
bool supprimeFichierDuCacheIE ()
{
bool bResultat = false ;
bool bFini = false ;
LPINTERNET_CACHE_ENTRY_INFO lpEntreeDuCache = NULL ;
DWORD dwLongueur, dwTaille = 4096 ;
HANDLE hCache = NULL ;
DWORD dwErreur = ERROR_INSUFFICIENT_BUFFER;
while (! bFini)
{
if (dwErreur = = ERROR_INSUFFICIENT_BUFFER)
{
VirtualFree (lpEntreeDuCache, 0 , MEM_RELEASE);
lpEntreeDuCache = (LPINTERNET_CACHE_ENTRY_INFO) VirtualAlloc (0 , dwTaille, MEMDISPO, PAGE_READWRITE);
if (! lpEntreeDuCache)
bFini = true ;
lpEntreeDuCache- > dwStructSize = dwTaille;
dwLongueur = dwTaille;
BOOL bRetour;
if (! hCache)
bRetour = (hCache = FindFirstUrlCacheEntry (NULL , lpEntreeDuCache, & dwLongueur)) ! = NULL ;
else
bRetour = FindNextUrlCacheEntry (hCache, lpEntreeDuCache, & dwLongueur);
if (bRetour)
dwErreur = ERROR_SUCCESS;
else
{
dwErreur = GetLastError ();
dwTaille = dwLongueur;
}
}
else if (dwErreur = = ERROR_NO_MORE_ITEMS)
{
bFini = true ;
bResultat = true ;
}
else if (dwErreur = = ERROR_SUCCESS)
{
if (! (lpEntreeDuCache- > CacheEntryType & COOKIE_CACHE_ENTRY) | |
! strstr (lpEntreeDuCache- > lpszSourceUrlName," www.developpez.net " ))
DeleteUrlCacheEntry (lpEntreeDuCache- > lpszSourceUrlName);
dwLongueur = dwTaille;
if (FindNextUrlCacheEntry (hCache, lpEntreeDuCache, & dwLongueur))
dwErreur = ERROR_SUCCESS;
else
{
dwErreur = GetLastError ();
dwTaille = dwLongueur;
}
}
else
{
LPVOID lpMsgBuf;
FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL , GetLastError (), 0 , (LPTSTR) & lpMsgBuf, 0 , NULL );
OutputDebugString ((LPCTSTR)lpMsgBuf);
LocalFree ( lpMsgBuf );
bFini = true ;
}
if (bFini)
{
VirtualFree (lpEntreeDuCache, 0 , MEM_RELEASE);
if (hCache)
FindCloseUrlCache (hCache);
}
}
return bResultat;
}
|
NB : la ligne qui ne supprime pas le cookie de developpez.com est surtout là à titre d'exemple pour montrer comme éviter que certains cookies ne soient supprimés
|
| auteur : nico-pyright(c) | En utilisant l'API SendInput :
void envoiChaine (char * sText)
{
bool bShift, bControl, bAlt;
unsigned int nPos, nCpt;
char cChar;
short nKeyScan;
INPUT input[256 ];
for (nPos= 0 ;nPos<= strlen (sText)- 1 ;nPos+ + )
{
ZeroMemory (input, sizeof input);
nCpt = 0 ;
cChar = sText[nPos];
nKeyScan = VkKeyScan (cChar);
bShift = (HIBYTE (nKeyScan) & 1 ?1 :0 );
bControl = (HIBYTE (nKeyScan) & 2 ?1 :0 );
bAlt = (HIBYTE (nKeyScan) & 4 ?1 :0 );
if (bShift)
{
input[nCpt].type = INPUT_KEYBOARD;
input[nCpt].ki.wVk = VK_SHIFT;
input[nCpt].ki.wScan = MapVirtualKey (VK_SHIFT, 0 );
nCpt+ + ;
}
if (bControl)
{
input[nCpt].type = INPUT_KEYBOARD;
input[nCpt].ki.wVk = VK_CONTROL;
input[nCpt].ki.wScan = MapVirtualKey (VK_CONTROL, 0 );
nCpt+ + ;
}
if (bAlt)
{
input[nCpt].type = INPUT_KEYBOARD;
input[nCpt].ki.wVk = VK_MENU;
input[nCpt].ki.wScan = MapVirtualKey (VK_MENU, 0 );
nCpt+ + ;
}
input[nCpt].type = INPUT_KEYBOARD;
input[nCpt].ki.wVk = LOBYTE (nKeyScan);
input[nCpt].ki.wScan = MapVirtualKey (LOBYTE (nKeyScan), 0 );
nCpt+ + ;
input[nCpt].type = INPUT_KEYBOARD;
input[nCpt].ki.wVk = LOBYTE (nKeyScan);
input[nCpt].ki.wScan = MapVirtualKey (LOBYTE (nKeyScan), 0 );
input[nCpt].ki.dwFlags = KEYEVENTF_KEYUP;
nCpt+ + ;
if (bShift)
{
input[nCpt].type = INPUT_KEYBOARD;
input[nCpt].ki.wVk = VK_SHIFT;
input[nCpt].ki.wScan = MapVirtualKey (VK_SHIFT, 0 );
input[nCpt].ki.dwFlags = KEYEVENTF_KEYUP;
nCpt+ + ;
}
if (bControl)
{
input[nCpt].type = INPUT_KEYBOARD;
input[nCpt].ki.wVk = VK_CONTROL;
input[nCpt].ki.wScan = MapVirtualKey (VK_CONTROL, 0 );
input[nCpt].ki.dwFlags = KEYEVENTF_KEYUP;
nCpt+ + ;
}
if (bAlt)
{
input[nCpt].type = INPUT_KEYBOARD;
input[nCpt].ki.wVk = VK_MENU;
input[nCpt].ki.wScan = MapVirtualKey (VK_MENU, 0 );
input[nCpt].ki.dwFlags = KEYEVENTF_KEYUP;
nCpt+ + ;
}
SendInput (nCpt, input, sizeof INPUT);
}
}
|
ex : envoiChaine (" Vive le c++ " );
|
|
| auteur : nico-pyright(c) | En utilisant les API SetCursorPos et SendInput
bool click (int x, int y)
{
SetCursorPos (x,y);
INPUT in[2 ] = { { INPUT_MOUSE, { 0 , 0 , 0 , MOUSEEVENTF_LEFTDOWN, 0 , 0 } } ,
{ INPUT_MOUSE, { 0 , 0 , 0 , MOUSEEVENTF_LEFTUP , 0 , 0 } } } ;
return SendInput (2 , in, sizeof (INPUT))> 0 ;
}
|
|
| auteur : nico-pyright(c) | En utilisant l'objet COM du shell
int CreerRaccourci (const char * pathExe,
const char * description,
const char * argument,
const char * repertoireDeTravail,
const char * iconePath,
int iconeIndex,
const char * destination)
{
HRESULT hr;
CoInitialize (NULL );
BOOL bRet = FALSE;
IShellLink* psl;
if (SUCCEEDED ( CoCreateInstance (CLSID_ShellLink,
NULL ,
CLSCTX_INPROC_SERVER,
IID_IShellLink,
(LPVOID* ) & psl)))
{
IPersistFile* ppf;
psl- > SetPath (pathExe);
psl- > SetDescription (description);
psl- > SetArguments (argument);
psl- > SetWorkingDirectory (repertoireDeTravail);
if (SUCCEEDED (psl- > QueryInterface (IID_IPersistFile, (LPVOID * )& ppf)))
{
wchar_t wsz[MAX_PATH];
MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, destination, - 1 , wsz, MAX_PATH);
hr = psl- > SetIconLocation (iconePath, iconeIndex);
if (SUCCEEDED (ppf- > Save (wsz, TRUE)))
bRet = TRUE;
ppf- > Release ();
}
psl- > Release ();
}
return bRet;
}
|
Cette fonction pourra s'appeller par exemple de cette manière if (CreerRaccourci (" c:\\install.exe " ," l'installation " ," " , " " ," c:\\monexe.exe " ,0 ," c:\\mon raccourci.lnk " ))
{
}
else
{
}
|
|
| auteur : nico-pyright(c) | Le framework MFC s'occupe d'un traitement par défaut de la ligne de commande, grâce à l'objet CCommandLineInfo et aux fonctions ParseCommandLine et ProcessShellCommand.
Ce mécanisme est décrit rapidement ici
Les plus classiques étant
msdn a écrit:
app --> New file.
app filename --> Open file.
Si l'on veut personnaliser ce traitement, il faut créer une classe dérivée de CCommandLineInfo et surcharger la méthode ParseParam.
Par exemple, on veut démarrer l'application en maximisé, minimisé ou normal suivant un paramètre.
(On crée une variable membre dans notre classe d'application qui va stocker le mode int cmdShow_;)
On crée une classe (sans classwizzard, puisqu'il ne propose pas la dérivation de CCommandLineInfo) (appellons là myCommandLineInfo) et on surcharge la méthode ParseParam |
void myCommandLineInfo:: ParseParam (const TCHAR* pszParam,BOOL bFlag,BOOL bLast)
{
CString param (pszParam);
CTestDeriveLigneCommandeApp * pTheApp = static_cast < CTestDeriveLigneCommandeApp * > (AfxGetApp ());
if (param = = " runMaximized " )
pTheApp- > cmdShow_ = SW_SOWMAXIMIZED;
else if (param = = " runMinimized " )
pTheApp- > cmdShow_ = SW_SHOWMINIMIZED;
else
pTheApp- > cmdShow_ = SW_SHOW;
}
|
Dans la méthode InitInstance de la classe d'application, il suffira de traiter la ligne de commande avec notre nouvelle classe |
myCommandLineInfo cmdInfo;
ParseCommandLine (cmdInfo);
if (! ProcessShellCommand (cmdInfo))
return FALSE;
m_pMainWnd- > ShowWindow (cmdShow_);
m_pMainWnd- > UpdateWindow ();
|
Application : |
c :\>monApp runMaximized - - > lance en maximisé
|
Remarque : Si on veut éviter d'appeler le mécanisme par défaut, et traiter la ligne de commande soi-même, il ne faudra pas oublier d'appeller OnFileNew() pour créer un document vide, sinon la fenêtre principale ne sera pas initialisée et cela provoquera une assertion.
|
lien : Comment récupérer la ligne d'arguments passée à l'application ?
|
| auteur : Farscape | En faisant clic droit propriétés sur un fichier .exe ou .dll dans l'explorateur Windows
On peut visualiser les informations liées à la version du programme.
Ces informations sont disponibles dans le fichier ressources de notre application dans la section Version\VS_VERSION_INFO.
La question qui se pose c'est comment accéder à ces informations à l'intérieur d'un programme ?
Il faudra utiliser les fonctions GetFileVersionInfo et VerQueryValue
La classe qui suit se propose de récupérer l'ensemble de ces informations et d'en fournir l'accès pour chaque élément.
Le paramétrage par défaut de la fonction GetInfosFile permet de retrouver les informations pour l'exécutable en cours pour première page de langue trouvée.
(Il est possible d'avoir plusieurs définitions de langues dans les ressources).
la définition:
class CVersionFile
{
private : CVersionFile (const CVersionFile& );
private : void operator = (const CVersionFile& );
public :
CVersionFile (){ }
CString GetInfos (const TCHAR * szLib);
bool GetNextInfos (bool & rFirstOne,CString & rstrKeyName,CString & rstrValue);
bool GetInfosFile (const TCHAR * szFileName= NULL ,WORD wLanguage= 0 ,WORD wCodePage= 0 );
protected :
CMap< CString ,const TCHAR * ,CString ,const TCHAR * > m_aListInfos;
POSITION m_pos;
} ;
|
l'implémentation
# pragma comment ( lib , " Version . lib " ) / / à rajouter dans le source .
CString CVersionFile:: GetInfos (const TCHAR * szLib)
{
CString str;
m_aListInfos.Lookup (szLib,str);
return str;
}
bool CVersionFile:: GetNextInfos (bool & rFirstOne,CString & rstrKeyName,CString & rstrValue)
{
if (rFirstOne) m_pos = m_aListInfos.GetStartPosition ();
rFirstOne= false ;
if (m_pos! = NULL )
{
m_aListInfos.GetNextAssoc (m_pos,rstrKeyName,rstrValue);
return true ;
}
return false ;
}
bool CVersionFile:: GetInfosFile (const TCHAR * szFileName ,WORD wLanguage ,WORD wCodePage )
{
DWORD dwVerInfoSize;
DWORD dwHnd;
void * pBuffer;
VS_FIXEDFILEINFO * pFixedInfo;
LPVOID lpVersionBuffer;
UINT uLen;
TCHAR szGetName[500 ];
TCHAR szExeName[MAX_PATH];
m_aListInfos.RemoveAll ();
if (! szFileName)
GetModuleFileName (AfxGetInstanceHandle (), szExeName, sizeof (szExeName));
# ifdef _UNICODE
else wcscpy (szExeName,szFileName);
# else
else strcpy (szExeName,szFileName);
# endif
dwVerInfoSize = GetFileVersionInfoSize (szExeName, & dwHnd);
if (dwVerInfoSize)
{
CString str;
pBuffer = new TCHAR[dwVerInfoSize];
if (pBuffer = = NULL ) return false ;
GetFileVersionInfo (szExeName, dwHnd, dwVerInfoSize, pBuffer);
VerQueryValue (pBuffer,_T (" \\ " ),(void * * )& pFixedInfo,(UINT * )& uLen);
str.Format (_T (" %u,%u,%u,%u " ), HIWORD (pFixedInfo- > dwProductVersionMS),
LOWORD (pFixedInfo- > dwProductVersionMS),
HIWORD (pFixedInfo- > dwProductVersionLS),
LOWORD (pFixedInfo- > dwProductVersionLS));
m_aListInfos.SetAt (_T (" FixedProductVersion " ),str);
str.Format (_T (" %u,%u,%u,%u " ),HIWORD (pFixedInfo- > dwFileVersionMS),
LOWORD (pFixedInfo- > dwFileVersionMS),
HIWORD (pFixedInfo- > dwFileVersionLS),
LOWORD (pFixedInfo- > dwFileVersionLS));
m_aListInfos.SetAt (_T (" FixedFileVersion " ),str);
unsigned int cbTranslate;
struct LANGANDCODEPAGE
{
WORD wLanguage;
WORD wCodePage;
} * lpTranslate;
VerQueryValue (pBuffer,
TEXT (" \\VarFileInfo\\Translation " ),
(LPVOID* )& lpTranslate,
& cbTranslate);
TCHAR * aszLib[]= { _T (" Comments " ),_T (" InternalName " ),_T (" ProductName " ),
_T (" CompanyName " ),_T (" LegalCopyright " ),_T (" ProductVersion " ),
_T (" FileDescription " ),_T (" LegalTrademarks " ),_T (" PrivateBuild " ),
_T (" FileVersion " ),_T (" OriginalFilename " ),_T (" SpecialBuild " )
} ;
for (int i= 0 ; i < (cbTranslate/ sizeof (struct LANGANDCODEPAGE)); i+ + )
{
if (wLanguage & & lpTranslate[i].wLanguage! = wLanguage) continue ;
if (wCodePage & & lpTranslate[i].wCodePage! = wCodePage) continue ;
for (int n= 0 ;n< sizeof (aszLib)/ sizeof (char * );n+ + )
{
str.Format (_T (" \\StringFileInfo\\%04x%04x\\%s " ),
lpTranslate[i].wLanguage,
lpTranslate[i].wCodePage,
aszLib[n]);
lstrcpy (szGetName,str);
if (VerQueryValue (pBuffer,szGetName,(void * * )& lpVersionBuffer,(UINT * )& uLen) ! = 0 )
{
if (lpVersionBuffer)
{
str = (LPTSTR)lpVersionBuffer;
m_aListInfos.SetAt (aszLib[n],str);
}
}
}
}
delete [] pBuffer;
}
return (m_aListInfos.GetCount ()! = 0 );
}
|
Exemple d'application:
CVersionFile InfosFile;
InfosFile.GetInfosFile ();
CString str= InfosFile.GetInfos (_T (" InternalName " ));
str+ = _T (" Version " );
str+ = InfosFile.GetInfos (_T (" PrivateBuild " ));
str+ = _T (" " );
str+ = InfosFile.GetInfos (_T (" LegalCopyright " ));
TRACE (_T (" \n Version:%s " ),static_cast < const TCHAR * > (str));
bool bFirst= true ;
CString strValue,strKeyName;
while (InfosFile.GetNextInfos (bFirst,strKeyName,strValue))
{
TRACE (_T (" \n KeyName:%s:%s " ),static_cast < const TCHAR * > (strKeyName),static_cast < const TCHAR * > (strValue));
}
|
|
Consultez les autres F.A.Q.
|
|