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

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Utilisation de Windows API dans un DLL


Sujet :

C++

  1. #1
    Membre à l'essai
    Femme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Avril 2016
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 38
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo

    Informations forums :
    Inscription : Avril 2016
    Messages : 8
    Points : 11
    Points
    11
    Par défaut Utilisation de Windows API dans un DLL
    Bonjour à tous.
    J'espère ne pas me tromper de catégorie. C'est la première fois que je poste car d'habitude je trouve la solution en cherchant mais dans ce cas j'ai du mal à me documenter. Ça se passe sur Windows (8.1 en l’occurrence) et avec Visual Studio Community 2015.

    J'ai des connaissances en C++, mais peu de connaissances sur les DLLs et Windows.

    Je programme des plugins (appellés ici X-Tensions) pour un logiciel d'analyse forensic qui s'appelle X-Ways (il s'agit d'un logiciel reconnu dans ce domaine, il permet notamment l'analyse poussée de tout type de support : fichiers effacés, carving, tout type de recherche, etc). Une API est livrée avec la licence. Les X-Tensions sont en fait des DLLs que l'on lance à la demande à partir du logiciel. On a ainsi accès à deux types de fonctions : les fonctions que l'on doit définir, exporter dans le DLL et qui sont lues séquentiellement par le logiciel ; et les fonctions que l'on peut appeler. Je n'ai aucun problème avec l'API et la génération du DLL, tout fonctionne.

    Là ou ça se gâte, c'est que j'aimerais créer une fenêtre avec menu etc en faisant appel à Windows API. J'ai suivi le cours suivant http://bob.developpez.com/tutapiwin/ et je comprend bien le principe (et ça marche ) mais dès que je veux implémenter ça dans mon dll je n'y arrive pas.

    Je ne souhaite pas forcement que l'on me donne la réponse toute faite, mais si pouviez me donner des éléments de réponse quand à la documentation à utiliser, ou peut-être même que je me trompe de méthode! Comment feriez vous à ma place? J'espère que ces éléments de réponse me permettront d'arriver à implémenter une simple fenetre dans mon plugin (pour commencer).

    Je vous montre la structure de mon programme :
    Nom : 2016-04-16 17_39_07-X-Tension - Microsoft Visual Studio (Administrateur).png
Affichages : 295
Taille : 4,7 Ko

    Dans le projet XT_Main, X-Tension.cpp contient les pointeurs de fonctions (fonctions du logiciel que l'on peut appeller). X-tension.h contient les déclarations de toutes les fonctions et structures utilisées.
    Le projet XT_New est notre fameux plugin.

    Ci-dessous New.cpp qui défini le coeur de notre X-Tension avec les fonctions exportées. Ici une seule est vraiment définie, les autres sont vides (elles retournent juste la valeur attendue).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    #include "X-Tension.h" 
    #include <string>
    #include <fstream>
    #include <Windows.h>
     
    using namespace std;
     
     
    /////////////////////////////////////////////////////////////////////////////
    // XT_Init = fonction lancée en premier après le démarrage de l'X-Tension
     
    LONG __stdcall XT_Init(DWORD nVersion, DWORD nFlags, HANDLE hMainWnd, void* lpReserved)
    {
     
    	XT_RetrieveFunctionPointers();
     
    	// messages d'accueil /
    	XWF_OutputMessage(L"INIT --- INIT --- INIT", 0);
    	XWF_OutputMessage(L"---------> Bienvenue dans ma première X-Tension!!!", 0);
     
    	return 1;
     
    }
     
    ///////////////////////////////////////////////////////////////////////////////////////////////
    // XT_About = fonction lancée quand on clique sur les trois petits points du menu X-Tensions 
     
    LONG __stdcall XT_About(HANDLE hParentWnd, void* lpReserved)
    {
    	XWF_OutputMessage(L"---------> About", 0);
     
    	return 0;
    }
     
    //////////////////////////////////////////////////////////////////////////////
    // XT_Prepare
     
    LONG __stdcall XT_Prepare(HANDLE hVolume, HANDLE hEvidence, DWORD nOpType, void* lpReserved)
    {
     
    	return 0;
    }
     
     
    //////////////////////////////////////////////////////////////////////////////
    // XT_ProcessItem
     
    LONG __stdcall XT_ProcessItem(LONG nItemID, void* lpReserved)
    {
     
    	XWF_OutputMessage(L"PROCESS ITEM --- PROCESS ITEM --- PROCESS ITEM", 0);
     
    	return 0;
    }
     
    ///////////////////////////////////////////////////////////////////////////////
    // XT_ProcessItemEx
     
    LONG __stdcall XT_ProcessItemEx(LONG nItemID, HANDLE hItem, void* lpReserved)
    {
    	XWF_OutputMessage(L"PROCESS ITEM EX --- PROCESS ITEM EX --- PROCESS ITEM EX", 0);
     
    	// on ajoute un commentaire à cet objet 
    	XWF_AddComment(nItemID, L"mon_commentaire_cool", 1);
     
    	// donne le nom et la taille du fichier traité 
    	wstring str;
    	auto num = XWF_GetItemSize(nItemID);
    	str = XWF_GetItemName(nItemID);
    	str += L" ";
    	str += to_wstring(num);
    	str += L" bytes";
    	XWF_OutputMessage(str.c_str(), 0);
     
    	return 0;
    }
     
     
    ////////////////////////////////////////////////////////////////////////////////
    // XT_PrepareSearch
     
    LONG __stdcall XT_PrepareSearch(struct PrepareSearchInfo* PSInfo, struct CodePages* CPages)
    {
    	XWF_OutputMessage(L"PREPARE SEARCH - PREPARE SEARCH - PREPARE SEARCH", 0);
     
    	return 1;
    }
     
     
    ///////////////////////////////////////////////////////////////////////////////
    // XT_ProcessSearchHit
     
    LONG __stdcall XT_ProcessSearchHit(struct SearchHitInfo* info)
    {
     
    	return 0;
     
    }
     
    //////////////////////////////////////////////////////////////////////////////
    // XT_Finalize
     
    LONG __stdcall XT_Finalize(HANDLE hVolume, HANDLE hEvidence, DWORD nOpType, void* lpReserved)
    {
    	XWF_OutputMessage(L"FINALIZE --- FINALIZE --- FINALYSE", 0);
     
    	SearchInfo SInfo;
    	SearchInfo *SIPtr = &SInfo;
     
    	SIPtr->iSize = sizeof(*SIPtr);
    	SIPtr->hVolume = 0;
    	//SIPtr->lpSearchTerms = L"[a-zA-Z]+:\/\/\0";        // une expression régulière avec GREP,  nFlags=65 (GREP + logical search)
    	SIPtr->lpSearchTerms = L"tartes\r\nflambee";
    	SIPtr->nFlags = 1;
    	SIPtr->nSearchWindow = 0;
     
    	CodePages CPages;
    	CodePages *CPPtr = &CPages;
     
    	CPPtr->iSize = sizeof(*CPPtr);
    	CPPtr->nCodePage1 = 1252;
    	CPPtr->nCodePage2 = 1200;
    	CPPtr->nCodePage3 = 65001;
    	CPPtr->nCodePage4 = 0;
    	CPPtr->nCodePage5 = 0;
     
     
    	// fonction qui permet une recherche simultanée selon les lpSearchTerms définis
    	XWF_Search(&SInfo, &CPages);
     
     
    	// a l'issue de la recherche on alimente un fichier txt sur le bureau de l'utilisateur 
    	string const nomFichier{ R"(C:\Users\tux\Desktop\history_search.txt)" };
    	ofstream monFlux{ nomFichier };
     
    	if (monFlux)
    	{
    		int taille;
    		taille = SIPtr->iSize;
     
    		wstring str;
    		str = SIPtr->lpSearchTerms;
    		XWF_OutputMessage(str.c_str(), 0);
     
    		XWF_OutputMessage(L"mon fichier est ouvert", 0);
    		monFlux << "Historique de recherche : " << endl;
    		monFlux << taille << endl;
     
    	}
    	else
    	{
    		XWF_OutputMessage(L"erreur ouverture fichier", 0);
    	}
     
    	return 0;
    }
     
     
    ///////////////////////////////////////////////////////////////////////////////
    // XT_Done
     
    LONG __stdcall XT_Done(void* lpReserved)
    {
    	XWF_OutputMessage(L"DONE --- DONE --- DONE", 0);
    	XWF_OutputMessage(L"------------------------------------------------------------------------------------", 0);
    	return 0;
    }
    Jusqu'à présent j'ai essayé d'implémenter ceci, en vain (ça fonctionne de manière autonome bien sur) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    #include <Windows.h>
     
    LRESULT CALLBACK MainProc(HWND Dlg,UINT message,WPARAM wParam,LPARAM lParam);
     
    int APIENTRY WinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPSTR     lpCmdLine,
                         int       nCmdShow)
    {
    	WNDCLASSEX principale;
    	principale.cbSize=sizeof(WNDCLASSEX);
    	principale.style=CS_HREDRAW|CS_VREDRAW;
    	principale.lpfnWndProc=MainProc;
    	principale.cbClsExtra=0;
    	principale.cbWndExtra=0;
    	principale.hInstance=hInstance;
    	principale.hIcon=LoadIcon(NULL,IDI_APPLICATION);
    	principale.hCursor=LoadCursor(NULL,IDC_ARROW);
    	principale.hbrBackground=reinterpret_cast<HBRUSH>(COLOR_WINDOW+1);
    	principale.lpszMenuName=NULL;
    	principale.lpszClassName="std";
    	principale.hIconSm=LoadIcon(NULL,IDI_APPLICATION);
    	RegisterClassEx(&principale);
     
    	HWND hWnd;
    	hWnd=CreateWindowEx(
    		WS_EX_CLIENTEDGE,
    		"std",
    		"Notre fenêtre",
    		WS_OVERLAPPEDWINDOW,
    		CW_USEDEFAULT,
    		CW_USEDEFAULT,
    		CW_USEDEFAULT,
    		CW_USEDEFAULT,
    		NULL,
    		NULL,
    		hInstance,
    		NULL
    		);
    	ShowWindow(hWnd,SW_SHOW);
     
    	MSG msg;
    	while(GetMessage(&msg,NULL,0,0)==TRUE)
    	{
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);
    	}
    	return 0;
    }
     
    LRESULT CALLBACK MainProc(HWND hWnd, UINT mes, WPARAM wParam, LPARAM lParam)
    {
    	HDC hDC;
    	PAINTSTRUCT paintst;
    	switch (mes)
    	{
    	case WM_PAINT:
    		hDC=BeginPaint(hWnd,&paintst);
    		EndPaint(hWnd,&paintst);
    		return 0;
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		return 0;
    	default:
    		return DefWindowProc(hWnd, mes, wParam, lParam);
    	}
    }
    En tout cas je vous remercie pour les éléments de réponse que vous pourriez m’apporter!

    Julien

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 071
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 071
    Points : 12 116
    Points
    12 116
    Par défaut
    Ajouter une IHM dans un programme existant, la seule méthode viable, c'est de lire la documentation du dit programme pour suivre la méthode recommandée.
    Chaque bibliothèque graphique, même Win32, demande beaucoup de prérequis, que le programme hôte peut ne pas respecter.

  3. #3
    Membre à l'essai
    Femme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Avril 2016
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 38
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo

    Informations forums :
    Inscription : Avril 2016
    Messages : 8
    Points : 11
    Points
    11
    Par défaut
    Merci pour la réponse.

    Malheureusement il n'y a rien dans la documentation. La chose chose qui y figure est ceci :

    Among other things, X-Tensions allow you to:
    ...
    and do practically everything else that is possible with a Windows program! (thanks to the Windows API)
    et ceci :

    Please note that all HANDLE variables for evidence objects, volumes, files, and directories and only valid handles in the context of this API. These handles cannot be used in conjunction with Windows API functions. Handles that are not available are initialized with 0.

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 071
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 071
    Points : 12 116
    Points
    12 116
    Par défaut
    J'espère que c'est juste vous qui avez lu un peu trop hâtivement la documentation.

    Vérifiez qu'il n'y a pas d'exemple proche de votre besoin dans la documentation.

    S'il n'y en a pas, c'est qu'ils n'ont vraisemblablement pas pensé à votre cas d'utilisation.

    Vous allez donc devoir cohabiter avec un truc que vous ne connaissez même pas ?

    Le plus "safe", c'est d'éviter au maximum les interférences avec l'application hôte.

    Vous devez avoir une fonction "DllMain" dans votre Dll, mais je vous conseille de ne pas vous en servir dans un premier temps, car le contexte d'appel de cette fonction est assez particulier.
    Je vous "conseille", c'est de créer votre propre thread d'affichage avec sa pompe à message autonome dès que possibles (dans "XT_Init" ?).
    Tous les affichages se feront dans ce thread et pas dans le thread utilisé lors de l'appel par le programme hôte de vos méthodes.

    En n'utilisant pas le thread de l'hôte, vous ne devriez pas perturber son affichage propre.

  5. #5
    Membre à l'essai
    Femme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Avril 2016
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 38
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo

    Informations forums :
    Inscription : Avril 2016
    Messages : 8
    Points : 11
    Points
    11
    Par défaut
    Merci encore une fois.

    Malheureusement je connais bien la doc, disons qu'elle est un peu particulière .

    En fait il y a plusieurs exemples, mais le seul qui fait appel à Windows API n'est pas livré avec le code source!

    Je vais me pencher sur votre conseil et je vous donne des nouvelles!

  6. #6
    Membre à l'essai
    Femme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Avril 2016
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 38
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo

    Informations forums :
    Inscription : Avril 2016
    Messages : 8
    Points : 11
    Points
    11
    Par défaut
    J'ai créé ce simple thread ça fonctionne plutôt bien (parfois le logiciel plante quand je quitte la box, je vois pas trop pourquoi pour l'instant), je vais continuer sur cette piste.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    DWORD WINAPI CreateMessageBox(LPVOID lpParam) {
    	MessageBoxA(NULL, (char*)lpParam, "Test", MB_OK);
    	return 0;
    }
     
    ///////////////////////////////////////////////////////////////////////////////////
    // XT_Init = fonction lancée en premier après le démarrage de l'X-Tension
     
    LONG __stdcall XT_Init(DWORD nVersion, DWORD nFlags, HANDLE hMainWnd, void* lpReserved)
    {
     
    	XT_RetrieveFunctionPointers();
     
    	// messages d'accueil /
    	XWF_OutputMessage(L"INIT --- INIT --- INIT", 0);
     
    	HANDLE monThread = CreateThread(NULL, 0, &CreateMessageBox, "Bienvenue dans le plugin", 0, NULL);
     
    	return 1;
     
    }

  7. #7
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 071
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 071
    Points : 12 116
    Points
    12 116
    Par défaut
    Il dit quoi le débogueur ???

  8. #8
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Attention, un programme qui échoue parfois est un programme avec un soucis dangereux et délicat.

    En effet, la plupart des soucis aléatoires (parfois appelé heisenbug) sont des problèmes de pointeurs gardés trop longtemps (dangling pointer et dangling reference).
    Ces problèmes peuvent provoquer n'importe quoi, y compris rien.
    Ils ont d'ailleurs tendance à ne provoquer des catastrophes qu'après mise en production, chez le client, ou quand enfin on dit "ca y est c'est terminé".

    La partie délicate du problème, c'est qu'en général, la solution passe par du nettoyage/refactoring, et que dans ce domaine, le plus tôt on s'y met, le moins c'est long.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  9. #9
    Membre à l'essai
    Femme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Avril 2016
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 38
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo

    Informations forums :
    Inscription : Avril 2016
    Messages : 8
    Points : 11
    Points
    11
    Par défaut
    Au niveau compilation il n'y a aucun problème.

    Je pense avoir trouvé la cause :

    Le programme principal charge le .dll et exécute toutes les fonctions de façon séquentielle puis il le décharge automatiquement.

    Si l'utilisateur n'a pas cliqué sur ok (ou la croix) pour quitter la fenêtre gérée par mon thread avant la fin de la séquence, alors le logiciel plante car il n'a plus accès à la ressource.

    Effectivement je suis bien d'accord parfois n'est pas acceptable surtout quand on le sait .

  10. #10
    Membre chevronné Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 043
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 043
    Points : 2 234
    Points
    2 234
    Par défaut
    J'ai créé ce simple thread ça fonctionne plutôt bien (parfois le logiciel plante quand je quitte la box, je vois pas trop pourquoi pour l'instant), je vais continuer sur cette piste.
    Je dirais que ca plante car tu ne passe pas le HANDLE ( premier parametre de MessageBoxA ). Pour info, sous Qt utiliser MessageBox(API Win32) sans passer le HANDLE à le même effet ( Qt utilise des threads dans certains cas ).

    Quel est l'erreur ? car tu dis ca marche pas mais Ou? Quand? Comment? Retour de fonction? As tu debugger? si oui dis nous quel fonction retourne une erreur.

    Edit : et le fait de decharger le DLL n'arrange pas non plus les choses.
    Homer J. Simpson


  11. #11
    Membre à l'essai
    Femme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Avril 2016
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 38
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo

    Informations forums :
    Inscription : Avril 2016
    Messages : 8
    Points : 11
    Points
    11
    Par défaut
    Bonjour! Merci pour votre aide.

    Une des difficultés c'est qu'effectivement je n'ai pas accès à la fonction WinMain implémentée dans le programme principal.

    J'ai passé beaucoup de temps à faire des tests avec Windows API et finalement j'ai trouvé ce bout de code qui fonctionne très bien (la différence c'est que je ne défini pas WinMain dans mon code) :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
     
    #include <Windows.h>
     
    #define Bouton1 500 // identificateur pour bouton 1
    #define Bouton2 501 // identificateur pour bouton 2
    #define Quitter 502 // identificateur pour bouton quitter
     
    HINSTANCE hInstance;
    HWND hstatic;
     
    LRESULT CALLBACK DialogProc(HWND,UINT ,WPARAM ,LPARAM );
     
    int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
    {
        HGLOBAL hmem; //handle mémoire globale
        LPDLGTEMPLATE lpdt; //pointeur sur structure dialog template
        LPWORD lpw; // pointeur sur un WORD
        LPWSTR lpnom; // pointeur sur chaine UNICODE pour le nom de la boite
     
        //allouer de la mémoire  pour notre dialog template
        hmem = GlobalAlloc(GPTR, 512); //GPTR=taille fixe initialisée à 0
        if (!hmem) return 1;
     
        //convertir le handle en pointeur DLGTEMPLATE sur le début de la mémoire allouée  
        lpdt = ( LPDLGTEMPLATE) hmem;
     
        // Définir les propriétés de la boite de dialogue
        lpdt->style = WS_POPUP | WS_BORDER |WS_MINIMIZEBOX| WS_SYSMENU | DS_MODALFRAME | WS_CAPTION;
        lpdt->x = 10;   //position x
        lpdt->y = 10;   //position y
        lpdt->cx = 300; //largeur
        lpdt->cy = 200; //hauteur
     
        //obtenir pointeur juste après la structure DLGTEMPLATE
        lpw = (LPWORD) (lpdt + 1);
     
        //obtenir pointeur sur la zone du nom de la boite de dialogue
        lpnom = (LPWSTR) lpw+2;
     
        //convertir le nom en UNICODE et le mettre dans la zone nom
        MultiByteToWideChar (CP_ACP, 0, "Ma Boîte de Dialogue", -1, lpnom, 128);
     
        // lancer la boite de dialogue
        DialogBoxIndirect(hInstance,lpdt,NULL,(DLGPROC)DialogProc);
     
        // libération de la mémoire allouée
        GlobalFree(hmem);
     
         return 0;
    }
     
    LRESULT CALLBACK DialogProc(HWND Dlg,UINT message,WPARAM wParam,LPARAM lParam)
    {
         HWND hbouton1,hbouton2,hcadre,hquitter;
         switch(message)
         {
     
         case WM_INITDIALOG:
             {
                 // Creer les boutons, le cadre et la zone de texte
                 hbouton1 = CreateWindow("BUTTON", "Bouton 1", WS_CHILD | WS_VISIBLE , 180, 190,80, 30, Dlg, (HMENU)Bouton1, hInstance, 0);
                 hbouton2 = CreateWindow("BUTTON", "Bouton 2", WS_CHILD | WS_VISIBLE , 330, 190,80, 30, Dlg, (HMENU)Bouton2, hInstance, 0);
                 hstatic    = CreateWindow("STATIC", 0, WS_CHILD | WS_VISIBLE , 200, 130,250, 30, Dlg, 0, hInstance, 0);
                 hcadre  = CreateWindow("BUTTON", "Cliquez sur un bouton :", WS_CHILD | WS_VISIBLE | BS_GROUPBOX, 100, 70,400, 180, Dlg, 0, hInstance, 0);
                 hquitter = CreateWindow("BUTTON", "Quitter", WS_CHILD | WS_VISIBLE , 260, 320,80, 30, Dlg, (HMENU)Quitter, hInstance, 0);
                 return 0;
             }
     
        case WM_CLOSE: //clic sur la croix de fermeture
            {
             EndDialog(Dlg,0);
            }
     
        case WM_COMMAND:    
            {
             switch(LOWORD(wParam))
             {
                     case Bouton1: //clic sur le bouton 1
                     {
                         SetWindowText(hstatic,"Vous avez cliqué sur le bouton 1");
                         break;
                     }
                     case Bouton2: //clic sur le bouton 2
                         {
                        SetWindowText(hstatic,"Vous avez cliqué sur le bouton 2");
                        break;
                         }
                     case Quitter: //clic sur le bouton Quitter
                         {
                             EndDialog(Dlg,0);
                         }
             }
            }   
            break;
         }
    return 0;
    }
    En fait je fais simplement appel aux fonctions de l'API Windows et ça se passe très bien (pas de conflit entre les fenêtres du logiciel et les miennes).

  12. #12
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 071
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 071
    Points : 12 116
    Points
    12 116
    Par défaut
    Attention, avec une boite de dialogue modale ("DialogBoxIndirect"), vous faites un espèce d'hold-up sur la gestion des messages Windows.
    Cela limite considérablement les possibilités d'IHM et cela peut mener à des dysfonctionnements car l'application hôte n'a vraisemblablement pas été conçu pour subir ce type de hold-up?

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Utilisation d'un Thread dans une DLL
    Par colorid dans le forum Langage
    Réponses: 7
    Dernier message: 14/03/2009, 11h05
  2. Utilisation d'un activex dans une dll mfc
    Par regdobey dans le forum MFC
    Réponses: 2
    Dernier message: 20/11/2008, 13h19
  3. [COM] utiliser la librairie standard dans une dll COM
    Par kacedda dans le forum Visual C++
    Réponses: 5
    Dernier message: 13/03/2008, 14h57
  4. [VBscript] Comment utiliser les windows API en vbs
    Par daniel_gre dans le forum VBScript
    Réponses: 3
    Dernier message: 21/05/2007, 18h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo