Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 8 sur 8
  1. #1
    Invité de passage
    Homme Profil pro Denis
    petite societe qui developpe son "in-house software"
    Inscrit en
    mars 2010
    Messages
    10
    Détails du profil
    Informations personnelles :
    Nom : Homme Denis
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : petite societe qui developpe son "in-house software"
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : mars 2010
    Messages : 10
    Points : 0
    Points
    0

    Par défaut resources VS2010 : resXResourceSet() ou ComponentResourceManager() ou GetManifestResourceStream() ?

    Bonjour a tous,

    Je cale sur l'utilisation des resources en C++/CLI sous VS2010.

    Pas mal de doc en VB ou C# mais a chaque fois par utilisation de Stream(s).

    Je voudrai betement utiliser une image de presentation dans un layout, Pour cela

    _ dans ma solution (.sln) et dans l'IDE

    _ je crée un UserControl (C++ Control) que je viens rattacher a un evenement (genre click bouton) pour ouvrir cette fenetre. UserControl mis dans un répertoire Layout qui contient tous les usercontrols de ma solution.

    _ dans ce UserControl, je voudrai afficher une image, (genre le logo du projet). Dans le [Design] je crée un PictureEdit (chez DevExpress) ou picturebox plus classique

    _ lors du chargement je voudrai lier une image a la picturebox mais sans utiliser un chargement de fichier image sur le disque quelconque.

    _ j'ai trouvé 3 solutions dans les divers forums, docs et tutoriaux :

    1) celle de Nico
    Code :
      this->pictureEdit1->Image = Image::FromStream(Reflection::Assembly::GetExecutingAssembly()->GetManifestResourceStream("splashScreen.png"));
    en mettant dans Project/Properties/Linker/Input/Embed Managed resource File le lien au fichier Image : F:\Developpement\Resources\Theme\Logo v1.png

    ca ok ca fonctionne mais il faut aller dans le "Solution" Property Pages et les options incomprehensibles :-)

    2) les deux autres qui ne fonctionnent pas :

    en ajoutant un images.resx dans ma solution
    et en specifiant poru l'image voulue (splashScreen)
    Persistence = Linked at compile time

    Code :
    1
    2
    3
     
    System::ComponentModel::ComponentResourceManager^  resources = (gcnew System::ComponentModel::ComponentResourceManager());
    this->pictureEdit1->Image = (cli::safe_cast<System::Drawing::Image^> (resources->GetObject(L"splashScreen")));
    ou encore
    Code :
    1
    2
    3
     
    ResXResourceSet^ resources = gcnew ResXResourceSet("ophResources\images.resx"); // nom du repertoire ou sont les resources du projet
    this->pictureEdit1->Image = (cli::safe_cast<System::Drawing::Image^> (resources->GetObject(L"splashScreen")));
    Aucune des deux ne charge l'image.

    Mes deux questions sont simple sans doute mais je ne comprends pas le systeme des resources dans C++/CLI :

    a) quelles sont les differences entre chaque systeme de chargement de resource ?

    b) comment utiliser un fichier images.resx ou sont contenues toutes les images (pour les boutons, les affichages, les logos etc..) et charger dans un composant les images voulues directement dans ce fichier images.resx.
    Image.resx qui serait lui meme lié a l'executable ou dans une dll.

    c) dans le pictureedit, si je mets la propriete Image au nom du fichier, il ne se passe rien (sans doute parceque je perds les liens avec le repertoire Debug).

    Je veux bien un coup de main ou une explication du systeme car la je m'y perds. Les deux fichiers jpg joints montrent ma solution
    Images attachées Images attachées

  2. #2
    Expert Confirmé Sénior
    Homme Profil pro Paul Bacelar
    Développeur informatique
    Inscrit en
    février 2005
    Messages
    2 935
    Détails du profil
    Informations personnelles :
    Nom : Homme Paul Bacelar
    Âge : 42
    Localisation : France

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

    Informations forums :
    Inscription : février 2005
    Messages : 2 935
    Points : 4 570
    Points
    4 570

    Par défaut

    C'est que vous avez une vue bien trop réduite de ce qu'est une ressource.

    Chacune des méthodes correspond à un type/ une utilisation de "ressources" bien particulière.

    Si vous ne distinguez pas les différentes type d'utilisation de ressource, c'est normal que vous soyez perdu.

    Une image d'un logo de société qui doit être le même sur tout les écrans du logiciel, une image spécifique à un control picturebox ou une table de hachage contenant des paires clé valeur correspondant à un paramétrage d'une application sont toutes des ressources. Mais nous sommes bien d'accord que leurs utilisations sont complètements différentes, non ?

    Le but n'est donc pas de prendre une méthode de récupération de ressources "au pif" mais de savoir à quoi elle sert. Les différentes méthodes ont été optimisés en fonction de leur utilisation, localisation en fonction de la langue de l'OS, la prise ne compte des modifications dynamiques ou pas, modifiable ou pas en fonction des hash de sécurité, etc...

    Il faut donc simplement prendre la bonne.

    Si l'image est spécifique à votre type de contrôle ou qu'il doit être localisable, utilisez ComponentResourceManager, mais correctement, donc avec un type en paramètre.

  3. #3
    Invité de passage
    Homme Profil pro Denis
    petite societe qui developpe son "in-house software"
    Inscrit en
    mars 2010
    Messages
    10
    Détails du profil
    Informations personnelles :
    Nom : Homme Denis
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : petite societe qui developpe son "in-house software"
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : mars 2010
    Messages : 10
    Points : 0
    Points
    0

    Par défaut

    Bonjour Paul,

    Tout d'abord merci pour votre réponse.

    Je vais essayer d'utiliser le ComponentResourceManager. Ok merci et je reviens si ca fonctionne.

    Je comprends mieux pourquoi plusieurs methodes.
    Effectivement, c'est un point que je n'avais pas "vu". (je vous avoue que pour moi c'est la que la doc Microsoft n'est pas ultra claire je trouve. On s'y perds
    facilement pour une debutant).

    De ce fait, existe t'il qque part un "résumé" plus applicable des grands principes ? comme par exemple une doc plutot générale.
    Je veux bien prendre la bonne bien sure, il suffit juste que l'explication de quelle methode pour quel type me soit plus claire.

    a bientot

  4. #4
    Expert Confirmé Sénior
    Homme Profil pro Paul Bacelar
    Développeur informatique
    Inscrit en
    février 2005
    Messages
    2 935
    Détails du profil
    Informations personnelles :
    Nom : Homme Paul Bacelar
    Âge : 42
    Localisation : France

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

    Informations forums :
    Inscription : février 2005
    Messages : 2 935
    Points : 4 570
    Points
    4 570

    Par défaut

    C'est un peu le problème de MSDN, quand on sait pas ce que l'on cherche.

    Désolé, mais je n'ai pas la documentation claire sous la main.
    Je ne l'ai pas lû non plus remarquez.
    Mes remarques se base plus sur l'observation des pages des références que vous avez donnés.

    L'assembly où est défini la classe, son namespace aussi, la conception de l'interface de la classe, les types d'entré des méthodes, etc... tous ceci donne de précieuses indication sur le comment et le pourquoi de ces primitives.

    C'est donc plus le sens de l'observation et une connaissance des normes M$ qu'une documentation exhaustive (donc rapidement obsolète) qu'il vous faudra exercer.

  5. #5
    Invité de passage
    Homme Profil pro Denis
    petite societe qui developpe son "in-house software"
    Inscrit en
    mars 2010
    Messages
    10
    Détails du profil
    Informations personnelles :
    Nom : Homme Denis
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : petite societe qui developpe son "in-house software"
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : mars 2010
    Messages : 10
    Points : 0
    Points
    0

    Par défaut

    Bon, de retour..

    j'ai créé un fichier "Image.resx" dans Fichiers De ressources
    proprietes Content = False / Included In Project = True
    comme les autres .resx de chaque form

    dans ce resx, j'ai une image (Name) "splashScreen" avec Persistence Linked at compile time

    Ensuite j'appelle le code :

    Code :
    1
    2
    3
    4
    5
    6
    7
     
       System::ComponentModel::ComponentResourceManager^ resources = gcnew System::ComponentModel::ComponentResourceManager(System::Drawing::Image::typeid);
     
       String ^toto = resources->BaseName;
       String ^tata = resources->ToString();
     
    System::Drawing::Image ^testimage = cli::safe_cast<System::Drawing::Image^> (resources->GetObject(L"splashScreen"));
    j'arrive a lire

    toto = "Image"
    tata = System.ComponentModel.ComponentResourceManager

    mais blocage du programme lors du cast de l'image. Comme si il ne trouvait pas la reference de la resource. Donc je n'y arrive tjrs pas.

    le "ComponentResourceManager" etant une sorte de container de toutes les ressources du projet, est t'il possible de lister son contenu ?

  6. #6
    Invité régulier
    Homme Profil pro Denis
    Inscrit en
    juillet 2012
    Messages
    13
    Détails du profil
    Informations personnelles :
    Nom : Homme Denis
    Localisation : France, Morbihan (Bretagne)

    Informations forums :
    Inscription : juillet 2012
    Messages : 13
    Points : 5
    Points
    5

    Par défaut

    La solution est assez simple finalement et je crois avoir compris :

    dans la solution j'ai ajoute un nouvel Item de type resources : Resources.resx
    (qui se trouve dans le repertoire monprojet\mesresources\Resources.resx)

    ensuite dans cette Resources.resx, j'ajoute une image : MyImageIMG (le Name)

    la je compile et je vais regarder dans le repertoire Debug (ou release) le nom du fichier resources associe : "monprojet.mesresources.Resources.resources"

    dans le code ou je veux utiliser mon image j'appelle le ResourceManager de l'assembly et je vais alors lire l'objet.
    J'ai mis des try/catch pour tout verifier

    Code :
    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
     
       Assembly^ monAssembly = System::Reflection::Assembly::GetExecutingAssembly();
     
       String ^resourcesource = "monprojet.mesresources.Resources";        // nom du fichier : aller voir dans Debug
       ResourceManager ^myresources = gcnew Resources::ResourceManager(resourcesource, opheliaAssembly);
     
       try
       {
          Object ^objet = myresources->GetObject("MyImageIMG");
     
          pictureBoxTest->Image = safe_cast<Image ^> (objet);
       }
       catch (InvalidOperationException ^e)
       {
          MessageBox::Show(e->ToString(),"InvalidOperationException");   	
       }
       catch (ArgumentNullException ^e)
       {
          MessageBox::Show(e->ToString(),"ArgumentNullException");   	
       }
       catch (MissingManifestResourceException ^e)
       {
          MessageBox::Show(e->ToString(),"MissingManifestResourceException");   	
       }
       catch (MissingSatelliteAssemblyException ^e)
       {
          MessageBox::Show(e->ToString(),"MissingSatelliteAssemblyException");   	
       }
       catch (ArgumentException ^e)
       {
          MessageBox::Show(e->ToString(),"ArgumentException");   	
       }
    Ca marche tres bien.

    Attention a un truc : j'ai essaye UnmanagedMemoryStream ^mystream = myresources->GetStream("MyImageIMG") en voulant faire un Image::FromStream(mystream) ensuite mais l'execution m'a retourné une exception "InvalidOperationException" en precisant dans le exception->ToString() qu'il etait preferable d'utiliser la methode myresources->GetObject()...

    avec un peu de recul j'ai finalement trouve la solution. content !
    @+

  7. #7
    Expert Confirmé Sénior
    Homme Profil pro Paul Bacelar
    Développeur informatique
    Inscrit en
    février 2005
    Messages
    2 935
    Détails du profil
    Informations personnelles :
    Nom : Homme Paul Bacelar
    Âge : 42
    Localisation : France

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

    Informations forums :
    Inscription : février 2005
    Messages : 2 935
    Points : 4 570
    Points
    4 570

    Par défaut

    avec un peu de recul j'ai finalement trouve la solution. content !
    Une solution.
    Elle est fonction de votre utilisation, mais je trouve votre solution assez lourde, peu flexible et fragile.

    Lourde car vous devez gérer manuellement le chargement des ressources, ce qui est assez rarement justifié si vous utilisez le bon type de ressources.

    Peu flexible car elle est dans l'assembly de ressource, alors quid de la globalisation/internationalisation, ou de la customisation en fonction d'un client (pour une application " en marque blanche" par exemple).

    Fragile, la liste des types d'exceptions mal traités dans vos clauses catch en est l'illustration.

    C'est peut-être une solution qui marche, mais est-ce la plus adapté et facile à mettre en œuvre ? J'en doute.

  8. #8
    Invité régulier
    Homme Profil pro Denis
    Inscrit en
    juillet 2012
    Messages
    13
    Détails du profil
    Informations personnelles :
    Nom : Homme Denis
    Localisation : France, Morbihan (Bretagne)

    Informations forums :
    Inscription : juillet 2012
    Messages : 13
    Points : 5
    Points
    5

    Par défaut

    Hello Paul,

    Merci pour le commentaire.
    Effectivement ce n'est peut etre pas la meilleure solution mais comme je n'ai pas eu beaucoup de reponses ou d'astuces, j'ai donc essaye de dégrossir qque chose qui fonctionnait.

    Il en existe surement d'autres et c'est en forgeant qu'on devient forgeron ;-)
    peut etre que je reviendrai avec d'autres solutions d'ici qques temps mais la ca fonctionne. C'est effectivement "bourrin" mais...

    Ne pas le prendre comme une critique, c'est juste que je ne vois pas trop comment faire autrement en fait. (pour le moment). Mais si vous avez une idée ca m'interesse de faire mieux.

    le truc c'est que j'ai l'impression que sous WinForm, VS2010 en C++/CLI ne gere pas (ou a un bug ?) l'aspect resources des le moment ou elles ne sont pas gérée dans le fichier de la Form. Typiquement dans un UserControl appele dans une form, si je mets en palce des Images par exemple sur un bouton, dans le Designer c'est ok mais a l'execution VS est perdu (chez moi en tout cas). C'est bizarre.

    a bientot en tout cas
    denis

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

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •