IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
logo
Sommaire > IDE ,Environnement de développement
        Que faire si le ClassView n'affiche pas toutes les classes ?
        Pourquoi la complétion automatique ne fonctionne pas ou plus ?
        Comment éviter d'avoir des problèmes avec les « includes » ?
        Comment indiquer l'emplacement des includes externes dans un projet ?
        Comment gérer l'arborescence des sources dans un projet ?
        Comment avoir le browser de code dans un projet Visual ?
        Comment activer l'option RTTI du compilateur?
        Comment sauvegarder le paramétrage de l'environnement Visual 6.0 ?
        Comment construire la librairie wxWidgets avec Visual 6.0 ?
        Comment inclure un fichier ressource d'une librairie dans le projet maître ?
        Comment faire apparaître dans ClassWizard certains messages Windows ?
        Comment désactiver un warning de compilation avec les STL ?
        Comment créer un modèle de projet avec VC 6.0 ?
        Comment créer une bibliothèque statique avec VC.Net ?
        Comment démarrer avec Visual C++ Toolkit 2003 ?
        Pourquoi mon code, pourtant valide, ne compile pas sous Visual C++ 6 ?
        Quelques raccourcis utiles de Visual C++ 6.0
        Comment sont initialisées les variables pointeurs ?
        Comment intégrer des sources C dans un projet C++ ?
        Comment inclure l'appel de l'aide avec un fichier .chm dans un programme MFC ?
        Que faire avec l'erreur de compilation C1010 (en-tête précompilé) ?
        Comment voir des informations de debbuggage/tracage simplement sans gestion avancée de log ?
        Comment augmenter la mémoire réservée par défaut de mon exécutable lors d'un stack overflow ?
        Comment éviter l'erreur la dll msvcr80d.dll est introuvable avec VC 2005 ?
        Comment personnaliser l'affichage des objets dans le débogueur ?
        Comment rajouter une extension de fichier prise en charge comme un .C ?
        Comment gérer la cohabitation de deux fonctions ayant le même nom dans l'API Win32 et le framework.net ?
        Comment lier une bibliothèque statiquement ?
        Comment régler l'édition des liens avec les bibliothèques statiques ?
        Comment demander une élévation des droits de l'application sous vista ?
        Où se procurer le dernier SDK de Visual 6.0 ?
        UAC et virtualisation des accès fichiers sous Vista
        Comment régler l'UAC avec visual 2008 ?
        Restriction de l'usage des classes templates avec les MFC et Visual 2008
        Comment rendre une application compatible terminal serveur ?
        Comment obtenir le chemin Windows virtualisé dans un environnement Terminal Serveur ?
        Comment régler la plateforme de distribution sous Visual 2008 ?



Que faire si le ClassView n'affiche pas toutes les classes ?
auteur : Farscape
Avant toute chose vérifier que les includes des classes sont bien situés dans le dossier «headers files» et non dans le dossier « external dependencies » .
Si ce n'est pas le cas procéder à un glisser déplacer avec la souris des fichiers dans le dossier «headers files».
Pour regénérer le « ClassView » la méthode la plus directe consiste à :

  1. Fermer le projet.
  2. Détruire avec l'explorateur les fichiers : .clw ,.opt ,.ncb situés dans le répertoire du projet.
  3. Ouvrir à nouveau le projet lancer le « ClassView ».
  4. Il détecte l'absence du fichier et vous ouvre alors une boîte de dialogue vous demandant de lui ré indiquer les fichiers sources.
  5. Indiquer le répertoire source du projet.
  6. Valider.
Logiquement on doit recouvrer l'usage de « intellisens » et le « ClassView » doit être opérationnel.


Pourquoi la complétion automatique ne fonctionne pas ou plus ?
Créé le 19/09/2005[haut]
auteur : Farscape
Plusieurs raisons possibles à ce problème :

Les includes des classes concernées ne sont pas dans le dossier header files mais dans le dossier external dependencies.
Solution faire un glisser déplacer des fichiers en question dans le bon dossier.

La ou les classes en questions ont été rajoutées manuellement ou par l'insertion d'un nouveau fichier include dans le projet sans passer par le générateur de classe.
Reconstruire le classview comme indiquer dans la faq :faq Que faire si le ClassView n'affiche pas toutes les classes ?


Comment éviter d'avoir des problèmes avec les « includes » ?
auteur : Farscape
En appliquant la technique suivante :

#ifndef _COOLTOOLBAR_H 
#define _COOLTOOLBAR_H 

class CMyBt; 
class COOlButtonTemplate 
{ 
//.................. 
//............... 
CMyBt *m_pbt; 
}; 

class CMyBt 
{ 
public:
COOlButtonTemplate  m_cooltoolbar;
}; 
#endif //_COOLTOOLBAR_H
Cette disposition permet d'éviter l'inclusion répétée du code du fichier dans un autre fichier.
A la première inclusion, le symbole _COOLTOOLBAR_H est défini, ce qui évite les inclusions supplémentaires du même code.
C'est une procédure standard dans les fichiers .h ,il est conseillé de faire de même dans tous vos fichiers .h pour éviter les problèmes liés à la duplication des définitions.
Visual C++ l'incorpore automatiquement dans tous les fichiers de définitions qu'il crée.
La déclaration « class CMyBt ; » au dessus de la classe « COOlButtonTemplate » permet l'utilisation de la classe avant sa déclaration, très pratique dans le cas où deux classes doivent contenir une variable de la classe voisine de manière croisée comme dans l'exemple ci-dessus.


Comment indiquer l'emplacement des includes externes dans un projet ?
auteur : Farscape
Pour indiquer dans visual l'emplacement des includes externes au projet deux possibilités :
headers de librairies privés:
sélectionner le menu tools / options .
Onglet directories.
Voir les différentes catégories de fichiers avec la combobox "show directories for":
Rajouter les différents chemins.
Headers propres au projet:
Sélectionner le menu : projects / settings .
onglet c++
Catégorie : preprocessor
Rajouter les chemins séparés par des ; dans l'édit "additional includes directories".
Notes :les includes référencés dans les sources du projet apparaissent directement dans le dossier headers files.
Le classview s'appuie sur les headers présents à cet emplacement.
Les autres références externes au projet sont placées automatiquement dans "external dependencies" .
Il est possible de déplacer des headers de ce dossier par glisser déplacer dans le dossier header files pour disposer du classview.
Pour rajouter des fichiers dans un dossier spécifique il faut faire add sur le dossier en question.
Il n'y a pas de limitations sur l'emplacement des fichiers à inclure dans un projet il faut juste veiller à fournir les références pour les headers par l'une des deux méthodes précitées


