Results 1 to 5 of 5

Thread: Strange Coloring

  1. #1

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,109

    Strange Coloring

    I have a custom control that consists of a textbox and two buttons. There is a grid of these controls in the program. In the control, I have this property:

    Code:
    Public Overrides Property ForeColor As System.Drawing.Color
        Get
            Return tbEntry.ForeColor
        End Get
        Set(value As System.Drawing.Color)
            tbEntry.ForeColor = value
            bComment.ForeColor = Drawing.Color.Black
            bMark.ForeColor = Drawing.Color.Black
        End Set
    End Property
    The intention is that when a certain action happens, the forecolor of the textbox changes color. In practice, it will either change to red or black.

    My question is about the two lines that change the fore colors of the two buttons. If those lines are there, all is well, if those lines are not there, a very peculiar thing is happening: After the action that causes the textbox forecolor to become red, if I then move the mouse over the grid, some number of buttons will change their forecolor to red. After a few buttons have changed color (1-5, perhaps), the effect will end. The buttons that will change color need not be in any way related to the control that changed to red.

    There is no code in the program that will change the forecolor of the buttons, as they are supposed to remain black at all times. Just to be sure, I've looked for all instances of Red, and all instances of ForeColor (all of which are shown in that code snippet). I also confirmed that the call to the ForeColor property of the user control is not called when it shouldn't be, though the buttons that get colored are whatever the mouse moves over, and need not be the control that got colored.

    I suspect that the key point in that property is that the final line is setting a color to black, and that somehow the mouse is causing some strange painting issue such that it paints the forecolor to whatever the last color used was, but that's absurd. It just happens to fit the behavior.

    Can anybody explain what is going on?
    My usual boring signature: Nothing

  2. #2
    PowerPoster
    Join Date
    Nov 2017
    Posts
    3,632

    Re: Strange Coloring

    What code do you have in place either in the control itself or in the program for Mouse movement events?

  3. #3

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,109

    Re: Strange Coloring

    The answer to that is going to have to wait, as I don't have it handy. In general, I was pre-filtering mouse messages and handling the Mouse Move and Mouse Up messages. This had nothing to do with coloring things red, it was part of a drag copy action where the mouse down event captured the mouse, then mouse move events were used to select/deselect textboxes, with the selected ones being colored a light green. Either mouse up, or leaving the grid entirely, would end the mouse capture, with mouse up resulting in the copy action.

    New data entered into a textbox, either directly or by that drag copy, would cause the text for the new values to be red, which is what that property is about. Only the text in the textbox, though, never the buttons. Still, I thought that drag copy might still happening, even after the mouse up, but every test I could think of showed that it was not. The back color was never set to green, breakpoints and logging showed that drag copy did, in fact, end when it should, and so forth.
    My usual boring signature: Nothing

  4. #4

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,109

    Re: Strange Coloring

    This is ho 'Tw the mouse movements are handled, it's all a prefilter on the messages:

    Code:
     Public Function PreFilterMessage(ByRef m As System.Windows.Forms.Message) As Boolean Implements System.Windows.Forms.IMessageFilter.PreFilterMessage
         If Not Me.pDisplaySurface.IsDisposed Then
             If Me.IsHandleCreated Then
    
                 If m.HWnd = mInitiatorHandle Then
                     Dim pt As Drawing.Point = Me.pDisplaySurface.PointToClient(MousePosition)
    
                     If Me.pDisplaySurface.ClientRectangle.Contains(pt) Then
                         Dim mtb As MortalityTB = Nothing
    
                         If m.Msg = WM_MOUSEMOVE Then
                             'Only do anything if the mouse is caught. Event then, do something on only two cases:
                             '1: Not on the original cell. OR
                             '2: On the original cell, but others have been selected.
                             If mMouseCaught Then
                                 For Each mtb In mControls
                                     If mtb.Bounds.Contains(pt) Then
                                         Exit For
                                     End If
                                 Next
                                 If mtb IsNot mStartMTB OrElse mSelMan.SomeSelections Then
                                     If mtb.RUID <> selP.RUID Then
                                         mCount = mCount
                                         selP = New SelectionPoint(mtb.DayShown, mtb.RUID)
                                     End If
    
                                     If Me.horScroll.Bounds.Contains(pt) Then
                                         Me.Cursor = Cursors.PanSouth
                                         mOrdinal = 3
                                         ScrollTimer.Start()
                                     ElseIf mRightRectangle.Contains(pt) Then
                                         Me.Cursor = Cursors.PanEast
                                         mOrdinal = 2
                                         ScrollTimer.Start()
                                     ElseIf mColRectangle.Contains(pt) Then
                                         Me.Cursor = Cursors.PanNorth
                                         mOrdinal = 1
                                         ScrollTimer.Start()
                                     ElseIf mRowRectangle.Contains(pt) Then
                                         Me.Cursor = Cursors.PanWest
                                         mOrdinal = 4
                                         ScrollTimer.Start()
                                     Else
                                         Me.Cursor = Cursors.Default
                                         mOrdinal = 0
                                         ScrollTimer.Stop()
                                     End If
                                     ManageSelections(pt)
                                 End If
                             End If
                         ElseIf m.Msg = WM_LBUTTONUP Then
                             Me.Cursor = Cursors.Default
                             If mMouseCaught Then
                                 mMouseCaught = False
                                 mStartMTB = Nothing
                                 CopySelection()
                                 mSelMan.Clear()
                             End If
                           End If
                     Else
                         'Anything that happens outside, as long as the mouse is caught, should cause the end of the mouse capture.
                         Me.Cursor = Cursors.Default
                         If mMouseCaught Then
                             mInitiatorHandle = Nothing
                             mMouseCaught = False
                             mStartMTB = Nothing
                             mSelMan.Clear()
                         End If
                     End If
                 End If
             End If
         End If
    
         'This is just an intercept, so always return false.
         Return False
     End Function
    MTB stands for the custom control, which are arranged in a grid on a panel. It looks much like a DGV, but is not. There are row labels and column headers, but those are just labels that are also arranged on the panel. There may also be scroll bars, but the panel does not scroll. All the labels and the controls are fixed in number and location. If the user moves the scroll bar, it changes what is displayed in the labels and the MTB controls, but they don't move. That gives the user the appearance of scrolling up, down, left, and right, but in fact they are not. They are just refilling the controls based on the setting of the scroll bars. That's pretty much how all scrollable controls work anyways.

    Scrolling is irrelevant to this question. I haven't actually tried scrolling the incorrectly colored items off the screen to see what happens, but this shows what the mouse events are.

    In that code, it is only CopySelection that will cause the forecolor to be red. The code that does that is here, and most of it is meaningless to anyone else:

    Code:
    For Each ctl In mControls
        If ctl.DayShown = mSelMan.SelectionList(x).Day AndAlso ctl.RUID = mSelMan.SelectionList(x).RUID Then
            Dim ttime = GetEstimatedMortalityTime(mSelMan.SelectionList(x).RUID, New Date(mSelYear, Me.cbMonth.SelectedIndex + 1, mSelMan.SelectionList(x).Day))
            'Only add an undo point if the control is enabled.
            If ctl.PseudoEnable Then
                Integer.TryParse(ctl.Text, i)
                nl.Add(New UndoPoint(mSelMan.SelectionList(x).Day, Me.cbMonth.SelectedIndex + 1, mSelYear, ttime.Hour, ttime.Minute, mSelMan.SelectionList(x).RUID, i, ni))
                ctl.Text = mSelMan.InitialValue
                ctl.ForeColor = Drawing.Color.Red
            End If
            'Either way, set the flag and exit the loop.
            flag = True
            Exit For
        End If
    Next
    The purpose is for drag copying a value from one cell to several. Some cells could be disabled, some could be irrelevant, but if enabled and relevant, then set the text and set the color.
    Last edited by Shaggy Hiker; Oct 27th, 2024 at 01:05 PM.
    My usual boring signature: Nothing

  5. #5

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,109

    Re: Strange Coloring

    I am setting the ForeColor property on a custom control that includes a series of other controls. The ForeColor property is overridden for the custom control. If the overriding property automatically called the base property of the same name, it would make sense that all three elements would change their fore color, but only for the control in question. What I am seeing is that the forecolor changes for a variety of OTHER custom controls, but now that I think about it, there are aspects of that which I haven't investigated fully, and which I can't look at right now.
    My usual boring signature: Nothing

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width