Results 1 to 17 of 17

Thread: Transparent UC on a Transparent UC

  1. #1

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2014
    Posts
    553

    Transparent UC on a Transparent UC

    I've sort of been entrenched as of late, dealing with UserControls and seem to be facing yet another twist.

    Can one use a Transparent UserControl when building a separate Transparent UserControl?

    The first UC has been well established, works well and has many hours of use. Just recently I had the need to enhance it's abilities to the point where it would take close to a re-write so I attempted to make use of it as part of a new UC to keep from having to support duplicate code and save development time.

    Things are not going well. Using the first UC as a constituent control of the second UC appears to start off quite well. When placing it on the second UC's object in design mode, it does indeed have a transparent background as planned.

    The second UC is also configured to be a transparent control, however when it is placed on a Projects Form, it's not fully transparent. Instead it displays the rectangular area / background color of the second UC's object around the first UC.

    The second UC is larger in size then the contents of the first UC and the surrounding areas which are outside the dimensions of the first UC are correctly displayed in a transparent manner. This indicates that the second UC is configured properly allowing one to see images behind it.

    So both UC have independently proven to be capable of the required transparency, but don't like to work in tandem.

    Sort of makes me think about pointing a Video Camera at it's own screen, or looking into a mirror at another mirror, not too sure why though.

    I now question whether this is even possible, and that I am completely missing the concept behind the workings of a transparent control?


    Thanks.

  2. #2
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Transparent UC on a Transparent UC

    For the various transparent controls I've created, these properties are always set:
    ClipBehavior = False
    Windowless = True
    HasDC = False (forces use of the Paint event, using UserControl.hDC outside of Paint event generates error)

    I want to say that I tested my Alpha Image Control in another VB-created windowless UC without any problems, but can't be 100% sure. I'd have to test that again to be confident of that statement.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  3. #3

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2014
    Posts
    553

    Re: Transparent UC on a Transparent UC

    LaVolpe, I've tried those particular settings, in fact they are the values used in the 'first' of my two UC's in question. In the second UC, the one hosting the first as a constituent control, also has the same settings, but I have been playing with the 'Windowless' property setting is back and forth from True to False and back again.

    Setting it to True will somewhat correct the transparency issue, but it then acts as if the control doesn't exist, seriously Transparent! Whether the IDE is in design or run mode, it can't seem to detect its presence. In design mode the UC can't even be selected to alter any of it's properties, and in run mode it's basically the same as it appears to ignore all input from the mouse.

    I understand that mouse enter and exit events will be screwy based on the UC’s settings, but I don’t get any mouse input at all! I enabled the KeyPreview and was able to Tab over to the UC and found that it will accept and properly display keystrokes, but even with knowing it’s the active control, it still wont respond to the mouse.

    In some part I can understand not receiving the mouse input directly, but I thought I’d be able to pass along mouse events down the chain of UC’s by implementing the Mouse/Down/Up events and then raising the corresponding events in each UC, but no luck.

    I have double checked everything with debug statements, and each UC properly accepts and displays mouse events when run independently, they just don’t want to play nice together. So it appears I have a choice of either no transparency or no mouse.

  4. #4
    PowerPoster
    Join Date
    Jun 2012
    Posts
    2,388

    Re: Transparent UC on a Transparent UC

    Quote Originally Posted by stuck-n-past View Post
    Setting it to True will somewhat correct the transparency issue, but it then acts as if the control doesn't exist, seriously Transparent! Whether the IDE is in design or run mode, it can't seem to detect its presence. In design mode the UC can't even be selected to alter any of it's properties, and in run mode it's basically the same as it appears to ignore all input from the mouse.
    You need to handle the UserControl_HitTest event.

    Sample:
    Code:
    Private Sub UserControl_HitTest(X As Single, Y As Single, HitResult As Integer)
    If HitResult = vbHitResultOutside Then HitResult = vbHitResultHit
    End Sub

  5. #5

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2014
    Posts
    553

    Re: Transparent UC on a Transparent UC

    Hey Krool, I have code in the UserControl HitTest in order to process the mouse events, but currently it's not even receiving any events when coupled with the second UC.

    My original UC which is transparent makes use of the HitTest routine so that It can process mouse events and it has been working well for some time.

    And my second UC which I am trying to use to host my first UC as a constituent control properly processes mouse events using the HitTests routine when I test it separately.

    I've done all the things I normally try when running into problems, yea know booting, checking for system errors, and I just recently installed SP6 for VB.

    Hum, while typing this I thought of something. I make use of quite a few compiled objects in the form of support routines, UserControls, Class Modules and DLLs, and the UC I am using as the constituent control. All of these were built using VB before I installed SP6. I wonder if there's any chance that could be causing a problem?

    Regardless of whether there could be any impact of mixing non-SP6 with SP6 code, I'm going to take the time to go back and rebuild all of my software now that I have SP6 loaded and try things again, perhaps it will make a difference.

    thanks.
    Last edited by stuck-n-past; Sep 21st, 2017 at 02:49 PM.

  6. #6
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Transparent UC on a Transparent UC

    Try setting this in your HitTest event: HitTest = vbHitResultTransparent
    That will allow you to select it during design time. At runtime, that setting results in the mouse message moving to contained control(s) in your UC. If a contained control handles the hit test, it will raise whatever event it was coded for. If not, then your control gets the mouse message.

    It does not appear that you can stack windowless VB-created UCs inside each other and use a scenario like: a) hey if no other control wants the mouse message then b) let me handle it and if I don't want it, c) then let it through to my container. Option c never occurs because of how VB handles the HitTest event for windowless controls:
    Hit testing is performed in the following order for multiple overlapping controls:

    The topmost control in the ZOrder that returns a HitResult of 3 (vbHitResultHit) will receive mouse messages.

    If no control in the ZOrder returns a hit, the topmost control that returns a HitResult of 2 (vbHitResultClose) will receive mouse messages.

    If no control returns a hit, the topmost control that returns a HitResult of 1 (vbHitResultTransparent) will receive mouse messages.

    If no control returns a hit, the mouse messages are forwarded to the underlying container.

    The HitTest event only occurs when the Windowless property of the UserControl has been set to True and the BackStyle property has been set to Transparent. If the Windowless property is False or the BackStyle property equals Opaque, any code in the HitTest event procedure will be ignored.
    Edited: Looking at the image below. All non-white areas are 'transparent'
    -- white area is the form
    -- gray area is your outer usercontrol (transparent)
    -- blue area is a label in the outer control
    -- red area is the inner usercontrol (transparent)
    -- yellow area is something within the inner usercontrol

    If the mouse is over the top part of the yellow square, and your UC returns vbHitResultTransparent in the HitTest event, then the following occurs:
    1) Yellow area gets hit test first. If it returns zero, then
    2) Red area (inner UC) gets hit test next. If it returns zero, then
    3) Blue area (label) gets hit test. It will not fail unless it is disabled. If it is disabled, then
    4) Your outer UC gets hit test and is coded to return vbHitResultTransparent, so the form never gets a chance

    Now if you had a image control placed on the form but under your UC, and under the mouse, and your UC did not return a hit, then the image control gets a chance and unless it is disabled it will return a hit.

    Name:  Untitled.png
Views: 229
Size:  1,002 Bytes
    Last edited by LaVolpe; Sep 21st, 2017 at 04:57 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  7. #7
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,253

    Re: Transparent UC on a Transparent UC

    I've just played that through with two UserControls (named ucParent and ucChild).

    The only Prop-settings I've touched on the outside on each of these two new created UserControls in a Testproject were:
    - the first one (by adjusting the Name to ucChild and ucParent)
    - the last one (switching to Windowless=True)

    The rest of my Test was the following identical Code in bot Controls:
    Code:
    Option Explicit
      
    Private Sub UserControl_Initialize()
      UserControl.ClipBehavior = 0
      UserControl.BackStyle = 0
    End Sub
    
    Private Sub UserControl_HitTest(X As Single, Y As Single, HitResult As Integer)
      HitResult = vbHitResultHit
    End Sub
     
    Private Sub UserControl_Click()
      MsgBox Extender.Name
    End Sub
    
    Private Sub UserControl_Paint()
      CurrentX = 0: CurrentY = 0
      With Font: .Name = "Arial": .Size = 15: .Bold = True: End With
      
      Print "Hello World from " & Extender.Name
    End Sub
    In ucParent I've only enlared the FontSize to 22, otherwise the code is (as said) the same in both Controls.

    Then I've placed two ucChild-Controls in ucParent, and finally dragged a ucParent1 onto the Test-Form, producing this:


    HTH

    As for the other problems you've described... without posting any code (or at least a ScreenShot),
    we can't be of much help - the Standard-Drawing (within UserControl_Paint) in conjunction with the HitTes-Event
    seems to work as it should with fully transparent Controls, which are then clickable in RunMode and
    draggable in DesignMode (in the same way as a VB.Label with BackStyle Transparent).


    Olaf

  8. #8

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2014
    Posts
    553

    Re: Transparent UC on a Transparent UC

    Hey LaVolpe and Olaf I certainly appreciate the time you guys put in to help me with this problem.

    Unfortunately this is one of those projects where I can’t reveal the code due to confidentiality agreements. I can however explain a bit more about the project. I know it’s a far cry from code examples but it might help to some degree.

    The project deals with a processing plant’s overall ‘status’ depicted through the use of animated ‘clip-art’ type graphics combined with actual images. It follows a process from the very first step to the last and the user has the ability to select / click on a particular location to enlarge and enhance the view / display.

    The main display is made up of several UserControls, some animated, others static. Spread throughout are key points containing animated images with true values/positions of meters, gauges, valves and other equipment which when clicked loads additional UserControls overlaying the lower ones, which make up the main display.

    With this design, there are UserControls everywhere, some span the boundaries of underlying UC’s, while others exist as contained controls within other UC’s. The possible combinations are countless and can create multiple layers of UC’s.

    To complicate matters, the user has the ability to edit the layout, adding or removing images where needed, which involves creating and or deleting UC’s.

    Fun project, but getting really involved.

    I’m still in the process of rebuilding all of my code to ensure everything is compiled using SP6. As with the problem I had accessing the ParentControl Object without SP6, I’m hoping that once all my code is brought up to date, my problems will magically disappear.

    Quite eager to try LaVolpe’s suggestion of using vbHitResultTransparent, but I have to wait till my rebuild has finished.

    Thanks.
    Last edited by stuck-n-past; Sep 21st, 2017 at 10:27 PM.

  9. #9

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2014
    Posts
    553

    Re: Transparent UC on a Transparent UC

    OK well my code rebuild finished but the original problem still exists, however a new error was revealed through the process.

    When performing HitTest and MouseDown events I calculate values using the parent’s ScaleMode with an inline check using VB’s Scale function. The UC seated on the main Form successfully accesses the UserControl.Parent.ScaleMode object and all is well.

    The second UC, using the same code, fails when accessing the UserControl.Parent.ScaleMode object. As I’m using the Scale function as a parameter to a function call, when it errors out the entire code line is ignored / skipped by VB, therefore never being executed. This is the root of the problem preventing mouse events from being ‘passed / forwarded’ down the line.

    This however raises further questions. I don’t quite understand why accessing the UserControl.Parent.ScaleMode object fails in the second UC. When viewing its properties in the IDE I can see and modify it’s ScaleMode indicating that its accessible, so there shouldn’t be any reason for it failing – should there?

    Name:  SS.jpg
