Transparent BackColor in Gauge

Posted by: olkasu on 27 September 2017, 9:10 pm EST

    • Post Options:
    • Link

    Posted 27 September 2017, 9:10 pm EST

    Hello Guys

    I have a problem with transparent backcolor in Gauge and hope you will help me.

    So in example there are 2 gauges. 1- UserControl with gauge, 2 - simple Gauge with transparent BackColor.

    the problem with first gauge is: during changing value of c1RadialGauge1- the circle round gauge became thicker and thicker. With second gauge, when I put button near the gauge, you will see that only the part of this button is visible.

    So what should I do?

    Thanks a lot.

    2017/02/WindowsFormsApplication3.zip

  • Posted 27 September 2017, 9:10 pm EST

    Hi,

    #Issue 1: Changing the value of c1RadialGauge1- the circle round gauge became thicker and thicker:

    Please share which build you are using. The current build works fine with your sample.

    #Issue 2: Transparent back colour hiding button:

    In GDI+, when a control paints a transparent background, it does not actually paint ARGB(0, X, X, X), but it gets BackColor of its parent and paint it on its surface. This is how GDI+ works. All you can do in this case is to bring the button control in front of your user control.

    ~nilay

  • Posted 27 September 2017, 9:10 pm EST

    Thank a lot for answering.

    Current version of components which I use is 4.0.20152.74

    Could you please tell me which version of Components is the nearest to my version,

    where this bug is fixed.

    thanks.

  • Posted 27 September 2017, 9:10 pm EST

    Hi,

    I have tested this against the build which you have provided. Unfortunately, I cannot reproduce the circle round gauge becoming thicker. Perhaps the issue is because of the environment. Please share the following

    1. VS version
    2. .Net Framework which you are building this against
    3. OS version and platform details

    Meanwhile, you can download builds of different versions from:

    http://prerelease.componentone.com/dotnet40/c1winforms/

    browse to …\bin\v4.0\ and reference the dlls.

    Test it against other versions at your end. There is a good chance that the issue is fixed in one of the versions. If not, this issue could be caused by the environment, in which case, we need to reproduce this at our end.

    ~nilay

  • Posted 27 September 2017, 9:10 pm EST

    Thanks Nilay

    1. Microsoft Visual C# 2010
    2. .Net Framework 4 Client Profile
    3. Windows 8.1. Pro, 64-bit

    Also I attach 2 files before value changing (11.png) and after (22.png).

    You can see that border became thicker and not smooth.

  • Posted 27 September 2017, 9:10 pm EST

    Nilay hi,

    I have an idea how to refresh UserControl with gauge when the value is changed without repaint all gauge,

    we can use Invalidate(region) and only repaint Pointer,

    but in this case I need the coordinates of Pointer, maybe you

    can help me with this question, sue you should have inner property for this Control.

    Thanks.

  • Posted 27 September 2017, 9:10 pm EST

    Hi,

    Unfortunately, you cannot actually deny painting the user control if it decides to repaint itself. Also, the gauge region when painted would draw a rectangular region.

    ~nilay

  • Posted 27 September 2017, 9:10 pm EST

    Hi

    In attached example in UserControl with transparent backcolor I paint Gauge from Image

    I try this on the latest version of components,

    but every time when the radialgauge value is changed, the image is repainted and we see the border at the

    Gauge like in pic22. It becomes thicker and not smooth. Do you see it? (please compare pic11 and pic22)

    So I try to repaint not all image but only the part of it (by using Invalidate(Region)), repaint only POINTER and in this case the border is ok, but I need the coordinate of Pointer(Location and Size).

    Could you please help me in this case?

    Thanks a lot.

  • Posted 27 September 2017, 9:10 pm EST

    Hi olkasu,

    This problem is in your code, not in C1Gauge. When you get the image with c1Gauge1.GetImage() it

    contains semi-transparent pixels at the border of the gauge. After changing value the OnPaint method draws the image once again but it doesn’t clear the previous image because of “SetStyle(ControlStyles.Opaque, true);”

    When you paint semi-transparent pixels over and over they eventually become “black”.

    If you remove “SetStyle(ControlStyles.Opaque, true);” the gauge starts to flicker each time when the value is changed because the UserControl fills its background with Form’s background color to simulate transparency.

    To get rid of flickering you can add:

    [csharp]SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);

    [/csharp]to the constructor of UserControl2 and remove “g.Dispose();” from the OnPaint method because that’s a bug.

    As the result of all those manipulations the first and second gauges will be drawn similarly, i.e. the button is still covered with either UserControl or C1Gauge.

    If you need real transparency use the layered popup window that is drawn with UpdateLayeredWindow API:

    [csharp][DllImport(“user32.dll”, ExactSpelling = true)]

    internal static extern bool UpdateLayeredWindow(

    IntPtr hwnd,

    IntPtr hdcDst,

    ref Win32.POINT pptDst,

    ref Win32.SIZE psize,

    IntPtr hdcSrc,

    ref Win32.POINT pptSrc,

    int crKey,

    ref Win32.BLENDFUNCTION pBlend,

    int dwFlags);

    [StructLayout(LayoutKind.Sequential, Pack = 1)]

    internal struct BLENDFUNCTION

    {

    public byte BlendOp;

    public byte BlendFlags;

    public byte SourceConstantAlpha;

    public byte AlphaFormat;

    }

    [StructLayout(LayoutKind.Sequential)]

    internal struct POINT

    {

    public int x;

    public int y;

    public POINT(int x, int y)
    {
        this.x = x;
        this.y = y;
    }
    

    }

    [StructLayout(LayoutKind.Sequential)]

    internal struct SIZE

    {

    public int cx;

    public int cy;

    public SIZE(int width, int height)
    {
        cx = width;
        cy = height;
    }
    

    }

    protected override CreateParams CreateParams

    {

    [SecurityPermission(SecurityAction.LinkDemand)]

    get

    {

    CreateParams cp = base.CreateParams;

    cp.Style = Win32.WS_POPUP;

    cp.ExStyle = Win32.WS_EX_LAYERED | Win32.WS_EX_NOACTIVATE;

    cp.ClassStyle = 0;

    return cp;

    }

    }

    protected override void OnHandleCreated(EventArgs e)

    {

    base.OnHandleCreated(e);

    UpdateLayeredGaugeWindow();

    }

    [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]

    protected override void WndProc(ref Message m)

    {

    base.WndProc(ref m);

    if (m.Msg == Win32.WM_MOUSEACTIVATE)

    {

    m.Result = new IntPtr(Win32.MA_NOACTIVATE);

    }

    }

    internal void ShowNoActivate()

    {

    NativeMethods.ShowWindow(Handle, Win32.SW_SHOWNOACTIVATE);

    }

    internal void BringGaugeToFront(bool topMost)

    {

    NativeMethods.SetWindowPos(Handle, topMost ? new IntPtr(Win32.HWND_TOPMOST) : IntPtr.Zero, Left, Top, Width, Height,

    Win32.SWP_NOACTIVATE | Win32.SWP_NOOWNERZORDER | Win32.SWP_NOSIZE | Win32.SWP_NOMOVE);

    }

    internal void UpdateLayeredGaugeWindow()

    {

    Bitmap bitmap = PrepareBitmapWithC1Gauge();

    IntPtr screenDc = NativeMethods.GetDC(IntPtr.Zero);

    IntPtr memDc = NativeMethods.CreateCompatibleDC(screenDc);

    IntPtr hBitmap = IntPtr.Zero;

    IntPtr oldBitmap = IntPtr.Zero;

    try

    {

    hBitmap = bitmap.GetHbitmap(Color.FromArgb(0));

    oldBitmap = NativeMethods.SelectObject(memDc, hBitmap);

    Win32.SIZE size = new Win32.SIZE(_bmpWidth, _bmpHeight);

    Win32.POINT ptSrc = new Win32.POINT(0, 0);

    Win32.POINT ptDst = new Win32.POINT(_x, _y);

    Win32.BLENDFUNCTION blend = new Win32.BLENDFUNCTION();

    blend.BlendOp = Win32.AC_SRC_OVER;

    blend.BlendFlags = 0;

    blend.SourceConstantAlpha = 255;

    blend.AlphaFormat = Win32.AC_SRC_ALPHA;

    NativeMethods.UpdateLayeredWindow(Handle, screenDc, ref ptDst, ref size, memDc, ref ptSrc, 0, ref blend, Win32.ULW_ALPHA);

    }

    finally

    {

    NativeMethods.ReleaseDC(IntPtr.Zero, screenDc);

    if (hBitmap != IntPtr.Zero)

    {

    NativeMethods.SelectObject(memDc, oldBitmap);

    NativeMethods.DeleteObject(hBitmap);

    }

    NativeMethods.DeleteDC(memDc);

    }

    }

    [/csharp]

    Something like that. Hope that helps.

    Regards,

    -Andrey

  • Posted 27 September 2017, 9:10 pm EST

    I’m just curious why people ask for the real transparency in C1Gauge? If you bring the button to the front of C1Gauge, how is that different from what are you looking for? If you need to layout several gauges side by side the best option would be to put them all into a single C1Gauge control.

    Thanks in advance.

    -Andrey

  • Posted 27 September 2017, 9:10 pm EST

    Hi olkasu,

    “this example is good, when we want to make all form or control transparent”

    This is a limitation of the SetLayeredWindowAttributes function. With the UpdateLayeredWindow method you can specify per-pixel transparency. For example, we use UpdateLayeredWindow in C1RibbonForm to draw semi-transparent gradients on the resizable borders.

    Regards,

    -Andrey

  • Posted 27 September 2017, 9:10 pm EST

    Hi Guys

    I can’t use this function for UserControl!

    So what can you recommend, I really need transparent backcolor and no flicking control when the value of gauge is changed.

    Could you give me some example with using this function in UserControl with Gauge.

    Tnahks a lot.

  • Posted 27 September 2017, 9:10 pm EST

    Hi,

    UpdateLayeredWindow/SetLayeredWindowAttributes are applicable on Forms only.

    ~nilay

  • Posted 27 September 2017, 9:10 pm EST

    Hi,

    thanks for answering. I understand this. According to my task: I need UserControl with Gauge with backcolor transparent and when the value in gauge is changed : this UserControl will not flick will not paint its border thicker and thicker. I attach example where you can see these bugs. There are 3 UserControls: diod and 2 gauges. Diod changes its color by clicking on checkbox = no flicking. Gauges change values by changing value at numericUpDown - flicking or lines on gauge became thicker and thicker.

    What can you recommend to do?

    THANKS!

    2017/04/Test0420.rar

  • Posted 27 September 2017, 9:10 pm EST

    Hi,

    Let me consult with the devs for this.

    (255415)

    ~nilay

  • Posted 27 September 2017, 9:10 pm EST

    Hi Andrey

    THANKS A LOT for answering!

    “I’m just curious why people ask for the real transparency in C1Gauge? If you bring the button to the front of C1Gauge, how is that different from what are you looking for? If you need to layout several gauges side by side the best option would be to put them all into a single C1Gauge control.”

    Example with button maybe was not real good. In my project User should have an opportunity to put gauges (at runtime) at work list(resize them, move them and so on). So I really need backcolor transparent and dispose of flickering during the value of gauge is changed.

    p.s. Thanks for example!

  • Posted 27 September 2017, 9:10 pm EST

    Hi,

    this example is good, when we want to make all form or control transparent, but in my case i want to make transparent only gauge but radialgauge should not be transparent. What can you recommend?

    Thanks a lot.

  • Posted 27 September 2017, 9:10 pm EST

    Hi olkasu,

    Sorry for delay, for some strange reason I don’t receive notification messages from this forum. I’ll try to create a sample with transparent UserControl and Gauge in a day or two, then let you know.

    Regards,

    -Andrey

  • Posted 27 September 2017, 9:10 pm EST

    Hi olkasu,

    Please take a look at the attached sample. It supports transparency for UserControls and Gauges. Hope that helps.

    Regards,

    -Andrey

    2017/04/TransparentTest.zip

  • Posted 27 September 2017, 9:10 pm EST

    The sample can be greatly simplified if your app targets only Windows 8/10. Child windows can be layered starting from Windows 8. That makes things much easier.

    Regards,

    -Andrey

  • Posted 27 September 2017, 9:10 pm EST

    Attached is another version of the same sample. Now it works better on Windows 8.1 and Windows 10. Also, the TransparentHost supports the standard controls with simulated transparency.

    Regards,

    -Andrey

    Update: The third version of the sample is attached :slight_smile:

    2017/04/TransparentTest2.zip

    2017/04/TransparentTest3.zip

    2017/05/TransparencyTest2.zip

  • Posted 27 September 2017, 9:10 pm EST

    Hi, Andrey

    Many many many thanks!!! It works great!!! You are my HERO !!! :slight_smile:

  • Posted 27 September 2017, 9:10 pm EST

    Thanks olkasu :slight_smile:

    You can find more info in the attached document.

    2017/05/Transparency.docx

  • Posted 27 September 2017, 9:10 pm EST

    Hi, Andrey

    I have worked with controls having Window 8. Everything works perfectly!

    But when I try to work on Windows7, I have some bugs and unfortunatly can not

    fix them without your help.

    1. When I create control at runtime and call function Control.ActivateTransparentMode()

      this Control has wrong Location and Setting the right Hostlocation did not bring the right result.
    2. When I move the form where the controls are located, I can not click on Checkbox or move track.
    3. Also controls moving does not work correctly.

    Could you please look once more at one of your example using Windows 7.

    Many many thanks!

    Best regards Olga Sukha

  • Posted 27 September 2017, 9:10 pm EST

    Hi Olga,

    Please find the updated sample in the attachment. Now it works better in Windows 7. Also, I added the “Add New Button” button. Hope that helps.

    Regards,

    -Andrey

    2017/06/TransparencyTest2.zip

  • Posted 27 September 2017, 9:10 pm EST

    Thank you Andrey. Everything works Great!:slight_smile:

  • Posted 27 September 2017, 9:10 pm EST

    Hi Andrey,

    This Windows 7 makes me crazy((((( Sorry for interrupting you,

    but I am really loser in these api functions (( Could you help me one more time?

    1. Is it possible to put c1Label on GaugeHost (not to make it HostLabel)?
    2. Is it possible to sendback ButtonHost and c1Button will be in front?
    3. Is it possible not to set parent null for HostControls in Windows7?

    Many many thanks!!!

    Best regards Olga Sukha

  • Posted 27 September 2017, 9:10 pm EST

    Hi Olga,

    1. Is it possible to put c1Label on GaugeHost (not to make it HostLabel)?

    Yes, it’s easy. Add a C1Label to GaugeHost, then add:

    DrawControl(g, c1Label1, this.BackColor);

    at the end of the GaugeHost.RenderControl method. You can set some non-default background for c1Label1 to make it more visible.

    Also, you probably need to add the following handler for the C1Label.TextChanged event:

    private void c1Label1_TextChanged(object sender, EventArgs e)

    {

    Invalidate();

    }

    1. Is it possible to sendback ButtonHost and c1Button will be in front?

    Sorry, I don’t understand what are you trying to do. If C1Button is a child control of the ButtonHost you can’t send the parent control to back and its child to front.

    1. Is it possible not to set parent null for HostControls in Windows7?

    No. Layered and child windows are mutually exclusive on Windows 7. This is a limitation of the OS. Your window either has not-null Parent or it is partially transparent.

    Regards,

    -Andrey

  • Posted 27 September 2017, 9:10 pm EST

    Thanks for answering :slight_smile:

    I have a c1Label with parent Panel(not HostLabel) and GaugeHost and at runtime I want to move Label and set it like at attached Picture - how can I do it?

    Or I want to sendBack GaugeHost and C1Label BringTofront.

    • maybe it is not possible in windows7, maybe I should make all controls (c1Label, C1textbox and so on) - hostcontrols.

    Best regards Olga Sukha

  • Posted 27 September 2017, 9:10 pm EST

    Hi Olga,

    Only host controls can appear in front of other host controls on Windows 7.

    I have no ideas about any workaround for that.

    Regards,

    -Andrey

  • Posted 15 October 2018, 3:40 am EST

    it is not possible in windows7.

    any issue related to Microsoft Outlook issue get help from this https://www.outlooktechnicalsupportnumbers.com/blog/microsoft-outlook-not-implemented/

Need extra support?

Upgrade your support plan and get personal unlimited phone support with our customer engagement team

Learn More

Forum Channels