Comment gérer l'arborescence des sources dans un projet ?
auteur : Farscape
L'arborescence d'un projet Visual n'est pas figée ,
On peut créer des sous répertoires par un click droit avec l'option « new folder » sur le dossier sources ou headers files.
Pensez à récupérer la liste des extensions de fichiers gérée par dossier en faisant click droit propriétés sur un dossier existant (sources ou headers) et procéder par copier coller pour recopier les extensions.
Ensuite il suffira de déplacer les fichiers par glisser déplacer ou de les insérer par un click droit « add files ».
On pourra organiser les sources par thèmes exemple :
Les sources concernant les différents outils,
Les gestions de fichiers,
Les traitements etc ...
On procédera de la même manière pour les « includes »


Comment avoir le browser de code dans un projet Visual ?
auteur : Farscape
Pour disposer du browser de code sélectionner :
Le menu projects option settings puis l'onglet C++ »
Dans la zone category sélectionner listing files .
Puis cocher « generate browse info. ».

Le fichier se construit et suivra l'évolution du projet.
Pour accéder au browser sélectionner le ClassView faire click droit et sélectionner une des trois options :

  • references ;
  • derived classes ;
  • base classes.

Comment activer l'option RTTI du compilateur?
auteur : Farscape
L'option RTTI ou Run-Time Type Information permet l'utilisation du mot clef dynamic_cast . (Voir documentation MDSN)
Pour l'activer sélectionner le menu Projects option Settings Onglet C++ .
Category : C++ Language.
Cocher :Enable Run-Time Type Information (RTTI).


Comment sauvegarder le paramétrage de l'environnement Visual 6.0 ?
auteur : Farscape
L'environnement de Visual 6.0 peut être sauvegardé en exportant la clef suivante de la base de registre:
HKEY_CURRENT_USER\Software\Microsoft\Devstudio\6.0

Pour sauvegarder uniquement les chemins des includes ,des librairies etc ..:
HKEY_CURRENT_USER\Software\Microsoft\DevStudio\6.0\Build System\Components\Platforms\Win32 (x86)\Directories


Comment construire la librairie wxWidgets avec Visual 6.0 ?
auteur : Farscape
Cette librairie était anciennement connue sous le nom wxWindows .

Pour commencer
Il faut télécharger le fichier wxMSW-2.4.2-setup.zip à l'adresse : http://www.wxwidgets.org/

Lancer le Setup .
Dans visual 6.0 faire :
File Open Workspace :
Ouvrir le fichier C:\wxWindows-2.4.2\src\wxWindows.dsp
Ensuite le menu ?project? option ?batch Build? et bouton build.

Rajouter les chemins des librairies et includes dans le menu :
Tools Options Directories :
Path Includes:
C:\wxWindows-2.4.2\include
C:\wxWindows-2.4.2\include\wx

Path Lib:
C:\wxWindows-2.4.2\lib

Un exemple pour faire un essai:
C:\wxWindows-2.4.2\samples\grid\grid.dsw

Enjoy.


Comment inclure un fichier ressource d'une librairie dans le projet maître ?
auteur : Farscape
Au niveau de la librairie :
Attention au départ des numéros d'id des contrôles dans le fichier resources.h
Celui-ci doit être renommé pour éviter les conflits avec le projet maître (voir ci-dessous).

Au niveau du projet maître :
il suffira de rajouter dans le menu :
View - ressources includes :
Dans la première partie de la fenêtre après axfres.h le fichier ressource de la librairie (dont il faudra changer le nom pour éviter les conflits :autre chose que resource.h !)
Exemple ici MyLibRes.h


#include "afxres.h"
#include "MyLibRes.h"


Deuxième partie de la fenêtre:
Il faudra rajouter le fichier .rc de la librairie ici MyLib.rc.

#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
#include "res\MonProjet.rc2"  // non-Microsoft Visual C++ edited resources
#include "l.fra\afxres.rc"          // Standard components
#include "l.fra\afxprint.rc"        // printing/print preview resources
#include "MyLib.rc"
#endif


Et procéder à la compilation des ressources.


Comment faire apparaître dans ClassWizard certains messages Windows ?
auteur : Farscape
Exemple : Prenons le cas d'une fenêtre CDialog où l'on voudrait intercepter le message WM_ACTIVATE.
Il n'apparaît pas par défaut dans la liste des messages de la boîte de dialogue .
Pour y remédier sélectionner l'onglet "Class Info" et mettre dans la liste déroulante "message filter": Windows à la place de Dialog ,revenir ensuite sur l'onglet "message maps" maintenant le message est disponible?


Comment désactiver un warning de compilation avec les STL ?
auteur : Farscape
Lors de la compilation de sources employant les STL on rencontre souvent le Warning C4786 avec un message à rallonge ressemblant à ceci :

warning C4786: 'blablabla ' : identifier was truncated to '255' characters in the debug information

Ce qui est souvent bénin, la solution pour enlever ce Warning est de rajouter la ligne suivante dans stdafx.h

#pragma warning(disable:4786)

Comment créer un modèle de projet avec VC 6.0 ?
auteur : Farscape
Après le lancement de l'option File new, sélectionner l'option Custom AppWizard
Entrer le nom du projet qui servira de modèle dans l'édit Project Name :
Exemple :MyCustomApp.
Valider le choix par le bouton Ok .

Sur le deuxième volet laisser l'option : An existing Projet
Cliquer sur le bouton Next pour choisir le projet source qui servira de modèle de génération.
Valider le choix par le bouton Finish.

Le projet est généré il ne reste plus qu'à le compiler et le linker.
Un nouveau type de projet sera alors disponible dans la boîte de dialogue de création de projets.

Description visuelle du procédé:
http://farscape.developpez.com/Samples/MakeCustomApp.pdf


Comment créer une bibliothèque statique avec VC.Net ?
auteur : Farscape
Il faut choisir le type : projet win32 ,et dans les paramètres application cocher l'option bibliothèque statique.


Comment démarrer avec Visual C++ Toolkit 2003 ?
Créé le 04/04/2005[haut]
auteur : Farscape
Après l'installation du setup il ne reste plus qu'à paramétrer les variables d'environnements liées au compilateur.
La distribution du toolkit fournit un fichier vcvars32.bat qui contient les différentes valeurs qui pourront être inscrites pour plus de souplesse dans les variables d'environnements systèmes :

