Problem de Controle invisible [Résolu]

Signaler
Messages postés
22
Date d'inscription
jeudi 9 octobre 2008
Statut
Membre
Dernière intervention
23 octobre 2012
-
Messages postés
834
Date d'inscription
samedi 15 novembre 2008
Statut
Membre
Dernière intervention
14 janvier 2017
-
Bonjour a tous

voila je suis en train de tester plusieurs système de transparence sur une form , le probleme est que mes controles (ProgressBar et Co...) sont invisibles avec cette méthode

voici la methode
public partial class EDSplash : Form
    {
        string downloadUrl = "";
        Version newVersion = null;
        string xmlUrl = "http://localhost/updates/launcher.xml";
        XmlTextReader reader = null;

        public EDSplash()
        {
            InitializeComponent();
            tCheck.Start();
        }

        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x00080000;
                return cp;
            }
        }

        public void UpdateFormDisplay(Image backgroundImage)
        {
            IntPtr screenDc = API.GetDC(IntPtr.Zero);
            IntPtr memDc = API.CreateCompatibleDC(screenDc);
            IntPtr hBitmap = IntPtr.Zero;
            IntPtr oldBitmap = IntPtr.Zero;

            try
            {
                Bitmap bmp = new Bitmap(backgroundImage);
                hBitmap = bmp.GetHbitmap(Color.FromArgb(0));
                oldBitmap = API.SelectObject(memDc, hBitmap);

                Size size = bmp.Size;
                Point pointSource = new Point(0, 0);
                Point topPos = new Point(this.Left, this.Top);

                API.BLENDFUNCTION blend = new API.BLENDFUNCTION();
                blend.BlendOp = 0;
                blend.BlendFlags = 0;
                blend.SourceConstantAlpha = 255;
                blend.AlphaFormat = API.AC_SRC_ALPHA;

                API.UpdateLayeredWindow(this.Handle, screenDc, ref topPos, ref size, memDc, ref pointSource, 0, ref blend, API.ULW_ALPHA);
                bmp.Dispose();
                API.ReleaseDC(IntPtr.Zero, screenDc);
                if (hBitmap != IntPtr.Zero)
                {
                    API.SelectObject(memDc, oldBitmap);
                    API.DeleteObject(hBitmap);
                }
                API.DeleteDC(memDc);

                pBUpdate.Visible = true;
                lblStatus.Visible = true;
            }
            catch (Exception)
            {
            }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            UpdateFormDisplay(this.BackgroundImage);
        }

        private void checkForUpdate(object sender, System.EventArgs e)
        {
            try
            {
                reader = new XmlTextReader(xmlUrl);
                reader.MoveToContent();
                string elementName = "";
                if ((reader.NodeType XmlNodeType.Element) && (reader.Name "launcher"))
                {
                    while (reader.Read())
                    {
                        if (reader.NodeType == XmlNodeType.Element)
                        {
                            elementName = reader.Name;
                        }
                        else
                        {
                            if ((reader.NodeType == XmlNodeType.Text) && (reader.HasValue))
                            {
                                switch (elementName)
                                {
                                    case "version":
                                        newVersion = new Version(reader.Value);
                                        break;
                                    case "url":
                                        downloadUrl = reader.Value;
                                        break;
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception)
            {

            }
            finally
            {
                if (reader != null)
                    reader.Close();
            }

            Version applicationVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
            if (applicationVersion.CompareTo(newVersion) < 0)
            {
                NotifyUpdate();
            }
            else
            {
                this.Hide();
                tCheck.Stop();
                EDMainForm mf = new EDMainForm();
                mf.Show();
                mf.initSkin();
            }
        }

        private void NotifyUpdate()
        {
            /*
            downloadUrl = "";
            WebClient webClient = new WebClient();
            webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
            webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
            webClient.DownloadFileAsync(new Uri(downloadUrl + "Updater.exe"), "Updater.exe");
             */
        }

        private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e)
        {
            pBUpdate.Value = e.ProgressPercentage;
        }

        private void Completed(object sender, AsyncCompletedEventArgs e)
        {
            this.Hide();
            Process.Start("updater.exe");
            this.Close();
        }

        private void tCheck_Tick(object sender, EventArgs e)
        {
            pBUpdate.Visible = true;
            lblStatus.Visible = true;
            
            tCheck.Tick += new System.EventHandler(this.checkForUpdate); 
            pBUpdate.Value = 100;
        }

        private void EDSplash_Load(object sender, EventArgs e)
        {
            UpdateFormDisplay(this.BackgroundImage);
        }
}

    internal class API
    {
        public const byte AC_SRC_OVER = 0x00;
        public const byte AC_SRC_ALPHA = 0x01;
        public const Int32 ULW_ALPHA = 0x00000002;

        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct BLENDFUNCTION
        {
            public byte BlendOp;
            public byte BlendFlags;
            public byte SourceConstantAlpha;
            public byte AlphaFormat;
        }

        [DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
        public static extern bool UpdateLayeredWindow(IntPtr hwnd, IntPtr hdcDst, ref Point pptDst, ref Size psize, IntPtr hdcSrc, ref Point pprSrc, Int32 crKey, ref BLENDFUNCTION pblend, Int32 dwFlags);


        [DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
        public static extern IntPtr GetDC(IntPtr hWnd);

        [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
        public static extern IntPtr CreateCompatibleDC(IntPtr hDC);

        [DllImport("user32.dll", ExactSpelling = true)]
        public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);

        [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
        public static extern bool DeleteDC(IntPtr hdc);


        [DllImport("gdi32.dll", ExactSpelling = true)]
        public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);

        [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
        public static extern bool DeleteObject(IntPtr hObject);
    }


Quelqu'un aurai une idée pour rendre mes controle de nouveau visible tout en gardant cette méthode , que je trouve la plus performante de toutes celles que j'ai pu trouver

10 réponses

Messages postés
22
Date d'inscription
jeudi 9 octobre 2008
Statut
Membre
Dernière intervention
23 octobre 2012

Problème résolu,
Robert33 je pense que ça devrais te plaire

http://www.codeproject.com/KB/graphics/alphaBG.aspx

Merci encore pour votre aide
Messages postés
22
Date d'inscription
jeudi 9 octobre 2008
Statut
Membre
Dernière intervention
23 octobre 2012

Je vois que ce forum remplis bien la première fonctionnalité d'un forum , c'est a dire l'entre aide et la communication!
Messages postés
15063
Date d'inscription
lundi 11 juillet 2005
Statut
Modérateur
Dernière intervention
18 juin 2021
95
Salut,
Ce n'est pas très sympa de critiquer l'activité des membres... dès le 5e message posté...surtout en cette période de congés...
Un peu de patience jeune Padawan...

J'ai trouvé un article parlant de la transparence avec les WinForms, ainsi qu'un article sur la KB MSDN

Hope it will help you...

@+
Buno
----------------------------------------
L'urgent est fait, l'impossible est en cours. Pour les miracles, prévoir un délai...
Messages postés
22
Date d'inscription
jeudi 9 octobre 2008
Statut
Membre
Dernière intervention
23 octobre 2012

Loin de moi de critiquer, c est juste une remarque déplacé,
Et il me semble que toutes inscription sur un site web signifie le commencement d'une activité au prés de celui ci, tout le monde commence toujours a un moment ou un autres , quelque en soit les domaines,

cependant je te remercie pour ta réponse et vais regarde ça de suite.
Thx u sir ;)
Messages postés
22
Date d'inscription
jeudi 9 octobre 2008
Statut
Membre
Dernière intervention
23 octobre 2012

Ces 2 articles sont pas ce que je recherche, en fait ma form est bien transparent je n ai aucun soucis avec ça, le seul problème est que si je rajoute un contrôle dessus(webbrowser , progressbar , textbox , label)enfin tout ce qu'il peut y avoir dans la boite a outils est invisible sur ma form.

J utilise une class blendalfapixel qui rend une image avec une ombre semi transparente en important la dll gdi(mauvais rendu avec les options classiques ==> color et transparencycolor).
Messages postés
834
Date d'inscription
samedi 15 novembre 2008
Statut
Membre
Dernière intervention
14 janvier 2017
30
Bonjour

J'ai regardé un peu ton code, et j'avoue ne pas bien comprendre ce que tu veux faire.

Si tu veux une forme invisible avec des controles visibles, alors utilise la propriété TransparentKey
cet exemple fonctionne, et je te garantis que les controles seront visibles sur une forme invisible (pense à enlever la barre de titre de la forme).

private void button1_Click(object sender, EventArgs e)
{
if (TransparencyKey == Color.Empty)
{
this.TransparencyKey = this.BackColor; 
}
else
{
this.TransparencyKey = Color.Empty;
}
}

Si tu veux une image de fond semi transparente, alors il te faudra la dessiner toi même, car la propriété Opacity de la Form agit également sur ses controles.
Exemple (pictureBox1 est en Dock=Fill et en fond de forme)
private void button1_Click(object sender, EventArgs e)
{
if (TransparencyKey == Color.Empty)
{
pictureBox1.Image = ChangeOpacity(Image.FromFile("image.png"), 0.5f); 

this.TransparencyKey = this.BackColor;
}
else
{
pictureBox1.Image = ChangeOpacity(Image.FromFile("image.png"), 1f); 
this.TransparencyKey = Color.Empty;
}

}
public Bitmap ChangeOpacity(Image img, float opacityvalue)
{
Bitmap bmp = new Bitmap(img.Width, img.Height);
Graphics graphics = Graphics.FromImage(bmp);
ColorMatrix colormatrix = new ColorMatrix();
colormatrix.Matrix33 = opacityvalue;
ImageAttributes imgAttribute = new ImageAttributes();
imgAttribute.SetColorMatrix(colormatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
graphics.DrawImage(img, new Rectangle(0, 0, bmp.Width, bmp.Height), 0, 0, img.Width, img.Height, GraphicsUnit.Pixel, imgAttribute);
graphics.Dispose();
return bmp;
}


Bon Code
Bob.
C# is amazing, enjoy it!
Messages postés
22
Date d'inscription
jeudi 9 octobre 2008
Statut
Membre
Dernière intervention
23 octobre 2012

Le problème TransparencyKey est que si l image a une ombre sur dégradée le rendu est horrible

exemple:
TransparencyKey = color.red
Backcolor = color.red

La form sera bien transparente mais les bordures seront "dégueulasse" ( pardonnez mon expression) car les bordure commenceront opaque et finiront transparente et le rouge se verra donc sur les bordures de limage, d ou mon utilisation de gdi pour un rendu bien plus propre.

je pense qu en image vous comprendrai mieu

donc voici ma form depuis le concepteur de vues
http://img11.hostingpics.net/pics/14902994p1.jpg

et la le rendu au debug
http://img11.hostingpics.net/pics/52779889p2.jpg

Mon problème de contrôle ce trouve a ce moment la ils sont invisibles.
Messages postés
834
Date d'inscription
samedi 15 novembre 2008
Statut
Membre
Dernière intervention
14 janvier 2017
30
Bonsoir

OK là je comprends :-D

Je pense que l'utilisation de la fonction UpdateLayeredWindow doit agir de la même manière que la propriété Opacity.
c-a-d que les controles du formulaire sont également impactés, donc transparents.
(en fait les contrôles ont le même canal Alpha que le formulaire parent)

Il faudrait donc les redéssiner à la main, sous fome d'image, de la même maniere que ton image de fond car je ne vois pas comment on pourrait forcer la "Form" une transparence complete et pas ses controles.

mais je suis preneur s'il y a des idées...

Bob.
C# is amazing, enjoy it!
Messages postés
22
Date d'inscription
jeudi 9 octobre 2008
Statut
Membre
Dernière intervention
23 octobre 2012

Oui ca me donne une idée tout ca, je vais tenter d utiliser une classe toute bete pour les gifs est tout simplement faire un next frame suivant la progrssion de la profess bar ( tordu non ? ^^)

explication en code

la classe
public class GifImage
    {
        private Image gifImage;
        private FrameDimension dimension;
        private int frameCount;
        private int currentFrame = -1;
        private bool reverse;
        private int step = 1;

        public GifImage(Image path)
        {
            gifImage = global::PoissonRouge.Properties.Resources.img01;
            dimension = new FrameDimension(gifImage.FrameDimensionsList[0]);
            frameCount = gifImage.GetFrameCount(dimension);
        }

        public bool ReverseAtEnd
        {
            get
            {
                return reverse;
            }
            set
            {
                reverse = value;
            }
        }

        public Image GetNextFrame()
        {

            currentFrame += step;

            if (currentFrame >= frameCount || currentFrame < 1)
            {
                if (reverse)
                {
                    step *= -1;
                    currentFrame += step;
                }
                else
                    currentFrame = 0;
            }
            return GetFrame(currentFrame);
        }

        public Image GetFrame(int index)
        {
            gifImage.SelectActiveFrame(dimension, index);
            return (Image)gifImage.Clone();
        }
    }



et donc dans la progression de la progress bar un simple

GifImage gi = new GifImage(global::programe1.Properties.Resources.gifimg);
BackgroundImage = gi.GetNextFrame();

devrais être nickel, maintenant a voir si je peux superposer 2 images avec cette méthode
Messages postés
834
Date d'inscription
samedi 15 novembre 2008
Statut
Membre
Dernière intervention
14 janvier 2017
30
Bonsoir

En effet ça me plait bcp
merci...


Bob.
C# is amazing, enjoy it!