Views: 229
Size:  35.6 KB
    Attached Files Attached Files
    Last edited by stuck-n-past; Sep 22nd, 2017 at 08:57 AM.

  10. #10
    PowerPoster
    Join Date
    Jun 2012
    Posts
    2,388

    Re: Transparent UC on a Transparent UC

    UserControl.Parent of UC2 is the Form and for UC1 it's Parent is UC2.
    Solution would be to expose the ScaleMode of UC2.

  11. #11

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2014
    Posts
    553

    Re: Transparent UC on a Transparent UC

    Krool, I guess that's the part I don't understand, isn't it exposed automatically?

    I can see it on the property page from the IDE, just as Top, Left, Width and many others are, and not just visible but also accessible. How can one tell if a property such as 'Top' is exposed and 'ScaleMode' is not, without checking each property in code.
    Last edited by stuck-n-past; Sep 22nd, 2017 at 11:18 AM.

  12. #12
    PowerPoster
    Join Date
    Jun 2012
    Posts
    2,388

    Re: Transparent UC on a Transparent UC


  13. #13

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2014
    Posts
    553

    Re: Transparent UC on a Transparent UC

    Krool, thanks for the link, I've read through that particular page a few times as I learn about UserControls and perhaps I'm missing something but Its still not clear to me as to when a property is exposed and when its not.

    If I create a new blank UserControl and look at it's list of properties from the IDE, there are quite a few listed, but not all are exposed?

    I had thought if a property was visible in the property list then it was exposed and could be accessed programmatically. In putting together my code, I saw and changed the ScaleMode property from within the IDE and due to the fact that I had access to it, by default I assumed it was an accessible object. This indicated to me that there was no need to set up a Get and Let property for it, just as I didn't have to create ones for others such as Top and Left.

    Other than trying to access each property displayed in the IDE from code in a Form, is there anyway to know which ones are 'publicly' exposed to the user?

  14. #14
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,936

    Re: Transparent UC on a Transparent UC

    Say Stuck, let me throw in a thought here.

    It sounds like LaVolpe and Krool are zeroing in on your problem, but here's my thought.

    I have a few different UCs in my primary project. However, for one in particular, users keep coming up with ways they'd like it to work differently/better. This is always a bit of a problem for me, and I find myself contemplating three alternatives:

    1. Is it really broken? I have a strong "if-it's-not-broke-don't-fix-it" attitude. Therefore, I have to think long and hard before altering something that basically works.
    2. To "fix/enhance" it, do I do what you're considering (wrap a UC in a UC), or I just enhance the existing UC, possibly with some "Optional" arguments in the methods.
    3. And yet another option (which I've done), is to copy my existing UC and make an enhanced version of it, possibly using both versions in various places in my project.


    And truth be told, although it creates some degree of redundant code, option #3 is often the one I choose.

    So, having said all of that, why don't you just consider a brand new UC that has all the functionality in it that you want, and forget the idea of a UC in a UC?

    Good Luck,
    Elroy
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  15. #15

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2014
    Posts
    553

    Re: Transparent UC on a Transparent UC

    Hey Elroy its funny you mentioned those in your post as I was contemplating almost the exact same options when this all first started. I was worried there might not be a fix and even started laying out a new UC with the combined functionality of both.

    Hopefully though the problem will be fixed with the proper access to the correct ScaleMode.

    When VB caught the error that no ScaleMode property was available and due to the structure of my code, the ScaleMode defaulted to 'User'. From there all of my calculations were completely out of wack including those in the HitTest and MouseDown events. Things snowballed from there preventing the UC's from 'bubbling' up the mouse events properly.

    Besides correcting the ScaleMode problem, I'm also looking into how I can get a UserControl error to propagate from n-Layers deep, all of the way to the originating Form so something like this doesn't happen again.
    Last edited by stuck-n-past; Sep 22nd, 2017 at 12:50 PM.

  16. #16
    PowerPoster
    Join Date
    Jun 2012
    Posts
    2,388

    Re: Transparent UC on a Transparent UC

    There is some kind of 'Hack' possible to walk up the chain of UserControls.
    If the UserControl is already the "first in the chain" it returns the same UserControl.

    Code:
    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
    
    Public Function GetTopUserControl(ByVal UserControl As Object) As VB.UserControl
    If UserControl Is Nothing Then Exit Function
    Dim TopUserControl As VB.UserControl, TempUserControl As VB.UserControl
    CopyMemory TempUserControl, ObjPtr(UserControl), 4
    Set TopUserControl = TempUserControl
    CopyMemory TempUserControl, 0&, 4
    With TopUserControl
    If .ParentControls.Count > 0 Then
        Dim OldParentControlsType As VBRUN.ParentControlsType
        OldParentControlsType = .ParentControls.ParentControlsType
        .ParentControls.ParentControlsType = vbExtender
        If TypeOf .ParentControls(0) Is VB.VBControlExtender Then
            .ParentControls.ParentControlsType = vbNoExtender
            CopyMemory TempUserControl, ObjPtr(.ParentControls(0)), 4
            Set TopUserControl = TempUserControl
            CopyMemory TempUserControl, 0&, 4
            Dim TempParentControlsType As VBRUN.ParentControlsType
            Do
                With TopUserControl
                If .ParentControls.Count = 0 Then Exit Do
                TempParentControlsType = .ParentControls.ParentControlsType
                .ParentControls.ParentControlsType = vbExtender
                If TypeOf .ParentControls(0) Is VB.VBControlExtender Then
                    .ParentControls.ParentControlsType = vbNoExtender
                    CopyMemory TempUserControl, ObjPtr(.ParentControls(0)), 4
                    Set TopUserControl = TempUserControl
                    CopyMemory TempUserControl, 0&, 4
                    .ParentControls.ParentControlsType = TempParentControlsType
                Else
                    .ParentControls.ParentControlsType = TempParentControlsType
                    Exit Do
                End If
                End With
            Loop
        End If
        .ParentControls.ParentControlsType = OldParentControlsType
    End If
    End With
    Set GetTopUserControl = TopUserControl
    End Function
    Example usage:
    Code:
    Private Sub UserControl_Show()
    With GetTopUserControl(Me)
    Debug.Print .ScaleMode
    End With
    End Sub
    Example 2:
    Code:
    Private Sub UserControl_Show()
    Dim Form As VB.Form
    With GetTopUserControl(Me)
    Set Form = .Parent ' Parent will never be another UserControl and most likely a Form.
    Debug.Print Form.ScaleMode
    End With
    End Sub
    Last edited by Krool; Sep 22nd, 2017 at 01:27 PM.

  17. #17

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2014
    Posts
    553

    Re: Transparent UC on a Transparent UC

    Krool - thanks for code!

    I was thinking about letting each UserControl try and relay it's ScaleMode down the line to each successive one, but then wondered if you can count on the order of initialization.

    If one UC hung for a moment or a task switch let one run further then another could they startup out of order and then pass off an incorrect ScaleMode? I haven't a clue.

    So I'm thinking your code seems much safer then going the way of relaying the ScaleMode.

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