Pour cela il faut accéder à l'icône système (sous Windows XP ou 2000) située dans le panneau de configuration.
Sélectionner ensuite l'onglet avancé puis le bouton : variables d'environnements sur les variables systèmes.
Modifier ou rajouter les valeurs suivantes du fichier de commandes vcvars32.bat situé dans le répertoire
C:\Program Files\Microsoft Visual C++ Toolkit 2003
Set PATH=C:\Program Files\Microsoft Visual C++ Toolkit 2003\bin;%PATH%
Set INCLUDE=C:\Program Files\Microsoft Visual C++ Toolkit 2003\include;%INCLUDE%
Set LIB=C:\Program Files\Microsoft Visual C++ Toolkit 2003\lib;%LIB%

Voilà il ne reste plus qu'à ouvrir une boîte de commande MSDOS et de tester la construction d'un projet fournit pour exemple dans le toolkit
Ou de lancer la construction par un fichier de commandes directement à partir de l'explorateur windows.


Pourquoi mon code, pourtant valide, ne compile pas sous Visual C++ 6 ?
Créé le 04/04/2005[haut]
auteur : Loulou24
Visual C++ 6 est sorti en 1998, et donc n'inclus pas la dernière norme du C++ , datant de la même année. Il en résulte certains manques, et des résultats parfois étonnants avec du code pourtant parfaitement valide.

Voici quelques exemples de codes standards mais qui ne compilent pas sous VC++ 6
for (int i = 0; i < 50; ++i)
{
   // ...
}

for (int i = 0; i < 20; ++i) // Erreur : "i : redefinition"
{
   // ...
}
Ce code est pourtant correct : en effet la portée de la variable i devrait être limitée au bloc de la boucle concernée.
Une solution (de derrière les fagots) pour corriger ce manque : inclure systématiquement nos boucles dans un if, ainsi la portée sera bien limitée
#define for if (true) for
struct A
{
    static const int Taille = 12; // Erreur : "syntaxe non valide"
    int Tab[Taille];
};
Ce code devrait compiler, car les constantes entières statiques peuvent être initialisées dans leur définition.
struct A
{
    void Func()
    {
    }
};

std::vector<A> Tab;
std::for_each(Tab.begin(), Tab.end(), std::mem_fun_ref(A::Func));

// Erreur : fonction 'void' renvoyant une valeur
Cette écriture devrait être possible, mais VC6 ne sait pas la gérer du fait de son manque de spécialisation partielle de template.
std::set<int> s;
std::vector<int> v(s.begin(), s.end()); // Erreur : "conversion impossible"

std::list<int> l;
l.sort(std::less<int>()); // Erreur
VC6 ne gère pas correctement les fonctions membres template de classe template, ce qui entre autre vous empêchera d'utiliser les fonctions de la STL prenant en entrée une paire d'itérateurs quelconques, ou list::sort avec un foncteur personnalisé.


Quelques raccourcis utiles de Visual C++ 6.0
Créé le 19/09/2005[haut]
auteur : nico-pyright(c)
Touche Action
CTRL+F2 marquer une ligne / F2 : passer à la marque suivante
ALT+F8 indentation de la sélection
CTRL+E identifier les accolades, parenthèses, crochets
CTRL+Espace complétion automatique
CTRL+SHIFT+Espace prototype de la fonction
F4 aller à la 1ere erreur de compilation, puis erreur suivante

Comment sont initialisées les variables pointeurs ?
Créé le 19/09/2005[haut]
auteur : Farscape
Le compilateur suivant les cas à l'exécution peut affecter des valeurs spécifiques à une variable pointeur, Connaître ces valeurs peut s'avérer fort utile en mode Debug :

0xFDFDFDFD indique une adresse en dehors de l'espace d'adressage du processus.
0xDDDDDDDD indique que la mémoire vient d'être libérée.
Attention ça ne veut pas dire que l'instruction delete va mettre cette valeur dans un pointeur.
0xCDCDCDCD mémoire globale non initialisée par exemple un pointeur membre d'une classe .
0xCCCCCCCC mémoire locale (pile /stack ) non initialisée par exemple un pointeur déclaré dans une fonction membre d'une classe.

On comprend l'utilité de toujours initialiser les pointeurs à NULL ,et de leur affecter cette valeur après libération de la mémoire.
Ce qui nous amène à l'erreur la plus commune : 0xc0000005 Access Violation
Un exemple simple :
Dans la fonction OnInitialUpdate d'une CFormView je fais la chose suivante :

CDialog *pdlg;
pdlg->ShowWindow(1);
J'ai droit à un beau message de violation d'accès 0xc0000005
En debug si je regarde la valeur de this dans ShowWindow il a la valeur reconnaissable 0xcccccccc et le debugger met des ??? Dans le handle de fenêtre.
Pour résumer lorsque vous tracez un programme en debug et que vous tombez sur ce message,
Pensez à regarder la valeur affectée à this ,
Ou remonter d'un cran dans la pile des appels pour regarder la valeur du pointeur.


Comment intégrer des sources C dans un projet C++ ?
Créé le 19/09/2005[haut]
auteur : Farscape
Il est tout à fait possible de mélanger des sources en C extension .c et des sources en C++ au sein du même projet.

Détail de la procédure :
Il faudra veiller à enlever au niveau des options de compilation des fichiers en C l'option entêtes pré compilés :

Avec Visual C++6.0 :
Dans la gestion de projet à gauche sélectionner le(s) fichier(s) en C Puis faire clic droit settings .
Dans l'onglet onglet C++ sur la catégorie precompiled header cocher not using precompiled headers.

Astuce : Pour la multi sélection des fichiers utiliser la touche CTRL+clic gauche.

Enfin tous les prototypes des fonctions en C devront être déclarés avec extern "C" :
Exemple de .h pour déclarer les fonctions en C pour utilisations en C et C++

#ifdef __cplusplus 
extern "C"
{
#endif

 void myfct(int c);

#ifdef __cplusplus 
}
#endif

Comment inclure l'appel de l'aide avec un fichier .chm dans un programme MFC ?
Créé le 19/09/2005[haut]
auteur : Farscape
Microsoft avec un outil gratuit dénommé HTML Help Workshop permet de fabriquer un système d'aide à partir de fichier HTML, remplaçant ainsi avantageusement l'ancien système à base de fichier RTF.
Ceux-ci pouvant être composés avec FrontPage par exemple.
Le fichier d'aide généré aura une extension .chm et peut être entièrement autonome, c'est-à-dire pas forcément rattaché à un programme.
Pour une prise en main du kit voir le tutoriel de thierry aim sur notre site: http://thierry_aim.developpez.com/htmlhelp/
Cliquer ici pour le téléchargement du kit sur le site de Microsoft Maintenant nous allons voir comment établir le lien entre un projet développé avec le kit de Microsoft et un programme MFC .
A terme l'appui de la touche F1 sur une fenêtre particulière (FormView) invoquera l'aide correspondante dans le fichier d'aide.

Génération du fichier de liens entre les formes et l'aide :
Pour établir un lien entre le fichier d'aide et le programme il faut faire un fichier de correspondance qui peut être généré automatiquement par visual .

Sur les propriétés du projet : (menu projects /settings )
Onglet custom build :
Dans la partie gauche des fichiers du projet, sélectionner le fichier resource.h
Dans l'édit descriptions : on renseigne le libellé par exemple : Making HTML Help Include File...
Et dans l'édit Commands :

makehm ID_,IDH_,0x10000 IDM_,IDH_,0x10000 resource.h >>"hlp\$(TargetName).hm" 
echo. >>"hlp\$(TargetName).hm" 
makehm IDP_,IDH_,0x30000 resource.h >>"hlp\$(TargetName).hm" 
makehm IDR_,IDH_,0x20000 resource.h >>"hlp\$(TargetName).hm" 
makehm IDD_,IDH_,0x20000 resource.h >>"hlp\$(TargetName).hm" 
makehm IDW_,IDH_,0x50000 resource.h >>"hlp\$(TargetName).hm" 
MakeIDH "hlp\$(TargetName).hm"
makehm va faire le lien entre les différents type de ressources du projet en un identifiant unique commençant par IDH et dont la plage des différents types est reparti .
le fichier généré portera le nom du projet suivi de l'extension .hm.
À indiquer dans l'édit Outputs

hlp\$(TargetName).hm
la première compilation des ressources le fichier .hm va être généré .
Note : le programme MakeIDH doit être présent à la racine du projet.


Compilation automatique du projet d'aide à partir de visual 6: (falcutatif)

Le fichier .hpp doit être inclu dans le projet.

Sur les propriétés du projet : (menu projects /settings )
Onglet custom build :
Dans la partie gauche des fichiers du projet, sélectionner le fichier .hpp
Dans l'édit descriptions : on renseigne le libellé par exemple : Making HTML Help Include File...
Et dans l'édit Commands :

hhc.exe html\$(InputName).hhp 
echo. 
copy html\$(InputName).chm $(OutDir)\$(InputName).chm
Dans l'édit Outputs:

html\$(InputName).chm
cliquer ensuite sur le bouton dependencies et rajouter

html\$(TargetName).hm
Dans l'onglet link :
Object/library modules, rajouter : htmlhelp.lib

Lien du fichier d'aide .chm avec le programme :

Dans la fonction InitInstance de la classe d'application on va modifier le lien de l'aide qui est par défaut sur une extension .HLP

 // Change the extension for the default help file
CString strHelpFile = m_pszHelpFilePath;
strHelpFile.Replace(".HLP", ".chm");
free((void*)m_pszHelpFilePath);
m_pszHelpFilePath = _tcsdup(strHelpFile);
Le fichier .chm devra être au même emplacement que le programme.

Appel de l'aide par la touche F1 :

Dans la classe CMainFrame rajouter manuellement le message

ON COMMAND(IDHELP_CMDIFrameWnd ::OnHelp)
END_MESSAGE_MAP()
dans le cas d'un projet SDI :

ON_COMMAND(ID_HELP, CFrameWnd::OnHelp)
Au niveau de la classe CMainFrame rajouter avec l'aide classwizard la fonction virtuelle :WinHelp .

virtual void WinHelp(DWORD dwData, UINT nCmd = HELP_CONTEXT);
Et remplacer le contenu par :

void CMainFrame::WinHelp(DWORD dwData, UINT nCmd) 
{
CMyApp *pApp=static_cast<CMyApp *>(AfxGetApp());
#if _MFC_VER >= 0x0700
::HtmlHelp((pApp->m_bHelpModal?m_hWnd:NULL), AfxGetApp()->m_pszHelpFilePath, HH_HELP_CONTEXT,nCmd==HELP_CONTEXT?dwData:0);
#else
HtmlHelp((pApp->m_bHelpModal?m_hWnd:NULL), AfxGetApp()->m_pszHelpFilePath, HH_HELP_CONTEXT,nCmd==HELP_CONTEXT?dwData:0);
#endif
}
la variable est un booleen permettant de choisir si l'appel de l'aide est bloquante ou non .
pour finir dans le hhp on doit avoir les sections suivantes :

[MAP]
#include MyApp.hm

[TEXT POPUPS]
MyApp.hm

[MERGE FILES]
MyApp.chm
on peut rajouter ces sections avec l'aide de notepad.
c'est au niveau de la section alias dans le programme help workshop que l' on va définir les liens :
on va associer un numero d'id IDH à une page web.
en faisant double click sur la section alias on renseignera le nom de l'include:
sur l'onglet map avec l'aide du bouton header file on indiquera le chemin du fichier .hm.
dans l'onglet alias on établira directement le lien entre l'id IDH_ et la page web.


Note:
à la racine du projet on doit avoir les répertoires :
html et hlp.



Que faire avec l'erreur de compilation C1010 (en-tête précompilé) ?
Créé le 27/11/2005[haut]
auteur : Farscape
Le détail de l'erreur avec visual .net :
Fin de fichier inattendue lors de la recherche d'une directive d'en-tête précompilé

Pour visual 6.0 :
unexpected end of file while looking for precompiled header directive

Explications :
Dans la plupart des cas Visual génère un projet avec l'option en-tête précompilé .
Les en-têtes précompilés représentent des instantanés de compilation pris à un certain emplacement du code source.
Il est pris juste après l'inclusion de la ligne #include "stdafx .h"
qui contient les fichiers d'en-têtes des MFC ou template .
Les en-têtes précompilés font donc gagner du temps à la compilation.
A partir du moment où cette option est réglée pour le projet tous les fichiers .CPP du projet doivent avoir en tout début du source la ligne :
#include "stdafx .h"
Sinon le compilateur généra le message C1010 ?

