3

Sorry for that very confusing title, here's my problem. I have a custom GroupBox, and inside of that is a custom picturebox and label.

The issue is, when I launch the form application whenever my mouse enters the GroupBox my my label's font color changes to black and my picture box seems to have "disappeared". I don't have a clue why that is.

GroupBox:

Class GhostGroupBox
    Inherits ThemeControl154

    Sub New()
        MyBase.New()
        SetStyle(ControlStyles.ResizeRedraw, True)
        SetStyle(ControlStyles.ContainerControl, True)
        DoubleBuffered = True
        BackColor = Color.Transparent
    End Sub

    Protected Overrides Sub ColorHook()

    End Sub

    Protected Overrides Sub PaintHook()
        G.Clear(Color.FromArgb(60, 60, 60))
        Dim asdf As HatchBrush
        asdf = New HatchBrush(HatchStyle.DarkDownwardDiagonal, Color.FromArgb(35, Color.Black), Color.FromArgb(0, Color.Gray))
        G.FillRectangle(New SolidBrush(Color.FromArgb(60, 60, 60)), New Rectangle(0, 0, Width, Height))
        asdf = New HatchBrush(HatchStyle.LightDownwardDiagonal, Color.DimGray)
        G.FillRectangle(asdf, 0, 0, Width, Height)
        G.FillRectangle(New SolidBrush(Color.FromArgb(230, 20, 20, 20)), 0, 0, Width, Height)
        G.FillRectangle(New SolidBrush(Color.FromArgb(70, Color.Black)), 1, 1, Width - 2, Me.CreateGraphics.MeasureString(Text, Font).Height + 8)

        G.DrawLine(New Pen(Color.FromArgb(90, 90, 90)), 1, Me.CreateGraphics.MeasureString(Text, Font).Height + 8, Width - 2, Me.CreateGraphics.MeasureString(Text, Font).Height + 8)

        DrawBorders(Pens.Black)
        DrawBorders(New Pen(Color.FromArgb(90, 90, 90)), 1)
        G.DrawString(Text, Font, Brushes.White, 5, 5)
    End Sub
End Class

Label & PictureBox (same code, just inherits the respective):

Public Class TransparentLabel
    Inherits Label

    Public Sub New()
        Me.SetStyle(ControlStyles.Opaque, True)
        Me.SetStyle(ControlStyles.OptimizedDoubleBuffer, False)
    End Sub

    Protected Overrides ReadOnly Property CreateParams() As CreateParams
        Get
            Dim parms As CreateParams = MyBase.CreateParams
            parms.ExStyle = parms.ExStyle Or &H20
            ' Turn on WS_EX_TRANSPARENT
            Return parms
        End Get
    End Property

End Class

Can someone see what's wrong? I tried commenting out the ControlBox's OnMouseMove, that didn't fix it. I also don't have any events set for the ControlBox.

DannyF247
  • 628
  • 4
  • 14
  • 35
  • Visual Basic wasn't a tag, VBA is Visual Basic Application so I thought that might be it. Sorry, I've removed the tag as I now re-read what VBA is. – DannyF247 Sep 02 '12 at 05:42

2 Answers2

3

Without working code it’s hard to say, I have two suggestions:

  1. Change Invalidate in OnMouseMove to Invalidate(True) so GroupBox's children get refreshed too. Child controls might not get a paint message.

  2. For a transparent control you should use SetStyle(ControlStyles.SupportsTransparentBackColor Or ControlStyles.UserPaint, True) In OnHandleCreated rather than setting the ExStyle in CreateParams. Plus &H20 means WS_EX_TRANSPARENT while in the constructor you set the control to be opaque.

Elmo
  • 6,409
  • 16
  • 72
  • 140
RollingCog
  • 294
  • 1
  • 5
  • Firstly, welcome to Stack Overflow! I updated the OP, the code for the GroupBox before was the wrong code, not the code I was using. I added the `OnMouseMove` to the correct section because it didn't exist, and made it `Invalidate(True)`. That seems to work most of the time, but it's not 100% reliable. The 2nd option crashed Visual Basic 2012 Express completely. So this will work for now, but I'll wait to accept this answer to see if someone else has a better solution. – DannyF247 Sep 02 '12 at 19:26
  • Just an FYI, your solution make it seem to flicker rapidly when I put my mouse in there, and when the mouse leaves most controls inside have disappeared. – DannyF247 Sep 04 '12 at 02:41
  • Flicker usually means double buffering isn't enabled. I see you turned on DoubleBuffered but may I suggest good old fashioned SetStyle? Double buffering is only activated with UserPaint style flag and it may not be set. On an unrelated note SetStyle should only be called after handle is created so constructor isn't a good place for it. OnHandleCreated? For the MouseLeave part without working code I can't really tell. – RollingCog Sep 04 '12 at 18:44
  • I'm sorry, could you tell me what code I need to include? I'm a noob at design and things like this, and didn't understand much of what you just wrote. – DannyF247 Sep 04 '12 at 22:04
1

I have another suggestion - clone your project and try to simplify your code there, to a point where it still has the problem, but is generic enough that you can publish it here. Also, you did not describe what all your custom controls are supposed to do. Other than that, have you tried the following to reduce flickering?

SendMessage(Me.Handle, WM_SETREDRAW, False, 0) ' Turn OFF UI updates

and

SendMessage(Me.Handle, WM_SETREDRAW, True, 0) ' Turn ON UI updates

I am using it for custom dropdown control in my project and it works well.

DoubleBuffered is useless, according to my experience.

For SendMessage to be available, you need to import it from user32:

Private Const WM_SETREDRAW As Integer = &HB
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal handle As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer

You would turn UI updates off before any processing inside PaintHook (the very first line), and turn it back on after all processing is done. Also need to call Me.Refresh() after SendMessage(...True...), otherwise you would get no updates at all.

Elmo
  • 6,409
  • 16
  • 72
  • 140
Victor Zakharov
  • 25,801
  • 18
  • 85
  • 151
  • `SendMessage is not declared.` I put this right under `DoubleBuffered`, is this correct? Sorry I don't know much about stuff like this. – DannyF247 Sep 07 '12 at 04:02
  • @DannyF247: You need to wrap your custom drawing with SendMessage lines, turning off and on UI updates respectively. I updated the answer with new information. – Victor Zakharov Sep 07 '12 at 11:17
  • I've done exactly as you said, turned off updates at start of PaintHook, re-enabled at end of PaintHook and then did `Me.Refresh()`, but it still flickers :/ Any suggestions? – DannyF247 Sep 07 '12 at 22:22
  • Create a POC (proof-of-concept) project and try to reproduce there. If you can, publish it here, maybe somebody will have a look. It's part of a regular debugging/troubleshooting procedure - and your responsibility as a programmer. – Victor Zakharov Sep 08 '12 at 11:52