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

FAQ VC++ et MFCConsultez toutes les FAQ

Nombre d'auteurs : 20, nombre de questions : 545, dernière mise à jour : 5 avril 2013  Ajouter une question

 

Cette faq a été réalisée pour répondre aux questions les plus fréquement posées sur le forum Développement Visual C++

Je tiens à souligner que cette faq ne garantit en aucun cas que les informations qu'elle contient sont correctes ; Les auteurs font le maximum, mais l'erreur est humaine. Si vous trouvez une erreur, ou si vous souhaitez devenir redacteur, lisez ceci.

Sur ce, je vous souhaite une bonne lecture. Farscape

SommaireDLL (13)
précédent sommaire suivant
 

Après avoir lancé AppWizard trois choix possibles sont disponibles à partir du choix MFC AppWizard DLL :

  • Regular dll with MFC staticaly linked.
  • Regular dll with using shared MFC DLL
  • MFC extension DLL (using shared MFC DLL)

Les deux premiers sélectionnent le mode de travail avec les MFC :
une DLL normale liée de manière statique aux MFC et une DLL normale liée de manière dynamique aux MFC (shared MFC DLL)
La troisième solution correspond à la construction d'une DLL d'extension des MFC.

Regular dll with MFC staticaly linked :
La construction d'une DLL liée de manière statique aux MFC permettra l'utilisation de celle-ci quelque soit le programme : WIN32 ou autre qu'il fasse appel ou non aux MFC ,l'inconvénient :la taille de la DLL étant donné que le code des MFC est incorporé dedans .

Regular dll with using shared MFC DLL:
La construction d'une DLL liée de manière dynamique aux MFC peut aussi être utilisée par tout programme WIN32 ou autre par contre la présence des DLL liées aux MFC sera exigée dans l'environnement d'exécution.

L'option sélectionnée ici sera une DLL avec les MFC en DLL partagées.
Après génération du projet par AppWizard il ne reste plus qu'à écrire les fonctions dans la DLL.

Dans mon exemple la définition sera dans le fichier interface.h et le code dans interface.cpp.

Code C++ : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// interface.h 
#ifdef _WINDLL 
#define DLLDEC __declspec(dllexport) 
#else 
#define DLLDEC __declspec(dllimport) 
#endif 
#ifdef __cplusplus 
extern "C" 
{ 
#endif 
DLLDEC void TestDll(); 
#ifdef __cplusplus 
} 
#endif
Code C++ : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
// interface.cpp 
#include "stdafx.h" 
#include "interface.h" 
  
#define WM_TEST WM_USER+100 
  
void TestDll() 
{ 
    CFrameWnd *pFrame=(CFrameWnd *)AfxGetMainWnd(); 
    CView *pView=pFrame->GetActiveView(); 
    pView->PostMessage(WM_TEST); 
}

Pour exporter une fonction d'une DLL il faut employer le mot clef dllexport conjointement avec le mot clef__declspec.

L'exemple ci-dessus permet d'exporter la fonction TestDll , celle-ci sera disponible aussi bien dans un source C++ ou C grâce à l'utilisation de la commande extern "C".

Il ne reste plus qu'à compiler, linker l'ensemble et à placer la DLL dans le répertoire d'exécution du programme appelant.

Insertion de la DLL dans un projet :
Il faudra rajouter dans le fichier testdll.lib dans l'onglet link du projet. Project Settings onglet link.
Et ajouter le fichier interface.h pour utiliser les fonctions de la dll.

Mis à jour le 5 avril 2013 farscape

Dans quels cas utiliser une DLL de ressources ?
A chaque fois que l'on voudra avoir un programme avec une interface multilingue, ou, par exemple s'adapter à une résolution d'écran :une dll de ressources pour la résolution 800*600 .

Procédure pour créer une DLL de ressources :

Après avoir lancé AppWizard choisir l'option :Win32 dynamic link Library .
Ensuite prendre l'option an empty DLL project.
Insérer le fichier ressource.h et le fichier .rc dans le projet.

Réglages des options de construction de la DLL :
Project setting onglet link :
Cocher les options :

  • Doesn't produce.lib
  • Ignore all default libraries

Et rajouter dans la partie project options : /noentry pour éviter d'avoir une référence à la fonction _main au link.

Compiler et linker.

Mis à jour le 5 avril 2013 farscape

1ere étape, Dans la "ResourceView" :

Dans l'onglet "ResourceView" de VC, choisir par exemple une boîte de dialogue, faire bouton droit "insert copy".
Il apparaît alors une boîte de dialogue demandant le langage pour lequel la copie va être affectée.
Imaginons que l'on choisisse "English (UK)" dans le combo, il faut saisir dans l'EditBox dessous une valeur pour le compilateur (pour savoir quelle ressource il va linker dans l'exe) par exemple "_ENG".
Ensuite évidement il faut traduire la ressource.

Il faut faire de même avec toutes les ressources.

Remarque :
Pour la string table il faut faire aussi"insert copy", on choisit la langue mais on ne saisit pas de condition.
On traduit les textes mais là (va savoir pourquoi), le compilo link toutes les stringtable et Windows ira chercher la StringTable de l'exe correspondant à son langage .

Bref, La stringTable est très interessante pour les messagebox :

Dans le Code on fait:

Code c++ : Sélectionner tout
1
2
3
4
5
6
7
  
CString Message;  
Message.LoadString(IDS_TASTRING_POUR_CE_MESSAGE);  
//IDS_TASTRING_POUR_CE_MESSAGE est l'id d'une string qui sera en français 
// dans la StringTable Française (et donc sur un Windows Français)  
//et en Anglais dans la StringTable en Anglais( et donc sur un Windows Anglais)  
//ça évite de dupliquer le code de faire 2 worspace ou d'avoir des surprise sur des Messagebox...
2eme étape la configuration du Workspace : Ensuite c'est là que ça devient intéressant il faut configurer le Workspace:

Dans le menu BUILD->Configurations
S'ouvre une boîte de dialogue :
Cliquer sur Add et la rajouter une debug par exemple Debug_ENG et une release : Release_ENG

Enfin taper Alt+F7 ou Menu Projects->Settings
Choisir par exemple le projet Release_ENG

Dans l'onglet "Ressource"

Dans le combo "Language" choisir la langue ici English (UK) et dans l'EditBox "Preprocessor Definition" rajoute",_ENG"
Ainsi seront linké dans l'exe que les ressources avec la condition _ENG

2eme remarque :
du coup il faut faire pareil avec la version Française (Condition _FRA par exemple)

Si l'on teste l'exe anglais sur un windows français on verra que les menus, les messagebox sont française, car les deux versions de la stringtable sont dans l'exe et windows choisit la plus apropriée à la version de Windows .

Bilan :

Il n'y as pas vraiment d'avantages ou d'inconvéniant par rapports aux DLL de resources, si ce n'est que l'Executable peut être plus lourd car si vous faites beaucoup de version il aura toutes les StringTables (pas les boites de dialogues).
C'est une question de goût on va dire...

Mis à jour le 4 avril 2005 matazz

On utilisera le stockage des ressources dans une DLL pour chaque langue.
Exemple :
Dans un projet existant dont les ressources sont en Anglais on veut implémenter les mêmes ressources mais en Français.

Procédure :
Dans le projet principal on appelle AppWizard pour la création d'un nouveau projet en utilisant l'option add to curent workspace.
Choisir l'option Win32 dynamic link Library .
Donner un nom à la DLL qui correspondra à la langue implémentée Exemple :ResDllFr
Ensuite prendre l'option an empty DLL project.

Réglages des options de construction de la DLL :
Project setting onglet link :
Cocher les options :

  • Doesn't produce.lib
  • Ignore all default libraries

Et rajouter dans la partie project options :/noentry pour éviter d'avoir une référence à la fonction _main au link.

Copier à partir du projet principal dans le répertoire de la DLL:
Le fichier ressource.h et le fichier .rc .
Copier aussi le répertoire res.

Procédure sous .NET:
Dans l'explorateur de projet (solution) faire click droit :
Ajouter / nouveau projet
Sélectionner le type de projet win32
Sélectionner le répertoire du projet principal
Donner un nom à la DLL qui correspondra à la langue implémentée Exemple :ResDllFr
Faire ok
Sélectionner paramètres de l'application
Cocher DLL et projet vide.
Valider avec le boutonterminer

Réglages des options de construction de la DLL :
Sur le nouveau projet faire click droit propriétés :
Sélectionner le chapitre éditeur de liens :
Option avancée :
Dans la rubrique DLL de ressource uniquementmettre oui
Option Entrée :
Dans la rubrique Toutes les bibliothèques par défaut ignorées mettre oui

Copier à partir du projet principal dans le répertoire de la DLL:
Le fichier ressource.h et le fichier .rc .
Copier aussi le répertoire res.
Ajouter par l'option ajouter un élément existant le .rc et le fichier ressource.h au projet .
Traduire les ressources dans la langue appropriée.
Compiler linker la DLL.

Sélection de la DLL dans le programme principal :
Dans la fonction InitInstance de la classe d'application on lira la DLL concernée :

Code c++ : Sélectionner tout
1
2
3
4
5
6
7
  
    m_bFrenchRes=(GetProfileInt("Language","SetInFr",0)==1); 
    if(m_bFrenchRes) 
    { 
        HINSTANCE dll=LoadLibrary("ResDllFr.dll"); 
        if(dll)  AfxSetResourceHandle(dll); 
    }
Dans la fonction ExitInstance on libèrera les ressources:

Code c++ : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  
int CTestResDllApp::ExitInstance()  
{ 
        // TODO: Add your specialized code here and/or call the base class 
        // recuperation du handle de ressource. 
        HMODULE hDLL = AfxGetResourceHandle(); 
        // comparaison avec le handle de l'instance 
        if (hDLL != AfxGetInstanceHandle()) 
        { 
             // si le handle des ressources est <> du handle de l'instance  
             // c'est que les ressouces sont externes ! 
             // restitution et liberation finale. 
             AfxSetResourceHandle(AfxGetInstanceHandle()); 
             FreeLibrary(hDLL); 
        } 
        return CWinApp::ExitInstance(); 
}

Mis à jour le 20 janvier 2005 farscape

Une DLL d'extensions permet l'export de classes complètes que le client peut instancier et même dériver.
Note : L'utilisation d'une DLL d'extensions impose l'utilisation des MFC en DLL partagées.

Comment procéder :
Au lancement de AppWizard par le menu file new Project.
Sélectionner l'option MFC AppWizard(dll)
Puis l'option MFC extension DLL (using shared MFC DLL).

Le squelette de la DLL est généré il ne reste plus qu'à implémenter les différentes classes en rajoutant la macro AFX_EXT_CLASS devant chaque nom de classe à exporter, comme dans l'exemple ci-dessous :

Code c++ : Sélectionner tout
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
  
///////////////////////////////////////////////////////////////////////////// 
// CMyListBox window 
class AFX_EXT_CLASS CMyListBox : public CListBox 
{ 
// Construction 
public: 
CMyListBox(); 
  
// Attributes 
public: 
  
// Operations 
public: 
  
// Overrides 
// ClassWizard generated virtual function overrides 
//{{AFX_VIRTUAL(CMyListBox) 
//}}AFX_VIRTUAL 
  
// Implementation 
public: 
virtual ~CMyListBox(); 
  
// Generated message map functions 
protected: 
//{{AFX_MSG(CMyListBox) 
// NOTE - the ClassWizard will add and remove member functions here. 
//}}AFX_MSG 
  
DECLARE_MESSAGE_MAP() 
};
Une fois la DLL compilée et linkée :
On utilisera le même include pour la définition des classes exportées dans la DLL et l'application MFC .
Le .lib de la DLL devra être rajouté au link de l'application MFC.

Mis à jour le 5 avril 2013 farscape

Pour sortir proprement du programme il ne faut surtout pas faire exit(0) à partir de la DLL mais faire la demande de fermeture sur le thread principal du programme .
Il suffira d'envoyer la commande suivante à partir de la DLL :

Code c++ : Sélectionner tout
1
2
  
AfxGetMainWnd()->PostMessage(WM_SYSCOMMAND,SC_CLOSE,0);

Mis à jour le 5 avril 2013 farscape

La distribution des DLL partagées pour une application Visual VC6.0 est nécessaire pour les systèmes antérieurs à Windows 2000 .
Les principales DLL sont à jour sur les systèmes récents.

Pour infos voici la liste des principales DLL concernées :

  • MFC42.DLL
  • MSVCRT.DLL

et éventuellement :

  • MSVCP60.DLL
  • NTDLL.DLL
  • MSVCIRT.DLL

il est à noter que la mise à jour de IE 5 ou 6.0 mets à jour un grand de composant sur ces systèmes....

Néanmoins pour distribuer une application en DLL partagées on dispose d'un utilitaire VCREDIST.EXE
consulter la note d'informations MSDN à ce sujet : Redistributing Microsoft Visual C++ 6.0 Applications

Note :VCREDIST.EXE est mis à jour avec la distribution du service pack de Visual 6.0 ,on le trouve généralement dans le répertoire : FRENCH\VS60SP5\VC98\REDIST\VCREDIST.EXE pour le SP5 .

Mis à jour le 5 avril 2013 farscape

En théorie, seuls les types de base sont passables d'une DLL C++ à VB:

Un petit résumé provenant de l'aide de VC++ et VB sur les types de Base :

EN VB :

Byte 1 byte 0 to 255
Boolean 2 bytes True or False
Integer 2 bytes -32,768 to 32,767
Long (long integer) 4 bytes -2,147,483,648 to 2,147,483,647
Single(single-precision floating-point) 4 bytes
Double (double-precision floating-point) 8 bytes
EN C++ :

char, unsigned char, signed char 1 byte
short, unsigned short 2 bytes
int, unsigned int 4 bytes
long, unsigned long 4 bytes
float 4 bytes
double 8 bytes
long double 1 8 bytes
Conclusion :
C++ VB
char byte
bool Boolean
short Integer
int Long
long Long ou rien
float Single
double Double
Résumé :
Une fonction déclarée en C++ comme suit :

Code c++ : Sélectionner tout
bool TestVB_Cpp(int Entier, double Reel, char Caractere, char* Chaine)
peut être récupérée en VB par la methode suivante :

Code c++ : Sélectionner tout
1
2
Public Declare Function TestVB_Cpp Lib "MaDLL.dll"  
(ByVal Entier As Long, ByVal Reel As Double, ByVal Caractere As Byte, ByVal Chaine As String) As Boolean
En pratique il existe un moyen détourné de manipuler des objets d'une classe C++ d'une DLL depuis VB :

En effet une adresse mémoire étant stockée sur 4 BYTES, on peut déclarer en C++ un pointeur de ce que l'on veut et le récupérer en VB grace à une variable déclarée en ByRef Long.
Par exemple, on peut manipuler les fonctions BMP du GDI
J'avais trouvé ça sur internet sachant que "&H" en VB correspond à "0x" de C++.

La structure BITMAP C++ correspond en VB à :

Code vb.net : Sélectionner tout
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
  
'**********BITMAP****************  
Public Const SRCCOPY = &HCC0020  
Public Const DIB_RGB_COLORS = 0  
  
  
Public Type BITMAP  
    biSize As Long  
    biWidth As Long  
    biHeight As Long  
    biPlanes As Integer  
    biBitCount As Integer  
    biCompression As Long  
    biSizeImage As Long  
    biXPelsPerMeter As Long  
    biYPelsPerMeter As Long  
    biClrUsed As Long  
    biClrImportant As Long  
End Type  
'**********WAPI****************  
Public Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long  
Public Declare Function GetObject Lib "gdi32" Alias  
                 "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long  
Public Declare Function GetBitmapBits Lib "gdi32"  
                (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long  
Public Declare Function SetBitmapBits Lib "gdi32" 
                 (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long
Sachant que la structure VB BITMAP correspond à ceci en C++

Code c++ : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  
typedef struct tagBITMAPINFOHEADER{ // bmih  
    DWORD  biSize;  
    LONG   biWidth;  
    LONG   biHeight;  
    WORD   biPlanes;  
    WORD   biBitCount  
    DWORD  biCompression;  
    DWORD  biSizeImage;  
    LONG   biXPelsPerMeter;  
    LONG   biYPelsPerMeter;  
    DWORD  biClrUsed;  
    DWORD  biClrImportant;  
} BITMAPINFOHEADER;
Conclusion : Avec une DLL C++ contenant une Classe, VB peut manipuler un pointeur sur un objet de cette classe et le passer à des fonctions globales de la DLL.
Par contre il n'existe pas à ma connaissance de moyen d'exporter un Objet C++ avec ces méthodes afin que VB puisse les appeler depuis une DLL. La seule solution est un ActiveX.

Mis à jour le 5 avril 2013 matazz

Pour définir l'accès procéder comme suit :
Dans le menu view option ressources includes.
Rajouter l'include des ressources contenant les définitions des identifiants de la DLL à la suite de la ligne

Code c++ : Sélectionner tout
1
2
3
  
#include "afxres.h" 
#include "MyLibres.h" // ressources DLL
Dans la seconde partie de la boîte de dialogue rajouter la référence au fichier .rc de la DLL à la suite des définitions existantes :

Code c++ : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  
#define _AFX_NO_SPLITTER_RESOURCES 
#define _AFX_NO_OLE_RESOURCES 
#define _AFX_NO_TRACKER_RESOURCES 
#define _AFX_NO_PROPERTY_RESOURCES 
  
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRA) 
#ifdef _WIN32 
LANGUAGE 12, 1 
#pragma code_page(1252) 
#endif //_WIN32 
#include "res\TestMdi.rc2"  // non-Microsoft Visual C++ edited resources 
#include "l.fra\afxres.rc"          // Standard components 
#include "l.fra\afxprint.rc"        // printing/print preview resources 
#endif 
  
#include « MyLib.rc »   // fichier ressources DLL
Sauvegarder et recompiler les ressources.

Mis à jour le 4 avril 2005 farscape

Voici un petit rappel pour ce qui est d'une dll normale ou régulière liée de manière dynamique aux MFC
Citation MSDN:
Une DLL normale liée de manière dynamique aux MFC est une DLL qui utilise les MFC en interne,
et les fonctions exportées de la DLL peuvent être appelées par des exécutables MFC ou non-MFC.
Comme son nom l'indique, ce type de DLL est généré à l'aide de la version bibliothèque de
liaisons dynamiques des MFC (appelée également version partagée des MFC).
Les fonctions sont généralement exportées à partir d'une DLL normale à l'aide de l'interface C standard.
Vous devez ajouter la macro AFX_MANAGE_STATE au début de toutes les fonctions exportées des
DLL normales qui sont liées de manière dynamique aux MFC pour définir l'état du module en cours
comme étant celui de la DLL.
Pour cela, ajoutez la ligne de code suivante au début des fonctions exportées à partir de la DLL :

Code c++ : Sélectionner tout
1
2
  
AFX_MANAGE_STATE(AfxGetStaticModuleState( ))

Une dll normale ou régulière possède un objet CWinApp comme n'importe quel module exe MFC.
Si nous voulons obtenir l'objet application dans le module exe nous faisons

Code c++ : Sélectionner tout
1
2
3
4
  
CDuplicataApp* pTheApp = static_cast<CDuplicataApp*>(AfxGetApp());   
ATLASSERT(pTheApp); 
//...

où Duplicata est le module exe.

Comment obtenir ce même pointeur dans une dll régulière tout en sachant qu'un appel à AfxGetApp()
retourne le CWinApp de la dll.

Voici comment nous pouvons procéder:
Duplicata est un module exe et
Duplicata.Data est une dll régulière liée dynamiquement aux MFC.

Dans ce genre de dll, toute fonction exportée doit inclure la macro

Code c++ : Sélectionner tout
1
2
  
AFX_MANAGE_STATE(AfxGetStaticModuleState( ))
au début de la définition de la fonction afin que les MFC puissent définir l'état du module en cours.

Voici du code.

Code c++ : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  
INT_PTR WINAPI ShowQuerySheet(UINT iSelectedPage, bool& bMultiSelectedQueryPage)   // est une fonction exportée de Duplicata.Data.dll 
{ 
    // Obtient le CWinApp de l'exécutable donc Duplicata.exe et non de Duplicata.Data.dll 
    // car l'appel à AfxGetApp() précède AFX_MANAGE_STATE(AfxGetStaticModuleState()) 
  
    CDuplicataApp* pTheApp = static_cast<CDuplicataApp*>(AfxGetApp());   // je suis dans le context du module exe 
    ATLASSERT(pTheApp); 
  
    AFX_MANAGE_STATE(AfxGetStaticModuleState());    // MFC définit l'état du module en cours 
  
        // Obtient le CWinApp de la dll donc Duplicata.Data.dll et non de Duplicata.exe 
    // car l'appel à AfxGetApp() est postérieur à AFX_MANAGE_STATE(AfxGetStaticModuleState()) 
  
        CDuplicataDataApp* pTheDll = static_cast<CDuplicataDataApp*>(AfxGetApp());  // je suis dans le context du module de la dll 
    ATLASSERT(pTheDll); 
  
        // maintenant dans le code de ma dll, je travaille à la fois avec pTheApp et pTheDll 
        // obtenu à l'aide du seul appel de AfxGetApp() dans des états de modules différents. 
        // ... 
}

En demeurant dans le contexte du module exe, avant que MFC rétablisse l'état du module en cours, nous pouvons récupérer
le CWinApp du module exe mais nous ne pouvons utiliser aucun objet de la dll.
Mais une fois que l'état du module en cours est rétabli, alors les objets de la dll sont maintenant disponibles et
à l'aide du même AfxGetApp() nous obtenons le CWinApp de la dll.
Les pointeurs obtenus sont valides et vous pouvez le vérifier avec le débogueur.
Dans le cas d'une dll MFC d'extension nous n'avons pas ce problème de changement de contexte de module d'état
avec AFX_MANAGE_STATE car le CWinApp est unique et est celui du module exe.

Mis à jour le 22 janvier 2007 Gabrielly

Avec Visual 2005 les dll concernant la bibliothèque CRT et MFC ont changé.
De ce fait la plupart des PC récents ne disposent pas des fichiers requis pour exécuter les programmes construits avec Visual 2005.
Vous trouverez sur ce lien l'accès à un setup permettant de distribuer les DLL sur un PC cible vcredist_x86.exe
Ce package installe les composants du runtime des bibliothèques C Runtime (CRT), Standard C++, ATL, MFC, OpenMP et MSDIA.
Note : ce fichier est aussi disponible dans l'environnement de développement à l'emplacement suivant :
C:\Program Files\Microsoft Visual Studio8\SDK\v2.0\BootStrapper\Packages\vcredist_x86\vcredist_x86.exe

Si on ne veut pas distribuer de DLL ,il faudra lier statiquement les MFC et sélectionner dans l'onglet C++ / option génération de code / bibliothèque runtime :Multithread (/MT)
Néanmoins il faudra veiller à ne pas mélanger les modes de fonctionnement avec la CRT en Multithread DLL et statique, pour éviter les problèmes sur les libérations d'objets entre modules ou partage de ressources fichiers.

Mis à jour le 22 janvier 2007 farscape

Il y a deux manières de construire une application MFC :

- La plus utilisée c'est d'utiliser les MFC en dll partagée, ce qui implique que la bibliothèque de runtime C (CRT) soit aussi dans ce mode partagé ( Multithread DLL :/MD ).
Avantage : l'exécutable produit est plus léger puisqu'il ne comporte pas les MFC et la dll de la CRT.
Inconvénient : il faut distribuer un ensemble de DLL sur le poste cible.

Il existe plusieurs manières de procéder :



Comment procéder :
Créer un répertoire de distribution en dehors de program file (pour éviter les problèmes sous vista).
Copier son exécutable dedans.
Ensuite copier les fichiers contenus dans les répertoires :
C:\Program Files\Microsoft Visual Studio 9.0\VC\redist\x86\Microsoft.VC90.CRT
Et
C:\Program Files\Microsoft Visual Studio 9.0\VC\redist\x86\Microsoft.VC90.MFC

- La deuxième option de construction du programme consiste à utiliser les MFC dans une bibliothèque statique, la bibliothèque de runtime C (CRT) doit suivre le même mode statique ( Multithread static : /MT ).
Avantage : un exécutable autonome
Inconvénients : taille de l'exécutable non négligeable, surtout si on utilise les nouvelles MFC …
Autre point : difficulté de construction du programme si on dispose d'un ensemble de bibliothèques tierces : il faudra en effet veiller à ce que celles-ci travaillent dans le même mode surtout au niveau de la bibliothèque de runtime C .

Mis à jour le 7 juillet 2008 farscape

En utilisant les méthodes LoadLibrary, GetProcAddress et FreeLibrary.
Exemple pour charger dynamiquement l'API MessageBox :

Code c++ : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  
typedef INT (WINAPI* PFNMESSAGEBOX)(HWND, LPCTSTR , LPCTSTR, UINT); 
static PFNMESSAGEBOX g_pfnMessageBox = NULL; 
  
  
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) 
{ 
   HMODULE hmodUser32 = LoadLibrary(TEXT("USER32")); 
   if (hmodUser32 != NULL) 
   { 
#ifdef UNICODE 
      g_pfnMessageBox = (PFNMESSAGEBOX) GetProcAddress(hmodUser32, "MessageBoxW"); 
#else 
      g_pfnMessageBox = (PFNMESSAGEBOX) GetProcAddress(hmodUser32, "MessageBoxA"); 
#endif       
   } 
   g_pfnMessageBox(NULL, TEXT("Test"), TEXT("Titre"), 0); 
   if (hmodUser32 != NULL) 
      FreeLibrary(hmodUser32); 
    return 0; 
}

Mis à jour le 17 septembre 2007 nico-pyright(c)

Proposer une nouvelle réponse sur la FAQ

Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour ça


Réponse à la question

Liens sous la question
précédent sommaire suivant
 

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 © 2022 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et 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.