Note : il est possible de désactiver spécifiquement par fichier cette option ,c'est le cas par exemple si on veut mixer des fichiers .c et .cpp dans un même projet Voir faq Comment intégrer des sources C dans un projet C++ ?


Comment voir des informations de debbuggage/tracage simplement sans gestion avancée de log ?
Créé le 27/11/2005[haut]
auteur : nico-pyright(c)
En utilisant l'API OutputDebugString et un petit logiciel qui intercepte ces informations de débugage (disponible ici) : pour NT/2000/XP - pour Win9x Une fois ce programme lancé, un simple
OutputDebugString("Informations à voir affichées");
permet de voir la ligne dans la fenêtre.


Comment augmenter la mémoire réservée par défaut de mon exécutable lors d'un stack overflow ?
Mise à jour le 22/01/2007[haut]
auteur : nico-pyright(c)
Lors de l'utilisation de grosses variables dans un programme, on se demande souvent comment sont allouées les différentes variables. (voir portée des variables)
On peut résumer rapidement en disant que :
Une déclaration de type
int monTableau[20000];
a une portée locale à la fonction (ou au bloc {} )et est allouée sur la pile (stack)
Une allocation dynamique de type
int * monTableau = new int[20000]
a une portée définie par l'utilisation de new et de delete et est allouée sur le tas (heap)
Les variables globales sont définies dans le segment de données.

La taille par défaut du tas est de 1 Mo. Cette taille par défaut peut être augmentée en réglant une option du linker
/HEAP:reserve[,commit]
C'est bien souvent inutile, car le tas peut augmenter tout seul lorsque l'allocation est supérieure à la mémoire par défaut.
C'est le système d'exploitation qui gère cela tout seul (de la même facon, il préfèrera déléger à VirtualAlloc lorsque l'allocation dépasse un certain seuil).

Cette option est rarement utilisée, sauf pour des questions de performances.

La pile dispose elle aussi d'une taille par défaut d'1 Mo. Cependant, celle-ci est fixe et ne peut augmenter seule. Ainsi, lorsque l'on déclare beaucoup de grosses variables, il peut se produire une erreur de dépassement de mémoire : stack overflow.

On peut de même facilement augmenter la mémoire de la pile par défaut en réglant une option du linker.



/STACK:reserve[,commit]

Le linker utilise par défaut une valeur de 0x100000 (1 Mo) et 0x1000 (4Ko) pour la mémoire commit

donc pour réserver 2 Mo par exemple, il suffit de réserver cette mémoire dans le linker par :
/STACK:0x200000, 0x1000

Remarque : C'est en général une mauvaise idée d'avoir une grosse pile. Il est plus judicieux d'utiliser des allocations dynamiques pour les gros objets.



Comment éviter l'erreur la dll msvcr80d.dll est introuvable avec VC 2005 ?
Créé le 20/05/2006[haut]
auteur : Farscape
cette erreur peut apparaitre à l'exécution du programme en mode debug,
Il faudra régler la valeur de génération du manifest à oui dans les options d'édition des liens du projet.
Menu Project / Properties /Configuration Properties /Linker/ Manifest File mettre "Generate Manifest" à Yes. Voir ce lien MSDN pour en savoir plus.


Comment personnaliser l'affichage des objets dans le débogueur ?
Créé le 22/01/2007[haut]
auteur : Farscape
Vous avez certainement remarqué qu'il est très pratique de visualiser directement le contenu de certains objets dans la fenêtre de Visual ou encore en passant la souris sur un objet pour inspecter le contenu d'une CString par exemple ?

Et bien cette fonctionnalité de visualiser les données membres importantes d'un objet qu'il soit MFC ou autre est personnalisable.
Ce paramétrage est à mettre en place dans un fichier nommé AUTOEXP.DAT

Il est situé pour Visual 6.0 à l'emplacement :
C:\Program Files\Microsoft Visual Studio\Common\MSDev98\Bin

Sous Visual 2005 :
C:\Program Files\Microsoft Visual Studio 8\Common7\Packages\Debugger

Voici un aperçu de son contenu:

; from afxwin.h
CDC =hDC=<m_hDC> attrib=<m_hAttribDC>
CPaintDC =<,t> hWnd=<m_hWnd>
CPoint =x=<x> y=<y>
CRect =top=<top> bottom=<bottom> left=<left> right=<right>
CSize =cx=<cx> cy=<cy>
CWnd =<,t> hWnd=<m_hWnd>
CWinApp =<,t> <m_pszAppName,s>
CWinThread =<,t> h=<m_hThread> proc=<m_pfnThreadProc>

; from afx.h
CArchiveException =cause=<m_cause>
CFile =hFile=<m_hFile> name=<m_strFileName.m_pchData,s>
CFileException =cause=<m_cause> OS Error=m_lOsError
CMemFile =pos=<m_nPosition> size=<m_nFileSize>
CObject =<,t>
CRuntimeClass =<m_lpszClassName,s>
CStdioFile =FILE*=<m_pStream> name=<m_strFilename.m_pchData,s>
CTimeSpan =time=<m_time>
CTime =time=<m_time>
On retrouve la liste des objets MFC avec les données membres importantes à visualiser.
Une description des formats d'affichages est disponible dans ce même fichier :

   Letter  Description                 Sample         Display
;   ------  --------------------------  ------------   -------------
;   d,i     Signed decimal integer      0xF000F065,d   -268373915
;   u       Unsigned decimal integer    0x0065,u       101
;   o       Unsigned octal integer      0xF065,o       0170145
;   x,X     Hexadecimal integer         61541,X        0X0000F065
;   l,h     long or short prefix for    00406042,hx    0x0c22
;             d, i, u, o, x, X
;   f       Signed floating-point       3./2.,f        1.500000
;   e       Signed scientific-notation  3./2.,e        1.500000e+000
;   g       Shorter of e and f          3./2.,g        1.5
;   c       Single character            0x0065,c       'e'
;   s       Zero-terminated string      pVar,s         "Hello world"
;   su      Unicode string              pVar,su        "Hello world"

Pour rajouter vos propres classes il suffit d'éditer ce fichier avec notepad et de rajouter une section pour vos différents objets.

La syntaxe générale est la suivante :
L'objet =leLibelledonnéemembre<donnée membre>
Plusieurs variables membre peuvent être indiquées à la suite.

Les types simples entiers double etc sont correctement interprétés.
Pour une variable membre de type CString il faudra donner le chemin de la chaîne interne :
name=<m_strFilename.m_pchData,s> avec le type s voulant dire chaîne se terminant par un zéro.


Comment rajouter une extension de fichier prise en charge comme un .C ?
Créé le 22/01/2007[haut]
auteur : Farscape
Pour inscrire un nouveau type de fichier procéder comme suit:
avec le programme regedit (faire démarrer exécuter, saisir regedit) ouvrir la clef :
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\8.0\Languages\File Extensions
suivant les versions de compilateurs on aura à la place de 8.0 pour VC 2005
7.0 pour .net2002 et 7.1 pour .net 2003
Si on désire que l'extension de fichier .pc soit reconnue comme un .C on créera le répertoire .PC en dessous de la clef File Extensions
Ensuite dans la clef .c copier le contenu de la zone défaut dans le presse papiers
Coller la valeur dans la zone défaut de la clef ajoutée (ici .pc)

Pour intégrer IntelliSense modifier la clef suivante :
HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\8.0\Languages\Language Services\C/C++\NCB Default C/C++ Extensions
il suffit de rajouter aux extensions existantes la nouvelle extension (ici .pc)


Comment gérer la cohabitation de deux fonctions ayant le même nom dans l'API Win32 et le framework.net ?
Créé le 22/01/2007[haut]
auteur : nico-pyright(c)
Lorsqu'on migre petit à petit son projet en C++.Net ou simplement lorsqu'on veut faire cohabiter l'Api Win32 (ou les MFC) et le framework.Net, on peut rencontrer des problèmes de compilation du style :

error C2039: 'GetObjectA' : is not a member of 'System::Resources::ResourceManager' 
error C2653: 'MessageBoxA' : is not a class or namespace name

Le problème vient du fait que lorsqu'on souhaite utiliser la fonction MessageBox par exemple, le compilateur ne sait pas s'il doit utiliser la fonction MessageBox définie dans Windows.h ou bien dans le namespace System::Windows::Forms.

Il faut donc à ce moment dire au compilateur quelle fonction on veut utiliser.
On enlève alors la définition du MessageBox comme ci-dessous
#pragma push_macro("MessageBox")
#undef MessageBox

...
MessageBox::Show(S"hello");
...

#pragma pop_macro("MessageBox")
Ainsi le compilateur saura qu'il faut utiliser le MessageBox de .Net


Comment lier une bibliothèque statiquement ?
Créé le 17/09/2007[haut]
auteur : nico-pyright(c)
- Soit en l'ajoutant dans les options du projet, pour VS2005 : propriétés du projet, configuration properties, linker, input, additional dependencies et indiquer ici le .lib à lier.
- Soit par pragma
#pragma comment(lib,"malib.lib")

Comment régler l'édition des liens avec les bibliothèques statiques ?
Créé le 17/09/2007[haut]
auteur : Farscape
Lorsque la bibliothèque de runtime (CRT) est utilisée en mode statique /MT (multi-thread statique)
(en opposition au mode dynamique /MD (dll)), il peut apparaitre ce type d'erreurs lorsqu'on utilise plusieurs bibliothèques :

nafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new(unsigned int)" (??2@YAPAXI@Z) already defined in LIBCMTD.lib(new.obj)
nafxcwd.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete(void *)" (??3@YAXPAX@Z) already defined in LIBCMTD.lib(dbgdel.obj)
nafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new[](unsigned int)" (??_U@YAPAXI@Z) already defined in libcpmtd.lib(newaop.obj)
nafxcwd.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete[](void *)" (??_V@YAXPAX@Z) already defined in LIBCMTD.lib(delete2.obj)
Comment régler ce problème ? , il faut changer l'ordre des liens des bibliothèques incriminées comme suggéré dans cette note MSDN.
Voici comment procéder :
Avec Visual 2005 dans les propriétés du projet, chapitre éditeur de liens.
Rubrique Entrée, zone : "bibliothèque spécifique ignorée", mettre : Nafxcwd.lib Libcmtd.lib (pour le mode debug).
Dans la zone : "dépendances supplémentaires" mettre en dernier à la suite des autres bibliothèques utilisées par le projet: Nafxcwd.lib Libcmtd.lib


Comment demander une élévation des droits de l'application sous vista ?
Mise à jour le 01/03/2008[haut]
auteur : Farscape
Sous Windows Vista avec l'UAC lorsqu'une tâche nécessite un privilège administrateur il faut elever les droits de l'application
Comment gérer la situation ?
Soit on change les droits d'accès sur le programme par clic droit onglet compatibilité : exécuter en tant que administrateur, un peu pénible...
ou bien on rajoutera le fichier manifest suivant à notre application :

?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity name="monapplication" 
                    version="1.0.0.0" 
                    processorArchitecture="X86" 
                   type="win32"/>
  <description>Mon Application</description> 
  <!-- Identify the app's security requirements. -->
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level="requireAdministrator" />
      </requestedPrivileges>
    </security>
  </trustInfo>
</assembly>
On placera le fichier dans le répertoire d'exécution du programme, le fichier portant le nom :
MyAppName.exe.manifest ,MYAppName correspondant au nom de l'application.
Avec Visual 2005 il est préférable d'inclure le manifest à notre programme en respectant la procédure indiquée dans la faq: faq Comment rajouter le fichier manifeste du style XP au manifeste existant dans Visual 2005 ?
Pour plus de détails sur les options du manifest consultez MSDN.
Voir aussi faq Comment fonctionne UAC ?


Où se procurer le dernier SDK de Visual 6.0 ?
Créé le 07/07/2008[haut]
auteur : Farscape
Le dernier SDK valide pour Visual 6.0 date de février 2003.
Il ne faut pas installer le SDK proposé en téléchargement sur MSDN il est prévu pour les versions Visual .Net et Visual 2005.

On peut encore télécharger ce SDK à l'emplacement :
http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm


UAC et virtualisation des accès fichiers sous Vista
Créé le 07/07/2008[haut]
auteur : Farscape
Au fil des ans et des différentes versions de Windows, nombre d'applications ont été conçues pour avoir un accès direct à des emplacements systèmes ou tout simplement à la base de registres.
Sous Vista ces emplacements sont maintenant verrouillés pour réduire la surface d'attaque du système.
Pour garder une compatibilité avec les anciens programmes Vista implémente un service de virtualisation de l'UAC qui redirige de manière transparente les accès aux parties protégées du système (fichier ,base de registres) vers un emplacement virtualisé et non protégé faisant croire ainsi à l'application qu'elle écrit à l'emplacement d'origine.

Exemple :
Un programme exécuté avec des droits utilisateurs s'installe dans le répertoire :
C:\Program Files\<application>\
L'accès sera automatiquement virtualisé à l'emplacement :
C:\Users\<votre_compte>\AppData\Local\VirtualStore\Program Files\<application>

Si le programme doit impérativement écrire à l'emplacement d'origine il faudra élever les droits de l'application en administrateur.

On procédera comme suit :
Soit on change les droits d'accès sur le programme par clic droit onglet compatibilité : exécuter en tant que administrateur, un peu pénible...
ou bien on rajoutera avec les versions de Visual antérieure à Visual 2008 le fichier manifest suivant à notre application :faq Comment rajouter le fichier manifeste du style XP au manifeste existant dans Visual 2005 ?

xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity name="monapplication"
                    version="1.0.0.0"
                    processorArchitecture="X86"
                   type="win32"/>
  <description>Mon Application</description>
  <!-- Identify the app's security requirements. -->
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level="requireAdministrator" />
      </requestedPrivileges>
    </security>
  </trustInfo>
</assembly>
à intégrer suivant la technique décrite dans la faq :faq Comment rajouter le fichier manifeste du style XP au manifeste existant dans Visual 2005 ?


au moment d'exécuter le programme Vista demandera l'acceptation de l'utilisateur pour l'élévation des droits sauf évidemment si vous avez désactivé l'UAC.

Pour conclure :
Il faut bien comprendre que ce mécanisme de virtualisation a été implémenté par Microsoft pour permettre une transition en « douceur » des applications.
Mais il ne faut pas trop compter sur la solution de la virtualisation, car rien ne garantit que ce mécanisme soit encore présent dans les futures versions de Windows?

lien : faq Comment rajouter le fichier manifeste du style XP au manifeste existant dans Visual 2005 ?

Comment régler l'UAC avec visual 2008 ?
Créé le 07/07/2008[haut]
auteur : Farscape
Visual 2008 permet la gestion du manifest UAC au niveau du projet.


Le réglage de cette option permet de spécifier le niveau d'exécution demandé pour l'application.

Trois options sont disponibles :
AsInvoker : l'application devra s'exécuter avec le jeton actuel de l'appelant sans demander une élévation de privilèges.
highestAvailable : l'application s'exécutera avec le privilège le plus haut que le compte utilisateur possède.
RequireAdministrator: l'application doit s'exécuter avec un jeton complet d'administration.
L'UAC demandera à l'utilisateur l'autorisation de donner l'accès au jeton complet si le compte administrateur fonctionne avec le jeton restreint.


Restriction de l'usage des classes templates avec les MFC et Visual 2008
Créé le 07/07/2008[haut]
auteur : Farscape
Les classes MFC utilisent l'héritage simple. Dans le cas où l'on voudrait se passer de l'héritage multiple pour enrichir des classes existantes il est possible d'utiliser les classes templates.
Démonstration :

L'exemple ci-dessus montre l'implémentation d'une classe template pour la gestion des couleurs,

Celle-ci est associée à trois classes dialogues.
Technique d'implémentation :
On déclare la classe avec un paramètre qui est aussi utilisé pour spécifier le parent.

template <class GENERIC_DLGCOLOR /*= CWnd*/>
class CTplDlgColor : public GENERIC_DLGCOLOR
{
public:

	CTplDlgColor(UINT nID=0,CWnd* pParent=NULL) :GENERIC_DLGCOLOR(nID,pParent)
	{
	/* HBRUSH   */  m_HbrClrCtlBk=NULL ;
	/* COLORREF */  m_ClrCtlText= RGB(0, 0, 0) ;
	}

	~CTplDlgColor()
	{
		if(m_HbrClrCtlBk) ::DeleteObject(m_HbrClrCtlBk);
	}
virtual BOOL OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
	{
		if(message==WM_CTLCOLOR)
		{
//?
		 return TRUE;
			
		}
		return GENERIC_DLGCOLOR::OnWndMsg(message,  wParam, lParam, pResult);
	}
//???????
};
La déclaration pour les classes à enrichir :

 class CTabInformation : public CTplDlgColor<CDialog>
{
// Construction
public:
	CTabInformation(CWnd* pParent = NULL);   // standard constructor
//?..
} ;
Coté source :

CTabInformation::CTabInformation(CWnd* pParent /*=NULL*/)
	: CTplDlgColor<CDialog>(CTabInformation::IDD, pParent)
{
	//{{AFX_DATA_INIT(CTabInformation)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	m_pTab = NULL;	
}
void CTabInformation::DoDataExchange(CDataExchange* pDX)
{
	CTplDlgColor<CDialog>::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CTabInformation)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}
Les avantages de la classe patron (template) utilisée de cette manière sur l'héritage multiple sont nombreux.
Les problèmes liés à des méthodes membres qui sont présentes plusieurs fois dans les ancêtres d'une classe peuvent être résolus simplement si ces méthodes sont virtuelles comme dans l'exemple ci-dessus avec la méthode OnWndMsg.
Utilisation native des méthodes sans cast sur la classe de base ici CWnd
Souplesse d'intégration dans une classe existante.
Etc..
Les Inconvénients :
Le fait de devoir mettre le code dans le .h, ce qui nuit à la lisibilité, même en séparant dans un deuxième fichier la partie implémentation, cela peut avoir un impact sur le temps de compilation si cette classe est souvent utilisée ou si le code est conséquent.

Alors les classes patrons solution idéale ?
Presque, j'en viens maintenant au problème qui est apparu avec Visual 2005,
Un bug du ClassView empêche pour des classes dialogues (CFormView, CDialog, CDialogBar) construites à partir de classe patron la reconnaissance de la classe.
Dans ce contexte la demande de génération d'une variable contrôle à partir des ressources échoue, l'option contrôle variable étant grisée.
Pour résumer si vous utilisez une classe patron sur une classe dialogue il faudra vous passer de l'assistant pour associer une variable à son contrôle.
J'ai signalé ce problème au support Microsoft, la réponse est qu'effectivement le problème est constaté mais ce n'est pas une priorité et ne sera pas résolu?
Donc en conclusion tout était parfait avec Visual 6.0 , avec Visual 2005 et 2008 beaucoup moins..
Si l'assistant est indispensable Il faudra donc recourir à l'héritage multiple et se passer des classes patrons.


