H ow T o.. .

Cette page vous permet de retrouver certaines méthodes de programmation.
Les codes fournis sont des exemples. Ils nécessitent souvent une adaptation avant d'être appliqués.
Les questions ne sont pas classées. Utilisez la fonction de recherche de votre navigateur pour chercher une question précise.


Q Comment détecter si mon application tourne déjà pour ne pas lancer une deuxième session en Win32?
R Pour faire cela, il faut créer un "mutex" qui est un objet général à Windows. L'application qui se lance doit créer le mutex, puis tester l'existence préalable de ce mutex. L'exemple suivant en C++ (MFC) indique la marche à suivre:

BOOL CDummyApp::InitInstance()
{
    /////////// Détection appli précédente ////////////
    HANDLE hMutex = CreateMutex(NULL, FALSE, "MonMutexUniqueAMoiToutSeul");
    if(!hMutex)
    {
        AfxMessageBox("Erreur à la création du mutex", MB_OK | MB_ICONSTOP);
        return FALSE;
    }

    if(GetLastError() == ERROR_ALREADY_EXISTS)
    {
        AfxMessageBox("L'appli tourne déjà!!", MB_OK | MB_ICONEXCLAMATION);
        CloseHandle(hMutex);
        return FALSE;
    }
.........

En sortie, (en fin de OnInitDialog pour une appli en boîte de dialogue, et dans ExitInstance pour une appli avec des fenêtres), ajouter:

    // Ferme le mutex en sortie
    CloseHandle(hMutex);


Q Comment lancer un application et attendre qu'elle se termine?
R Il faut lancer l'application avec CreateProcess() et non ShellExecute(). Ensuite, pour attendre que l'application se termine pour continuer, il faut utiliser WaitForSingleObjet() . Exemple:

// Lancement du programme en tant que Process
PROCESS_INFORMATION Process;
STARTUPINFO StartInfo;
memset(&StartInfo, 0, sizeof(StartInfo));
StartInfo.cb = sizeof(StartInfo);
if(!CreateProcess(NULL, "ProgrammeALancer.exe", NULL, NULL, FALSE,
        CREATE_DEFAULT_ERROR_MODE, NULL, NULL, &StartInfo, &Process))
{
    // Erreur au lancement du programme
}

// Attente de la fin du programme
WaitForSingleObject(Process.hProcess, INFINITE);

// On continue après la fin du programme lancé...



Q Comment placer une icône dans le systray (zone de la barre de tâche où se trouve l'heure, le volume sonore...)
R Vous devez utiliser la fonction Shell_NotifyIcon pour gérer cette icône. Voir la documentation de la fonction pour plus de détails. Le fichier SystrayApplication.txt décrit comment créer une application qui met une icône dans le systray et n'apparaît pas à l'écran sauf sur demande. Il suffit de générer un projet avec AppWizard de type Boîte de dialogue, puis de suivre les instructions de ce fichier.



Q Comment créer une boite de dialogue de forme ovale
R Il faut créer une région. Le code suivant indique comme faire dans une boite dérivée de CDialog:

int CDlgOvaleDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CDialog::OnCreate(lpCreateStruct) == -1)
        return -1;

    HRGN hRgn;
    RECT rect;
    GetClientRect(&rect);
    hRgn = CreateEllipticRgn(0,0,rect.right,rect.bottom);
    SetWindowRgn(m_hWnd,hRgn,TRUE);
    SetProp(m_hWnd,"region",hRgn);
    return 0;
    }

void CDlgOvaleDlg::OnDestroy()
{
    CDialog::OnDestroy();
    if (GetProp(m_hWnd,"region"))
    {
        DeleteObject(GetProp(m_hWnd,"region"));
        RemoveProp(m_hWnd,"region");
    }
}



Q Comment changer la résolution de l'écran ou enlever la barre de tâche pour se mettre en plein écran
R Il faut utiliser les fonctions de l'API EnumDisplaySettings et ChangeDisplaySettings . La documentation de ces fonctions fournie dans la MSDN donne la marche à suivre.



Q Comment trouver le nom réel d'un répertoire spécial, comme le "menu démarrer", le répertoire des polices...
R Les fonctions SHGetSpecialFolderLocation et SHGetSpecialFolderPath sont faites pour cela.



Q Comment ouvrir une boite de sélection de répertoire pour que l'utilisateur puisse choisir un répertoire
R La fonction SHBrowseForFolder permet d'ouvrir cette boite. Il faut ensuite récupérer le chemin à l'aide de la fonction SHGetPathFromIDList puis désallouer le PIDL. Voici un exemple fourni par Microsoft:

LPMALLOC pMalloc;
/* Gets the Shell's default allocator */
if (::SHGetMalloc(&pMalloc) == NOERROR)
{
    BROWSEINFO bi;
    char pszBuffer[MAX_PATH];
    LPITEMIDLIST pidl;
    // Get help on BROWSEINFO struct - it's got all the bit settings.
    bi.hwndOwner = GetSafeHwnd();
    bi.pidlRoot = NULL;
    bi.pszDisplayName = pszBuffer;
    bi.lpszTitle = _T("Select a Starting Directory");
    bi.ulFlags = BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS;
    bi.lpfn = NULL;
    bi.lParam = 0;
    // This next call issues the dialog box.
    if ((pidl = ::SHBrowseForFolder(&bi)) != NULL)
    {
        if (::SHGetPathFromIDList(pidl, pszBuffer))
       {
            // At this point pszBuffer contains the selected path */.
            DoingSomethingUseful(pszBuffer);
        }
        // Free the PIDL allocated by SHBrowseForFolder.
        pMalloc->Free(pidl);
    }
    // Release the shell's allocator.
    pMalloc->Release();
}


[Sommaire] [Coin du programmeur]