IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
logo
Sommaire > Divers
        Comment afficher le message d'erreur correspondant au code d'erreur renvoyé par GetLastError() ?
        Comment récupérer le nom de la machine ?
        Comment lancer une application au démarrage du système ?
        Comment travailler avec le compteur de haute précision ?
        Comment appliquer le style XP aux fenêtres ?
        Comment inclure directement le fichier manifest dans les ressources ?
        Comment rajouter le fichier manifeste du style XP au manifeste existant dans Visual 2005 ?
        Comment faire une application win32 sans fenêtre apparente ?
        Comment émettre un son ?
        Comment bloquer les 'touches spéciales' de Windows ?
        Comment faire clignoter une fenêtre dans la barre des tâches ?
        Comment utiliser printf/cout/... avec une console créée dynamiquement ?
        Comment avoir une icône avec un menu pour mon application dans la barre des tâches système (systray) ?
        Comment vider le cache d'Internet Explorer ?
        Comment simuler le clavier pour écrire une phrase complète ?
        Comment simuler un clic de souris à une position donnée ?
        Comment créer un raccourci ?
        Comment personnaliser le traitement par défaut de la ligne de commande ?
        Comment récupérer les informations de version dans un programme Windows ?



Comment afficher le message d'erreur correspondant au code d'erreur renvoyé par GetLastError() ?
auteur : Farscape

LPVOID lpMsgBuf;
 FormatMessage(
    FORMAT_MESSAGE_ALLOCATE_BUFFER |
    FORMAT_MESSAGE_FROM_SYSTEM |
    FORMAT_MESSAGE_IGNORE_INSERTS,
    NULL,
    GetLastError(),
    0, // Default language
    (LPTSTR) &lpMsgBuf,
    0,
    NULL
   );
   // Process any inserts in lpMsgBuf.
   // ...
   // Display the string.
   AfxMessageBox((LPCTSTR)lpMsgBuf, MB_OK | MB_ICONINFORMATION );
   // Free the buffer.
   LocalFree( lpMsgBuf ); 

Comment récupérer le nom de la machine ?
auteur : Farscape
Avec la fonction GetComputerName.

char szBuffer[MAX_COMPUTERNAME_LENGTH + 1];
if(GetComputerName(szBuffer,MAX_COMPUTERNAME_LENGTH))
{
  AfxMessageBox(szBuffer);
}

Comment lancer une application au démarrage du système ?
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


Comment travailler avec le compteur de haute précision ?
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++); // code à évaluer
// **************
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)


Comment appliquer le style XP aux fenêtres ?
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>

Comment inclure directement le fichier manifest dans les ressources ?
Créé le 19/09/2005[haut]
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 :

// Add manually edited resources here...
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 :

#define RT_MANIFEST  24
devra être mise en commentaire pour éviter le warning à la compilation.


Comment rajouter le fichier manifeste du style XP au manifeste existant dans Visual 2005 ?
Créé le 22/01/2007[haut]
auteur : Farscape
En premier lieu au procédera à la création de notre fichier manifeste pour le style XP comme expliqué ici faq 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 : faq Comment appliquer le style XP aux fenêtres ?

Comment faire une application win32 sans fenêtre apparente ?
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) 
{ 
    // TODO: Place code here. 

   return 0; 
}

Comment émettre un son ?
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.


Comment bloquer les "touches spéciales" de Windows ?
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) // bloque touches windows
                return 1;
            
            if (kbStruct.vkCode == VK_ESCAPE && GetAsyncKeyState(VK_CONTROL)) // bloque control+echap
                return 1;
            if (kbStruct.vkCode == VK_SNAPSHOT) // bloque impr écran
                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


Comment faire clignoter une fenêtre dans la barre des tâches ?
Créé le 04/04/2005[haut]
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.


Comment utiliser printf/cout/... avec une console créée dynamiquement ?
Créé le 20/05/2006[haut]
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()
{
    // si une console est rattachée au processus, alors il existe des fichiers
    // virtuel CONIN$ et CONOUT$ qui permettent respectivement de lire
    // et d'écrire depuis / dans cette console (voir la doc de CreateFile).

#if _MSC_VER >= 1400 // VC++ 8 
    { 
    // éviter le warning C4996: 'freopen' was declared deprecated 
    // This function or variable may be unsafe. Consider using freopen_s instead. 
    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 

    // la ligne suivante synchronise les flux standards C++ (cin, cout, cerr...)
    std::ios_base::sync_with_stdio();    
}

int WINAPI WinMain(          
    HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpCmdLine,
    int nCmdShow
)
{
    // créer une console
    ::AllocConsole();
    // synchroniser la CRT
    InitializeConsoleStdIO();
    // tester
    std::cout << "Hello World!\n";
    std::cout << "Appuyez sur Entree pour quitter...";
    std::cin.ignore();
}

Comment avoir une icône avec un menu pour mon application dans la barre des tâches système (systray) ?
Créé le 20/05/2006[haut]
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é
NOTIFYICONDATA TrayIcon;
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


Comment vider le cache d'Internet Explorer ?
Créé le 20/05/2006[haut]
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; // taille initiale du buffer
    HANDLE hCache = NULL;
    DWORD  dwErreur = ERROR_INSUFFICIENT_BUFFER;
    
    while (!bFini)
    {
        // on a besoin d'un plus gros buffer (ou initialisation du buffer)
        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) // première fois
                bRetour = (hCache = FindFirstUrlCacheEntry(NULL, lpEntreeDuCache, &dwLongueur)) != NULL;
            else
                bRetour = FindNextUrlCacheEntry(hCache, lpEntreeDuCache, &dwLongueur);
            if (bRetour)
                dwErreur = ERROR_SUCCESS;
            else
            {
                dwErreur = GetLastError();
                dwTaille = dwLongueur; // nouvelle taille à utiliser
            }
        }
        else if (dwErreur == ERROR_NO_MORE_ITEMS) // fini
        {
            bFini = true;
            bResultat = true;
        }
        else if (dwErreur == ERROR_SUCCESS) // traitement de l'entrée
        {
            // on ne supprime pas le cookie de DVP.COM :-)
            if (!(lpEntreeDuCache->CacheEntryType & COOKIE_CACHE_ENTRY) || 
                !strstr(lpEntreeDuCache->lpszSourceUrlName,"www.developpez.net")) 
                DeleteUrlCacheEntry(lpEntreeDuCache->lpszSourceUrlName); // suppression
            dwLongueur = dwTaille;
            if (FindNextUrlCacheEntry(hCache, lpEntreeDuCache, &dwLongueur))
                dwErreur = ERROR_SUCCESS;
            else
            {
                dwErreur = GetLastError();
                dwTaille = dwLongueur; // nouvelle taille à utiliser
            }
        }
        else // erreur inconnue
        {
            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


Comment simuler le clavier pour écrire une phrase complète ?
Créé le 20/05/2006[haut]
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++");

Comment simuler un clic de souris à une position donnée ?
Créé le 20/05/2006[haut]
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;
}
if (click(0,0)) // ...

Comment créer un raccourci ?
Créé le 20/05/2006[haut]
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"))
{
// reussi
}
else
{
// raté
}

Comment personnaliser le traitement par défaut de la ligne de commande ?
Créé le 22/01/2007[haut]
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

  // Parse command line for standard shell commands, DDE, file open
    myCommandLineInfo cmdInfo;
    ParseCommandLine(cmdInfo);

   // Dispatch commands specified on the command line
    if (!ProcessShellCommand(cmdInfo))
        return FALSE;

   // The one and only window has been initialized, so show and update it.
    m_pMainWnd->ShowWindow(cmdShow_); // ici appel avec notre variable membre
    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 : faq Comment récupérer la ligne d'arguments passée à l'application ?

Comment récupérer les informations de version dans un programme Windows ?
Créé le 22/01/2007[haut]
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:

// récupération des informations de version du fichier .exe ou dll.
// les zones suivantes sont disponibles:/
//        "FixedFileVersion","FixedProductVersion"
//        "Comments","InternalName","ProductName",
//        "CompanyName","LegalCopyright","ProductVersion",
//        "FileDescription","LegalTrademarks","PrivateBuild",
//        "FileVersion","OriginalFilename","SpecialBuild"
class CVersionFile
{
    private: CVersionFile(const CVersionFile&);      // pas de constructeur de copie
    private: void operator=(const CVersionFile&); // pas d'operateur de copie.

public:

    CVersionFile(){}

    // la valeur de la clef szLib correspondant a une entrée du dossier version
    CString GetInfos(const TCHAR *szLib);
    
    // permet d'itérer les valeurs stockées.
    // charge la valeur rValue pour la clef correspondante dans rKeyName
    // rFirstOne doit etre initialisée à true au premier appel de la fonction.
    bool  GetNextInfos(bool &rFirstOne,CString &rstrKeyName,CString &rstrValue);


    // récuperation des valeurs
    // const char *szFileName  le module spécifié ou si null 'exe en cours d'execution.
    // WORD wLanguage : le langage à lire ex:SUBLANG_ENGLISH_US ou si 0 le premier langage utilisé
    // WORD wCodePage : la page code à lire ex:LANG_ENGLISH        ou si 0 la premiere page de code utilisée.
    bool GetInfosFile(const TCHAR *szFileName=NULL,WORD wLanguage=0,WORD wCodePage=0);
    
protected:
    CMap<CString ,const TCHAR *,CString ,const TCHAR *> m_aListInfos;// rajouter include <afxtempl.h> dans stdafx.h
    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 /*=NULL*/,WORD wLanguage /*=0*/,WORD wCodePage /*=0*/)
{
    //
    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);
        
        // récupère les infos fixes indépendantes du langage.
        // FixedProductVersion
        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);
        
        //FixedFileVersion
        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);
        
        // infos liées au langage.
        unsigned int cbTranslate;
        struct LANGANDCODEPAGE
        {
            WORD wLanguage;
            WORD wCodePage;
        } *lpTranslate;
        
        // Read the list of languages and code pages.
        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")
                        };
        // lecture des infos pour chage langue et page de code            
        for(int i=0; i < (cbTranslate/sizeof(struct LANGANDCODEPAGE)); i++ )
        {
            // filtrage langage et page de code désirée ?
            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);
                // recuperation de l'information.
                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();        

// accés par libellé  
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));

// itération
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.


Valid XHTML 1.0 TransitionalValid CSS!

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2004 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.