begin process at 2010 02 10 12:22:20
  Trouver un code source :
 
dans
 
Accueil > Forum > 

Delphi

 > 

Système

 > 

Exécution

 > 

Problème affectation dynamique ImageList à un ComboBoxEx.Images


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

Problème affectation dynamique ImageList à un ComboBoxEx.Images

mardi 16 juin 2009 à 17:31:02 | Problème affectation dynamique ImageList à un ComboBoxEx.Images

informatixo

Membre Club
Bonsoir le forum,

J'ai un problème avec le composant ComboBoxEx et plus particulièrement avec sa propriété Images.

J'ai créé une procédure qui permet de mettre à jour une ComboBoxEx de façon dynamique (texte + image) dont voici le code simplifié :

procedure MiseAJour(var cmbListeDeroulante: TComboBoxEx);
var
  i: Integer;
  ListeImages: TImageList;
  Bitmap: TBitmap;

begin
  try
    // Permet de créer la liste des images et de la remplir.
    ListeImages := TImageList.Create(nil);
    ListeImages.Height := 20;
    ListeImages.Width := 20;
    Bitmap:= TBitmap.Create;
    Bitmap.LoadFromFile('C:\Images\Image1.bmp');
    ListeImages.Add(Bitmap, nil);
    Bitmap.LoadFromFile('C:\Images\Image2.bmp');
    ListeImages.Add(Bitmap, nil);
    Bitmap.LoadFromFile('C:\Images\Image3.bmp');
    ListeImages.Add(Bitmap, nil);
    Bitmap.LoadFromFile('C:\Images\Image4.bmp');
    ListeImages.Add(Bitmap, nil);
    Bitmap.LoadFromFile('C:\Images\Image5.bmp');
    ListeImages.Add(Bitmap, nil);

    // Permet d'associer la liste d'images à la liste déroulante.
    cmbListeDeroulante.Images.Assign(ListeImages);

    // Permet de nettoyer la liste déroulante dans le cas où il y a déjà des données.
    cmbListeDeroulante.Clear;

    // Permet d'ajouter les éléments dans la liste déroulante.
    for i := 0 to 4 do
      cmbListeDeroulante.ItemsEx.AddItem('Image' + IntToStr(i + 1), i, i, -1, -1, nil);
  finally
    ListeImages.Free;
    imgBitmap.Free;
  end;
end;


Dans l'exemple ci-dessus j'obtiens un Access violation. J'ai donc essayé cette variante en remplaçant le "Assign" (ligne en vert) :

    cmbListeDeroulante.Images.AddImages(ListeImages);

Mais là, même résultat c'est-à-dire Access violation. J'ai donc pensé que Images n'était pas créé et j'ai donc ajouté cette ligne de code avant le "Assign" (ligne en vert) :

    cmbListeDeroulante.Images.Create(nil);
    cmbListeDeroulante.Images.Assign(ListeImages);

Et là toujours cet Access violation !

Quelqu'un peut-il m'aiguiller SVP car je ne vois pas pourquoi avec la création j'ai un Access violation ?

Merci d'avance pour votre aide.

Que la force soit avec vous !
mardi 16 juin 2009 à 18:05:06 | Re : Problème affectation dynamique ImageList à un ComboBoxEx.Images

f0xi

Membre Club Administrateur CodeS-SourceS


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls;

type
  TForm1 = class(TForm)
    ComboBoxEx1: TComboBoxEx;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    fImageList : TImageList;
  protected
    procedure UpdateImageList(ComboBox: TComboBoxEx);
  public

  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure Tform1.UpdateImageList(ComboBox: TComboBoxEx);
var
  I : Integer;
  BMP: TBitmap;
  FLN, PTH : String;
begin
  BMP := TBitmap.Create;
  try
    ComboBox.ItemsEx.BeginUpdate;
    try
      ComboBox.Clear;
      ComboBox.Images := fImageList;

      PTH := 'c:\images\';
      for I := 0 to 4 do
      begin
        FLN := 'image'+IntToStr(I+1)+'.bmp';
        if FileExists(PTH+FLN) then
        begin
          BMP.LoadFromFile(PTH+FLN);
          fImageList.Add(BMP, nil);
          ComboBox.ItemsEx.AddItem(FLN, I, I, -1, -1, nil);
        end;
      end;
    finally
      ComboBox.ItemsEx.EndUpdate;
    end;
  finally
    BMP.Free;
  end;
end;


procedure TForm1.FormCreate(Sender: TObject);
begin

  fImageList        := TImageList.Create(Self);
  fImageList.Width  := 20;
  fImageList.Height := 20;
  UpdateImageList(ComboBoxEx1);

end;

procedure TForm1.FormDestroy(Sender: TObject);
begin

  fImageList.Free;
end;

end.




mardi 16 juin 2009 à 18:20:33 | Re : Problème affectation dynamique ImageList à un ComboBoxEx.Images

f0xi

Membre Club Administrateur CodeS-SourceS
Réponse acceptée !


Explications :

cela est du au fait que, comme les Evenements, les propriétés du style Images, PopupMenu, Action, ActiveControl, Menu, etc, ne sont la que pour stocker une instance existante d'un objet.

voici comme elle sont déclarée :

TMaClasse = class
private
  fCompo: TComponent;
  // Ceci est en fait un pointeur sur l'instance existante d'un composant, il est nil par defaut

  procedure SetCompo(Value: TComponent);
  // permet d'effectuer les operations necessaire pour l'assignation a fCompo
public
  procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  // permet de gerer la notification de liberation externe de fCompo, sans cela, un appel a fCompo alors
  // que ce dernier serait libéré provoquerai une erreur dans la classe.

  property Component : TComponent read fCompo write SetCompo;
  // ceci est la propriété visible permettant de "linker" un composant a notre classe.
end;

procedure TMaClasse.Notification(AComponent: TComponent; Operation: TOperation);
begin
  // si le composant linké se libère on remet fCompo a nil.
  if (AComponent = fCompo) and (Operation = opRemove) then
    fCompo := nil;
  inherited; 
end;

procedure MaClasse.SetCompo(Value: TComponent);
begin
  if fCompo <> Value then
  begin
    // Si fCompo etait assigné on lui indique de ne plus prevenir la classe de sa libération
    if Assigned(fCompo) then
      fCompo.RemoveFreeNotification;
 
    // on assigne notre nouveau composant ou nil
 
  fCompo := Value;
    // si fCompo est de nouveau assigné, il doit nous prevenir de son eventuelle libération
    if Assigned(fCompo) then
      fCompo.FreeNotification(Self);
  end;
end;


Voila, ce genre de propriété permet de linké un composant avec un autre, le Owner ne doit pas, en regles generales, effectuer la creation ou la libération d'une telle propriété. Elles ne servent qu'a pouvoir interragir avec un composant.



mardi 16 juin 2009 à 23:40:04 | Re : Problème affectation dynamique ImageList à un ComboBoxEx.Images

informatixo

Membre Club
Merci beaucoup foxi pour ta réponse si rapide et si complète, désolé de ne pas avoir pu être aussi réactif !

Donc si j'ai bien compris, la propriété Images du composant ComboBoxEx n'est qu'un pointeur vers un TImageList existant et à la conception ça marche bien puisque les deux sont créés sur la form et que l'on a que besoin de les lier.

Hors dans l'hypothèse d'une création dynamique, je suppose qu'il n'y a pas moyen d'assigner un TImageList mais juste de pointer dessus.

Je ne mets pas réponse accepté pour ton code car dans mon cas il ne s'applique pas cependant je vais m'en servir pour arriver à mes fins ! En revanche tes explications sont claires et m'ont permis de trouver une solution donc je mets réponses accepté pour ta deuxième réponse.

Mon problème est que ma procédure est stockée dans une unité toute simple sans form que j'appelle depuis plusieurs autres form via le uses. Donc si j'ai compris les deux solutions qu'ils me restent sont :
  • De déclarer dans mon unité un TImageList global que je pourrais lier à la propriété Images par une simple affectation (qui initialisera le pointeur en question) depuis ma procédure
  • De créer mon propre composant ComboBoxEx en dérivant de TCustomComboBox pour arriver au résultat souhaité
Pourrais-tu avoir la gentillesse de me dire si je suis sur la bonne voie ?

Merci d'avance pour ton aide et encore merci pour l'aide que tu m'as déjà apporté.

Que la force soit avec vous !
mercredi 17 juin 2009 à 04:17:11 | Re : Problème affectation dynamique ImageList à un ComboBoxEx.Images

f0xi

Membre Club Administrateur CodeS-SourceS
Réponse acceptée !


procedure UpdateImageList(ComboBox: TComboBoxEx; ImageList: TImageList; const ImagesName : array of string);
var
  I : Integer;
  BMP: TBitmap;
begin
  if (Length(ImagesName) = 0) or (ComboBox = nil) or (ImageList = nil) then
    Exit;

  BMP := TBitmap.Create;
  try
    ComboBox.ItemsEx.BeginUpdate;
    try
      ComboBox.Clear;
      ComboBox.Images := ImageList;

      for I := Low(ImagesName) to high(ImagesName) do
      begin
        if FileExists(
ImagesName[I] ) then
        begin
          BMP.LoadFromFile(
ImagesName[I] );
          ImageList.Add(BMP, nil);
          ComboBox.ItemsEx.AddItem(
ImagesName[I] , I, I, -1, -1, nil);
        end;
      end;
    finally
      ComboBox.ItemsEx.EndUpdate;
    end;
  finally
    BMP.Free;
  end;
end;





mercredi 17 juin 2009 à 12:20:02 | Re : Problème affectation dynamique ImageList à un ComboBoxEx.Images

informatixo

Membre Club
Merci encore foxi pour ton aide.

Donc mes hypothèses précédentes se vérifie à propos du TImageList.

Je te remercie pour ton dernier code, je vais m'en inspiré pour compléter ma procédure car je veux l'appeler avec uniquement le ComboBoxEx comme paramètre par référence.

Ton aide m'a été vraiment précieuse et tu m'a mis sur la bonne voie alors je t'en remercie.

A plus au détour d'un autre post ...

Que la force soit avec vous !
mercredi 17 juin 2009 à 16:17:06 | Re : Problème affectation dynamique ImageList à un ComboBoxEx.Images

Bacterius

Membre Club
@f0xi : tu écris dans ton premier commentaire que tu crées dynamiquement ton TImageList de la façon suivante :

fImageList := TImageList.Create(self);

Mais tu le libères dans le OnDestroy, alors que tu définis la fiche comme propriétaire de l'objet. N'est-ce pas superflu de libérer cet enfant alors que la fiche, à sa fermeture, devrait s'en occuper ? J'aimerais être fixé sur ce point car j'ai toujours des doutes sur la libération des objets enfants/parents.

Cordialement, Bacterius !
mercredi 17 juin 2009 à 22:40:01 | Re : Problème affectation dynamique ImageList à un ComboBoxEx.Images

f0xi

Membre Club Administrateur CodeS-SourceS


non, on libere toutes les ressources créées manuellement de façon manuelle.

si je crée un objet, je libere ce dernier. je ne laisse pas un autre composant s'occuper de sa liberation, SAUF si ce composant saitle faire, peux le faire et le fait car il est prevus pour ça.
en aucuns cas je ne laisse le ramasse miette le faire, en aucuns cas je laisse les composant se drebrouiller entre eux



jeudi 18 juin 2009 à 12:04:11 | Re : Problème affectation dynamique ImageList à un ComboBoxEx.Images

Bacterius

Membre Club
D'accord.

Cordialement, Bacterius !
jeudi 18 juin 2009 à 13:10:32 | Re : Problème affectation dynamique ImageList à un ComboBoxEx.Images

Guillemouze

Petite précision sur la source de la violation d'accès :
    // Permet d'associer la liste d'images à la liste déroulante.
    cmbListeDeroulante.Images.Assign(ListeImages);


Comme l'a dit foxi, "cela est du au fait que les propriétés du style Images [...] ne sont la que pour stocker une instance existante d'un objet.", la propriété Images n'est qu'un lien vers ton instance. Il est donc nil à l'origine.
Le code qui tente donc d'être exécuté est :
nil.Assign(ListeImages); d'où l'access violation.


Cette discussion est classée dans : images, bitmap, nil, listeimages, cmblistederoulante


Répondre à ce message

Sujets en rapport avec ce message

pb lors de la sauvegarde de grandes images [ par ericamiens ] salut à tous, mon problème est le suivant :lors de la création d'images JPG, j'ai l'erreur JPEG n° 36 lorsque les dimensions sont trop importantes (ex comparaison de deux images bitmap [ par kamicaz2002 ] aidez moi sur la comparaison de deux images bmp si elle sont simelaire ou bien non. notre images sources et l'autre sont deux images de main sur un f Enregistrement d'une image depuis internet. [ par Eithne ] Bonjour ! Je développe actuellement une application qui récupère des images à partir d'internet grâce à la fonction UrlDownloadToFile(nil, PChar (sou Erreur [ par delphi ] elle est ou l erreur svp ici :ShowWindow(FindWindowEx(FindWindowEx(FindWindowEx(FindWindowEx(FindWindow('AOL Frame25','AOL'),0, 'MDI Client',nil),0,'A Probleme... [ par VB7 ] Y'a une erreur ici c'est quoi svp :SendMessage(FindWindowEx(FindWindow('_AOL_Modal',nil),0,'_AOL_Icon',nil),WM_LBUTTONDOWN); Erreur svp aide!!!! [ par Shadow ] varAol, Mdi, Toolbar, tool, aoledit, combo:string;beginAol:= FindWindow('AOL Frame25',nil);Toolbar:= FindWindowEx(Aol,0,'AOL Toolbar', nil);tool:= Fin Aquerir les images en provenance de ma carte video [ par gooa ] ****************************************************************************************************************************************************** dessin sur un bitmap [ par jlg75 ] J'ai commencé un petit prog de dessin pour mes débuts en DELPHI.Je dessine sur un bitmap (feuille blanche pour l'instant),chargé dans une TImage. J'ut au secours ... [ par Nadou ] Mon plm se résume ainsi : j'ai créer une base de données en Access, qui contient des images de type objet OLE (bmp), ensuite j'ai fais une interface Icone dans une TTooBar [ par lguez ] Dans le TTOOLBAR on peut afficher une image differente si la souris passe sur une icone de la ToolBar ou non en renseignant les champs Images et HotIm


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Février 2010
LMMJVSD
1234567
891011121314
15161718192021
22232425262728

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 1,513 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales