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

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

Windows Forms Discussion :

[BufferedGraphics] Lenteurs avec un arrière plan


Sujet :

Windows Forms

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de PoZZyX
    Inscrit en
    Août 2005
    Messages
    426
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 426
    Par défaut [BufferedGraphics] Lenteurs avec un arrière plan
    Bonjour à tous,

    J'ai essayé comme on m'avais précédemment conseillé ici d'utiliser les buffered graphics pour un programme que je suis en train de faire :

    un menu avec 5 boutons (images) et qui affiche une image transparente par dessus l'image séléctionnée au moment T.
    Mon menu :
    A B C [D] E

    Tout allait bien, quand je déplaçais avec les flèches ça allait assez vite et tout. Mais depuis que j'ai ajouté un fond à mon programme (en plein écran), il faut presque attendre une seconde quand j'appuie sur la flèche pour passer à l'icone suivante.

    Les éléments essentiels de mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
            BufferedGraphicsContext context;
            BufferedGraphics bufferedGraphics;
            Graphics g;
    ...
     
    //dans le load :
                context = new BufferedGraphicsContext();
                context.MaximumBuffer = new Size(this.Width + 1, this.Height + 1);
     
                bufferedGraphics = context.Allocate(this.CreateGraphics(), new Rectangle(0, 0, this.Width, this.Height));
     
                g = bufferedGraphics.Graphics;
    ...
    //Dans la fonction lors que j'appiue sur une flèche du clavier :
                g.Clear(Color.Black);
                g.DrawImage(Image.FromFile(@"C:\wall.jpg"), new Point(0, 0));
                Image img_over = Image.FromFile(@"C:\over.png");
                int espace = (this.Width - (imglist.Images.Count * imglist.ImageSize.Width)) / (imglist.Images.Count + 1);
                int position_x = 0;
                for (int i = 0; i < imglist.Images.Count; i++) // 0 ==> 6
                {
                    position_x += espace;
                    g.DrawImage(imglist.Images[i], new Point(position_x, (this.Height - imglist.ImageSize.Height) / 2));
                    if (i == menu_position)
                    {
                        g.DrawImage(img_over, new Point(position_x - ((img_over.Width - imglist.ImageSize.Width) / 2), ((this.Height - imglist.ImageSize.Height) / 2) - ((img_over.Height - imglist.ImageSize.Height) / 2)));
                    }
                    position_x += imglist.ImageSize.Width;
                }
                bufferedGraphics.Render();
    Y a-t'il quelque chose que j'ai mal fait ??? ou est-ce que j'ai déja atteint les limites de c# (j'espère pas) ???

    Merci d'avance pour votre gracieuse aide !!!

  2. #2
    Membre éclairé Avatar de TrEiZe85
    Inscrit en
    Février 2007
    Messages
    82
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Février 2007
    Messages : 82
    Par défaut
    Meme probleme que toi ! Je me suis résigné javai créé un background tout simple avec un dégradé de couleur mais ca faisait ramer enormement mon appli ! Je me suis résigné et j'utilise une simple couleur de background, et en effet aucun probleme de lenteur !

    Si quelqu'un a une solution je suis prenneur !

  3. #3
    Membre éclairé Avatar de PoZZyX
    Inscrit en
    Août 2005
    Messages
    426
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 426
    Par défaut
    bah en fait j'ai mis le chargement des images dans le load dans des variables images prédéfinies au lieu de les ouvrir à chaque fois et ça va déja bcp mieux, bon je sais pas si y a encore une façon d'améliorer.

  4. #4
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 204
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 204
    Par défaut
    autant le .net est très performant quand on fait des calculs, des boucles sur des collections énormes etc... autant en graphisme, c'est pas trop ca
    rajouter un fond non uni avec des objets transparents dessus et c'est fini !

    heureusement il y a moyen de s'en sortir mais ca peut etre assez long

    j'ai bien une solution, ayant fait des trucs dans le genre qui sont au final très performant

    en l'occurence il faut que tu créé un control spécial pour ton menu, hérité de control
    tu overrides onpaintbackground sans faire le mybase et tu va gérer la transparence toi meme
    donc prendre me.parent.backgroundimage, enfin juste la partie qui est dessous ton control, en faire un drawimage sur un bufferedgraphics puis dessiner ce que tu voulais mettre sur ce bufferedgraphics
    et donc quand tu fais ton render c'est joli et instantané
    après tu peux avoir deux buffer par image de ton menu, un sélectionné et un pas sélectionné vu que c'est que l'affichage normal qui est lent, le fait de créer les images c'est rapide, et de faire render c'est rapide aussi (un render prend moins d'une ms)


    et désolé si je t'ai découragé


    info supplémentaire : tous les controles héritent de control, c'est lui qui gère la transparence et bien d'autres choses sur onpaintbackground
    le problème aussi du framework c'est que onpaintbackground est appelé un peu trop souvent à mon gout, et 2x plus sur certains pc (à priori selon la carte graphique)
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  5. #5
    Membre éclairé Avatar de PoZZyX
    Inscrit en
    Août 2005
    Messages
    426
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 426
    Par défaut
    Non ça va tu ne m'a pas décourragé (je suis courrageux ), je te remercie pour tes infos je vais travailler tout ça.

    En tout cas merci bcp pour ton aide !!

  6. #6
    Rédacteur
    Avatar de Erakis
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2003
    Messages
    523
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 523
    Par défaut
    Bonjour à tous,

    Et bien voilà, j'ai le même problème que vous tous

    J'ai besion d'un panel transparent qui lui même doit héberger des label transparent. J'ai suivi votre discussion et j'en suis venu à la conclusion que je devais ré-écrire des composants.

    Donc je prend une capture du background du parent (form) et je la copie sur le DC du panel.

    Voici ce que j'ai réalisé jusqu'ici dans le cas du Panel transparent :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
     
        class TransparentPanel : Control
        {
            public const int SRCCOPY = 13369376;
     
            [DllImport("gdi32.dll", EntryPoint = "DeleteDC")]
            public static extern IntPtr DeleteDC(IntPtr hDc);
     
            [DllImport("gdi32.dll", EntryPoint = "DeleteObject")]
            public static extern IntPtr DeleteObject(IntPtr hDc);
     
            [DllImport("gdi32.dll", EntryPoint = "BitBlt")]
            public static extern bool BitBlt(IntPtr hdcDest, int xDest,
                       int yDest, int wDest, int hDest, IntPtr hdcSource,
                       int xSrc, int ySrc, int RasterOp);
     
            [DllImport("gdi32.dll", EntryPoint = "CreateCompatibleBitmap")]
            public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc,
                       int nWidth, int nHeight);
     
            [DllImport("gdi32.dll", EntryPoint = "CreateCompatibleDC")]
            public static extern IntPtr CreateCompatibleDC(IntPtr hdc);
     
            [DllImport("gdi32.dll", EntryPoint = "SelectObject")]
            public static extern IntPtr SelectObject(IntPtr hdc, IntPtr bmp);
     
            [DllImport("user32.dll", EntryPoint = "ReleaseDC")]
            public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDc);
     
            [DllImport("user32.dll", EntryPoint = "GetDC")]
            public static extern IntPtr GetDC(IntPtr ptr);
     
            private BufferedGraphics bufferedGraphics;
     
            public TransparentPanel()
            {
                SetStyle( ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);
                BufferedGraphicsManager.Current.MaximumBuffer = new Size(this.Width + 1, this.Height + 1);
                bufferedGraphics = BufferedGraphicsManager.Current.Allocate(this.CreateGraphics(), ClientRectangle);
            }
     
            protected override void OnPaintBackground(PaintEventArgs pevent)
            {
                // base.OnPaintBackground(pevent);
            }
     
            protected override void OnPaint(PaintEventArgs e)
            {
                Bitmap b = GetWindowBackgroundAsBitmap( this.Parent.Handle, this.Left, this.Top, this.Width, this.Height);
                bufferedGraphics.Graphics.DrawImage(b, 0, 0);
                bufferedGraphics.Render(e.Graphics);
                //base.OnPaint(e);
            }
     
            public static Bitmap GetWindowBackgroundAsBitmap(IntPtr wndHWND, int x, int y, int width, int height)
            {
                IntPtr wndHDC = GetDC(wndHWND);
                IntPtr capHDC = CreateCompatibleDC(wndHDC);
                IntPtr capBMP = CreateCompatibleBitmap(wndHDC, width, height);
                if (capBMP == IntPtr.Zero)
                {
                    ReleaseDC(wndHWND, wndHDC);
                    DeleteDC(capHDC);
                    return null;
                }
     
                IntPtr prvHDC = (IntPtr)SelectObject(capHDC, capBMP);
                BitBlt(capHDC, 0, 0, width, height, wndHDC, x, y, SRCCOPY);
                SelectObject(capHDC, prvHDC);
     
                Bitmap bmp = System.Drawing.Image.FromHbitmap(capBMP);
     
                ReleaseDC(wndHWND, wndHDC);
                DeleteDC(capHDC);
                DeleteObject(capBMP);
     
                return bmp;
            }              
        }
    Cependant, cela ne semble pas fonctionner, le panel ne se dessine pas. Pourtant si je sauvegarde le bitmap que la fonction de capture me génère, c'est exactement l'image qui correspond à l'arrière plan. Qu'est-ce qui ne fonctionne pas exactement ?

    Merci à tous

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

Discussions similaires

  1. Problème avec l'arrière plan d'un JComboBox
    Par amine1980 dans le forum AWT/Swing
    Réponses: 2
    Dernier message: 11/02/2011, 00h19
  2. Réponses: 3
    Dernier message: 27/11/2008, 16h50
  3. Encore un souci avec l'arrière-plan Word !
    Par spyto dans le forum Word
    Réponses: 5
    Dernier message: 28/05/2008, 15h24
  4. Réponses: 4
    Dernier message: 21/05/2007, 07h34
  5. Afficher un fond en arrière plan avec des boutons
    Par eGen dans le forum Agents de placement/Fenêtres
    Réponses: 15
    Dernier message: 03/04/2005, 23h37

Partager

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