3

I have an issue with yellow objects being 'click-through' on multiple vb6 forms in my application:

Image Example

The only thing I can think of that may affect it is the following (from VBForums, which I used to make cyan elements transparent, like you can see in the image, however this should have no effect on vbYellow.

Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" ( _
            ByVal hwnd As Long, _
            ByVal nIndex As Long) As Long

Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" ( _
            ByVal hwnd As Long, _
            ByVal nIndex As Long, _
            ByVal dwNewLong As Long) As Long

Private Declare Function SetLayeredWindowAttributes Lib "user32" ( _
            ByVal hwnd As Long, _
            ByVal crKey As Long, _
            ByVal bAlpha As Byte, _
            ByVal dwFlags As Long) As Long

Private Const GWL_STYLE = (-16)
Private Const GWL_EXSTYLE = (-20)
Private Const WS_EX_LAYERED = &H80000
Private Const LWA_COLORKEY = &H1
Private Const LWA_ALPHA = &H2

Private Sub Form_Load()
Me.BackColor = vbCyan
SetWindowLong Me.hwnd, GWL_EXSTYLE, GetWindowLong(Me.hwnd, GWL_EXSTYLE) Or WS_EX_LAYERED
SetLayeredWindowAttributes Me.hwnd, vbCyan, 0&, LWA_COLORKEY
End Sub

I have tried to replace the vbYellow shape with an image of the same color. This would also have the plus of having a Click function, however ends up with the same result, not even triggering any set Click function.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
  • 1
    Yeah, this is an old issue, and it seems I've forgotten most of the details. Basically, the problem is the call to `SetLayeredWindowAttributes` with `LWA_COLORKEY`. You've set a color that should be rendered as transparent, but Windows has a bug in how it responds to hit-tests for certain colors once you've done that. This only applies when the Aero theme is enabled, meaning that DWM is used for drawing, but of course that is always the case in Windows 8 and later, which you are clearly running from the screenshot. Related Q&A here: https://stackoverflow.com/q/4448771/ – Cody Gray - on strike Jun 17 '17 at 12:36
  • Why do you need cyan to be transparent? Can you switch that to a different key color, say fuchsia, that doesn't exhibit the bug? There is really no other workaround that I can recall. – Cody Gray - on strike Jun 17 '17 at 12:40
  • 1
    @CodyGray You're right, I don't need cyan to be transparent. I just never changed it. Thanks, however, for pointing me in the right direction with 'SetLayeredWindowAttributes' and 'LWA_COLORKEY'. I'll look into it and report back. – Dulf Merrion Jun 18 '17 at 05:44
  • @CodyGray Okay. By changing the color from vbCyan, it does work, however I've used vbCyan over tons of forms with this code, and it will be a pain to change all of the colors in all of the forms. Is there any actual *fix* to this issue? Or only workarounds? – Dulf Merrion Jun 18 '17 at 06:58
  • Also, note that under windows 7 and earlier (tested on 95 too), vbCyan is click-though and see through, yellow is untouched [example](http://imgur.com/d3VAx24), yet on windows 8 and above, yellow is the click through one [example](http://imgur.com/gIjmpXY). – Dulf Merrion Jun 18 '17 at 07:20
  • That is weird that you can't repro it on Windows 7. This bug definitely *does* show up on Windows 7, but it may be related to the choice of colors. It is a strange bug, and like I said, I have forgotten most of what I figured out when I investigated it years ago, and since I didn't catalog my findings on Stack Overflow, they are basically gone forever. :-) I could go back and research this, but I distinctly remember that I did *not* find any workarounds, just an explanation of the behavior. Which is interesting in its own regard, but not helpful for the pragmatic programmer. – Cody Gray - on strike Jun 18 '17 at 10:30
  • Cyan is supposed to be click-through and see-through, of course. That's what the function call does. The strange part is that sometimes *other* colors become click-through transparent (not see-through transparent) when they shouldn't. In this case, it's yellow, which is the complementary color to cyan. I've seen this in other cases, too, like with green and red. But I don't think it's quite as simple as complementarity, and like I said before, it doesn't happen with fuchsia (for which the inverse would be green). I'm pretty sure it's related to DWM, so if you had that disabled... – Cody Gray - on strike Jun 18 '17 at 10:32
  • …because you were running Windows 7 in "Classic" mode, then that would explain why you couldn't reproduce it there. From the screenshot, you are running with the "Aero Basic" theme, and I can't recall if it was reproducible with that theme or not. Try it with the full Aero on Win 7, and you'll see it. Maybe Vista too. I don't remember if you can work around this by disabling theming for a particular window, but you really wouldn't want to, because this would make your app really ugly and inconsistent with the rest of the OS. Easier to change the transparent color. It's just tedious. – Cody Gray - on strike Jun 18 '17 at 10:34
  • @CodyGray Yeah. I see your point. I'll change to Fuchsia, as this program is going to be deployed to many different machines on many different versions of windows. If Fuchsia works everywhere, I'll just change everything to that. – Dulf Merrion Jun 18 '17 at 23:04

1 Answers1

0

I believe the problem is the fact that VB6/Win32 sometimes use different color codes. Sometimes it's just a matter of switching from #RRGGBB (RGB) to/from #BBGGRR (BGR).

A good color to choose over yellow is Magenta, #FF00FF, as this color will work regardless of whether the red and blue components are switched.

vbMagenta can then simply be used directly without issues.

Mike Weir
  • 3,094
  • 1
  • 30
  • 46