Comment rendre une application compatible terminal serveur ?
Créé le 07/07/2008[haut]
auteur : Farscape
Dans les propriétés du projet sur l'onglet link/system on trouve l'option /TSAWARE.
Cette option permet de spécifier que l'application est compatible Terminal Serveur et n'apporte pas de modification au chargement du programme.

Quelles sont les conséquences de cette option ?
Dans le cas d'une application non compatible (on parle d'application héritée ou legacy)
Terminal Serveur apporte des modifications pour faire fonctionner correctement l'application dans un environnement multi-utilisateur.
Ainsi il va créer un dossier Windows virtuel pour que chaque utilisateur puisse accéder à ses propres fichiers .ini ou à son paramétrage dans la base de registres dans la clef HKEY_CURRENT_USER
Donc par défaut Visual 2008 considère que l'application est compatible avec Terminal Serveur et que vous n'utilisez pas les .ini ou la clef HKEY_CURRENT_USER
Ce qui signifie que par exemple que l'api32 GetWindowsDirectory renvoie toujours C:\windows quelque soit l'utilisateur, j'en ai fait les frais il n'y pas longtemps?
Ce qui n'était pas le cas sous Visual 6.0?


Comment obtenir le chemin Windows virtualisé dans un environnement Terminal Serveur ?
Créé le 07/07/2008[haut]
auteur : Farscape
Une application compatible Terminal serveur ne gère plus un emplacement virtualisé pour la gestion des fichiers ini.
Voir ce post de la faq pour plus de renseignements faq Comment rendre une application compatible terminal serveur ?
Dans ces conditions comment récupérer ce chemin virtualisé ?
On utilisera la fonction SHGetFolderPath avec l'option CSIDL_PROFILE.
L'exemple ci-dessous récupère le chemin du profil utilisateur et crée le répertoire Windows s'il n'existe pas.

TCHAR szPath[MAX_PATH];
if(SUCCEEDED(SHGetFolderPath(NULL, 
			CSIDL_PROFILE |CSIDL_FLAG_CREATE, 
			NULL, 0,szPath))) 
			{
				PathAppend(szPath, TEXT("Windows"));
				if(!PathIsDirectory(szPath)) CreateDirectory(szPath,NULL);
			}
lien : faq Comment rendre une application compatible terminal serveur ?

Comment régler la plateforme de distribution sous Visual 2008 ?
Créé le 07/07/2008[haut]
auteur : Farscape
Le passage de Visual 2005 à Visual 2008 n'est pas sans surprises ?
Vous avez dû certainement vous rendre compte que pour de vieux projets issus de Visual6 ou autres Visual définissait par défaut la plateforme système à Windows Vista ?
Laisser ce choix par défaut n'est pas sans danger, en effet certaines API comme SystemParametersInfo ne fonctionneront plus sous windows XP, la fonction renverra NULL!.

Je me sers de cette API pour récupérer la fonte système par défaut, donc par chance je me suis rendu assez vite compte du problème avec le code suivant :

NONCLIENTMETRICS ncm; 
ncm.cbSize = sizeof(NONCLIENTMETRICS); 
VERIFY(SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0)); 
SetFont(&(ncm.lfMessageFont)); 
à qui La faute ?
Eh bien la structure utilisée a changée de taille sous Vista, en laissant le paramétrage par défaut sur Vista la taille de la structure évaluée par sizeof correspond donc à la version de l'API sous Vista, et l'appel échouera sous Windows XP.
En cherchant un peu dans les sources de Visual 2008 on trouve une référence à l'ancienne structure que vous pouvez comparer à la nouvelle..

struct AFX_OLDNONCLIENTMETRICS 
  { 
    UINT cbSize; 
    int iBorderWidth; 
    int iScrollWidth; 
    int iScrollHeight; 
    int iCaptionWidth; 
    int iCaptionHeight; 
    LOGFONT lfCaptionFont; 
    int iSmCaptionWidth; 
    int iSmCaptionHeight; 
    LOGFONT lfSmCaptionFont; 
    int iMenuWidth; 
    int iMenuHeight; 
    LOGFONT lfMenuFont; 
    LOGFONT lfStatusFont; 
    LOGFONT lfMessageFont; 
  }; 
typedef struct tagNONCLIENTMETRICS { 
  UINT cbSize; 
  int iBorderWidth; 
  int iScrollWidth; 
  int iScrollHeight; 
  int iCaptionWidth; 
  int iCaptionHeight; 
  LOGFONT lfCaptionFont; 
  int iSmCaptionWidth; 
  int iSmCaptionHeight; 
  LOGFONT lfSmCaptionFont; 
  int iMenuWidth; 
  int iMenuHeight; 
  LOGFONT lfMenuFont; 
  LOGFONT lfStatusFont; 
  LOGFONT lfMessageFont; 
  int iPaddedBorderWidth; 
} NONCLIENTMETRICS, 
Comment résoudre ce problème ?
Dans les sources de Visual 2008, le problème est résolu pour cette API comme suit :

struct AFX_OLDNONCLIENTMETRICS 
  { 
    UINT cbSize; 
    int iBorderWidth; 
    int iScrollWidth; 
    int iScrollHeight; 
    int iCaptionWidth; 
    int iCaptionHeight; 
    LOGFONT lfCaptionFont; 
    int iSmCaptionWidth; 
    int iSmCaptionHeight; 
    LOGFONT lfSmCaptionFont; 
    int iMenuWidth; 
    int iMenuHeight; 
    LOGFONT lfMenuFont; 
    LOGFONT lfStatusFont; 
    LOGFONT lfMessageFont; 
  }; 
 
const UINT cbProperSize = (_AfxGetComCtlVersion() < MAKELONG(1, 6)) 
    ? sizeof(AFX_OLDNONCLIENTMETRICS) : sizeof(NONCLIENTMETRICS); 
 
  NONCLIENTMETRICS NonClientMetrics; 
  NonClientMetrics.cbSize = cbProperSize; 
 
::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, cbProperSize, &NonClientMetrics, 0); 
 
m_MenuFont.CreateFontIndirect(&NonClientMetrics.lfMenuFont); 
Comme il est difficile de connaître les autres incompatibilités, il est préférable de définir un niveau de plateforme de Windows compatible au plus près de sa cible.
Dans mon cas avec un poste de production sous Windows XP je l'ai défini dans stdafx.h (au sommet)
 
#if _MSC_VER > 1200  
#define   WINVER 0x0500    // windows 2000 
#define _WIN32_WINNT 0x0501     // xp 
#endif


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.